proposal.md 2.9 KB

Proposal

Why

客户一次运输常对应多份合同或同一合同内同品同包装多行(单价不同)。现行合同禁止同品同包装重复,运输计划每段只能选一份合同,用量按 (productId, packageSpec) 匹配,无法按合同明细行记账。计划员出车前已知道各合同行的目标量,归档时再确认实际量;司机与现场只需对货、不必见合同。

What Changes

  • 合同产品明细:允许同一合同内同一产品、同一包装规格出现多行(不同数量/单价)。一行多包装共享数量池仍保留。
  • 运输计划装货/送货段:允许选择多份合同(须属于该段客户)。段产品行绑定 contract_id + contract_product_id,填写目标量(plan_qty)。
  • 选品交互:从合同明细行选择(合同号、包装、单价、剩余),不按「仅产品名」合并。
  • 用量与硬拦:可安排量、安排运输硬拦、合同详情挂量均按合同产品行 ID 池,不再用包装唯一性做解析。
  • 保存计划:目标量允许暂时超过该行剩余;安排运输时超过则硬拦。
  • 归档:在已拆好的行上填实际量;有本车实发时各行合计须对齐。某行实际量超过该行剩余时红字高亮、指出行、二次确认后仍可归档,超交只记该行。
  • 司机/现场端:不展示合同号、单价、合同行;只展示产品与数量。
  • BREAKING:放开「同品包装不重复」后,未绑合同行的计划无法正确分账;新保存的段产品必须带合同行 ID(无合同/内部客户除外)。历史未绑行数据按旧复合键回退。

UI 示意:docs/superpowers/demos/2026-10-05-contract-plan-line-qty-demo.html。

Capabilities

New Capabilities

  • contract-line-plan-qty-bind:合同同品同包装多行;计划段多合同并绑定合同产品行;目标量/实际量分阶段校验;司机现场不暴露合同。

Modified Capabilities

  • 无基线 openspec/specs/。落地后覆盖 crm-contract-multi-package-shared-qty 中「同一 productId 下包装规格全局不重复」及「计划不绑 contractProductId」的假定;一行多包装共享池仍有效。

Impact

  • 后端:合同包装唯一校验;pl_plan_load_product / pl_plan_delivery_product(及必要的 pl_plan_product)增列;assert_at_most_one_contract;pl_contract_plan_qty.py 主键;安排硬拦;归档超交确认;arrange-qty API。
  • 前端 web-admin:ContractFormDialog 去重;PlPlanFormDialog 多合同与合同行选品;归档弹窗实际量、地磅合计、超交二次确认;合同详情按行挂量。
  • 小程序/现场:默认不改交互;若有合同号展示则隐藏。
  • 数据库:docs/sql/ + 迁移脚本。
  • 测试:合同多行保存、多合同计划、安排硬拦、归档超交确认、历史回退匹配。