pl_models.py 44 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739
  1. """运输计划管理模块数据模型"""
  2. from datetime import datetime
  3. from decimal import Decimal
  4. from sqlalchemy import (
  5. BigInteger,
  6. Column,
  7. DECIMAL,
  8. Date,
  9. DateTime,
  10. Integer,
  11. SmallInteger,
  12. String,
  13. Text,
  14. CHAR,
  15. ForeignKey,
  16. )
  17. from sqlalchemy.orm import relationship
  18. from app.core.database import Base
  19. # =============================================================================
  20. # 1. 基础数据:承运商、车辆、司机
  21. # =============================================================================
  22. class PlCarrier(Base):
  23. """承运商表 pl_carrier"""
  24. __tablename__ = "pl_carrier"
  25. id = Column(String(64), primary_key=True, comment="主键ID")
  26. carrier_name = Column(String(200), nullable=False, comment="承运商名称")
  27. contact_name = Column(String(100), nullable=True, comment="联系人")
  28. contact_phone = Column(String(32), nullable=True, comment="联系电话")
  29. status = Column(CHAR(1), nullable=False, default="1", comment="合作状态 1-合作中 0-已终止")
  30. tenant_no = Column(String(64), nullable=False, default="shanxia2.0", comment="租户编号")
  31. order_num = Column(Integer, nullable=True, comment="排序号")
  32. remark = Column(String(512), nullable=True, comment="备注")
  33. create_by = Column(String(64), nullable=True, comment="创建人id")
  34. create_dept_id = Column(String(64), nullable=False, default="", comment="创建人部门ID")
  35. create_time = Column(DateTime, nullable=False, default=datetime.now, comment="创建时间")
  36. update_by = Column(String(64), nullable=True, comment="更新人id")
  37. update_time = Column(DateTime, nullable=False, default=datetime.now, onupdate=datetime.now, comment="更新时间")
  38. del_flag = Column(SmallInteger, nullable=False, default=0, comment="删除标记:0-正常 1-已删除")
  39. class PlVehicle(Base):
  40. """车辆表 pl_vehicle"""
  41. __tablename__ = "pl_vehicle"
  42. id = Column(String(64), primary_key=True, comment="主键ID")
  43. vehicle_type = Column(String(20), nullable=False, comment="车辆类型 self-自有 carrier-承运商")
  44. carrier_id = Column(String(64), nullable=True, comment="承运商ID(类型为承运商时必填)")
  45. carrier_name = Column(String(200), nullable=True, comment="承运商名称(冗余)")
  46. license_plate = Column(String(20), nullable=False, unique=True, comment="车牌号")
  47. trailer_no = Column(String(20), nullable=True, comment="挂车号")
  48. default_driver_id = Column(String(64), nullable=True, comment="默认司机ID")
  49. default_driver_name = Column(String(100), nullable=True, comment="默认司机姓名(冗余)")
  50. load_capacity = Column(DECIMAL(10, 2), nullable=True, comment="载重(吨)")
  51. vehicle_status = Column(String(20), nullable=False, default="available", comment="车辆状态 available-可用 maintaining-维修中 scrapped-报废")
  52. tenant_no = Column(String(64), nullable=False, default="shanxia2.0", comment="租户编号")
  53. order_num = Column(Integer, nullable=True, comment="排序号")
  54. remark = Column(String(512), nullable=True, comment="备注")
  55. create_by = Column(String(64), nullable=True, comment="创建人id")
  56. create_dept_id = Column(String(64), nullable=False, default="", comment="创建人部门ID")
  57. create_time = Column(DateTime, nullable=False, default=datetime.now, comment="创建时间")
  58. update_by = Column(String(64), nullable=True, comment="更新人id")
  59. update_time = Column(DateTime, nullable=False, default=datetime.now, onupdate=datetime.now, comment="更新时间")
  60. del_flag = Column(SmallInteger, nullable=False, default=0, comment="删除标记:0-正常 1-已删除")
  61. class PlPersonnel(Base):
  62. """人员表 pl_personnel"""
  63. __tablename__ = "pl_personnel"
  64. id = Column(String(64), primary_key=True, comment="主键ID")
  65. personnel_name = Column(String(100), nullable=False, comment="姓名")
  66. phone_no = Column(String(32), nullable=True, comment="手机号(非必填)")
  67. age = Column(Integer, nullable=True, comment="年龄")
  68. id_card_no = Column(String(32), nullable=True, comment="身份证号")
  69. status = Column(CHAR(1), nullable=False, default="1", comment="状态 1-在职 0-停用")
  70. tenant_no = Column(String(64), nullable=False, default="shanxia2.0", comment="租户编号")
  71. order_num = Column(Integer, nullable=True, comment="排序号")
  72. remark = Column(String(512), nullable=True, comment="备注")
  73. create_by = Column(String(64), nullable=True, comment="创建人id")
  74. create_dept_id = Column(String(64), nullable=False, default="", comment="创建人部门ID")
  75. create_time = Column(DateTime, nullable=False, default=datetime.now, comment="创建时间")
  76. update_by = Column(String(64), nullable=True, comment="更新人id")
  77. update_time = Column(DateTime, nullable=False, default=datetime.now, onupdate=datetime.now, comment="更新时间")
  78. del_flag = Column(SmallInteger, nullable=False, default=0, comment="删除标记:0-正常 1-已删除")
  79. class PlCert(Base):
  80. """证书表 pl_cert"""
  81. __tablename__ = "pl_cert"
  82. id = Column(String(64), primary_key=True, comment="主键ID")
  83. owner_type = Column(String(20), nullable=False, comment="归属类型 vehicle-车辆 personnel-人员")
  84. owner_id = Column(String(64), nullable=False, comment="归属主体ID")
  85. cert_name = Column(String(100), nullable=False, comment="证书名称")
  86. cert_no = Column(String(64), nullable=True, comment="证号")
  87. expire_date = Column(Date, nullable=True, comment="有效期")
  88. remind_days = Column(Integer, nullable=False, default=30, comment="提前提醒天数")
  89. attachment_urls = Column(String(2000), nullable=True, comment="附件URL(逗号分隔)")
  90. status = Column(String(20), nullable=False, default="valid", comment="状态 valid-有效 expired-已过期 revoked-已作废")
  91. tenant_no = Column(String(64), nullable=False, default="shanxia2.0", comment="租户编号")
  92. order_num = Column(Integer, nullable=True, comment="排序号")
  93. remark = Column(String(512), nullable=True, comment="备注")
  94. create_by = Column(String(64), nullable=True, comment="创建人id")
  95. create_dept_id = Column(String(64), nullable=False, default="", comment="创建人部门ID")
  96. create_time = Column(DateTime, nullable=False, default=datetime.now, comment="创建时间")
  97. update_by = Column(String(64), nullable=True, comment="更新人id")
  98. update_time = Column(DateTime, nullable=False, default=datetime.now, onupdate=datetime.now, comment="更新时间")
  99. del_flag = Column(SmallInteger, nullable=False, default=0, comment="删除标记:0-正常 1-已删除")
  100. class PlDriver(Base):
  101. """司机表 pl_driver(兼容旧表,迁移后逐步废弃)"""
  102. __tablename__ = "pl_driver"
  103. id = Column(String(64), primary_key=True, comment="主键ID")
  104. driver_name = Column(String(100), nullable=False, comment="姓名")
  105. phone_no = Column(String(32), nullable=False, comment="手机号")
  106. id_card_no = Column(String(32), nullable=True, comment="身份证号")
  107. driving_license_no = Column(String(32), nullable=True, comment="驾驶证号")
  108. driving_license_expire = Column(Date, nullable=True, comment="驾驶证有效期")
  109. vehicle_license_no = Column(String(32), nullable=True, comment="行驶证号")
  110. vehicle_license_expire = Column(Date, nullable=True, comment="行驶证有效期")
  111. hazmat_cert_no = Column(String(32), nullable=True, comment="危化品证号")
  112. hazmat_cert_expire = Column(Date, nullable=True, comment="危化品证有效期")
  113. tenant_no = Column(String(64), nullable=False, default="shanxia2.0", comment="租户编号")
  114. order_num = Column(Integer, nullable=True, comment="排序号")
  115. remark = Column(String(512), nullable=True, comment="备注")
  116. create_by = Column(String(64), nullable=True, comment="创建人id")
  117. create_dept_id = Column(String(64), nullable=False, default="", comment="创建人部门ID")
  118. create_time = Column(DateTime, nullable=False, default=datetime.now, comment="创建时间")
  119. update_by = Column(String(64), nullable=True, comment="更新人id")
  120. update_time = Column(DateTime, nullable=False, default=datetime.now, onupdate=datetime.now, comment="更新时间")
  121. del_flag = Column(SmallInteger, nullable=False, default=0, comment="删除标记:0-正常 1-已删除")
  122. class PlVehiclePersonnel(Base):
  123. """车辆-人员关联表 pl_vehicle_personnel"""
  124. __tablename__ = "pl_vehicle_personnel"
  125. id = Column(String(64), primary_key=True, comment="主键ID")
  126. vehicle_id = Column(String(64), nullable=False, comment="车辆ID")
  127. personnel_id = Column(String(64), nullable=False, comment="人员ID")
  128. role = Column(String(20), nullable=False, default="driver", comment="角色 driver-司机 escort-押运员")
  129. is_default = Column(SmallInteger, nullable=False, default=0, comment="是否默认司机 0-否 1-是")
  130. tenant_no = Column(String(64), nullable=False, default="shanxia2.0", comment="租户编号")
  131. order_num = Column(Integer, nullable=True, comment="排序号")
  132. remark = Column(String(512), nullable=True, comment="关联备注")
  133. create_by = Column(String(64), nullable=True, comment="创建人id")
  134. create_dept_id = Column(String(64), nullable=False, default="", comment="创建人部门ID")
  135. create_time = Column(DateTime, nullable=False, default=datetime.now, comment="创建时间")
  136. update_by = Column(String(64), nullable=True, comment="更新人id")
  137. update_time = Column(DateTime, nullable=False, default=datetime.now, onupdate=datetime.now, comment="更新时间")
  138. del_flag = Column(SmallInteger, nullable=False, default=0, comment="删除标记:0-正常 1-已删除")
  139. class PlVehicleDriver(Base):
  140. """车辆-司机关联表 pl_vehicle_driver(兼容旧表)"""
  141. __tablename__ = "pl_vehicle_driver"
  142. id = Column(String(64), primary_key=True, comment="主键ID")
  143. vehicle_id = Column(String(64), nullable=False, comment="车辆ID")
  144. driver_id = Column(String(64), nullable=False, comment="司机ID")
  145. is_default = Column(SmallInteger, nullable=False, default=0, comment="是否默认 0-否 1-是")
  146. tenant_no = Column(String(64), nullable=False, default="shanxia2.0", comment="租户编号")
  147. order_num = Column(Integer, nullable=True, comment="排序号")
  148. remark = Column(String(512), nullable=True, comment="备注")
  149. create_by = Column(String(64), nullable=True, comment="创建人id")
  150. create_dept_id = Column(String(64), nullable=False, default="", comment="创建人部门ID")
  151. create_time = Column(DateTime, nullable=False, default=datetime.now, comment="创建时间")
  152. update_by = Column(String(64), nullable=True, comment="更新人id")
  153. update_time = Column(DateTime, nullable=False, default=datetime.now, onupdate=datetime.now, comment="更新时间")
  154. del_flag = Column(SmallInteger, nullable=False, default=0, comment="删除标记:0-正常 1-已删除")
  155. # =============================================================================
  156. # 2. 计划管理:计划主表、产品明细、变更记录
  157. # =============================================================================
  158. class PlPlan(Base):
  159. """计划主表 pl_plan"""
  160. __tablename__ = "pl_plan"
  161. id = Column(String(64), primary_key=True, comment="主键ID")
  162. # 编号信息
  163. plan_no = Column(String(32), nullable=False, unique=True, comment="计划订单编号 SXDDHYYYYMMDD######")
  164. plan_date = Column(Date, nullable=False, comment="计划日期")
  165. # 基本信息
  166. belongs_company = Column(String(20), nullable=False, comment="归属公司 shanxia-安庆山峡 yundong-安徽云栋")
  167. plan_type = Column(String(20), nullable=False, comment="单据类型 direct-直销单 inbound-入库单 outbound-出库单")
  168. follow_status = Column(String(30), nullable=False, default="draft", comment="跟进状态")
  169. transport_status = Column(String(20), nullable=False, default="pending", comment="运输安排状态 pending-待安排 arranged-已安排")
  170. archive_status = Column(String(20), nullable=False, default="unarchived", comment="归档状态 unarchived-未归档 archived-已归档")
  171. complete_status = Column(String(10), nullable=False, default="no", comment="完成状态 yes-是 no-否")
  172. # 合同关联
  173. contract_id = Column(String(64), nullable=True, comment="CRM合同ID")
  174. contract_no = Column(String(50), nullable=True, comment="合同编号")
  175. # 供应商与目的地
  176. supplier_id = Column(String(64), nullable=True, comment="供应商ID")
  177. supplier_name = Column(String(200), nullable=True, comment="供应商名称")
  178. destination_id = Column(String(64), nullable=True, comment="目的地ID")
  179. destination_name = Column(String(200), nullable=True, comment="目的地名称")
  180. # 客户信息(冗余自合同)
  181. customer_id = Column(String(64), nullable=True, comment="客户ID")
  182. customer_name = Column(String(200), nullable=True, comment="客户名称")
  183. contact_name = Column(String(100), nullable=True, comment="联系人")
  184. contact_phone = Column(String(32), nullable=True, comment="联系电话")
  185. party_a = Column(String(200), nullable=True, comment="甲方")
  186. party_b = Column(String(200), nullable=True, comment="乙方")
  187. # 合同有效期
  188. contract_start_date = Column(Date, nullable=True, comment="合同开始日期")
  189. contract_end_date = Column(Date, nullable=True, comment="合同结束日期")
  190. # 送货与结算
  191. delivery_method = Column(String(20), nullable=True, comment="送货方式 self_pick-山峡自提 one_ticket-一票制 customer_pick-客户自提")
  192. settlement_method = Column(String(50), nullable=True, comment="结算方式")
  193. # 运输信息
  194. has_freight = Column(SmallInteger, nullable=False, default=0, comment="是否有运输费用 0-否 1-是")
  195. pickup_address = Column(String(500), nullable=True, comment="取货地址")
  196. pickup_time = Column(DateTime, nullable=True, comment="取货时间")
  197. pickup_notes = Column(String(500), nullable=True, comment="取货注意事项")
  198. destination_address = Column(String(500), nullable=True, comment="目的地地址")
  199. delivery_time = Column(DateTime, nullable=True, comment="送达时间")
  200. destination_notes = Column(String(500), nullable=True, comment="目的地注意事项")
  201. transport_id = Column(String(64), nullable=True, comment="运输ID")
  202. transport_no = Column(String(32), nullable=True, comment="运输编号")
  203. vehicle_id = Column(String(64), nullable=True, comment="车辆ID")
  204. license_plate = Column(String(20), nullable=True, comment="车牌号")
  205. driver_id = Column(String(64), nullable=True, comment="司机ID")
  206. driver_name = Column(String(100), nullable=True, comment="司机姓名")
  207. # 金额汇总
  208. total_amount = Column(DECIMAL(15, 2), nullable=False, default=0, comment="计划总金额")
  209. freight_amount = Column(DECIMAL(15, 2), nullable=False, default=0, comment="运费合计")
  210. # 通知信息
  211. notify_message = Column(Text, nullable=True, comment="通知信息(标准模板)")
  212. # 跟进人
  213. follow_user_id = Column(String(64), nullable=True, comment="跟进人ID")
  214. follow_user_name = Column(String(100), nullable=True, comment="跟进人姓名")
  215. # 公共字段
  216. tenant_no = Column(String(64), nullable=False, default="shanxia2.0", comment="租户编号")
  217. order_num = Column(Integer, nullable=True, comment="排序号")
  218. remark = Column(String(512), nullable=True, comment="备注")
  219. create_by = Column(String(64), nullable=True, comment="创建人id")
  220. create_dept_id = Column(String(64), nullable=False, default="", comment="创建人部门ID")
  221. create_time = Column(DateTime, nullable=False, default=datetime.now, comment="创建时间")
  222. update_by = Column(String(64), nullable=True, comment="更新人id")
  223. update_time = Column(DateTime, nullable=False, default=datetime.now, onupdate=datetime.now, comment="更新时间")
  224. del_flag = Column(SmallInteger, nullable=False, default=0, comment="删除标记:0-正常 1-已删除")
  225. class PlPlanProduct(Base):
  226. """计划产品明细表 pl_plan_product"""
  227. __tablename__ = "pl_plan_product"
  228. id = Column(String(64), primary_key=True, comment="主键ID")
  229. plan_id = Column(String(64), nullable=False, comment="计划ID")
  230. # 产品信息
  231. product_id = Column(String(64), nullable=False, comment="产品ID")
  232. product_no = Column(String(50), nullable=False, comment="产品编号")
  233. product_name = Column(String(200), nullable=False, comment="产品名称")
  234. model = Column(String(100), nullable=True, comment="规格型号")
  235. unit = Column(String(20), nullable=False, default="吨", comment="单位")
  236. category_name = Column(String(200), nullable=True, comment="产品分类")
  237. package_spec = Column(String(200), nullable=True, comment="包装规格")
  238. delivery_method = Column(String(50), nullable=True, comment="送货方式")
  239. quantity = Column(DECIMAL(15, 3), nullable=True, comment="合同数量")
  240. actual_qty = Column(DECIMAL(15, 3), nullable=True, comment="实际数量")
  241. tax_price = Column(DECIMAL(15, 4), nullable=True, comment="含税单价")
  242. tax_amount = Column(DECIMAL(15, 2), nullable=True, comment="税费")
  243. tax_subtotal = Column(DECIMAL(15, 2), nullable=True, comment="含税总价")
  244. # 产品属性(冗余自产品主数据)
  245. is_explosive = Column(SmallInteger, nullable=False, default=0, comment="是否易制爆 0-否 1-是")
  246. is_toxic = Column(SmallInteger, nullable=False, default=0, comment="是否易制毒 0-否 1-是")
  247. # 购买证/运输证
  248. purchase_cert_url = Column(String(500), nullable=True, comment="购买证URL")
  249. transport_cert_url = Column(String(500), nullable=True, comment="运输证URL")
  250. # 入库信息
  251. inbound_estimate_qty = Column(DECIMAL(15, 3), nullable=True, comment="入库预估数")
  252. inbound_qty = Column(DECIMAL(15, 3), nullable=True, comment="入库数")
  253. inbound_price = Column(DECIMAL(15, 4), nullable=True, comment="入库价")
  254. inbound_amount = Column(DECIMAL(15, 2), nullable=True, comment="入库金额")
  255. # 出库信息
  256. outbound_estimate_qty = Column(DECIMAL(15, 3), nullable=True, comment="出库预估数")
  257. outbound_qty = Column(DECIMAL(15, 3), nullable=True, comment="出库数")
  258. outbound_price = Column(DECIMAL(15, 4), nullable=True, comment="出库单价")
  259. outbound_amount = Column(DECIMAL(15, 2), nullable=True, comment="出库金额")
  260. # 公共字段
  261. tenant_no = Column(String(64), nullable=False, default="shanxia2.0", comment="租户编号")
  262. order_num = Column(Integer, nullable=True, comment="排序号")
  263. remark = Column(String(512), nullable=True, comment="备注")
  264. create_by = Column(String(64), nullable=True, comment="创建人id")
  265. create_dept_id = Column(String(64), nullable=False, default="", comment="创建人部门ID")
  266. create_time = Column(DateTime, nullable=False, default=datetime.now, comment="创建时间")
  267. update_by = Column(String(64), nullable=True, comment="更新人id")
  268. update_time = Column(DateTime, nullable=False, default=datetime.now, onupdate=datetime.now, comment="更新时间")
  269. del_flag = Column(SmallInteger, nullable=False, default=0, comment="删除标记:0-正常 1-已删除")
  270. class PlPlanChange(Base):
  271. """计划变更记录表 pl_plan_change"""
  272. __tablename__ = "pl_plan_change"
  273. id = Column(String(64), primary_key=True, comment="主键ID")
  274. plan_id = Column(String(64), nullable=False, comment="计划ID")
  275. change_type = Column(String(30), nullable=False, comment="变更类型")
  276. change_content = Column(Text, nullable=True, comment="变更内容")
  277. change_user_id = Column(String(64), nullable=True, comment="变更人ID")
  278. change_user_name = Column(String(100), nullable=True, comment="变更人姓名")
  279. tenant_no = Column(String(64), nullable=False, default="shanxia2.0", comment="租户编号")
  280. order_num = Column(Integer, nullable=True, comment="排序号")
  281. remark = Column(String(512), nullable=True, comment="备注")
  282. create_by = Column(String(64), nullable=True, comment="创建人id")
  283. create_dept_id = Column(String(64), nullable=False, default="", comment="创建人部门ID")
  284. create_time = Column(DateTime, nullable=False, default=datetime.now, comment="创建时间")
  285. update_by = Column(String(64), nullable=True, comment="更新人id")
  286. update_time = Column(DateTime, nullable=False, default=datetime.now, onupdate=datetime.now, comment="更新时间")
  287. del_flag = Column(SmallInteger, nullable=False, default=0, comment="删除标记:0-正常 1-已删除")
  288. # =============================================================================
  289. # 3. 运输管理:运输表、审批记录
  290. # =============================================================================
  291. class PlTransport(Base):
  292. """运输表 pl_transport"""
  293. __tablename__ = "pl_transport"
  294. id = Column(String(64), primary_key=True, comment="主键ID")
  295. transport_no = Column(String(32), nullable=False, unique=True, comment="运输编号 SXYS######")
  296. # 车辆与司机
  297. vehicle_id = Column(String(64), nullable=True, comment="车辆ID")
  298. license_plate = Column(String(20), nullable=True, comment="车牌号")
  299. driver_id = Column(String(64), nullable=True, comment="司机ID")
  300. driver_name = Column(String(100), nullable=True, comment="司机姓名")
  301. driver_phone = Column(String(32), nullable=True, comment="司机电话")
  302. # 承运商
  303. carrier_id = Column(String(64), nullable=True, comment="承运商ID")
  304. carrier_name = Column(String(200), nullable=True, comment="承运商名称")
  305. # 运输信息
  306. transport_medium = Column(String(100), nullable=True, comment="运输介质")
  307. start_point = Column(String(200), nullable=True, comment="运输起点")
  308. end_point = Column(String(200), nullable=True, comment="运输终点")
  309. distance_km = Column(DECIMAL(10, 2), nullable=True, comment="运输公里数")
  310. unit = Column(String(20), nullable=True, comment="计量单位 吨/趟")
  311. transport_qty = Column(DECIMAL(15, 3), nullable=True, comment="运输量(按重量计费基数)")
  312. # 运费
  313. freight_price = Column(DECIMAL(15, 4), nullable=True, comment="运输单价")
  314. freight_amount = Column(DECIMAL(15, 2), nullable=False, default=0, comment="运输费用")
  315. freight_type = Column(String(20), nullable=False, default="by_weight", comment="运费计算方式 by_weight-按重量 by_trip-按趟次")
  316. has_invoice = Column(SmallInteger, nullable=False, default=0, comment="是否开票 0-否 1-是")
  317. # 二维码
  318. qr_code = Column(String(500), nullable=True, comment="二维码内容")
  319. qr_expire_date = Column(Date, nullable=True, comment="二维码有效期")
  320. driver_access_token = Column(String(64), nullable=True, comment="司机免登录访问令牌")
  321. # 运输状态
  322. transport_status = Column(String(20), nullable=False, default="draft", comment="运输状态 draft-草稿 pending-待执行 executing-执行中 completed-已完成 cancelled-已取消")
  323. approval_status = Column(String(20), nullable=False, default="none", comment="审批状态 none-无需 pending-审批中 approved-已通过 rejected-已拒绝")
  324. # 司机回传信息
  325. feedback_time = Column(DateTime, nullable=True, comment="回传时间")
  326. feedback_qty = Column(DECIMAL(15, 3), nullable=True, comment="回传数量")
  327. feedback_images = Column(Text, nullable=True, comment="回传图片URLs(JSON数组)")
  328. feedback_remark = Column(String(500), nullable=True, comment="回传备注")
  329. # 公共字段
  330. tenant_no = Column(String(64), nullable=False, default="shanxia2.0", comment="租户编号")
  331. order_num = Column(Integer, nullable=True, comment="排序号")
  332. remark = Column(String(512), nullable=True, comment="备注")
  333. create_by = Column(String(64), nullable=True, comment="创建人id")
  334. create_dept_id = Column(String(64), nullable=False, default="", comment="创建人部门ID")
  335. create_time = Column(DateTime, nullable=False, default=datetime.now, comment="创建时间")
  336. update_by = Column(String(64), nullable=True, comment="更新人id")
  337. update_time = Column(DateTime, nullable=False, default=datetime.now, onupdate=datetime.now, comment="更新时间")
  338. del_flag = Column(SmallInteger, nullable=False, default=0, comment="删除标记:0-正常 1-已删除")
  339. class PlTransportDbLink(Base):
  340. """运输-地磅出入库关联 pl_transport_db_link"""
  341. __tablename__ = "pl_transport_db_link"
  342. id = Column(String(64), primary_key=True, comment="主键ID")
  343. transport_id = Column(String(64), nullable=False, comment="运输单ID")
  344. plan_id = Column(String(64), nullable=False, comment="运输计划ID")
  345. plan_product_id = Column(String(64), nullable=False, comment="计划产品行ID")
  346. db_purchase_plan_id = Column(String(64), nullable=False, comment="地磅计划ID")
  347. db_inventory_id = Column(String(64), nullable=False, comment="出入库单ID")
  348. tenant_no = Column(String(64), nullable=False, default="shanxia2.0", comment="租户编号")
  349. order_num = Column(Integer, nullable=True, comment="排序号")
  350. remark = Column(String(512), nullable=True, comment="备注")
  351. create_by = Column(String(64), nullable=True, comment="创建人id")
  352. create_dept_id = Column(String(64), nullable=False, default="", comment="创建人部门ID")
  353. create_time = Column(DateTime, nullable=False, default=datetime.now, comment="创建时间")
  354. update_by = Column(String(64), nullable=True, comment="更新人id")
  355. update_time = Column(DateTime, nullable=False, default=datetime.now, onupdate=datetime.now, comment="更新时间")
  356. del_flag = Column(SmallInteger, nullable=False, default=0, comment="删除标记:0-正常 1-已删除")
  357. class PlPlanTransport(Base):
  358. """计划-运输关联表 pl_plan_transport"""
  359. __tablename__ = "pl_plan_transport"
  360. id = Column(String(64), primary_key=True, comment="主键ID")
  361. plan_id = Column(String(64), nullable=False, comment="计划ID")
  362. transport_id = Column(String(64), nullable=False, comment="运输ID")
  363. tenant_no = Column(String(64), nullable=False, default="shanxia2.0", comment="租户编号")
  364. order_num = Column(Integer, nullable=True, comment="排序号")
  365. remark = Column(String(512), nullable=True, comment="备注")
  366. create_by = Column(String(64), nullable=True, comment="创建人id")
  367. create_dept_id = Column(String(64), nullable=False, default="", comment="创建人部门ID")
  368. create_time = Column(DateTime, nullable=False, default=datetime.now, comment="创建时间")
  369. update_by = Column(String(64), nullable=True, comment="更新人id")
  370. update_time = Column(DateTime, nullable=False, default=datetime.now, onupdate=datetime.now, comment="更新时间")
  371. del_flag = Column(SmallInteger, nullable=False, default=0, comment="删除标记:0-正常 1-已删除")
  372. class PlTransportSiteLink(Base):
  373. """运输计划现场链接 pl_transport_site_link(与地磅出入库单解耦)"""
  374. __tablename__ = "pl_transport_site_link"
  375. id = Column(String(64), primary_key=True, comment="主键ID")
  376. transport_id = Column(String(64), nullable=False, comment="运输单ID")
  377. plan_id = Column(String(64), nullable=False, comment="运输计划ID")
  378. plan_product_id = Column(String(64), nullable=False, comment="计划产品行ID")
  379. site_access_token = Column(String(64), nullable=False, comment="现场人员免登录访问令牌")
  380. business_type = Column(String(20), nullable=False, comment="业务类型:入库/出库")
  381. partner_company = Column(String(200), nullable=True, comment="往来单位")
  382. product_id = Column(String(64), nullable=True, comment="CRM产品ID")
  383. product = Column(String(200), nullable=True, comment="产品名称快照")
  384. specification = Column(String(200), nullable=True, comment="规格快照")
  385. quantity = Column(DECIMAL(15, 3), nullable=True, comment="数量(吨)")
  386. vehicle_no = Column(String(32), nullable=True, comment="车牌号")
  387. plan_no = Column(String(64), nullable=True, comment="运输计划号")
  388. plan_date = Column(Date, nullable=True, comment="计划日期")
  389. site_feedback_remark = Column(String(500), nullable=True, comment="现场回执备注")
  390. site_feedback_images = Column(Text, nullable=True, comment="现场回执附件URLs(JSON数组)")
  391. site_feedback_time = Column(DateTime, nullable=True, comment="现场回执保存时间")
  392. tenant_no = Column(String(64), nullable=False, default="shanxia2.0", comment="租户编号")
  393. order_num = Column(Integer, nullable=True, comment="排序号")
  394. remark = Column(String(512), nullable=True, comment="备注")
  395. create_by = Column(String(64), nullable=True, comment="创建人id")
  396. create_dept_id = Column(String(64), nullable=False, default="", comment="创建人部门ID")
  397. create_time = Column(DateTime, nullable=False, default=datetime.now, comment="创建时间")
  398. update_by = Column(String(64), nullable=True, comment="更新人id")
  399. update_time = Column(DateTime, nullable=False, default=datetime.now, onupdate=datetime.now, comment="更新时间")
  400. del_flag = Column(SmallInteger, nullable=False, default=0, comment="删除标记:0-正常 1-已删除")
  401. class PlTransportApproval(Base):
  402. """运输审批记录表 pl_transport_approval"""
  403. __tablename__ = "pl_transport_approval"
  404. id = Column(String(64), primary_key=True, comment="主键ID")
  405. transport_id = Column(String(64), nullable=False, comment="运输ID")
  406. approver_id = Column(String(64), nullable=False, comment="审批人ID")
  407. approver_name = Column(String(100), nullable=False, comment="审批人姓名")
  408. approval_order = Column(Integer, nullable=False, comment="审批顺序")
  409. status = Column(String(20), nullable=False, default="pending", comment="审批状态 pending-待审批 approved-已通过 rejected-已拒绝")
  410. comment = Column(String(500), nullable=True, comment="审批意见")
  411. approval_time = Column(DateTime, nullable=True, comment="审批时间")
  412. tenant_no = Column(String(64), nullable=False, default="shanxia2.0", comment="租户编号")
  413. order_num = Column(Integer, nullable=True, comment="排序号")
  414. remark = Column(String(512), nullable=True, comment="备注")
  415. create_by = Column(String(64), nullable=True, comment="创建人id")
  416. create_dept_id = Column(String(64), nullable=False, default="", comment="创建人部门ID")
  417. create_time = Column(DateTime, nullable=False, default=datetime.now, comment="创建时间")
  418. update_by = Column(String(64), nullable=True, comment="更新人id")
  419. update_time = Column(DateTime, nullable=False, default=datetime.now, onupdate=datetime.now, comment="更新时间")
  420. del_flag = Column(SmallInteger, nullable=False, default=0, comment="删除标记:0-正常 1-已删除")
  421. # =============================================================================
  422. # 4. 运费结算
  423. # =============================================================================
  424. class PlFreightSettlement(Base):
  425. """运费结算表 pl_freight_settlement"""
  426. __tablename__ = "pl_freight_settlement"
  427. id = Column(String(64), primary_key=True, comment="主键ID")
  428. settlement_no = Column(String(32), nullable=False, unique=True, comment="结算单编号")
  429. # 结算金额
  430. total_freight = Column(DECIMAL(15, 2), nullable=False, default=0, comment="运费合计")
  431. invoice_amount = Column(DECIMAL(15, 2), nullable=True, comment="发票金额")
  432. # 发票信息
  433. invoice_no = Column(String(50), nullable=True, comment="发票号")
  434. invoice_date = Column(Date, nullable=True, comment="开票日期")
  435. invoice_attachment_urls = Column(Text, nullable=True, comment="发票附件URLs,逗号分隔")
  436. # 结算状态
  437. settlement_status = Column(String(20), nullable=False, default="pending", comment="结算状态 pending-待提交 submitted-已提交 approved-审核通过 confirmed-已确认")
  438. # 公共字段
  439. tenant_no = Column(String(64), nullable=False, default="shanxia2.0", comment="租户编号")
  440. order_num = Column(Integer, nullable=True, comment="排序号")
  441. remark = Column(String(512), nullable=True, comment="备注")
  442. create_by = Column(String(64), nullable=True, comment="创建人id")
  443. create_dept_id = Column(String(64), nullable=False, default="", comment="创建人部门ID")
  444. create_time = Column(DateTime, nullable=False, default=datetime.now, comment="创建时间")
  445. update_by = Column(String(64), nullable=True, comment="更新人id")
  446. update_time = Column(DateTime, nullable=False, default=datetime.now, onupdate=datetime.now, comment="更新时间")
  447. del_flag = Column(SmallInteger, nullable=False, default=0, comment="删除标记:0-正常 1-已删除")
  448. class PlFreightSettlementApproval(Base):
  449. """运费结算审批 pl_freight_settlement_approval"""
  450. __tablename__ = "pl_freight_settlement_approval"
  451. id = Column(String(64), primary_key=True, comment="主键ID")
  452. settlement_id = Column(String(64), nullable=False, comment="结算单ID")
  453. step = Column(Integer, nullable=False, default=1, comment="步骤序号")
  454. step_name = Column(String(50), nullable=True, comment="步骤名称")
  455. approver_id = Column(String(64), nullable=False, comment="审批人ID")
  456. approver_name = Column(String(64), nullable=True, comment="审批人姓名")
  457. approval_type = Column(String(20), nullable=False, default="sequential", comment="审批类型")
  458. approval_result = Column(String(20), nullable=False, default="pending", comment="审批结果")
  459. approval_opinion = Column(String(500), nullable=True, comment="审批意见")
  460. approval_time = Column(DateTime, nullable=True, comment="审批时间")
  461. is_current = Column(SmallInteger, nullable=False, default=0, comment="是否当前节点")
  462. tenant_no = Column(String(64), nullable=False, default="shanxia2.0", comment="租户编号")
  463. order_num = Column(Integer, nullable=True, comment="排序号")
  464. remark = Column(String(512), nullable=True, comment="备注")
  465. create_by = Column(String(64), nullable=True, comment="创建人id")
  466. create_dept_id = Column(String(64), nullable=False, default="", comment="创建人部门ID")
  467. create_time = Column(DateTime, nullable=False, default=datetime.now, comment="创建时间")
  468. update_by = Column(String(64), nullable=True, comment="更新人id")
  469. update_time = Column(DateTime, nullable=False, default=datetime.now, onupdate=datetime.now, comment="更新时间")
  470. del_flag = Column(SmallInteger, nullable=False, default=0, comment="删除标记:0-正常 1-已删除")
  471. class PlFreightSettlementTransport(Base):
  472. """结算单-运输关联表 pl_freight_settlement_transport"""
  473. __tablename__ = "pl_freight_settlement_transport"
  474. id = Column(String(64), primary_key=True, comment="主键ID")
  475. settlement_id = Column(String(64), nullable=False, comment="结算单ID")
  476. transport_id = Column(String(64), nullable=False, comment="运输ID")
  477. freight_amount = Column(DECIMAL(15, 2), nullable=False, comment="运费金额")
  478. tenant_no = Column(String(64), nullable=False, default="shanxia2.0", comment="租户编号")
  479. order_num = Column(Integer, nullable=True, comment="排序号")
  480. remark = Column(String(512), nullable=True, comment="备注")
  481. create_by = Column(String(64), nullable=True, comment="创建人id")
  482. create_dept_id = Column(String(64), nullable=False, default="", comment="创建人部门ID")
  483. create_time = Column(DateTime, nullable=False, default=datetime.now, comment="创建时间")
  484. update_by = Column(String(64), nullable=True, comment="更新人id")
  485. update_time = Column(DateTime, nullable=False, default=datetime.now, onupdate=datetime.now, comment="更新时间")
  486. del_flag = Column(SmallInteger, nullable=False, default=0, comment="删除标记:0-正常 1-已删除")
  487. class PlRemittanceVoucher(Base):
  488. """汇款凭证表 pl_remittance_voucher"""
  489. __tablename__ = "pl_remittance_voucher"
  490. id = Column(String(64), primary_key=True, comment="主键ID")
  491. settlement_id = Column(String(64), nullable=False, comment="结算单ID")
  492. voucher_no = Column(String(32), nullable=True, comment="凭证编号")
  493. remittance_date = Column(Date, nullable=True, comment="汇款日期")
  494. remittance_amount = Column(DECIMAL(15, 2), nullable=True, comment="汇款金额")
  495. voucher_urls = Column(Text, nullable=True, comment="凭证文件URLs(JSON数组)")
  496. tenant_no = Column(String(64), nullable=False, default="shanxia2.0", comment="租户编号")
  497. order_num = Column(Integer, nullable=True, comment="排序号")
  498. remark = Column(String(512), nullable=True, comment="备注")
  499. create_by = Column(String(64), nullable=True, comment="创建人id")
  500. create_dept_id = Column(String(64), nullable=False, default="", comment="创建人部门ID")
  501. create_time = Column(DateTime, nullable=False, default=datetime.now, comment="创建时间")
  502. update_by = Column(String(64), nullable=True, comment="更新人id")
  503. update_time = Column(DateTime, nullable=False, default=datetime.now, onupdate=datetime.now, comment="更新时间")
  504. del_flag = Column(SmallInteger, nullable=False, default=0, comment="删除标记:0-正常 1-已删除")
  505. # =============================================================================
  506. # 5. 库存管理
  507. # =============================================================================
  508. class PlInventory(Base):
  509. """库存表 pl_inventory"""
  510. __tablename__ = "pl_inventory"
  511. id = Column(String(64), primary_key=True, comment="主键ID")
  512. product_id = Column(String(64), nullable=False, comment="产品ID")
  513. product_no = Column(String(50), nullable=False, comment="产品编号")
  514. product_name = Column(String(200), nullable=False, comment="产品名称")
  515. model = Column(String(100), nullable=True, comment="规格型号")
  516. unit = Column(String(20), nullable=False, default="吨", comment="单位")
  517. # 库存数量与金额
  518. stock_qty = Column(DECIMAL(15, 3), nullable=False, default=0, comment="库存数量")
  519. stock_amount = Column(DECIMAL(15, 2), nullable=False, default=0, comment="库存金额")
  520. # 预警阈值
  521. low_stock_warning = Column(DECIMAL(15, 3), nullable=True, comment="最低库存预警值")
  522. high_stock_warning = Column(DECIMAL(15, 3), nullable=True, comment="最高库存预警值")
  523. # 公共字段
  524. tenant_no = Column(String(64), nullable=False, default="shanxia2.0", comment="租户编号")
  525. order_num = Column(Integer, nullable=True, comment="排序号")
  526. remark = Column(String(512), nullable=True, comment="备注")
  527. create_by = Column(String(64), nullable=True, comment="创建人id")
  528. create_dept_id = Column(String(64), nullable=False, default="", comment="创建人部门ID")
  529. create_time = Column(DateTime, nullable=False, default=datetime.now, comment="创建时间")
  530. update_by = Column(String(64), nullable=True, comment="更新人id")
  531. update_time = Column(DateTime, nullable=False, default=datetime.now, onupdate=datetime.now, comment="更新时间")
  532. del_flag = Column(SmallInteger, nullable=False, default=0, comment="删除标记:0-正常 1-已删除")
  533. class PlInventoryTransaction(Base):
  534. """库存流水表 pl_inventory_transaction"""
  535. __tablename__ = "pl_inventory_transaction"
  536. id = Column(String(64), primary_key=True, comment="主键ID")
  537. product_id = Column(String(64), nullable=False, comment="产品ID")
  538. product_name = Column(String(200), nullable=False, comment="产品名称")
  539. transaction_type = Column(String(20), nullable=False, comment="事务类型 inbound-入库 outbound-出库")
  540. plan_id = Column(String(64), nullable=True, comment="计划ID")
  541. plan_no = Column(String(32), nullable=True, comment="计划编号")
  542. # 数量与价格
  543. qty = Column(DECIMAL(15, 3), nullable=False, comment="变动数量(正数入库/负数出库)")
  544. unit_price = Column(DECIMAL(15, 4), nullable=False, comment="单价")
  545. amount = Column(DECIMAL(15, 2), nullable=False, comment="金额")
  546. stock_after = Column(DECIMAL(15, 3), nullable=False, comment="变动后库存")
  547. tenant_no = Column(String(64), nullable=False, default="shanxia2.0", comment="租户编号")
  548. order_num = Column(Integer, nullable=True, comment="排序号")
  549. remark = Column(String(512), nullable=True, comment="备注")
  550. create_by = Column(String(64), nullable=True, comment="创建人id")
  551. create_dept_id = Column(String(64), nullable=False, default="", comment="创建人部门ID")
  552. create_time = Column(DateTime, nullable=False, default=datetime.now, comment="创建时间")
  553. update_by = Column(String(64), nullable=True, comment="更新人id")
  554. update_time = Column(DateTime, nullable=False, default=datetime.now, onupdate=datetime.now, comment="更新时间")
  555. del_flag = Column(SmallInteger, nullable=False, default=0, comment="删除标记:0-正常 1-已删除")
  556. class PlInventoryWarning(Base):
  557. """库存预警表 pl_inventory_warning"""
  558. __tablename__ = "pl_inventory_warning"
  559. id = Column(String(64), primary_key=True, comment="主键ID")
  560. product_id = Column(String(64), nullable=False, comment="产品ID")
  561. product_name = Column(String(200), nullable=False, comment="产品名称")
  562. warning_type = Column(String(20), nullable=False, comment="预警类型 low-低于最低 high-高于最高")
  563. current_qty = Column(DECIMAL(15, 3), nullable=False, comment="当前库存")
  564. threshold_value = Column(DECIMAL(15, 3), nullable=False, comment="阈值")
  565. status = Column(String(20), nullable=False, default="pending", comment="状态 pending-待处理 resolved-已处理")
  566. resolve_time = Column(DateTime, nullable=True, comment="处理时间")
  567. resolve_remark = Column(String(500), nullable=True, comment="处理备注")
  568. tenant_no = Column(String(64), nullable=False, default="shanxia2.0", comment="租户编号")
  569. order_num = Column(Integer, nullable=True, comment="排序号")
  570. remark = Column(String(512), nullable=True, comment="备注")
  571. create_by = Column(String(64), nullable=True, comment="创建人id")
  572. create_dept_id = Column(String(64), nullable=False, default="", comment="创建人部门ID")
  573. create_time = Column(DateTime, nullable=False, default=datetime.now, comment="创建时间")
  574. update_by = Column(String(64), nullable=True, comment="更新人id")
  575. update_time = Column(DateTime, nullable=False, default=datetime.now, onupdate=datetime.now, comment="更新时间")
  576. del_flag = Column(SmallInteger, nullable=False, default=0, comment="删除标记:0-正常 1-已删除")
  577. class PlDocumentReminder(Base):
  578. """证件到期提醒表 pl_document_reminder"""
  579. __tablename__ = "pl_document_reminder"
  580. id = Column(String(64), primary_key=True, comment="主键ID")
  581. cert_id = Column(String(64), nullable=True, comment="证书ID")
  582. owner_type = Column(String(20), nullable=True, comment="归属类型 vehicle/personnel")
  583. owner_id = Column(String(64), nullable=True, comment="归属主体ID")
  584. owner_label = Column(String(200), nullable=True, comment="归属展示名(车牌/姓名)")
  585. driver_id = Column(String(64), nullable=True, comment="司机/人员ID(兼容)")
  586. driver_name = Column(String(100), nullable=True, comment="司机/人员姓名(兼容)")
  587. document_type = Column(String(100), nullable=False, comment="证件类型/证书名称")
  588. document_no = Column(String(50), nullable=True, comment="证件号")
  589. expire_date = Column(Date, nullable=False, comment="到期日期")
  590. days_remaining = Column(Integer, nullable=False, comment="剩余天数")
  591. status = Column(String(20), nullable=False, default="pending", comment="状态 pending-待处理 resolved-已处理")
  592. tenant_no = Column(String(64), nullable=False, default="shanxia2.0", comment="租户编号")
  593. order_num = Column(Integer, nullable=True, comment="排序号")
  594. remark = Column(String(512), nullable=True, comment="备注")
  595. create_by = Column(String(64), nullable=True, comment="创建人id")
  596. create_dept_id = Column(String(64), nullable=False, default="", comment="创建人部门ID")
  597. create_time = Column(DateTime, nullable=False, default=datetime.now, comment="创建时间")
  598. update_by = Column(String(64), nullable=True, comment="更新人id")
  599. update_time = Column(DateTime, nullable=False, default=datetime.now, onupdate=datetime.now, comment="更新时间")
  600. del_flag = Column(SmallInteger, nullable=False, default=0, comment="删除标记:0-正常 1-已删除")