2320 lines
79 KiB
Python
2320 lines
79 KiB
Python
"""中试服务管理 CRUD(细胞产品类型/规格/价格体系/项目价格、渠道信息、体检机构)"""
|
|
from __future__ import annotations
|
|
|
|
import math
|
|
from datetime import datetime
|
|
from typing import Any, Dict, List, Optional, Tuple
|
|
|
|
from sqlalchemy import and_, func, or_
|
|
from sqlalchemy.orm import Session
|
|
|
|
from app.core.utils import generate_uuid
|
|
from app.crud.collection_protocol import urls_to_attachment_list
|
|
from app.models.models import (
|
|
BizCellProductType,
|
|
BizCellProductSpec,
|
|
BizCellProductPrice,
|
|
BizCellProductProjectSystem,
|
|
BizCellProductProjectSystemItem,
|
|
BizChannel,
|
|
BizChannelAgreement,
|
|
BizChannelAgreementProductPrice,
|
|
BizChannelInvoice,
|
|
BizChannelMailAddress,
|
|
BizCheckupInstitution,
|
|
BizCheckupInstitutionInvoice,
|
|
BizCheckupInstitutionProject,
|
|
BizCheckupInstitutionPackage,
|
|
BizCheckupInstitutionPackageItem,
|
|
)
|
|
|
|
|
|
# ────────────────────────────────────────────
|
|
# Entity 1: BizCellProductType 细胞产品类型
|
|
# ────────────────────────────────────────────
|
|
|
|
def _row_to_dict_cell_product_type(row) -> Dict[str, Any]:
|
|
return {
|
|
"id": row.id,
|
|
"productTypeCode": row.product_type_code or "",
|
|
"productTypeName": row.product_type_name or "",
|
|
"tenantNo": row.tenant_no or "",
|
|
"orderNum": row.order_num if row.order_num is not None else 0,
|
|
"remark": row.remark or "",
|
|
"createTime": row.create_time.strftime("%Y-%m-%d %H:%M:%S") if row.create_time else "",
|
|
"updateTime": row.update_time.strftime("%Y-%m-%d %H:%M:%S") if row.update_time else "",
|
|
}
|
|
|
|
|
|
def list_cell_product_types(db, *, page=1, page_size=10, keyword=None, tenant_no=None, user_info=None):
|
|
def _filtered():
|
|
q0 = db.query(BizCellProductType).filter(BizCellProductType.del_flag == 0)
|
|
if tenant_no:
|
|
q0 = q0.filter(BizCellProductType.tenant_no == tenant_no)
|
|
kw = (keyword or "").strip()
|
|
if kw:
|
|
like = f"%{kw}%"
|
|
q0 = q0.filter(
|
|
or_(
|
|
BizCellProductType.product_type_code.like(like),
|
|
BizCellProductType.product_type_name.like(like),
|
|
)
|
|
)
|
|
if user_info:
|
|
from app.core.data_scope import apply_data_scope
|
|
q0 = apply_data_scope(q0, BizCellProductType, user_info, db, tenant_no)
|
|
return q0
|
|
|
|
total = _filtered().order_by(None).with_entities(func.count(BizCellProductType.id)).scalar() or 0
|
|
page = max(1, page)
|
|
page_size = min(max(1, page_size), 100)
|
|
rows = _filtered().order_by(BizCellProductType.create_time.desc()).offset((page - 1) * page_size).limit(page_size).all()
|
|
return [_row_to_dict_cell_product_type(x) for x in rows], int(total)
|
|
|
|
|
|
def get_cell_product_type(db, type_id, tenant_no=None):
|
|
q = db.query(BizCellProductType).filter(and_(BizCellProductType.id == type_id, BizCellProductType.del_flag == 0))
|
|
if tenant_no:
|
|
q = q.filter(BizCellProductType.tenant_no == tenant_no)
|
|
return q.first()
|
|
|
|
|
|
def cell_product_type_code_exists(db, code, tenant_no, exclude_id=None):
|
|
q = db.query(BizCellProductType).filter(
|
|
and_(BizCellProductType.product_type_code == code, BizCellProductType.del_flag == 0)
|
|
)
|
|
if tenant_no:
|
|
q = q.filter(BizCellProductType.tenant_no == tenant_no)
|
|
if exclude_id:
|
|
q = q.filter(BizCellProductType.id != exclude_id)
|
|
return db.query(q.exists()).scalar()
|
|
|
|
|
|
def create_cell_product_type(db, *, product_type_code, product_type_name, tenant_no="zkxw", order_num=None, remark=None, user_id=None):
|
|
if cell_product_type_code_exists(db, product_type_code, tenant_no):
|
|
raise ValueError(f"产品类型编码 {product_type_code} 已存在")
|
|
obj = BizCellProductType(
|
|
id=generate_uuid(),
|
|
product_type_code=product_type_code,
|
|
product_type_name=product_type_name,
|
|
tenant_no=tenant_no,
|
|
order_num=order_num or 0,
|
|
remark=remark or "",
|
|
create_by=user_id,
|
|
create_time=datetime.now(),
|
|
update_by=user_id,
|
|
update_time=datetime.now(),
|
|
del_flag=0,
|
|
)
|
|
db.add(obj)
|
|
db.commit()
|
|
db.refresh(obj)
|
|
return obj
|
|
|
|
|
|
def update_cell_product_type(db, type_id, *, product_type_code=None, product_type_name=None, order_num=None, remark=None, user_id=None, tenant_no=None):
|
|
obj = get_cell_product_type(db, type_id, tenant_no)
|
|
if not obj:
|
|
raise ValueError("记录不存在")
|
|
if product_type_code is not None and product_type_code != obj.product_type_code:
|
|
if cell_product_type_code_exists(db, product_type_code, tenant_no, exclude_id=type_id):
|
|
raise ValueError(f"产品类型编码 {product_type_code} 已存在")
|
|
obj.product_type_code = product_type_code
|
|
if product_type_name is not None:
|
|
obj.product_type_name = product_type_name
|
|
if order_num is not None:
|
|
obj.order_num = order_num
|
|
if remark is not None:
|
|
obj.remark = remark
|
|
obj.update_by = user_id
|
|
obj.update_time = datetime.now()
|
|
db.add(obj)
|
|
db.commit()
|
|
db.refresh(obj)
|
|
return obj
|
|
|
|
|
|
def soft_delete_cell_product_type(db, type_id, tenant_no=None):
|
|
obj = get_cell_product_type(db, type_id, tenant_no)
|
|
if not obj:
|
|
raise ValueError("记录不存在")
|
|
obj.del_flag = 1
|
|
obj.update_time = datetime.now()
|
|
db.add(obj)
|
|
db.commit()
|
|
|
|
|
|
# ────────────────────────────────────────────
|
|
# Entity 2: BizCellProductSpec 细胞产品规格
|
|
# ────────────────────────────────────────────
|
|
|
|
def _row_to_dict_cell_product_spec(row) -> Dict[str, Any]:
|
|
return {
|
|
"id": row.id,
|
|
"specCode": row.spec_code or "",
|
|
"specName": row.spec_name or "",
|
|
"tenantNo": row.tenant_no or "",
|
|
"orderNum": row.order_num if row.order_num is not None else 0,
|
|
"remark": row.remark or "",
|
|
"createTime": row.create_time.strftime("%Y-%m-%d %H:%M:%S") if row.create_time else "",
|
|
"updateTime": row.update_time.strftime("%Y-%m-%d %H:%M:%S") if row.update_time else "",
|
|
}
|
|
|
|
|
|
def list_cell_product_specs(db, *, page=1, page_size=10, keyword=None, tenant_no=None, user_info=None):
|
|
def _filtered():
|
|
q0 = db.query(BizCellProductSpec).filter(BizCellProductSpec.del_flag == 0)
|
|
if tenant_no:
|
|
q0 = q0.filter(BizCellProductSpec.tenant_no == tenant_no)
|
|
kw = (keyword or "").strip()
|
|
if kw:
|
|
like = f"%{kw}%"
|
|
q0 = q0.filter(
|
|
or_(
|
|
BizCellProductSpec.spec_code.like(like),
|
|
BizCellProductSpec.spec_name.like(like),
|
|
)
|
|
)
|
|
if user_info:
|
|
from app.core.data_scope import apply_data_scope
|
|
q0 = apply_data_scope(q0, BizCellProductSpec, user_info, db, tenant_no)
|
|
return q0
|
|
|
|
total = _filtered().order_by(None).with_entities(func.count(BizCellProductSpec.id)).scalar() or 0
|
|
page = max(1, page)
|
|
page_size = min(max(1, page_size), 100)
|
|
rows = _filtered().order_by(BizCellProductSpec.create_time.desc()).offset((page - 1) * page_size).limit(page_size).all()
|
|
return [_row_to_dict_cell_product_spec(x) for x in rows], int(total)
|
|
|
|
|
|
def get_cell_product_spec(db, spec_id, tenant_no=None):
|
|
q = db.query(BizCellProductSpec).filter(and_(BizCellProductSpec.id == spec_id, BizCellProductSpec.del_flag == 0))
|
|
if tenant_no:
|
|
q = q.filter(BizCellProductSpec.tenant_no == tenant_no)
|
|
return q.first()
|
|
|
|
|
|
def cell_product_spec_code_exists(db, code, tenant_no, exclude_id=None):
|
|
q = db.query(BizCellProductSpec).filter(
|
|
and_(BizCellProductSpec.spec_code == code, BizCellProductSpec.del_flag == 0)
|
|
)
|
|
if tenant_no:
|
|
q = q.filter(BizCellProductSpec.tenant_no == tenant_no)
|
|
if exclude_id:
|
|
q = q.filter(BizCellProductSpec.id != exclude_id)
|
|
return db.query(q.exists()).scalar()
|
|
|
|
|
|
def create_cell_product_spec(db, *, spec_code, spec_name, tenant_no="zkxw", order_num=None, remark=None, user_id=None):
|
|
if cell_product_spec_code_exists(db, spec_code, tenant_no):
|
|
raise ValueError(f"规格编码 {spec_code} 已存在")
|
|
obj = BizCellProductSpec(
|
|
id=generate_uuid(),
|
|
spec_code=spec_code,
|
|
spec_name=spec_name,
|
|
tenant_no=tenant_no,
|
|
order_num=order_num or 0,
|
|
remark=remark or "",
|
|
create_by=user_id,
|
|
create_time=datetime.now(),
|
|
update_by=user_id,
|
|
update_time=datetime.now(),
|
|
del_flag=0,
|
|
)
|
|
db.add(obj)
|
|
db.commit()
|
|
db.refresh(obj)
|
|
return obj
|
|
|
|
|
|
def update_cell_product_spec(db, spec_id, *, spec_code=None, spec_name=None, order_num=None, remark=None, user_id=None, tenant_no=None):
|
|
obj = get_cell_product_spec(db, spec_id, tenant_no)
|
|
if not obj:
|
|
raise ValueError("记录不存在")
|
|
if spec_code is not None and spec_code != obj.spec_code:
|
|
if cell_product_spec_code_exists(db, spec_code, tenant_no, exclude_id=spec_id):
|
|
raise ValueError(f"规格编码 {spec_code} 已存在")
|
|
obj.spec_code = spec_code
|
|
if spec_name is not None:
|
|
obj.spec_name = spec_name
|
|
if order_num is not None:
|
|
obj.order_num = order_num
|
|
if remark is not None:
|
|
obj.remark = remark
|
|
obj.update_by = user_id
|
|
obj.update_time = datetime.now()
|
|
db.add(obj)
|
|
db.commit()
|
|
db.refresh(obj)
|
|
return obj
|
|
|
|
|
|
def soft_delete_cell_product_spec(db, spec_id, tenant_no=None):
|
|
obj = get_cell_product_spec(db, spec_id, tenant_no)
|
|
if not obj:
|
|
raise ValueError("记录不存在")
|
|
obj.del_flag = 1
|
|
obj.update_time = datetime.now()
|
|
db.add(obj)
|
|
db.commit()
|
|
|
|
|
|
# ────────────────────────────────────────────
|
|
# Entity 3: BizCellProductPrice 细胞产品价格
|
|
# ────────────────────────────────────────────
|
|
|
|
def _row_to_dict_cell_product_price(row) -> Dict[str, Any]:
|
|
return {
|
|
"id": row.id,
|
|
"projectName": row.project_name or "",
|
|
"projectCode": row.project_code or "",
|
|
"cellTypeCode": row.cell_type_code or "",
|
|
"cellTypeName": row.cell_type_name or "",
|
|
"specText": row.spec_text or "",
|
|
"specId": row.spec_id or "",
|
|
"cellProductTypeId": row.cell_product_type_id or "",
|
|
"unitPrice": float(row.unit_price) if row.unit_price is not None else None,
|
|
"tenantNo": row.tenant_no or "",
|
|
"orderNum": row.order_num if row.order_num is not None else 0,
|
|
"remark": row.remark or "",
|
|
"createTime": row.create_time.strftime("%Y-%m-%d %H:%M:%S") if row.create_time else "",
|
|
"updateTime": row.update_time.strftime("%Y-%m-%d %H:%M:%S") if row.update_time else "",
|
|
}
|
|
|
|
|
|
def list_cell_product_prices(db, *, page=1, page_size=10, keyword=None, tenant_no=None, cell_product_type_id=None, user_info=None):
|
|
def _filtered():
|
|
q0 = db.query(BizCellProductPrice).filter(BizCellProductPrice.del_flag == 0)
|
|
if tenant_no:
|
|
q0 = q0.filter(BizCellProductPrice.tenant_no == tenant_no)
|
|
if cell_product_type_id:
|
|
q0 = q0.filter(BizCellProductPrice.cell_product_type_id == cell_product_type_id)
|
|
kw = (keyword or "").strip()
|
|
if kw:
|
|
like = f"%{kw}%"
|
|
q0 = q0.filter(
|
|
or_(
|
|
BizCellProductPrice.project_name.like(like),
|
|
BizCellProductPrice.project_code.like(like),
|
|
BizCellProductPrice.cell_type_name.like(like),
|
|
)
|
|
)
|
|
if user_info:
|
|
from app.core.data_scope import apply_data_scope
|
|
q0 = apply_data_scope(q0, BizCellProductPrice, user_info, db, tenant_no)
|
|
return q0
|
|
|
|
total = _filtered().order_by(None).with_entities(func.count(BizCellProductPrice.id)).scalar() or 0
|
|
page = max(1, page)
|
|
page_size = min(max(1, page_size), 100)
|
|
rows = _filtered().order_by(BizCellProductPrice.create_time.desc()).offset((page - 1) * page_size).limit(page_size).all()
|
|
return [_row_to_dict_cell_product_price(x) for x in rows], int(total)
|
|
|
|
|
|
def get_cell_product_price(db, price_id, tenant_no=None):
|
|
q = db.query(BizCellProductPrice).filter(and_(BizCellProductPrice.id == price_id, BizCellProductPrice.del_flag == 0))
|
|
if tenant_no:
|
|
q = q.filter(BizCellProductPrice.tenant_no == tenant_no)
|
|
return q.first()
|
|
|
|
|
|
def cell_product_price_code_exists(db, code, tenant_no, exclude_id=None):
|
|
q = db.query(BizCellProductPrice).filter(
|
|
and_(BizCellProductPrice.project_code == code, BizCellProductPrice.del_flag == 0)
|
|
)
|
|
if tenant_no:
|
|
q = q.filter(BizCellProductPrice.tenant_no == tenant_no)
|
|
if exclude_id:
|
|
q = q.filter(BizCellProductPrice.id != exclude_id)
|
|
return db.query(q.exists()).scalar()
|
|
|
|
|
|
def create_cell_product_price(
|
|
db,
|
|
*,
|
|
project_name,
|
|
project_code,
|
|
cell_type_code,
|
|
cell_type_name,
|
|
spec_text,
|
|
spec_id,
|
|
cell_product_type_id,
|
|
unit_price,
|
|
tenant_no="zkxw",
|
|
order_num=None,
|
|
remark=None,
|
|
user_id=None,
|
|
):
|
|
if cell_product_price_code_exists(db, project_code, tenant_no):
|
|
raise ValueError(f"项目编码 {project_code} 已存在")
|
|
obj = BizCellProductPrice(
|
|
id=generate_uuid(),
|
|
project_name=project_name,
|
|
project_code=project_code,
|
|
cell_type_code=cell_type_code,
|
|
cell_type_name=cell_type_name,
|
|
spec_text=spec_text or "",
|
|
spec_id=spec_id or "",
|
|
cell_product_type_id=cell_product_type_id or "",
|
|
unit_price=unit_price,
|
|
tenant_no=tenant_no,
|
|
order_num=order_num or 0,
|
|
remark=remark or "",
|
|
create_by=user_id,
|
|
create_time=datetime.now(),
|
|
update_by=user_id,
|
|
update_time=datetime.now(),
|
|
del_flag=0,
|
|
)
|
|
db.add(obj)
|
|
db.commit()
|
|
db.refresh(obj)
|
|
return obj
|
|
|
|
|
|
def update_cell_product_price(
|
|
db,
|
|
price_id,
|
|
*,
|
|
project_name=None,
|
|
project_code=None,
|
|
cell_type_code=None,
|
|
cell_type_name=None,
|
|
spec_text=None,
|
|
spec_id=None,
|
|
cell_product_type_id=None,
|
|
unit_price=None,
|
|
order_num=None,
|
|
remark=None,
|
|
user_id=None,
|
|
tenant_no=None,
|
|
):
|
|
obj = get_cell_product_price(db, price_id, tenant_no)
|
|
if not obj:
|
|
raise ValueError("记录不存在")
|
|
if project_code is not None and project_code != obj.project_code:
|
|
if cell_product_price_code_exists(db, project_code, tenant_no, exclude_id=price_id):
|
|
raise ValueError(f"项目编码 {project_code} 已存在")
|
|
obj.project_code = project_code
|
|
if project_name is not None:
|
|
obj.project_name = project_name
|
|
if cell_type_code is not None:
|
|
obj.cell_type_code = cell_type_code
|
|
if cell_type_name is not None:
|
|
obj.cell_type_name = cell_type_name
|
|
if spec_text is not None:
|
|
obj.spec_text = spec_text
|
|
if spec_id is not None:
|
|
obj.spec_id = spec_id
|
|
if cell_product_type_id is not None:
|
|
obj.cell_product_type_id = cell_product_type_id
|
|
if unit_price is not None:
|
|
obj.unit_price = unit_price
|
|
if order_num is not None:
|
|
obj.order_num = order_num
|
|
if remark is not None:
|
|
obj.remark = remark
|
|
obj.update_by = user_id
|
|
obj.update_time = datetime.now()
|
|
db.add(obj)
|
|
db.commit()
|
|
db.refresh(obj)
|
|
return obj
|
|
|
|
|
|
def soft_delete_cell_product_price(db, price_id, tenant_no=None):
|
|
obj = get_cell_product_price(db, price_id, tenant_no)
|
|
if not obj:
|
|
raise ValueError("记录不存在")
|
|
obj.del_flag = 1
|
|
obj.update_time = datetime.now()
|
|
db.add(obj)
|
|
db.commit()
|
|
|
|
|
|
# ────────────────────────────────────────────
|
|
# Entity 4: BizCellProductProjectSystem 项目价格体系(主)
|
|
# ────────────────────────────────────────────
|
|
|
|
def _row_to_dict_project_system(row) -> Dict[str, Any]:
|
|
return {
|
|
"id": row.id,
|
|
"systemName": row.system_name or "",
|
|
"systemCode": row.system_code or "",
|
|
"status": row.status or "1",
|
|
"tenantNo": row.tenant_no or "",
|
|
"orderNum": row.order_num if row.order_num is not None else 0,
|
|
"remark": row.remark or "",
|
|
"createTime": row.create_time.strftime("%Y-%m-%d %H:%M:%S") if row.create_time else "",
|
|
"updateTime": row.update_time.strftime("%Y-%m-%d %H:%M:%S") if row.update_time else "",
|
|
}
|
|
|
|
|
|
def list_project_systems(db, *, page=1, page_size=10, keyword=None, tenant_no=None, user_info=None):
|
|
def _filtered():
|
|
q0 = db.query(BizCellProductProjectSystem).filter(BizCellProductProjectSystem.del_flag == 0)
|
|
if tenant_no:
|
|
q0 = q0.filter(BizCellProductProjectSystem.tenant_no == tenant_no)
|
|
kw = (keyword or "").strip()
|
|
if kw:
|
|
like = f"%{kw}%"
|
|
q0 = q0.filter(
|
|
or_(
|
|
BizCellProductProjectSystem.system_code.like(like),
|
|
BizCellProductProjectSystem.system_name.like(like),
|
|
)
|
|
)
|
|
if user_info:
|
|
from app.core.data_scope import apply_data_scope
|
|
q0 = apply_data_scope(q0, BizCellProductProjectSystem, user_info, db, tenant_no)
|
|
return q0
|
|
|
|
total = _filtered().order_by(None).with_entities(func.count(BizCellProductProjectSystem.id)).scalar() or 0
|
|
page = max(1, page)
|
|
page_size = min(max(1, page_size), 100)
|
|
rows = _filtered().order_by(BizCellProductProjectSystem.create_time.desc()).offset((page - 1) * page_size).limit(page_size).all()
|
|
return [_row_to_dict_project_system(x) for x in rows], int(total)
|
|
|
|
|
|
def get_project_system(db, system_id, tenant_no=None):
|
|
q = db.query(BizCellProductProjectSystem).filter(
|
|
and_(BizCellProductProjectSystem.id == system_id, BizCellProductProjectSystem.del_flag == 0)
|
|
)
|
|
if tenant_no:
|
|
q = q.filter(BizCellProductProjectSystem.tenant_no == tenant_no)
|
|
return q.first()
|
|
|
|
|
|
def project_system_code_exists(db, code, tenant_no, exclude_id=None):
|
|
q = db.query(BizCellProductProjectSystem).filter(
|
|
and_(BizCellProductProjectSystem.system_code == code, BizCellProductProjectSystem.del_flag == 0)
|
|
)
|
|
if tenant_no:
|
|
q = q.filter(BizCellProductProjectSystem.tenant_no == tenant_no)
|
|
if exclude_id:
|
|
q = q.filter(BizCellProductProjectSystem.id != exclude_id)
|
|
return db.query(q.exists()).scalar()
|
|
|
|
|
|
def create_project_system(db, *, system_name, system_code, status="1", tenant_no="zkxw", order_num=None, remark=None, user_id=None):
|
|
if project_system_code_exists(db, system_code, tenant_no):
|
|
raise ValueError(f"体系编码 {system_code} 已存在")
|
|
obj = BizCellProductProjectSystem(
|
|
id=generate_uuid(),
|
|
system_name=system_name,
|
|
system_code=system_code,
|
|
status=status or "1",
|
|
tenant_no=tenant_no,
|
|
order_num=order_num or 0,
|
|
remark=remark or "",
|
|
create_by=user_id,
|
|
create_time=datetime.now(),
|
|
update_by=user_id,
|
|
update_time=datetime.now(),
|
|
del_flag=0,
|
|
)
|
|
db.add(obj)
|
|
db.commit()
|
|
db.refresh(obj)
|
|
return obj
|
|
|
|
|
|
def update_project_system(db, system_id, *, system_name=None, system_code=None, status=None, order_num=None, remark=None, user_id=None, tenant_no=None):
|
|
obj = get_project_system(db, system_id, tenant_no)
|
|
if not obj:
|
|
raise ValueError("记录不存在")
|
|
if system_code is not None and system_code != obj.system_code:
|
|
if project_system_code_exists(db, system_code, tenant_no, exclude_id=system_id):
|
|
raise ValueError(f"体系编码 {system_code} 已存在")
|
|
obj.system_code = system_code
|
|
if system_name is not None:
|
|
obj.system_name = system_name
|
|
if status is not None:
|
|
obj.status = status
|
|
if order_num is not None:
|
|
obj.order_num = order_num
|
|
if remark is not None:
|
|
obj.remark = remark
|
|
obj.update_by = user_id
|
|
obj.update_time = datetime.now()
|
|
db.add(obj)
|
|
db.commit()
|
|
db.refresh(obj)
|
|
return obj
|
|
|
|
|
|
def soft_delete_project_system(db, system_id, tenant_no=None):
|
|
obj = get_project_system(db, system_id, tenant_no)
|
|
if not obj:
|
|
raise ValueError("记录不存在")
|
|
obj.del_flag = 1
|
|
obj.update_time = datetime.now()
|
|
db.add(obj)
|
|
db.commit()
|
|
|
|
|
|
# ────────────────────────────────────────────
|
|
# Entity 5: BizCellProductProjectSystemItem 项目价格体系明细
|
|
# ────────────────────────────────────────────
|
|
|
|
def _row_to_dict_project_system_item(row) -> Dict[str, Any]:
|
|
return {
|
|
"id": row.id,
|
|
"projectSystemId": row.project_system_id or "",
|
|
"sourcePriceId": row.source_price_id or "",
|
|
"projectName": row.project_name or "",
|
|
"projectCode": row.project_code or "",
|
|
"cellTypeCode": row.cell_type_code or "",
|
|
"cellTypeName": row.cell_type_name or "",
|
|
"specText": row.spec_text or "",
|
|
"specId": row.spec_id or "",
|
|
"cellProductTypeId": row.cell_product_type_id or "",
|
|
"unitPrice": float(row.unit_price) if row.unit_price is not None else None,
|
|
"tenantNo": row.tenant_no or "",
|
|
"orderNum": row.order_num if row.order_num is not None else 0,
|
|
"remark": row.remark or "",
|
|
"createTime": row.create_time.strftime("%Y-%m-%d %H:%M:%S") if row.create_time else "",
|
|
"updateTime": row.update_time.strftime("%Y-%m-%d %H:%M:%S") if row.update_time else "",
|
|
}
|
|
|
|
|
|
def list_project_system_items(db, project_system_id, tenant_no=None, user_info=None):
|
|
q = db.query(BizCellProductProjectSystemItem).filter(
|
|
and_(
|
|
BizCellProductProjectSystemItem.project_system_id == project_system_id,
|
|
BizCellProductProjectSystemItem.del_flag == 0,
|
|
)
|
|
)
|
|
if tenant_no:
|
|
q = q.filter(BizCellProductProjectSystemItem.tenant_no == tenant_no)
|
|
if user_info:
|
|
from app.core.data_scope import apply_data_scope
|
|
q = apply_data_scope(q, BizCellProductProjectSystemItem, user_info, db, tenant_no)
|
|
rows = q.order_by(
|
|
BizCellProductProjectSystemItem.order_num.asc(),
|
|
BizCellProductProjectSystemItem.create_time.asc(),
|
|
).all()
|
|
return [_row_to_dict_project_system_item(x) for x in rows]
|
|
|
|
|
|
def create_project_system_item(
|
|
db,
|
|
*,
|
|
project_system_id,
|
|
source_price_id="",
|
|
project_name,
|
|
project_code,
|
|
cell_type_code,
|
|
cell_type_name,
|
|
spec_text="",
|
|
spec_id="",
|
|
cell_product_type_id="",
|
|
unit_price,
|
|
tenant_no="zkxw",
|
|
order_num=None,
|
|
remark=None,
|
|
user_id=None,
|
|
):
|
|
obj = BizCellProductProjectSystemItem(
|
|
id=generate_uuid(),
|
|
project_system_id=project_system_id,
|
|
source_price_id=source_price_id,
|
|
project_name=project_name,
|
|
project_code=project_code,
|
|
cell_type_code=cell_type_code,
|
|
cell_type_name=cell_type_name,
|
|
spec_text=spec_text or "",
|
|
spec_id=spec_id or "",
|
|
cell_product_type_id=cell_product_type_id or "",
|
|
unit_price=unit_price,
|
|
tenant_no=tenant_no,
|
|
order_num=order_num or 0,
|
|
remark=remark or "",
|
|
create_by=user_id,
|
|
create_time=datetime.now(),
|
|
update_by=user_id,
|
|
update_time=datetime.now(),
|
|
del_flag=0,
|
|
)
|
|
db.add(obj)
|
|
db.commit()
|
|
db.refresh(obj)
|
|
return obj
|
|
|
|
|
|
def update_project_system_item(
|
|
db,
|
|
item_id,
|
|
*,
|
|
source_price_id=None,
|
|
project_name=None,
|
|
project_code=None,
|
|
cell_type_code=None,
|
|
cell_type_name=None,
|
|
spec_text=None,
|
|
spec_id=None,
|
|
cell_product_type_id=None,
|
|
unit_price=None,
|
|
order_num=None,
|
|
remark=None,
|
|
user_id=None,
|
|
tenant_no=None,
|
|
):
|
|
q = db.query(BizCellProductProjectSystemItem).filter(
|
|
and_(BizCellProductProjectSystemItem.id == item_id, BizCellProductProjectSystemItem.del_flag == 0)
|
|
)
|
|
if tenant_no:
|
|
q = q.filter(BizCellProductProjectSystemItem.tenant_no == tenant_no)
|
|
obj = q.first()
|
|
if not obj:
|
|
raise ValueError("记录不存在")
|
|
if source_price_id is not None:
|
|
obj.source_price_id = source_price_id
|
|
if project_name is not None:
|
|
obj.project_name = project_name
|
|
if project_code is not None:
|
|
obj.project_code = project_code
|
|
if cell_type_code is not None:
|
|
obj.cell_type_code = cell_type_code
|
|
if cell_type_name is not None:
|
|
obj.cell_type_name = cell_type_name
|
|
if spec_text is not None:
|
|
obj.spec_text = spec_text
|
|
if spec_id is not None:
|
|
obj.spec_id = spec_id
|
|
if cell_product_type_id is not None:
|
|
obj.cell_product_type_id = cell_product_type_id
|
|
if unit_price is not None:
|
|
obj.unit_price = unit_price
|
|
if order_num is not None:
|
|
obj.order_num = order_num
|
|
if remark is not None:
|
|
obj.remark = remark
|
|
obj.update_by = user_id
|
|
obj.update_time = datetime.now()
|
|
db.add(obj)
|
|
db.commit()
|
|
db.refresh(obj)
|
|
return obj
|
|
|
|
|
|
def soft_delete_project_system_item(db, item_id, tenant_no=None):
|
|
q = db.query(BizCellProductProjectSystemItem).filter(
|
|
and_(BizCellProductProjectSystemItem.id == item_id, BizCellProductProjectSystemItem.del_flag == 0)
|
|
)
|
|
if tenant_no:
|
|
q = q.filter(BizCellProductProjectSystemItem.tenant_no == tenant_no)
|
|
obj = q.first()
|
|
if not obj:
|
|
raise ValueError("记录不存在")
|
|
obj.del_flag = 1
|
|
obj.update_time = datetime.now()
|
|
db.add(obj)
|
|
db.commit()
|
|
|
|
|
|
# ────────────────────────────────────────────
|
|
# Entity 6: BizChannel 渠道信息
|
|
# ────────────────────────────────────────────
|
|
|
|
def _row_to_dict_channel(
|
|
row,
|
|
db: Optional[Session] = None,
|
|
tenant_no: Optional[str] = None,
|
|
) -> Dict[str, Any]:
|
|
tn = tenant_no or row.tenant_no
|
|
return {
|
|
"id": row.id,
|
|
"channelName": row.channel_name or "",
|
|
"creditCode": row.credit_code or "",
|
|
"channelType": row.channel_type or "",
|
|
"contactName": row.contact_name or "",
|
|
"contactPhone": row.contact_phone or "",
|
|
"contactEmail": row.contact_email or "",
|
|
"protocolAttachments": row.protocol_attachments or "",
|
|
"attachmentFiles": urls_to_attachment_list(row.protocol_attachments, db, tn) if db else [],
|
|
"tenantNo": row.tenant_no or "",
|
|
"orderNum": row.order_num if row.order_num is not None else 0,
|
|
"remark": row.remark or "",
|
|
"createTime": row.create_time.strftime("%Y-%m-%d %H:%M:%S") if row.create_time else "",
|
|
"updateTime": row.update_time.strftime("%Y-%m-%d %H:%M:%S") if row.update_time else "",
|
|
}
|
|
|
|
|
|
def list_channels(db, *, page=1, page_size=10, keyword=None, tenant_no=None, user_info=None):
|
|
def _filtered():
|
|
q0 = db.query(BizChannel).filter(BizChannel.del_flag == 0)
|
|
if tenant_no:
|
|
q0 = q0.filter(BizChannel.tenant_no == tenant_no)
|
|
kw = (keyword or "").strip()
|
|
if kw:
|
|
like = f"%{kw}%"
|
|
q0 = q0.filter(
|
|
or_(
|
|
BizChannel.channel_name.like(like),
|
|
BizChannel.credit_code.like(like),
|
|
BizChannel.contact_name.like(like),
|
|
)
|
|
)
|
|
if user_info:
|
|
from app.core.data_scope import apply_data_scope
|
|
q0 = apply_data_scope(q0, BizChannel, user_info, db, tenant_no)
|
|
return q0
|
|
|
|
total = _filtered().order_by(None).with_entities(func.count(BizChannel.id)).scalar() or 0
|
|
page = max(1, page)
|
|
page_size = min(max(1, page_size), 100)
|
|
rows = _filtered().order_by(BizChannel.create_time.desc()).offset((page - 1) * page_size).limit(page_size).all()
|
|
return [_row_to_dict_channel(x, db, tenant_no) for x in rows], int(total)
|
|
|
|
|
|
def get_channel(db, channel_id, tenant_no=None):
|
|
q = db.query(BizChannel).filter(and_(BizChannel.id == channel_id, BizChannel.del_flag == 0))
|
|
if tenant_no:
|
|
q = q.filter(BizChannel.tenant_no == tenant_no)
|
|
return q.first()
|
|
|
|
|
|
def create_channel(
|
|
db,
|
|
*,
|
|
channel_name,
|
|
credit_code=None,
|
|
channel_type=None,
|
|
contact_name=None,
|
|
contact_phone=None,
|
|
contact_email=None,
|
|
protocol_attachments=None,
|
|
tenant_no="zkxw",
|
|
order_num=None,
|
|
remark=None,
|
|
user_id=None,
|
|
):
|
|
obj = BizChannel(
|
|
id=generate_uuid(),
|
|
channel_name=channel_name,
|
|
credit_code=credit_code or "",
|
|
channel_type=channel_type or "",
|
|
contact_name=contact_name or "",
|
|
contact_phone=contact_phone or "",
|
|
contact_email=contact_email or "",
|
|
protocol_attachments=protocol_attachments or "",
|
|
tenant_no=tenant_no,
|
|
order_num=order_num or 0,
|
|
remark=remark or "",
|
|
create_by=user_id,
|
|
create_time=datetime.now(),
|
|
update_by=user_id,
|
|
update_time=datetime.now(),
|
|
del_flag=0,
|
|
)
|
|
db.add(obj)
|
|
db.commit()
|
|
db.refresh(obj)
|
|
return obj
|
|
|
|
|
|
def update_channel(
|
|
db,
|
|
channel_id,
|
|
*,
|
|
channel_name=None,
|
|
credit_code=None,
|
|
channel_type=None,
|
|
contact_name=None,
|
|
contact_phone=None,
|
|
contact_email=None,
|
|
protocol_attachments=None,
|
|
order_num=None,
|
|
remark=None,
|
|
user_id=None,
|
|
tenant_no=None,
|
|
):
|
|
obj = get_channel(db, channel_id, tenant_no)
|
|
if not obj:
|
|
raise ValueError("记录不存在")
|
|
if channel_name is not None:
|
|
obj.channel_name = channel_name
|
|
if credit_code is not None:
|
|
obj.credit_code = credit_code
|
|
if channel_type is not None:
|
|
obj.channel_type = channel_type
|
|
if contact_name is not None:
|
|
obj.contact_name = contact_name
|
|
if contact_phone is not None:
|
|
obj.contact_phone = contact_phone
|
|
if contact_email is not None:
|
|
obj.contact_email = contact_email
|
|
if protocol_attachments is not None:
|
|
obj.protocol_attachments = protocol_attachments
|
|
if order_num is not None:
|
|
obj.order_num = order_num
|
|
if remark is not None:
|
|
obj.remark = remark
|
|
obj.update_by = user_id
|
|
obj.update_time = datetime.now()
|
|
db.add(obj)
|
|
db.commit()
|
|
db.refresh(obj)
|
|
return obj
|
|
|
|
|
|
def soft_delete_channel(db, channel_id, tenant_no=None):
|
|
obj = get_channel(db, channel_id, tenant_no)
|
|
if not obj:
|
|
raise ValueError("记录不存在")
|
|
obj.del_flag = 1
|
|
obj.update_time = datetime.now()
|
|
db.add(obj)
|
|
db.commit()
|
|
|
|
|
|
# ────────────────────────────────────────────
|
|
# Entity 7: BizChannelInvoice 渠道开票信息
|
|
# ────────────────────────────────────────────
|
|
|
|
def _row_to_dict_channel_invoice(row) -> Dict[str, Any]:
|
|
return {
|
|
"id": row.id,
|
|
"channelId": row.channel_id or "",
|
|
"companyName": row.company_name or "",
|
|
"taxNo": row.tax_no or "",
|
|
"companyAddress": row.company_address or "",
|
|
"companyPhone": row.company_phone or "",
|
|
"bankName": row.bank_name or "",
|
|
"bankAccount": row.bank_account or "",
|
|
"tenantNo": row.tenant_no or "",
|
|
"orderNum": row.order_num if row.order_num is not None else 0,
|
|
"remark": row.remark or "",
|
|
"createTime": row.create_time.strftime("%Y-%m-%d %H:%M:%S") if row.create_time else "",
|
|
"updateTime": row.update_time.strftime("%Y-%m-%d %H:%M:%S") if row.update_time else "",
|
|
}
|
|
|
|
|
|
def list_channel_invoices(db, channel_id, tenant_no=None, user_info=None):
|
|
q = db.query(BizChannelInvoice).filter(
|
|
and_(
|
|
BizChannelInvoice.channel_id == channel_id,
|
|
BizChannelInvoice.del_flag == 0,
|
|
)
|
|
)
|
|
if tenant_no:
|
|
q = q.filter(BizChannelInvoice.tenant_no == tenant_no)
|
|
if user_info:
|
|
from app.core.data_scope import apply_data_scope
|
|
q = apply_data_scope(q, BizChannelInvoice, user_info, db, tenant_no)
|
|
rows = q.order_by(BizChannelInvoice.create_time.desc()).all()
|
|
return [_row_to_dict_channel_invoice(x) for x in rows]
|
|
|
|
|
|
def create_channel_invoice(
|
|
db,
|
|
*,
|
|
channel_id,
|
|
company_name,
|
|
tax_no=None,
|
|
company_address=None,
|
|
company_phone=None,
|
|
bank_name=None,
|
|
bank_account=None,
|
|
tenant_no="zkxw",
|
|
order_num=None,
|
|
remark=None,
|
|
user_id=None,
|
|
):
|
|
obj = BizChannelInvoice(
|
|
id=generate_uuid(),
|
|
channel_id=channel_id,
|
|
company_name=company_name,
|
|
tax_no=tax_no or "",
|
|
company_address=company_address or "",
|
|
company_phone=company_phone or "",
|
|
bank_name=bank_name or "",
|
|
bank_account=bank_account or "",
|
|
tenant_no=tenant_no,
|
|
order_num=order_num or 0,
|
|
remark=remark or "",
|
|
create_by=user_id,
|
|
create_time=datetime.now(),
|
|
update_by=user_id,
|
|
update_time=datetime.now(),
|
|
del_flag=0,
|
|
)
|
|
db.add(obj)
|
|
db.commit()
|
|
db.refresh(obj)
|
|
return obj
|
|
|
|
|
|
def update_channel_invoice(
|
|
db,
|
|
invoice_id,
|
|
*,
|
|
company_name=None,
|
|
tax_no=None,
|
|
company_address=None,
|
|
company_phone=None,
|
|
bank_name=None,
|
|
bank_account=None,
|
|
order_num=None,
|
|
remark=None,
|
|
user_id=None,
|
|
tenant_no=None,
|
|
):
|
|
q = db.query(BizChannelInvoice).filter(
|
|
and_(BizChannelInvoice.id == invoice_id, BizChannelInvoice.del_flag == 0)
|
|
)
|
|
if tenant_no:
|
|
q = q.filter(BizChannelInvoice.tenant_no == tenant_no)
|
|
obj = q.first()
|
|
if not obj:
|
|
raise ValueError("记录不存在")
|
|
if company_name is not None:
|
|
obj.company_name = company_name
|
|
if tax_no is not None:
|
|
obj.tax_no = tax_no
|
|
if company_address is not None:
|
|
obj.company_address = company_address
|
|
if company_phone is not None:
|
|
obj.company_phone = company_phone
|
|
if bank_name is not None:
|
|
obj.bank_name = bank_name
|
|
if bank_account is not None:
|
|
obj.bank_account = bank_account
|
|
if order_num is not None:
|
|
obj.order_num = order_num
|
|
if remark is not None:
|
|
obj.remark = remark
|
|
obj.update_by = user_id
|
|
obj.update_time = datetime.now()
|
|
db.add(obj)
|
|
db.commit()
|
|
db.refresh(obj)
|
|
return obj
|
|
|
|
|
|
def soft_delete_channel_invoice(db, invoice_id, tenant_no=None):
|
|
q = db.query(BizChannelInvoice).filter(
|
|
and_(BizChannelInvoice.id == invoice_id, BizChannelInvoice.del_flag == 0)
|
|
)
|
|
if tenant_no:
|
|
q = q.filter(BizChannelInvoice.tenant_no == tenant_no)
|
|
obj = q.first()
|
|
if not obj:
|
|
raise ValueError("记录不存在")
|
|
obj.del_flag = 1
|
|
obj.update_time = datetime.now()
|
|
db.add(obj)
|
|
db.commit()
|
|
|
|
|
|
# ────────────────────────────────────────────
|
|
# Entity 8: BizChannelMailAddress 渠道邮寄地址
|
|
# ────────────────────────────────────────────
|
|
|
|
def _row_to_dict_channel_mail_address(row) -> Dict[str, Any]:
|
|
return {
|
|
"id": row.id,
|
|
"channelId": row.channel_id or "",
|
|
"mailAddress": row.mail_address or "",
|
|
"mailContact": row.mail_contact or "",
|
|
"mailPhone": row.mail_phone or "",
|
|
"tenantNo": row.tenant_no or "",
|
|
"orderNum": row.order_num if row.order_num is not None else 0,
|
|
"remark": row.remark or "",
|
|
"createTime": row.create_time.strftime("%Y-%m-%d %H:%M:%S") if row.create_time else "",
|
|
"updateTime": row.update_time.strftime("%Y-%m-%d %H:%M:%S") if row.update_time else "",
|
|
}
|
|
|
|
|
|
def list_channel_mail_addresses(db, channel_id, tenant_no=None, user_info=None):
|
|
q = db.query(BizChannelMailAddress).filter(
|
|
and_(
|
|
BizChannelMailAddress.channel_id == channel_id,
|
|
BizChannelMailAddress.del_flag == 0,
|
|
)
|
|
)
|
|
if tenant_no:
|
|
q = q.filter(BizChannelMailAddress.tenant_no == tenant_no)
|
|
if user_info:
|
|
from app.core.data_scope import apply_data_scope
|
|
q = apply_data_scope(q, BizChannelMailAddress, user_info, db, tenant_no)
|
|
rows = q.order_by(BizChannelMailAddress.create_time.desc()).all()
|
|
return [_row_to_dict_channel_mail_address(x) for x in rows]
|
|
|
|
|
|
def create_channel_mail_address(
|
|
db,
|
|
*,
|
|
channel_id,
|
|
mail_address,
|
|
mail_contact=None,
|
|
mail_phone=None,
|
|
tenant_no="zkxw",
|
|
order_num=None,
|
|
remark=None,
|
|
user_id=None,
|
|
):
|
|
obj = BizChannelMailAddress(
|
|
id=generate_uuid(),
|
|
channel_id=channel_id,
|
|
mail_address=mail_address,
|
|
mail_contact=mail_contact or "",
|
|
mail_phone=mail_phone or "",
|
|
tenant_no=tenant_no,
|
|
order_num=order_num or 0,
|
|
remark=remark or "",
|
|
create_by=user_id,
|
|
create_time=datetime.now(),
|
|
update_by=user_id,
|
|
update_time=datetime.now(),
|
|
del_flag=0,
|
|
)
|
|
db.add(obj)
|
|
db.commit()
|
|
db.refresh(obj)
|
|
return obj
|
|
|
|
|
|
def update_channel_mail_address(
|
|
db,
|
|
address_id,
|
|
*,
|
|
mail_address=None,
|
|
mail_contact=None,
|
|
mail_phone=None,
|
|
order_num=None,
|
|
remark=None,
|
|
user_id=None,
|
|
tenant_no=None,
|
|
):
|
|
q = db.query(BizChannelMailAddress).filter(
|
|
and_(BizChannelMailAddress.id == address_id, BizChannelMailAddress.del_flag == 0)
|
|
)
|
|
if tenant_no:
|
|
q = q.filter(BizChannelMailAddress.tenant_no == tenant_no)
|
|
obj = q.first()
|
|
if not obj:
|
|
raise ValueError("记录不存在")
|
|
if mail_address is not None:
|
|
obj.mail_address = mail_address
|
|
if mail_contact is not None:
|
|
obj.mail_contact = mail_contact
|
|
if mail_phone is not None:
|
|
obj.mail_phone = mail_phone
|
|
if order_num is not None:
|
|
obj.order_num = order_num
|
|
if remark is not None:
|
|
obj.remark = remark
|
|
obj.update_by = user_id
|
|
obj.update_time = datetime.now()
|
|
db.add(obj)
|
|
db.commit()
|
|
db.refresh(obj)
|
|
return obj
|
|
|
|
|
|
def soft_delete_channel_mail_address(db, address_id, tenant_no=None):
|
|
q = db.query(BizChannelMailAddress).filter(
|
|
and_(BizChannelMailAddress.id == address_id, BizChannelMailAddress.del_flag == 0)
|
|
)
|
|
if tenant_no:
|
|
q = q.filter(BizChannelMailAddress.tenant_no == tenant_no)
|
|
obj = q.first()
|
|
if not obj:
|
|
raise ValueError("记录不存在")
|
|
obj.del_flag = 1
|
|
obj.update_time = datetime.now()
|
|
db.add(obj)
|
|
db.commit()
|
|
|
|
|
|
# ────────────────────────────────────────────
|
|
# Entity 9: BizChannelAgreement 渠道协议
|
|
# ────────────────────────────────────────────
|
|
|
|
def _row_to_dict_channel_agreement(row) -> Dict[str, Any]:
|
|
def _fmt_date(v):
|
|
"""CHAR(8) YYYYMMDD → YYYY-MM-DD"""
|
|
if not v or len(v) != 8:
|
|
return v or ""
|
|
return f"{v[:4]}-{v[4:6]}-{v[6:8]}"
|
|
|
|
return {
|
|
"id": row.id,
|
|
"channelId": row.channel_id or "",
|
|
"agreementType": row.agreement_type or "",
|
|
"businessType": row.business_type or "",
|
|
"settleMode": row.settle_mode or "",
|
|
"creditLimitAmount": float(row.credit_limit_amount) if row.credit_limit_amount is not None else None,
|
|
"effectiveDate": _fmt_date(row.effective_date),
|
|
"expireDate": _fmt_date(row.expire_date),
|
|
"agreementStatus": row.agreement_status or "",
|
|
"tenantNo": row.tenant_no or "",
|
|
"orderNum": row.order_num if row.order_num is not None else 0,
|
|
"remark": row.remark or "",
|
|
"createTime": row.create_time.strftime("%Y-%m-%d %H:%M:%S") if row.create_time else "",
|
|
"updateTime": row.update_time.strftime("%Y-%m-%d %H:%M:%S") if row.update_time else "",
|
|
}
|
|
|
|
|
|
def list_channel_agreements(db, channel_id, tenant_no=None, user_info=None):
|
|
q = db.query(BizChannelAgreement).filter(
|
|
and_(
|
|
BizChannelAgreement.channel_id == channel_id,
|
|
BizChannelAgreement.del_flag == 0,
|
|
)
|
|
)
|
|
if tenant_no:
|
|
q = q.filter(BizChannelAgreement.tenant_no == tenant_no)
|
|
if user_info:
|
|
from app.core.data_scope import apply_data_scope
|
|
q = apply_data_scope(q, BizChannelAgreement, user_info, db, tenant_no)
|
|
rows = q.order_by(BizChannelAgreement.create_time.desc()).all()
|
|
return [_row_to_dict_channel_agreement(x) for x in rows]
|
|
|
|
|
|
def create_channel_agreement(
|
|
db,
|
|
*,
|
|
channel_id,
|
|
agreement_type,
|
|
business_type=None,
|
|
settle_mode=None,
|
|
credit_limit_amount=None,
|
|
effective_date=None,
|
|
expire_date=None,
|
|
agreement_status="dsx",
|
|
tenant_no="zkxw",
|
|
order_num=None,
|
|
remark=None,
|
|
user_id=None,
|
|
):
|
|
_ed = (effective_date or "").replace("-", "") if effective_date else ""
|
|
_xd = (expire_date or "").replace("-", "") if expire_date else ""
|
|
obj = BizChannelAgreement(
|
|
id=generate_uuid(),
|
|
channel_id=channel_id,
|
|
agreement_type=agreement_type,
|
|
business_type=business_type or "",
|
|
settle_mode=settle_mode or "",
|
|
credit_limit_amount=credit_limit_amount,
|
|
effective_date=_ed,
|
|
expire_date=_xd,
|
|
agreement_status=agreement_status or "dsx",
|
|
tenant_no=tenant_no,
|
|
order_num=order_num or 0,
|
|
remark=remark or "",
|
|
create_by=user_id,
|
|
create_time=datetime.now(),
|
|
update_by=user_id,
|
|
update_time=datetime.now(),
|
|
del_flag=0,
|
|
)
|
|
db.add(obj)
|
|
db.commit()
|
|
db.refresh(obj)
|
|
return obj
|
|
|
|
|
|
def update_channel_agreement(
|
|
db,
|
|
agreement_id,
|
|
*,
|
|
agreement_type=None,
|
|
business_type=None,
|
|
settle_mode=None,
|
|
credit_limit_amount=None,
|
|
effective_date=None,
|
|
expire_date=None,
|
|
order_num=None,
|
|
remark=None,
|
|
user_id=None,
|
|
tenant_no=None,
|
|
):
|
|
q = db.query(BizChannelAgreement).filter(
|
|
and_(BizChannelAgreement.id == agreement_id, BizChannelAgreement.del_flag == 0)
|
|
)
|
|
if tenant_no:
|
|
q = q.filter(BizChannelAgreement.tenant_no == tenant_no)
|
|
obj = q.first()
|
|
if not obj:
|
|
raise ValueError("记录不存在")
|
|
if agreement_type is not None:
|
|
obj.agreement_type = agreement_type
|
|
if business_type is not None:
|
|
obj.business_type = business_type
|
|
if settle_mode is not None:
|
|
obj.settle_mode = settle_mode
|
|
if credit_limit_amount is not None:
|
|
obj.credit_limit_amount = credit_limit_amount
|
|
if effective_date is not None:
|
|
obj.effective_date = effective_date.replace("-", "") if effective_date else ""
|
|
if expire_date is not None:
|
|
obj.expire_date = expire_date.replace("-", "") if expire_date else ""
|
|
if order_num is not None:
|
|
obj.order_num = order_num
|
|
if remark is not None:
|
|
obj.remark = remark
|
|
obj.update_by = user_id
|
|
obj.update_time = datetime.now()
|
|
db.add(obj)
|
|
db.commit()
|
|
db.refresh(obj)
|
|
return obj
|
|
|
|
|
|
def soft_delete_channel_agreement(db, agreement_id, tenant_no=None):
|
|
q = db.query(BizChannelAgreement).filter(
|
|
and_(BizChannelAgreement.id == agreement_id, BizChannelAgreement.del_flag == 0)
|
|
)
|
|
if tenant_no:
|
|
q = q.filter(BizChannelAgreement.tenant_no == tenant_no)
|
|
obj = q.first()
|
|
if not obj:
|
|
raise ValueError("记录不存在")
|
|
obj.del_flag = 1
|
|
obj.update_time = datetime.now()
|
|
db.add(obj)
|
|
db.commit()
|
|
|
|
|
|
def activate_channel_agreement(db, agreement_id, tenant_no=None, user_id=None):
|
|
"""生效协议:仅待生效(dsx)可变为生效中(sxz)"""
|
|
q = db.query(BizChannelAgreement).filter(
|
|
and_(BizChannelAgreement.id == agreement_id, BizChannelAgreement.del_flag == 0)
|
|
)
|
|
if tenant_no:
|
|
q = q.filter(BizChannelAgreement.tenant_no == tenant_no)
|
|
obj = q.first()
|
|
if not obj:
|
|
raise ValueError("记录不存在")
|
|
if (obj.agreement_status or "").strip() != "dsx":
|
|
raise ValueError("仅待生效状态的协议可执行生效操作")
|
|
obj.agreement_status = "sxz"
|
|
obj.update_by = user_id
|
|
obj.update_time = datetime.now()
|
|
db.add(obj)
|
|
db.commit()
|
|
db.refresh(obj)
|
|
return obj
|
|
|
|
|
|
def void_channel_agreement(db, agreement_id, tenant_no=None, user_id=None):
|
|
"""作废协议:设置 agreement_status='yzf'"""
|
|
q = db.query(BizChannelAgreement).filter(
|
|
and_(BizChannelAgreement.id == agreement_id, BizChannelAgreement.del_flag == 0)
|
|
)
|
|
if tenant_no:
|
|
q = q.filter(BizChannelAgreement.tenant_no == tenant_no)
|
|
obj = q.first()
|
|
if not obj:
|
|
raise ValueError("记录不存在")
|
|
obj.agreement_status = "yzf"
|
|
obj.update_by = user_id
|
|
obj.update_time = datetime.now()
|
|
db.add(obj)
|
|
db.commit()
|
|
db.refresh(obj)
|
|
return obj
|
|
|
|
|
|
# ────────────────────────────────────────────
|
|
# Entity 10: BizChannelAgreementProductPrice 渠道协议产品价格
|
|
# ────────────────────────────────────────────
|
|
|
|
def _row_to_dict_channel_agreement_price(row) -> Dict[str, Any]:
|
|
return {
|
|
"id": row.id,
|
|
"channelAgreementId": row.channel_agreement_id or "",
|
|
"projectName": row.project_name or "",
|
|
"projectCode": row.project_code or "",
|
|
"cellTypeCode": row.cell_type_code or "",
|
|
"cellTypeName": row.cell_type_name or "",
|
|
"specText": row.spec_text or "",
|
|
"originalPrice": float(row.original_price) if row.original_price is not None else None,
|
|
"agreementPrice": float(row.agreement_price) if row.agreement_price is not None else None,
|
|
"tenantNo": row.tenant_no or "",
|
|
"orderNum": row.order_num if row.order_num is not None else 0,
|
|
"remark": row.remark or "",
|
|
"createTime": row.create_time.strftime("%Y-%m-%d %H:%M:%S") if row.create_time else "",
|
|
"updateTime": row.update_time.strftime("%Y-%m-%d %H:%M:%S") if row.update_time else "",
|
|
}
|
|
|
|
|
|
def _channel_agreement_price_item_key(
|
|
project_code=None,
|
|
project_name=None,
|
|
cell_type_code=None,
|
|
cell_type_name=None,
|
|
spec_text=None,
|
|
) -> str:
|
|
code = (project_code or project_name or "").strip().lower()
|
|
cell = (cell_type_code or cell_type_name or "").strip().lower()
|
|
spec = (spec_text or "").strip().lower()
|
|
return f"{code}|{cell}|{spec}"
|
|
|
|
|
|
def _channel_agreement_price_exists(
|
|
db,
|
|
channel_agreement_id,
|
|
*,
|
|
project_code=None,
|
|
project_name=None,
|
|
cell_type_code=None,
|
|
cell_type_name=None,
|
|
spec_text=None,
|
|
tenant_no=None,
|
|
exclude_price_id=None,
|
|
):
|
|
target_key = _channel_agreement_price_item_key(
|
|
project_code=project_code,
|
|
project_name=project_name,
|
|
cell_type_code=cell_type_code,
|
|
cell_type_name=cell_type_name,
|
|
spec_text=spec_text,
|
|
)
|
|
q = db.query(BizChannelAgreementProductPrice).filter(
|
|
and_(
|
|
BizChannelAgreementProductPrice.channel_agreement_id == channel_agreement_id,
|
|
BizChannelAgreementProductPrice.del_flag == 0,
|
|
)
|
|
)
|
|
if tenant_no:
|
|
q = q.filter(BizChannelAgreementProductPrice.tenant_no == tenant_no)
|
|
if exclude_price_id:
|
|
q = q.filter(BizChannelAgreementProductPrice.id != exclude_price_id)
|
|
for row in q.all():
|
|
if _channel_agreement_price_item_key(
|
|
project_code=row.project_code,
|
|
project_name=row.project_name,
|
|
cell_type_code=row.cell_type_code,
|
|
cell_type_name=row.cell_type_name,
|
|
spec_text=row.spec_text,
|
|
) == target_key:
|
|
return True
|
|
return False
|
|
|
|
|
|
def list_channel_agreement_prices(db, channel_agreement_id, tenant_no=None, user_info=None):
|
|
q = db.query(BizChannelAgreementProductPrice).filter(
|
|
and_(
|
|
BizChannelAgreementProductPrice.channel_agreement_id == channel_agreement_id,
|
|
BizChannelAgreementProductPrice.del_flag == 0,
|
|
)
|
|
)
|
|
if tenant_no:
|
|
q = q.filter(BizChannelAgreementProductPrice.tenant_no == tenant_no)
|
|
if user_info:
|
|
from app.core.data_scope import apply_data_scope
|
|
q = apply_data_scope(q, BizChannelAgreementProductPrice, user_info, db, tenant_no)
|
|
rows = q.order_by(BizChannelAgreementProductPrice.create_time.desc()).all()
|
|
return [_row_to_dict_channel_agreement_price(x) for x in rows]
|
|
|
|
|
|
def create_channel_agreement_price(
|
|
db,
|
|
*,
|
|
channel_agreement_id,
|
|
project_name=None,
|
|
project_code=None,
|
|
cell_type_code=None,
|
|
cell_type_name=None,
|
|
spec_text=None,
|
|
original_price=None,
|
|
agreement_price=None,
|
|
tenant_no="zkxw",
|
|
order_num=None,
|
|
remark=None,
|
|
user_id=None,
|
|
):
|
|
if _channel_agreement_price_exists(
|
|
db,
|
|
channel_agreement_id,
|
|
project_code=project_code,
|
|
project_name=project_name,
|
|
cell_type_code=cell_type_code,
|
|
cell_type_name=cell_type_name,
|
|
spec_text=spec_text,
|
|
tenant_no=tenant_no,
|
|
):
|
|
raise ValueError("该项目信息已存在,不可重复添加")
|
|
obj = BizChannelAgreementProductPrice(
|
|
id=generate_uuid(),
|
|
channel_agreement_id=channel_agreement_id,
|
|
project_name=project_name or "",
|
|
project_code=project_code or "",
|
|
cell_type_code=cell_type_code or "",
|
|
cell_type_name=cell_type_name or "",
|
|
spec_text=spec_text or "",
|
|
original_price=original_price,
|
|
agreement_price=agreement_price,
|
|
tenant_no=tenant_no,
|
|
order_num=order_num or 0,
|
|
remark=remark or "",
|
|
create_by=user_id,
|
|
create_time=datetime.now(),
|
|
update_by=user_id,
|
|
update_time=datetime.now(),
|
|
del_flag=0,
|
|
)
|
|
db.add(obj)
|
|
db.commit()
|
|
db.refresh(obj)
|
|
return obj
|
|
|
|
|
|
def update_channel_agreement_price(
|
|
db,
|
|
price_id,
|
|
*,
|
|
project_name=None,
|
|
project_code=None,
|
|
cell_type_code=None,
|
|
cell_type_name=None,
|
|
spec_text=None,
|
|
original_price=None,
|
|
agreement_price=None,
|
|
order_num=None,
|
|
remark=None,
|
|
user_id=None,
|
|
tenant_no=None,
|
|
):
|
|
q = db.query(BizChannelAgreementProductPrice).filter(
|
|
and_(BizChannelAgreementProductPrice.id == price_id, BizChannelAgreementProductPrice.del_flag == 0)
|
|
)
|
|
if tenant_no:
|
|
q = q.filter(BizChannelAgreementProductPrice.tenant_no == tenant_no)
|
|
obj = q.first()
|
|
if not obj:
|
|
raise ValueError("记录不存在")
|
|
next_project_name = project_name if project_name is not None else obj.project_name
|
|
next_project_code = project_code if project_code is not None else obj.project_code
|
|
next_cell_type_code = cell_type_code if cell_type_code is not None else obj.cell_type_code
|
|
next_cell_type_name = cell_type_name if cell_type_name is not None else obj.cell_type_name
|
|
next_spec_text = spec_text if spec_text is not None else obj.spec_text
|
|
if _channel_agreement_price_exists(
|
|
db,
|
|
obj.channel_agreement_id,
|
|
project_code=next_project_code,
|
|
project_name=next_project_name,
|
|
cell_type_code=next_cell_type_code,
|
|
cell_type_name=next_cell_type_name,
|
|
spec_text=next_spec_text,
|
|
tenant_no=tenant_no,
|
|
exclude_price_id=price_id,
|
|
):
|
|
raise ValueError("该项目信息已存在,不可重复添加")
|
|
if project_name is not None:
|
|
obj.project_name = project_name
|
|
if project_code is not None:
|
|
obj.project_code = project_code
|
|
if cell_type_code is not None:
|
|
obj.cell_type_code = cell_type_code
|
|
if cell_type_name is not None:
|
|
obj.cell_type_name = cell_type_name
|
|
if spec_text is not None:
|
|
obj.spec_text = spec_text
|
|
if original_price is not None:
|
|
obj.original_price = original_price
|
|
if agreement_price is not None:
|
|
obj.agreement_price = agreement_price
|
|
if order_num is not None:
|
|
obj.order_num = order_num
|
|
if remark is not None:
|
|
obj.remark = remark
|
|
obj.update_by = user_id
|
|
obj.update_time = datetime.now()
|
|
db.add(obj)
|
|
db.commit()
|
|
db.refresh(obj)
|
|
return obj
|
|
|
|
|
|
def soft_delete_channel_agreement_price(db, price_id, tenant_no=None):
|
|
q = db.query(BizChannelAgreementProductPrice).filter(
|
|
and_(BizChannelAgreementProductPrice.id == price_id, BizChannelAgreementProductPrice.del_flag == 0)
|
|
)
|
|
if tenant_no:
|
|
q = q.filter(BizChannelAgreementProductPrice.tenant_no == tenant_no)
|
|
obj = q.first()
|
|
if not obj:
|
|
raise ValueError("记录不存在")
|
|
obj.del_flag = 1
|
|
obj.update_time = datetime.now()
|
|
db.add(obj)
|
|
db.commit()
|
|
|
|
|
|
# ────────────────────────────────────────────
|
|
# Entity 11: BizCheckupInstitution 体检机构
|
|
# ────────────────────────────────────────────
|
|
|
|
def _row_to_dict_checkup_institution(row) -> Dict[str, Any]:
|
|
return {
|
|
"id": row.id,
|
|
"institutionName": row.institution_name or "",
|
|
"institutionAddress": row.institution_address or "",
|
|
"contactName": row.contact_name or "",
|
|
"contactPhone": row.contact_phone or "",
|
|
"status": row.status or "1",
|
|
"tenantNo": row.tenant_no or "",
|
|
"orderNum": row.order_num if row.order_num is not None else 0,
|
|
"remark": row.remark or "",
|
|
"createTime": row.create_time.strftime("%Y-%m-%d %H:%M:%S") if row.create_time else "",
|
|
"updateTime": row.update_time.strftime("%Y-%m-%d %H:%M:%S") if row.update_time else "",
|
|
}
|
|
|
|
|
|
def list_checkup_institutions(db, *, page=1, page_size=10, keyword=None, status=None, tenant_no=None, user_info=None):
|
|
def _filtered():
|
|
q0 = db.query(BizCheckupInstitution).filter(BizCheckupInstitution.del_flag == 0)
|
|
if tenant_no:
|
|
q0 = q0.filter(BizCheckupInstitution.tenant_no == tenant_no)
|
|
kw = (keyword or "").strip()
|
|
if kw:
|
|
like = f"%{kw}%"
|
|
q0 = q0.filter(
|
|
or_(
|
|
BizCheckupInstitution.institution_name.like(like),
|
|
BizCheckupInstitution.contact_name.like(like),
|
|
)
|
|
)
|
|
st = (status or "").strip()
|
|
if st in ("0", "1"):
|
|
q0 = q0.filter(BizCheckupInstitution.status == st)
|
|
if user_info:
|
|
from app.core.data_scope import apply_data_scope
|
|
q0 = apply_data_scope(q0, BizCheckupInstitution, user_info, db, tenant_no)
|
|
return q0
|
|
|
|
total = _filtered().order_by(None).with_entities(func.count(BizCheckupInstitution.id)).scalar() or 0
|
|
page = max(1, page)
|
|
page_size = min(max(1, page_size), 100)
|
|
rows = _filtered().order_by(BizCheckupInstitution.create_time.desc()).offset((page - 1) * page_size).limit(page_size).all()
|
|
return [_row_to_dict_checkup_institution(x) for x in rows], int(total)
|
|
|
|
|
|
def get_checkup_institution(db, institution_id, tenant_no=None):
|
|
q = db.query(BizCheckupInstitution).filter(
|
|
and_(BizCheckupInstitution.id == institution_id, BizCheckupInstitution.del_flag == 0)
|
|
)
|
|
if tenant_no:
|
|
q = q.filter(BizCheckupInstitution.tenant_no == tenant_no)
|
|
return q.first()
|
|
|
|
|
|
def create_checkup_institution(
|
|
db,
|
|
*,
|
|
institution_name,
|
|
institution_address=None,
|
|
contact_name=None,
|
|
contact_phone=None,
|
|
status="1",
|
|
tenant_no="zkxw",
|
|
order_num=None,
|
|
remark=None,
|
|
user_id=None,
|
|
):
|
|
obj = BizCheckupInstitution(
|
|
id=generate_uuid(),
|
|
institution_name=institution_name,
|
|
institution_address=institution_address or "",
|
|
contact_name=contact_name or "",
|
|
contact_phone=contact_phone or "",
|
|
status=status or "1",
|
|
tenant_no=tenant_no,
|
|
order_num=order_num or 0,
|
|
remark=remark or "",
|
|
create_by=user_id,
|
|
create_time=datetime.now(),
|
|
update_by=user_id,
|
|
update_time=datetime.now(),
|
|
del_flag=0,
|
|
)
|
|
db.add(obj)
|
|
db.commit()
|
|
db.refresh(obj)
|
|
return obj
|
|
|
|
|
|
def update_checkup_institution(
|
|
db,
|
|
institution_id,
|
|
*,
|
|
institution_name=None,
|
|
institution_address=None,
|
|
contact_name=None,
|
|
contact_phone=None,
|
|
status=None,
|
|
order_num=None,
|
|
remark=None,
|
|
user_id=None,
|
|
tenant_no=None,
|
|
):
|
|
obj = get_checkup_institution(db, institution_id, tenant_no)
|
|
if not obj:
|
|
raise ValueError("记录不存在")
|
|
if institution_name is not None:
|
|
obj.institution_name = institution_name
|
|
if institution_address is not None:
|
|
obj.institution_address = institution_address
|
|
if contact_name is not None:
|
|
obj.contact_name = contact_name
|
|
if contact_phone is not None:
|
|
obj.contact_phone = contact_phone
|
|
if status is not None:
|
|
obj.status = status
|
|
if order_num is not None:
|
|
obj.order_num = order_num
|
|
if remark is not None:
|
|
obj.remark = remark
|
|
obj.update_by = user_id
|
|
obj.update_time = datetime.now()
|
|
db.add(obj)
|
|
db.commit()
|
|
db.refresh(obj)
|
|
return obj
|
|
|
|
|
|
def soft_delete_checkup_institution(db, institution_id, tenant_no=None):
|
|
obj = get_checkup_institution(db, institution_id, tenant_no)
|
|
if not obj:
|
|
raise ValueError("记录不存在")
|
|
obj.del_flag = 1
|
|
obj.update_time = datetime.now()
|
|
db.add(obj)
|
|
db.commit()
|
|
|
|
|
|
# ────────────────────────────────────────────
|
|
# Entity 12: BizCheckupInstitutionInvoice 体检机构开票信息
|
|
# ────────────────────────────────────────────
|
|
|
|
def _row_to_dict_checkup_institution_invoice(row) -> Dict[str, Any]:
|
|
return {
|
|
"id": row.id,
|
|
"checkupInstitutionId": row.checkup_institution_id or "",
|
|
"companyName": row.company_name or "",
|
|
"taxNo": row.tax_no or "",
|
|
"companyAddress": row.company_address or "",
|
|
"companyPhone": row.company_phone or "",
|
|
"bankName": row.bank_name or "",
|
|
"bankAccount": row.bank_account or "",
|
|
"tenantNo": row.tenant_no or "",
|
|
"orderNum": row.order_num if row.order_num is not None else 0,
|
|
"remark": row.remark or "",
|
|
"createTime": row.create_time.strftime("%Y-%m-%d %H:%M:%S") if row.create_time else "",
|
|
"updateTime": row.update_time.strftime("%Y-%m-%d %H:%M:%S") if row.update_time else "",
|
|
}
|
|
|
|
|
|
def list_checkup_institution_invoices(db, checkup_institution_id, tenant_no=None, user_info=None):
|
|
q = db.query(BizCheckupInstitutionInvoice).filter(
|
|
and_(
|
|
BizCheckupInstitutionInvoice.checkup_institution_id == checkup_institution_id,
|
|
BizCheckupInstitutionInvoice.del_flag == 0,
|
|
)
|
|
)
|
|
if tenant_no:
|
|
q = q.filter(BizCheckupInstitutionInvoice.tenant_no == tenant_no)
|
|
if user_info:
|
|
from app.core.data_scope import apply_data_scope
|
|
q = apply_data_scope(q, BizCheckupInstitutionInvoice, user_info, db, tenant_no)
|
|
rows = q.order_by(BizCheckupInstitutionInvoice.create_time.desc()).all()
|
|
return [_row_to_dict_checkup_institution_invoice(x) for x in rows]
|
|
|
|
|
|
def create_checkup_institution_invoice(
|
|
db,
|
|
*,
|
|
checkup_institution_id,
|
|
company_name,
|
|
tax_no=None,
|
|
company_address=None,
|
|
company_phone=None,
|
|
bank_name=None,
|
|
bank_account=None,
|
|
tenant_no="zkxw",
|
|
order_num=None,
|
|
remark=None,
|
|
user_id=None,
|
|
):
|
|
obj = BizCheckupInstitutionInvoice(
|
|
id=generate_uuid(),
|
|
checkup_institution_id=checkup_institution_id,
|
|
company_name=company_name,
|
|
tax_no=tax_no or "",
|
|
company_address=company_address or "",
|
|
company_phone=company_phone or "",
|
|
bank_name=bank_name or "",
|
|
bank_account=bank_account or "",
|
|
tenant_no=tenant_no,
|
|
order_num=order_num or 0,
|
|
remark=remark or "",
|
|
create_by=user_id,
|
|
create_time=datetime.now(),
|
|
update_by=user_id,
|
|
update_time=datetime.now(),
|
|
del_flag=0,
|
|
)
|
|
db.add(obj)
|
|
db.commit()
|
|
db.refresh(obj)
|
|
return obj
|
|
|
|
|
|
def update_checkup_institution_invoice(
|
|
db,
|
|
invoice_id,
|
|
*,
|
|
company_name=None,
|
|
tax_no=None,
|
|
company_address=None,
|
|
company_phone=None,
|
|
bank_name=None,
|
|
bank_account=None,
|
|
order_num=None,
|
|
remark=None,
|
|
user_id=None,
|
|
tenant_no=None,
|
|
):
|
|
q = db.query(BizCheckupInstitutionInvoice).filter(
|
|
and_(BizCheckupInstitutionInvoice.id == invoice_id, BizCheckupInstitutionInvoice.del_flag == 0)
|
|
)
|
|
if tenant_no:
|
|
q = q.filter(BizCheckupInstitutionInvoice.tenant_no == tenant_no)
|
|
obj = q.first()
|
|
if not obj:
|
|
raise ValueError("记录不存在")
|
|
if company_name is not None:
|
|
obj.company_name = company_name
|
|
if tax_no is not None:
|
|
obj.tax_no = tax_no
|
|
if company_address is not None:
|
|
obj.company_address = company_address
|
|
if company_phone is not None:
|
|
obj.company_phone = company_phone
|
|
if bank_name is not None:
|
|
obj.bank_name = bank_name
|
|
if bank_account is not None:
|
|
obj.bank_account = bank_account
|
|
if order_num is not None:
|
|
obj.order_num = order_num
|
|
if remark is not None:
|
|
obj.remark = remark
|
|
obj.update_by = user_id
|
|
obj.update_time = datetime.now()
|
|
db.add(obj)
|
|
db.commit()
|
|
db.refresh(obj)
|
|
return obj
|
|
|
|
|
|
def soft_delete_checkup_institution_invoice(db, invoice_id, tenant_no=None):
|
|
q = db.query(BizCheckupInstitutionInvoice).filter(
|
|
and_(BizCheckupInstitutionInvoice.id == invoice_id, BizCheckupInstitutionInvoice.del_flag == 0)
|
|
)
|
|
if tenant_no:
|
|
q = q.filter(BizCheckupInstitutionInvoice.tenant_no == tenant_no)
|
|
obj = q.first()
|
|
if not obj:
|
|
raise ValueError("记录不存在")
|
|
obj.del_flag = 1
|
|
obj.update_time = datetime.now()
|
|
db.add(obj)
|
|
db.commit()
|
|
|
|
|
|
# ────────────────────────────────────────────
|
|
# Entity 13: BizCheckupInstitutionProject 体检机构项目及价格
|
|
# ────────────────────────────────────────────
|
|
|
|
def _row_to_dict_checkup_institution_project(row) -> Dict[str, Any]:
|
|
return {
|
|
"id": row.id,
|
|
"checkupInstitutionId": row.checkup_institution_id or "",
|
|
"projectName": row.project_name or "",
|
|
"projectFee": float(row.project_fee) if row.project_fee is not None else None,
|
|
"status": row.status or "1",
|
|
"tenantNo": row.tenant_no or "",
|
|
"orderNum": row.order_num if row.order_num is not None else 0,
|
|
"remark": row.remark or "",
|
|
"createTime": row.create_time.strftime("%Y-%m-%d %H:%M:%S") if row.create_time else "",
|
|
"updateTime": row.update_time.strftime("%Y-%m-%d %H:%M:%S") if row.update_time else "",
|
|
}
|
|
|
|
|
|
def list_checkup_institution_projects(db, checkup_institution_id, tenant_no=None, user_info=None):
|
|
q = db.query(BizCheckupInstitutionProject).filter(
|
|
and_(
|
|
BizCheckupInstitutionProject.checkup_institution_id == checkup_institution_id,
|
|
BizCheckupInstitutionProject.del_flag == 0,
|
|
)
|
|
)
|
|
if tenant_no:
|
|
q = q.filter(BizCheckupInstitutionProject.tenant_no == tenant_no)
|
|
if user_info:
|
|
from app.core.data_scope import apply_data_scope
|
|
q = apply_data_scope(q, BizCheckupInstitutionProject, user_info, db, tenant_no)
|
|
rows = q.order_by(BizCheckupInstitutionProject.create_time.desc()).all()
|
|
return [_row_to_dict_checkup_institution_project(x) for x in rows]
|
|
|
|
|
|
def create_checkup_institution_project(
|
|
db,
|
|
*,
|
|
checkup_institution_id,
|
|
project_name,
|
|
project_fee=None,
|
|
status="1",
|
|
tenant_no="zkxw",
|
|
order_num=None,
|
|
remark=None,
|
|
user_id=None,
|
|
):
|
|
obj = BizCheckupInstitutionProject(
|
|
id=generate_uuid(),
|
|
checkup_institution_id=checkup_institution_id,
|
|
project_name=project_name,
|
|
project_fee=project_fee,
|
|
status=status or "1",
|
|
tenant_no=tenant_no,
|
|
order_num=order_num or 0,
|
|
remark=remark or "",
|
|
create_by=user_id,
|
|
create_time=datetime.now(),
|
|
update_by=user_id,
|
|
update_time=datetime.now(),
|
|
del_flag=0,
|
|
)
|
|
db.add(obj)
|
|
db.commit()
|
|
db.refresh(obj)
|
|
return obj
|
|
|
|
|
|
def update_checkup_institution_project(
|
|
db,
|
|
project_id,
|
|
*,
|
|
project_name=None,
|
|
project_fee=None,
|
|
status=None,
|
|
order_num=None,
|
|
remark=None,
|
|
user_id=None,
|
|
tenant_no=None,
|
|
):
|
|
q = db.query(BizCheckupInstitutionProject).filter(
|
|
and_(BizCheckupInstitutionProject.id == project_id, BizCheckupInstitutionProject.del_flag == 0)
|
|
)
|
|
if tenant_no:
|
|
q = q.filter(BizCheckupInstitutionProject.tenant_no == tenant_no)
|
|
obj = q.first()
|
|
if not obj:
|
|
raise ValueError("记录不存在")
|
|
if project_name is not None:
|
|
obj.project_name = project_name
|
|
if project_fee is not None:
|
|
obj.project_fee = project_fee
|
|
if status is not None:
|
|
obj.status = status
|
|
if order_num is not None:
|
|
obj.order_num = order_num
|
|
if remark is not None:
|
|
obj.remark = remark
|
|
obj.update_by = user_id
|
|
obj.update_time = datetime.now()
|
|
db.add(obj)
|
|
db.commit()
|
|
db.refresh(obj)
|
|
return obj
|
|
|
|
|
|
def soft_delete_checkup_institution_project(db, project_id, tenant_no=None):
|
|
q = db.query(BizCheckupInstitutionProject).filter(
|
|
and_(BizCheckupInstitutionProject.id == project_id, BizCheckupInstitutionProject.del_flag == 0)
|
|
)
|
|
if tenant_no:
|
|
q = q.filter(BizCheckupInstitutionProject.tenant_no == tenant_no)
|
|
obj = q.first()
|
|
if not obj:
|
|
raise ValueError("记录不存在")
|
|
obj.del_flag = 1
|
|
obj.update_time = datetime.now()
|
|
db.add(obj)
|
|
db.commit()
|
|
|
|
|
|
# ────────────────────────────────────────────
|
|
# Entity 14: BizCheckupInstitutionPackage 体检机构项目套餐
|
|
# ────────────────────────────────────────────
|
|
|
|
def _sum_package_item_fees(items: List[Dict[str, Any]]) -> float:
|
|
total = 0.0
|
|
for it in items:
|
|
fee = it.get("project_fee")
|
|
if fee is None and "projectFee" in it:
|
|
fee = it.get("projectFee")
|
|
total += float(fee) if fee is not None else 0.0
|
|
return total
|
|
|
|
|
|
def _row_to_dict_checkup_institution_package(
|
|
row,
|
|
*,
|
|
total_fee: Optional[float] = None,
|
|
item_count: Optional[int] = None,
|
|
) -> Dict[str, Any]:
|
|
d = {
|
|
"id": row.id,
|
|
"checkupInstitutionId": row.checkup_institution_id or "",
|
|
"packageName": row.package_name or "",
|
|
"packageCode": row.package_code or "",
|
|
"status": row.status or "1",
|
|
"tenantNo": row.tenant_no or "",
|
|
"orderNum": row.order_num if row.order_num is not None else 0,
|
|
"remark": row.remark or "",
|
|
"createTime": row.create_time.strftime("%Y-%m-%d %H:%M:%S") if row.create_time else "",
|
|
"updateTime": row.update_time.strftime("%Y-%m-%d %H:%M:%S") if row.update_time else "",
|
|
}
|
|
if total_fee is not None:
|
|
d["totalFee"] = total_fee
|
|
if item_count is not None:
|
|
d["itemCount"] = item_count
|
|
return d
|
|
|
|
|
|
def _row_to_dict_checkup_institution_package_item(
|
|
row,
|
|
*,
|
|
source_project_deleted: bool = False,
|
|
source_project_status: Optional[str] = None,
|
|
) -> Dict[str, Any]:
|
|
return {
|
|
"id": row.id,
|
|
"packageId": row.package_id or "",
|
|
"checkupInstitutionProjectId": row.checkup_institution_project_id or "",
|
|
"projectName": row.project_name or "",
|
|
"projectFee": float(row.project_fee) if row.project_fee is not None else None,
|
|
"status": source_project_status if source_project_status is not None else "1",
|
|
"sourceProjectDeleted": source_project_deleted,
|
|
"tenantNo": row.tenant_no or "",
|
|
"orderNum": row.order_num if row.order_num is not None else 0,
|
|
"remark": row.remark or "",
|
|
"createTime": row.create_time.strftime("%Y-%m-%d %H:%M:%S") if row.create_time else "",
|
|
"updateTime": row.update_time.strftime("%Y-%m-%d %H:%M:%S") if row.update_time else "",
|
|
}
|
|
|
|
|
|
def checkup_package_code_exists(db, institution_id, code, tenant_no, exclude_id=None):
|
|
q = db.query(BizCheckupInstitutionPackage).filter(
|
|
and_(
|
|
BizCheckupInstitutionPackage.checkup_institution_id == institution_id,
|
|
BizCheckupInstitutionPackage.package_code == code,
|
|
BizCheckupInstitutionPackage.del_flag == 0,
|
|
)
|
|
)
|
|
if tenant_no:
|
|
q = q.filter(BizCheckupInstitutionPackage.tenant_no == tenant_no)
|
|
if exclude_id:
|
|
q = q.filter(BizCheckupInstitutionPackage.id != exclude_id)
|
|
return db.query(q.exists()).scalar()
|
|
|
|
|
|
def _get_checkup_project_for_package(db, project_id, institution_id, tenant_no=None):
|
|
q = db.query(BizCheckupInstitutionProject).filter(
|
|
BizCheckupInstitutionProject.id == project_id,
|
|
BizCheckupInstitutionProject.checkup_institution_id == institution_id,
|
|
)
|
|
if tenant_no:
|
|
q = q.filter(BizCheckupInstitutionProject.tenant_no == tenant_no)
|
|
return q.first()
|
|
|
|
|
|
def _validate_package_items_for_save(
|
|
db,
|
|
institution_id,
|
|
items,
|
|
tenant_no=None,
|
|
existing_item_project_ids=None,
|
|
):
|
|
if not items:
|
|
raise ValueError("套餐至少包含一个体检项目")
|
|
existing_ids = set(existing_item_project_ids or [])
|
|
seen = set()
|
|
for it in items:
|
|
pid = it.get("checkup_institution_project_id") or it.get("checkupInstitutionProjectId")
|
|
if not pid:
|
|
raise ValueError("套餐明细缺少机构项目")
|
|
if pid in seen:
|
|
raise ValueError("套餐内不能重复添加同一体检项目")
|
|
seen.add(pid)
|
|
proj = _get_checkup_project_for_package(db, pid, institution_id, tenant_no)
|
|
if not proj:
|
|
raise ValueError("存在无效的体检项目")
|
|
if pid in existing_ids:
|
|
continue
|
|
if proj.del_flag != 0:
|
|
raise ValueError("不能新添加已删除的体检项目")
|
|
if (proj.status or "1") != "1":
|
|
raise ValueError("套餐不能包含已停用的体检项目")
|
|
|
|
|
|
def _list_package_items_raw(db, package_id, tenant_no=None):
|
|
q = db.query(BizCheckupInstitutionPackageItem).filter(
|
|
and_(
|
|
BizCheckupInstitutionPackageItem.package_id == package_id,
|
|
BizCheckupInstitutionPackageItem.del_flag == 0,
|
|
)
|
|
)
|
|
if tenant_no:
|
|
q = q.filter(BizCheckupInstitutionPackageItem.tenant_no == tenant_no)
|
|
return q.order_by(BizCheckupInstitutionPackageItem.order_num.asc(), BizCheckupInstitutionPackageItem.create_time.asc()).all()
|
|
|
|
|
|
def _package_items_to_dicts(db, institution_id, item_rows, tenant_no=None):
|
|
result = []
|
|
for row in item_rows:
|
|
proj = _get_checkup_project_for_package(
|
|
db, row.checkup_institution_project_id, institution_id, tenant_no
|
|
)
|
|
deleted = proj is None or proj.del_flag != 0
|
|
proj_status = (proj.status or "1") if proj else "1"
|
|
result.append(
|
|
_row_to_dict_checkup_institution_package_item(
|
|
row,
|
|
source_project_deleted=deleted,
|
|
source_project_status=proj_status,
|
|
)
|
|
)
|
|
return result
|
|
|
|
|
|
def _insert_package_items(
|
|
db,
|
|
*,
|
|
package_id,
|
|
institution_id,
|
|
items,
|
|
tenant_no,
|
|
user_id=None,
|
|
):
|
|
for idx, it in enumerate(items):
|
|
pid = it.get("checkup_institution_project_id") or it.get("checkupInstitutionProjectId")
|
|
proj = _get_checkup_project_for_package(db, pid, institution_id, tenant_no)
|
|
name = (it.get("project_name") or it.get("projectName") or "").strip()
|
|
if not name and proj:
|
|
name = proj.project_name or ""
|
|
fee = it.get("project_fee")
|
|
if fee is None:
|
|
fee = it.get("projectFee")
|
|
obj = BizCheckupInstitutionPackageItem(
|
|
id=generate_uuid(),
|
|
package_id=package_id,
|
|
checkup_institution_project_id=pid,
|
|
project_name=name,
|
|
project_fee=fee,
|
|
tenant_no=tenant_no,
|
|
order_num=it.get("order_num") if it.get("order_num") is not None else it.get("orderNum") or (idx + 1),
|
|
remark=it.get("remark") or "",
|
|
create_by=user_id,
|
|
create_time=datetime.now(),
|
|
update_by=user_id,
|
|
update_time=datetime.now(),
|
|
del_flag=0,
|
|
)
|
|
db.add(obj)
|
|
|
|
|
|
def list_checkup_institution_packages(db, checkup_institution_id, tenant_no=None, user_info=None):
|
|
q = db.query(BizCheckupInstitutionPackage).filter(
|
|
and_(
|
|
BizCheckupInstitutionPackage.checkup_institution_id == checkup_institution_id,
|
|
BizCheckupInstitutionPackage.del_flag == 0,
|
|
)
|
|
)
|
|
if tenant_no:
|
|
q = q.filter(BizCheckupInstitutionPackage.tenant_no == tenant_no)
|
|
if user_info:
|
|
from app.core.data_scope import apply_data_scope
|
|
q = apply_data_scope(q, BizCheckupInstitutionPackage, user_info, db, tenant_no)
|
|
rows = q.order_by(BizCheckupInstitutionPackage.create_time.desc()).all()
|
|
out = []
|
|
for row in rows:
|
|
item_rows = _list_package_items_raw(db, row.id, tenant_no)
|
|
fees = [float(x.project_fee) if x.project_fee is not None else 0.0 for x in item_rows]
|
|
out.append(
|
|
_row_to_dict_checkup_institution_package(
|
|
row,
|
|
total_fee=sum(fees),
|
|
item_count=len(item_rows),
|
|
)
|
|
)
|
|
return out
|
|
|
|
|
|
def get_checkup_institution_package(db, package_id, tenant_no=None):
|
|
q = db.query(BizCheckupInstitutionPackage).filter(
|
|
and_(BizCheckupInstitutionPackage.id == package_id, BizCheckupInstitutionPackage.del_flag == 0)
|
|
)
|
|
if tenant_no:
|
|
q = q.filter(BizCheckupInstitutionPackage.tenant_no == tenant_no)
|
|
return q.first()
|
|
|
|
|
|
def get_checkup_institution_package_detail(db, package_id, tenant_no=None):
|
|
pkg = get_checkup_institution_package(db, package_id, tenant_no)
|
|
if not pkg:
|
|
return None
|
|
item_rows = _list_package_items_raw(db, package_id, tenant_no)
|
|
items = _package_items_to_dicts(db, pkg.checkup_institution_id, item_rows, tenant_no)
|
|
fees = [float(x.project_fee) if x.project_fee is not None else 0.0 for x in item_rows]
|
|
d = _row_to_dict_checkup_institution_package(pkg, total_fee=sum(fees), item_count=len(item_rows))
|
|
d["items"] = items
|
|
return d
|
|
|
|
|
|
def create_checkup_institution_package(
|
|
db,
|
|
*,
|
|
checkup_institution_id,
|
|
package_name,
|
|
package_code,
|
|
status="1",
|
|
items,
|
|
tenant_no="zkxw",
|
|
order_num=None,
|
|
remark=None,
|
|
user_id=None,
|
|
):
|
|
code = (package_code or "").strip()
|
|
if not code:
|
|
raise ValueError("套餐编码不能为空")
|
|
if checkup_package_code_exists(db, checkup_institution_id, code, tenant_no):
|
|
raise ValueError(f"套餐编码 {code} 已存在")
|
|
_validate_package_items_for_save(db, checkup_institution_id, items, tenant_no)
|
|
pkg = BizCheckupInstitutionPackage(
|
|
id=generate_uuid(),
|
|
checkup_institution_id=checkup_institution_id,
|
|
package_name=package_name,
|
|
package_code=code,
|
|
status=status or "1",
|
|
tenant_no=tenant_no,
|
|
order_num=order_num or 0,
|
|
remark=remark or "",
|
|
create_by=user_id,
|
|
create_time=datetime.now(),
|
|
update_by=user_id,
|
|
update_time=datetime.now(),
|
|
del_flag=0,
|
|
)
|
|
db.add(pkg)
|
|
db.flush()
|
|
_insert_package_items(
|
|
db,
|
|
package_id=pkg.id,
|
|
institution_id=checkup_institution_id,
|
|
items=items,
|
|
tenant_no=tenant_no,
|
|
user_id=user_id,
|
|
)
|
|
db.commit()
|
|
db.refresh(pkg)
|
|
return get_checkup_institution_package_detail(db, pkg.id, tenant_no)
|
|
|
|
|
|
def update_checkup_institution_package(
|
|
db,
|
|
package_id,
|
|
*,
|
|
package_name=None,
|
|
package_code=None,
|
|
status=None,
|
|
items=None,
|
|
order_num=None,
|
|
remark=None,
|
|
user_id=None,
|
|
tenant_no=None,
|
|
):
|
|
pkg = get_checkup_institution_package(db, package_id, tenant_no)
|
|
if not pkg:
|
|
raise ValueError("记录不存在")
|
|
institution_id = pkg.checkup_institution_id
|
|
if package_code is not None:
|
|
code = package_code.strip()
|
|
if not code:
|
|
raise ValueError("套餐编码不能为空")
|
|
if code != pkg.package_code and checkup_package_code_exists(
|
|
db, institution_id, code, tenant_no, exclude_id=package_id
|
|
):
|
|
raise ValueError(f"套餐编码 {code} 已存在")
|
|
pkg.package_code = code
|
|
if package_name is not None:
|
|
pkg.package_name = package_name
|
|
if status is not None:
|
|
pkg.status = status
|
|
if order_num is not None:
|
|
pkg.order_num = order_num
|
|
if remark is not None:
|
|
pkg.remark = remark
|
|
if items is not None:
|
|
old_rows = _list_package_items_raw(db, package_id, tenant_no)
|
|
existing_pids = {r.checkup_institution_project_id for r in old_rows}
|
|
_validate_package_items_for_save(
|
|
db,
|
|
institution_id,
|
|
items,
|
|
tenant_no,
|
|
existing_item_project_ids=existing_pids,
|
|
)
|
|
# 全量替换:物理删除旧明细,避免 uk(package_id, project_id) 与软删行冲突
|
|
q_items = db.query(BizCheckupInstitutionPackageItem).filter(
|
|
BizCheckupInstitutionPackageItem.package_id == package_id
|
|
)
|
|
if tenant_no:
|
|
q_items = q_items.filter(BizCheckupInstitutionPackageItem.tenant_no == tenant_no)
|
|
for row in q_items.all():
|
|
db.delete(row)
|
|
db.flush()
|
|
_insert_package_items(
|
|
db,
|
|
package_id=package_id,
|
|
institution_id=institution_id,
|
|
items=items,
|
|
tenant_no=tenant_no or pkg.tenant_no,
|
|
user_id=user_id,
|
|
)
|
|
pkg.update_by = user_id
|
|
pkg.update_time = datetime.now()
|
|
db.add(pkg)
|
|
db.commit()
|
|
return get_checkup_institution_package_detail(db, package_id, tenant_no)
|
|
|
|
|
|
def soft_delete_checkup_institution_package(db, package_id, tenant_no=None):
|
|
pkg = get_checkup_institution_package(db, package_id, tenant_no)
|
|
if not pkg:
|
|
raise ValueError("记录不存在")
|
|
now = datetime.now()
|
|
pkg.del_flag = 1
|
|
pkg.update_time = now
|
|
db.add(pkg)
|
|
for row in _list_package_items_raw(db, package_id, tenant_no):
|
|
row.del_flag = 1
|
|
row.update_time = now
|
|
db.add(row)
|
|
db.commit()
|
|
|
|
|
|
# ────────────────────────────────────────────
|
|
# Shared utility
|
|
# ────────────────────────────────────────────
|
|
|
|
def total_pages(total, page_size):
|
|
if total <= 0:
|
|
return 0
|
|
return int(math.ceil(total / float(page_size)))
|