Files
shanxia2.0/backend/app/models/pl_quota_models.py
T
wuzilong 9f855423d8 fix(pl): 客户品类规则预占不再依赖合同绑证 scope。
新规则自动选证后账本仍按合同绑证判定适用,导致预占报人工分配不适用;改为客户品类路径跳过 scope,明细合同绑证字段可空,并统一关联购买证文案。
2026-11-15 08:01:14 +08:00

388 lines
32 KiB
Python

"""购买证、运输证额度与历史流水;区别于车辆人员证件。"""
from datetime import datetime
from decimal import Decimal
from sqlalchemy import Column, String, Text, Integer, SmallInteger, Date, DateTime, Numeric, JSON, UniqueConstraint, Index
from app.core.database import Base
class PlPurchaseCert(Base):
__tablename__ = "pl_purchase_cert"
id = Column(String(64), primary_key=True, comment='主键UUID')
cert_no = Column(String(100), nullable=False, comment='证件编号,租户内按证种唯一;删除后不得重建另一额度池')
issue_date = Column(Date, nullable=True, comment='核发日期')
product_name_on_cert = Column(String(200), nullable=False, comment='证面物品名称原文,不随产品主数据更名')
total_qty = Column(Numeric(18,6), nullable=False, comment='证面核定总量,单位为quantity_unit')
quantity_unit = Column(String(32), nullable=False, comment='数量单位代码;同证全部余额使用此单位,异单位不自动换算')
valid_from = Column(Date, nullable=True, comment='有效期起始日期')
valid_to = Column(Date, nullable=True, comment='有效期截止日期')
valid_use_text = Column(String(32), nullable=False, comment='有效次数:一次有效或多次有效;不增加数值次数表单')
entry_mode = Column(String(20), nullable=False, default='manual', comment='首次建档方式:manual手工录入/image_parse图片解析后确认;补图不改变来源')
attachment_urls = Column(Text, nullable=True, comment='MinIO原件附件地址,可空,多附件逗号分隔;无图片也可手工建档')
status = Column(String(20), nullable=False, default='draft', comment='draft草稿/active可用/suspended停用/closed已核销/void作废;到期由日期判断')
verified_by = Column(String(64), nullable=True, comment='证件信息复核人')
verified_time = Column(DateTime, nullable=True, comment='证件信息复核时间')
reserved_qty = Column(Numeric(18,6), nullable=False, default=Decimal('0'), comment='已安排未结转预占量;余额缓存,禁止手工直接编辑')
used_qty = Column(Numeric(18,6), nullable=False, default=Decimal('0'), comment='已发生量;余额缓存,包含有凭据的期初及调整流水')
opening_single_use_consumed = Column(SmallInteger, nullable=False, default=0, comment='期初明确核实的一次有效证已使用标记,不能由已用数量推算')
revision = Column(Integer, nullable=False, default=1, comment='证面信息修订版本;使用时保留快照')
buyer_name = Column(String(255), nullable=False, comment='购买单位或个人名称')
buyer_address = Column(String(1000), nullable=True, comment='购买方住所或地址')
buyer_legal_representative = Column(String(100), nullable=True, comment='购买方法定代表人')
buyer_phone = Column(String(100), nullable=True, comment='购买方电话')
seller_name = Column(String(255), nullable=False, comment='销售单位名称')
seller_address = Column(String(1000), nullable=True, comment='销售单位住所')
seller_legal_representative = Column(String(100), nullable=True, comment='销售方法定代表人')
seller_phone = Column(String(100), nullable=True, comment='销售方电话')
purchase_purpose = Column(String(1000), nullable=True, comment='用途')
customer_id = Column(String(64), nullable=True, comment='系统客户ID;选证必填')
category_id = Column(String(64), nullable=True, comment='证用品类ID;选证必填')
tenant_no = Column(String(64), nullable=False, comment='租户编号,由服务端当前用户上下文设置')
order_num = Column(Integer, nullable=True, comment='公共排序号')
remark = Column(String(1000), nullable=True, comment='系统备注,与证面备注分开')
create_by = Column(String(64), nullable=True, comment='创建人')
create_dept_id = Column(String(64), nullable=False, default='', comment='创建部门')
create_time = Column(DateTime, nullable=False, default=datetime.now, comment='创建时间')
update_by = Column(String(64), nullable=True, comment='更新人')
update_time = Column(DateTime, nullable=False, default=datetime.now, onupdate=datetime.now, comment='更新时间')
del_flag = Column(SmallInteger, nullable=False, default=0, comment='软删除标记:0正常,1删除')
__table_args__ = (
UniqueConstraint('tenant_no', 'cert_no', name='uk_purchase_cert_no'),
Index('idx_purchase_cert_select', 'tenant_no', 'status', 'del_flag', 'valid_to'),
)
class PlTransportCert(Base):
__tablename__ = "pl_transport_cert"
id = Column(String(64), primary_key=True, comment='主键UUID')
cert_no = Column(String(100), nullable=False, comment='证件编号,租户内按证种唯一;删除后不得重建另一额度池')
issue_date = Column(Date, nullable=True, comment='核发日期')
product_name_on_cert = Column(String(200), nullable=False, comment='证面物品名称原文,不随产品主数据更名')
total_qty = Column(Numeric(18,6), nullable=False, comment='证面核定总量,单位为quantity_unit')
quantity_unit = Column(String(32), nullable=False, comment='数量单位代码;同证全部余额使用此单位,异单位不自动换算')
valid_from = Column(Date, nullable=True, comment='有效期起始日期')
valid_to = Column(Date, nullable=True, comment='有效期截止日期')
valid_use_text = Column(String(32), nullable=False, comment='有效次数:一次有效或多次有效;不增加数值次数表单')
entry_mode = Column(String(20), nullable=False, default='manual', comment='首次建档方式:manual手工录入/image_parse图片解析后确认;补图不改变来源')
attachment_urls = Column(Text, nullable=True, comment='MinIO原件附件地址,可空,多附件逗号分隔;无图片也可手工建档')
status = Column(String(20), nullable=False, default='draft', comment='draft草稿/active可用/suspended停用/closed已核销/void作废;到期由日期判断')
verified_by = Column(String(64), nullable=True, comment='证件信息复核人')
verified_time = Column(DateTime, nullable=True, comment='证件信息复核时间')
reserved_qty = Column(Numeric(18,6), nullable=False, default=Decimal('0'), comment='已安排未结转预占量;余额缓存,禁止手工直接编辑')
used_qty = Column(Numeric(18,6), nullable=False, default=Decimal('0'), comment='已发生量;余额缓存,包含有凭据的期初及调整流水')
opening_single_use_consumed = Column(SmallInteger, nullable=False, default=0, comment='期初明确核实的一次有效证已使用标记,不能由已用数量推算')
revision = Column(Integer, nullable=False, default=1, comment='证面信息修订版本;使用时保留快照')
shipper_name = Column(String(255), nullable=False, comment='货主名称或姓名')
shipper_address = Column(String(1000), nullable=True, comment='货主住所或地址')
shipper_legal_representative = Column(String(100), nullable=True, comment='货主法定代表人')
shipper_phone = Column(String(100), nullable=True, comment='货主电话')
packaging_text = Column(String(255), nullable=True, comment='包装,例如槽罐')
carrier_name = Column(String(255), nullable=True, comment='运输单位名称')
carrier_address_phone = Column(String(1200), nullable=True, comment='运输单位住所/电话,按用户指定证面合并栏保存')
transport_mode = Column(String(100), nullable=True, comment='运输方式,例如汽车')
vehicle_numbers_json = Column(JSON, nullable=False, comment='车号列表,例如[皖HA3190,皖H10291],所有车共用该证额度')
route_text = Column(Text, nullable=True, comment='运输路线完整原文')
consignee_name = Column(String(255), nullable=True, comment='收货单位名称或姓名')
applicant_name = Column(String(255), nullable=True, comment='申请单位名称或姓名')
customer_id = Column(String(64), nullable=True, comment='系统客户ID;选证必填')
tenant_no = Column(String(64), nullable=False, comment='租户编号,由服务端当前用户上下文设置')
order_num = Column(Integer, nullable=True, comment='公共排序号')
remark = Column(String(1000), nullable=True, comment='系统备注,与证面备注分开')
create_by = Column(String(64), nullable=True, comment='创建人')
create_dept_id = Column(String(64), nullable=False, default='', comment='创建部门')
create_time = Column(DateTime, nullable=False, default=datetime.now, comment='创建时间')
update_by = Column(String(64), nullable=True, comment='更新人')
update_time = Column(DateTime, nullable=False, default=datetime.now, onupdate=datetime.now, comment='更新时间')
del_flag = Column(SmallInteger, nullable=False, default=0, comment='软删除标记:0正常,1删除')
__table_args__ = (
UniqueConstraint('tenant_no', 'cert_no', name='uk_transport_cert_no'),
Index('idx_transport_cert_select', 'tenant_no', 'status', 'del_flag', 'valid_to'),
)
class PlTransportCertPurchaseRef(Base):
__tablename__ = "pl_transport_cert_purchase_ref"
id = Column(String(64), primary_key=True, comment='主键UUID')
transport_cert_id = Column(String(64), nullable=False, comment='运输证ID')
reference_type = Column(String(24), nullable=False, comment='purchase_permit/purchase_filing/export_permit/unknown')
reference_no = Column(String(100), nullable=False, comment='被引用的证号,保留未建档号码')
purchase_cert_id = Column(String(64), nullable=True, comment='如为山峡所管理购买证,关联其ID;外部未知证号可空')
tenant_no = Column(String(64), nullable=False, comment='租户编号,由服务端当前用户上下文设置')
order_num = Column(Integer, nullable=True, comment='公共排序号')
remark = Column(String(1000), nullable=True, comment='系统备注,与证面备注分开')
create_by = Column(String(64), nullable=True, comment='创建人')
create_dept_id = Column(String(64), nullable=False, default='', comment='创建部门')
create_time = Column(DateTime, nullable=False, default=datetime.now, comment='创建时间')
update_by = Column(String(64), nullable=True, comment='更新人')
update_time = Column(DateTime, nullable=False, default=datetime.now, onupdate=datetime.now, comment='更新时间')
del_flag = Column(SmallInteger, nullable=False, default=0, comment='软删除标记:0正常,1删除')
__table_args__ = (
UniqueConstraint('tenant_no', 'transport_cert_id', 'reference_no', name='uk_transport_ref'),
Index('idx_ref_purchase', 'tenant_no', 'purchase_cert_id', 'del_flag'),
)
class PlContractCertLink(Base):
__tablename__ = "pl_contract_cert_link"
id = Column(String(64), primary_key=True, comment='主键UUID')
contract_id = Column(String(64), nullable=False, comment='山峡自身CRM合同ID,不录入客户下游合同')
contract_no_snapshot = Column(String(100), nullable=False, comment='系统关联合同编号快照,不等于证件编号')
cert_type = Column(String(16), nullable=False, comment='purchase或transport')
cert_id = Column(String(64), nullable=False, comment='按cert_type指向对应证件表;服务层校验同租户')
link_status = Column(String(16), nullable=False, default='active', comment='active可选/inactive停止新增使用;历史使用不迁移')
scope_revision = Column(Integer, nullable=False, default=1, comment='适用产品范围版本,增删或停用产品时递增,使未执行用证确认失效')
tenant_no = Column(String(64), nullable=False, comment='租户编号,由服务端当前用户上下文设置')
order_num = Column(Integer, nullable=True, comment='公共排序号')
remark = Column(String(1000), nullable=True, comment='系统备注,与证面备注分开')
create_by = Column(String(64), nullable=True, comment='创建人')
create_dept_id = Column(String(64), nullable=False, default='', comment='创建部门')
create_time = Column(DateTime, nullable=False, default=datetime.now, comment='创建时间')
update_by = Column(String(64), nullable=True, comment='更新人')
update_time = Column(DateTime, nullable=False, default=datetime.now, onupdate=datetime.now, comment='更新时间')
del_flag = Column(SmallInteger, nullable=False, default=0, comment='软删除标记:0正常,1删除')
__table_args__ = (
UniqueConstraint('tenant_no', 'contract_id', 'cert_type', 'cert_id', name='uk_contract_cert'),
Index('idx_contract_cert', 'tenant_no', 'contract_id', 'del_flag'),
Index('idx_link_cert', 'tenant_no', 'cert_type', 'cert_id', 'del_flag'),
)
class PlContractCertProduct(Base):
__tablename__ = "pl_contract_cert_product"
id = Column(String(64), primary_key=True, comment='主键UUID')
contract_cert_link_id = Column(String(64), nullable=False, comment='pl_contract_cert_link.id,继承合同、证种及证件身份')
contract_product_id = Column(String(64), nullable=False, comment='该合同中的产品明细ID;多条产品行可属于同一合同证件绑定')
scope_status = Column(String(16), nullable=False, default='active', comment='active允许新增使用/inactive停止新增使用;保留历史')
tenant_no = Column(String(64), nullable=False, comment='租户编号,由服务端当前用户上下文设置')
order_num = Column(Integer, nullable=True, comment='公共排序号')
remark = Column(String(1000), nullable=True, comment='系统备注')
create_by = Column(String(64), nullable=True, comment='创建人')
create_dept_id = Column(String(64), nullable=False, default='', comment='创建部门')
create_time = Column(DateTime, nullable=False, default=datetime.now, comment='创建时间')
update_by = Column(String(64), nullable=True, comment='更新人')
update_time = Column(DateTime, nullable=False, default=datetime.now, onupdate=datetime.now, comment='更新时间')
del_flag = Column(SmallInteger, nullable=False, default=0, comment='软删除标记:0正常,1删除')
__table_args__ = (
UniqueConstraint('tenant_no', 'contract_cert_link_id', 'contract_product_id', name='uk_contract_cert_product'),
Index('idx_scope_product', 'tenant_no', 'contract_product_id', 'scope_status', 'del_flag'),
)
class PlPlanCertUsage(Base):
__tablename__ = "pl_plan_cert_usage"
id = Column(String(64), primary_key=True, comment='主键UUID')
plan_id = Column(String(64), nullable=False, comment='运输计划ID')
plan_no_snapshot = Column(String(100), nullable=False, comment='计划编号快照')
transport_id = Column(String(64), nullable=True, comment='运输单ID')
cert_type = Column(String(16), nullable=False, comment='purchase或transport')
cert_id = Column(String(64), nullable=False, comment='购买证或运输证ID')
cert_no_snapshot = Column(String(100), nullable=False, comment='本次使用证号快照')
cert_revision = Column(Integer, nullable=False, comment='本次确认的证件版本')
quantity_unit = Column(String(32), nullable=False, comment='数量单位代码;同证全部余额使用此单位,异单位不自动换算')
reserved_qty = Column(Numeric(18,6), nullable=False, default=Decimal('0'), comment='本计划对该证当前未结转的占用')
used_qty = Column(Numeric(18,6), nullable=False, default=Decimal('0'), comment='本计划对该证已发生量')
usage_status = Column(String(20), nullable=False, default='draft', comment='draft/reserved/in_transit/settled/released/exception')
confirmed_by = Column(String(64), nullable=True, comment='最近一次用证确认人')
confirmed_time = Column(DateTime, nullable=True, comment='最近一次用证确认时间')
settled_time = Column(DateTime, nullable=True, comment='最近一次实际量结转时间')
row_version = Column(Integer, nullable=False, default=1, comment='用量记录版本,防止使用旧版本重复修改')
confirmation_snapshot = Column(JSON, nullable=True, comment='证面、计划量、车号、实际装送主体/地址及核验结果快照')
tenant_no = Column(String(64), nullable=False, comment='租户编号,由服务端当前用户上下文设置')
order_num = Column(Integer, nullable=True, comment='公共排序号')
remark = Column(String(1000), nullable=True, comment='系统备注,与证面备注分开')
create_by = Column(String(64), nullable=True, comment='创建人')
create_dept_id = Column(String(64), nullable=False, default='', comment='创建部门')
create_time = Column(DateTime, nullable=False, default=datetime.now, comment='创建时间')
update_by = Column(String(64), nullable=True, comment='更新人')
update_time = Column(DateTime, nullable=False, default=datetime.now, onupdate=datetime.now, comment='更新时间')
del_flag = Column(SmallInteger, nullable=False, default=0, comment='软删除标记:0正常,1删除')
__table_args__ = (
UniqueConstraint('tenant_no', 'plan_id', 'cert_type', 'cert_id', name='uk_plan_cert_usage'),
Index('idx_usage_cert', 'tenant_no', 'cert_type', 'cert_id', 'usage_status', 'del_flag'),
)
class PlPlanCertUsageItem(Base):
__tablename__ = "pl_plan_cert_usage_item"
id = Column(String(64), primary_key=True, comment='主键UUID')
usage_id = Column(String(64), nullable=False, comment='pl_plan_cert_usage.id')
contract_cert_link_id = Column(String(64), nullable=True, comment='合同与证件绑定ID;客户品类规则可空')
contract_cert_product_id = Column(String(64), nullable=True, comment='合同证件产品范围明细ID;客户品类规则可空')
contract_scope_revision = Column(Integer, nullable=False, default=0, comment='合同证件适用范围版本;客户品类规则为0')
contract_id = Column(String(64), nullable=False, comment='本次履行的山峡合同ID')
contract_product_id = Column(String(64), nullable=False, comment='对应合同产品行ID')
plan_product_id = Column(String(64), nullable=False, comment='计划产品行ID')
source_stop_type = Column(String(16), nullable=False, comment='唯一计量侧:load或delivery')
source_stop_id = Column(String(64), nullable=False, comment='计量来源装货或送货段ID')
source_stop_product_id = Column(String(64), nullable=False, comment='计量来源段次产品行ID')
related_stop_products = Column(JSON, nullable=True, comment='关联另一侧段产品ID列表,仅用于追溯,不另行扣量')
allocation_seq = Column(Integer, nullable=False, comment='同计划同合同来源同证种的分配顺序,正数且不重复;归档按此顺序结转')
source_unit = Column(String(32), nullable=False, comment='来源段产品单位')
planned_source_qty = Column(Numeric(18,6), nullable=False, comment='安排时来源段产品完整计划数量快照,来源单位;跨证重复快照不得求和')
allocated_source_qty = Column(Numeric(18,6), nullable=True, comment='本证分配的来源计划数量,来源单位;同产品同证种各证合计须等于完整计划量')
actual_source_qty = Column(Numeric(18,6), nullable=True, comment='归档时来源段产品完整实际数量快照,来源单位;未知为NULL')
actual_allocated_source_qty = Column(Numeric(18,6), nullable=True, comment='归档时本证分配的来源实际数量;同产品同证种各证合计须等于完整实际量;异单位重新确认')
planned_cert_qty = Column(Numeric(18,6), nullable=True, comment='自动分配或人工确认的安排用证量,证件单位;草稿可空,预占前必填')
reserve_input_mode = Column(String(16), nullable=True, comment='same_unit同单位带入/standard固定质量体积换算/manual异单位人工填写')
reserve_conversion_note = Column(String(1000), nullable=True, comment='异单位人工折算说明;standard固定质量体积换算不填')
reserve_confirmed_by = Column(String(64), nullable=True, comment='安排折算量确认人,服务端取当前用户')
reserve_confirmed_time = Column(DateTime, nullable=True, comment='安排折算量确认时间')
actual_cert_qty = Column(Numeric(18,6), nullable=True, comment='按实际来源量自动分配或人工确认的实际用证量,证件单位;不可用预占量替代')
settle_input_mode = Column(String(16), nullable=True, comment='same_unit同单位带入/manual异单位重新人工填写')
settle_conversion_note = Column(String(1000), nullable=True, comment='异单位归档折算说明,manual时必填')
settle_confirmed_by = Column(String(64), nullable=True, comment='归档实际用证量确认人,服务端取当前用户')
settle_confirmed_time = Column(DateTime, nullable=True, comment='归档实际用证量确认时间')
source_fingerprint = Column(String(64), nullable=True, comment='源数据版本摘要;数量/单位/合同/产品/车辆/装送范围变化使确认失效')
reserved_qty = Column(Numeric(18,6), nullable=False, default=Decimal('0'), comment='本分配当前预占量,证件单位')
used_qty = Column(Numeric(18,6), nullable=False, default=Decimal('0'), comment='本分配已发生量,证件单位')
item_status = Column(String(20), nullable=False, default='draft', comment='draft/reserved/in_transit/settled/released/exception')
source_snapshot = Column(JSON, nullable=True, comment='合同、产品、原始计划/归档量与分配依据快照')
tenant_no = Column(String(64), nullable=False, comment='租户编号,由服务端当前用户上下文设置')
order_num = Column(Integer, nullable=True, comment='公共排序号')
remark = Column(String(1000), nullable=True, comment='系统备注,与证面备注分开')
create_by = Column(String(64), nullable=True, comment='创建人')
create_dept_id = Column(String(64), nullable=False, default='', comment='创建部门')
create_time = Column(DateTime, nullable=False, default=datetime.now, comment='创建时间')
update_by = Column(String(64), nullable=True, comment='更新人')
update_time = Column(DateTime, nullable=False, default=datetime.now, onupdate=datetime.now, comment='更新时间')
del_flag = Column(SmallInteger, nullable=False, default=0, comment='软删除标记:0正常,1删除')
__table_args__ = (
UniqueConstraint('tenant_no', 'usage_id', 'source_stop_type', 'source_stop_product_id', name='uk_usage_source'),
Index('idx_usage_item_contract', 'tenant_no', 'contract_product_id', 'del_flag'),
)
class PlCertQtyLog(Base):
__tablename__ = "pl_cert_qty_log"
id = Column(String(64), primary_key=True, comment='主键UUID')
operation_id = Column(String(64), nullable=False, comment='业务幂等操作号;同一次双证操作共用一个号')
request_hash = Column(String(64), nullable=False, comment='规范化业务请求SHA256,同幂等号不同请求应拒绝')
cert_type = Column(String(16), nullable=False, comment='purchase或transport')
cert_id = Column(String(64), nullable=False, comment='证件ID')
usage_id = Column(String(64), nullable=True, comment='计划用量ID;有凭据的期初导入可空')
plan_id = Column(String(64), nullable=True, comment='计划ID;期初导入可空')
event_type = Column(String(24), nullable=False, comment='opening/reserve/resize/release/settle/adjust/total_adjust')
quantity_unit = Column(String(32), nullable=False, comment='数量单位代码;同证全部余额使用此单位,异单位不自动换算')
total_delta = Column(Numeric(18,6), nullable=False, default=Decimal('0'), comment='核定总量变动,须附修订依据')
reserved_delta = Column(Numeric(18,6), nullable=False, default=Decimal('0'), comment='预占增量,释放或结转为负数')
used_delta = Column(Numeric(18,6), nullable=False, default=Decimal('0'), comment='实际使用增量,有依据的纠错可以为负数')
before_total_qty = Column(Numeric(18,6), nullable=False, comment='操作前核定总量')
after_total_qty = Column(Numeric(18,6), nullable=False, comment='操作后核定总量')
before_reserved_qty = Column(Numeric(18,6), nullable=False, comment='操作前预占')
after_reserved_qty = Column(Numeric(18,6), nullable=False, comment='操作后预占')
before_used_qty = Column(Numeric(18,6), nullable=False, comment='操作前已发生')
after_used_qty = Column(Numeric(18,6), nullable=False, comment='操作后已发生')
reason = Column(String(1000), nullable=False, comment='操作原因或业务动作说明')
evidence_urls = Column(Text, nullable=True, comment='期初、核定量修订或实际量调整凭据,多个URL逗号分隔')
event_snapshot = Column(JSON, nullable=True, comment='来源分配、证面版本、校验及变更前后明细')
tenant_no = Column(String(64), nullable=False, comment='租户编号,由服务端当前用户上下文设置')
order_num = Column(Integer, nullable=True, comment='公共排序号')
remark = Column(String(1000), nullable=True, comment='系统备注,与证面备注分开')
create_by = Column(String(64), nullable=True, comment='创建人')
create_dept_id = Column(String(64), nullable=False, default='', comment='创建部门')
create_time = Column(DateTime, nullable=False, default=datetime.now, comment='创建时间')
update_by = Column(String(64), nullable=True, comment='更新人')
update_time = Column(DateTime, nullable=False, default=datetime.now, onupdate=datetime.now, comment='更新时间')
del_flag = Column(SmallInteger, nullable=False, default=0, comment='软删除标记:0正常,1删除')
__table_args__ = (
UniqueConstraint('tenant_no', 'operation_id', 'cert_type', 'cert_id', name='uk_cert_operation'),
Index('idx_qty_log_cert', 'tenant_no', 'cert_type', 'cert_id', 'create_time'),
Index('idx_qty_log_usage', 'tenant_no', 'usage_id', 'create_time'),
)
class PlCertOperation(Base):
__tablename__ = "pl_cert_operation"
id = Column(String(64), primary_key=True, comment='主键UUID')
operation_id = Column(String(64), nullable=False, comment='客户端请求操作号')
action = Column(String(32), nullable=False, comment='请求动作')
plan_id = Column(String(64), nullable=True, comment='关联计划')
request_hash = Column(String(64), nullable=False, comment='规范请求SHA256')
result_json = Column(JSON, nullable=True, comment='原请求结果')
tenant_no = Column(String(64), nullable=False, comment='租户编号,由服务端当前用户上下文设置')
order_num = Column(Integer, nullable=True, comment='公共排序号')
remark = Column(String(1000), nullable=True, comment='系统备注,与证面备注分开')
create_by = Column(String(64), nullable=True, comment='创建人')
create_dept_id = Column(String(64), nullable=False, default='', comment='创建部门')
create_time = Column(DateTime, nullable=False, default=datetime.now, comment='创建时间')
update_by = Column(String(64), nullable=True, comment='更新人')
update_time = Column(DateTime, nullable=False, default=datetime.now, onupdate=datetime.now, comment='更新时间')
del_flag = Column(SmallInteger, nullable=False, default=0, comment='软删除标记:0正常,1删除')
__table_args__ = (
UniqueConstraint('tenant_no', 'operation_id', name='uk_cert_request'),
)
class PlStopLegalDocument(Base):
"""逐段产品证明;稳定身份不随附件更新重建。"""
__tablename__ = 'pl_stop_legal_document'
id = Column(String(64), primary_key=True)
plan_id = Column(String(64), nullable=False)
stop_type = Column(String(16), nullable=False)
stop_product_id = Column(String(64), nullable=False)
legal_use_cert_url = Column(Text, nullable=True)
uploaded_by = Column(String(64), nullable=True)
uploaded_time = Column(DateTime, nullable=True)
tenant_no = Column(String(64), nullable=False)
order_num = Column(Integer, nullable=True)
remark = Column(String(1000), nullable=True)
create_by = Column(String(64), nullable=True)
create_dept_id = Column(String(64), nullable=False, default='')
create_time = Column(DateTime, nullable=False, default=datetime.now)
update_by = Column(String(64), nullable=True)
update_time = Column(DateTime, nullable=False, default=datetime.now, onupdate=datetime.now)
del_flag = Column(SmallInteger, nullable=False, default=0)
__table_args__ = (
UniqueConstraint('tenant_no', 'plan_id', 'stop_type', 'stop_product_id', name='uk_stop_legal_document'),
)
class PlCertCategory(Base):
"""证用品类(与 CRM 产品分类独立)。"""
__tablename__ = 'pl_cert_category'
id = Column(String(64), primary_key=True, comment='主键UUID')
category_name = Column(String(128), nullable=False, comment='证用品类名称,如硫酸')
category_code = Column(String(64), nullable=True, comment='品类编码,可选')
status = Column(String(1), nullable=False, default='1', comment='状态 1启用 0停用')
tenant_no = Column(String(64), nullable=False, comment='租户编号')
order_num = Column(Integer, nullable=True, comment='排序号')
remark = Column(String(1000), nullable=True, comment='备注')
create_by = Column(String(64), nullable=True, comment='创建人')
create_dept_id = Column(String(64), nullable=False, default='', comment='创建部门')
create_time = Column(DateTime, nullable=False, default=datetime.now, comment='创建时间')
update_by = Column(String(64), nullable=True, comment='更新人')
update_time = Column(DateTime, nullable=False, default=datetime.now, onupdate=datetime.now, comment='更新时间')
del_flag = Column(SmallInteger, nullable=False, default=0, comment='软删除标记:0正常,1删除')
class PlCertCategoryProduct(Base):
"""证用品类关联系统产品。"""
__tablename__ = 'pl_cert_category_product'
id = Column(String(64), primary_key=True, comment='主键UUID')
category_id = Column(String(64), nullable=False, comment='证用品类ID')
product_id = Column(String(64), nullable=False, comment='CRM产品ID')
scope_status = Column(String(20), nullable=False, default='active', comment='active/inactive')
tenant_no = Column(String(64), nullable=False, comment='租户编号')
order_num = Column(Integer, nullable=True, comment='排序号')
remark = Column(String(1000), nullable=True, comment='备注')
create_by = Column(String(64), nullable=True, comment='创建人')
create_dept_id = Column(String(64), nullable=False, default='', comment='创建部门')
create_time = Column(DateTime, nullable=False, default=datetime.now, comment='创建时间')
update_by = Column(String(64), nullable=True, comment='更新人')
update_time = Column(DateTime, nullable=False, default=datetime.now, onupdate=datetime.now, comment='更新时间')
del_flag = Column(SmallInteger, nullable=False, default=0, comment='软删除标记:0正常,1删除')
__table_args__ = (
UniqueConstraint('tenant_no', 'category_id', 'product_id', name='uk_cert_category_product'),
Index('idx_cert_cat_prod_product', 'tenant_no', 'product_id', 'del_flag', 'scope_status'),
)
class PlCertQuotaRuleConfig(Base):
"""客户品类额度规则切点;每租户一行。"""
__tablename__ = 'pl_cert_quota_rule_config'
id = Column(String(64), primary_key=True, comment='主键UUID')
effective_at = Column(DateTime, nullable=True, comment='客户品类额度生效时间;空表示未配置')
tenant_no = Column(String(64), nullable=False, comment='租户编号')
order_num = Column(Integer, nullable=True, comment='排序号')
remark = Column(String(1000), nullable=True, comment='备注')
create_by = Column(String(64), nullable=True, comment='创建人')
create_dept_id = Column(String(64), nullable=False, default='', comment='创建部门')
create_time = Column(DateTime, nullable=False, default=datetime.now, comment='创建时间')
update_by = Column(String(64), nullable=True, comment='更新人')
update_time = Column(DateTime, nullable=False, default=datetime.now, onupdate=datetime.now, comment='更新时间')
del_flag = Column(SmallInteger, nullable=False, default=0, comment='软删除标记:0正常,1删除')
__table_args__ = (
UniqueConstraint('tenant_no', name='uk_cert_quota_rule_tenant'),
)