"""购买证、运输证额度与历史流水;区别于车辆人员证件。""" 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停用/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='用途') 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停用/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='申请单位名称或姓名') 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=False, comment='合同与证件绑定ID,须与usage的证件相同') contract_cert_product_id = Column(String(64), nullable=False, comment='本产品的适用范围明细ID:pl_contract_cert_product.id') contract_scope_revision = Column(Integer, nullable=False, comment='本次确认的合同证件适用范围版本') 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同单位带入/manual异单位人工填写') reserve_conversion_note = Column(String(1000), nullable=True, comment='异单位安排折算说明,manual时必填;不存自动换算系数') 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'), )