Files
dealerhub/backend/PROGRESS_P0_GAPS.md

6.0 KiB
Raw Permalink Blame History

dealerhub · P0 改造实施报告(对标竞品差距清单)

依据:docs/差距分析与改造清单.md P0 六项 + docs/P0改造实施计划.md。 结果:六项全部落地,专项新增 38 个测试,全量回归 141 passed(原 103 + 新增 38),manage.py check 0 issues。

✅ #1 批次/效期管理(食品饮料线地基)

  • catalog.Product:新增 is_batch_managed / shelf_life_days;入库未传到期日时按生产日期+保质期自动推算
  • inventory.StockBatch:批次账(warehouse×product×batch_no 唯一),与总账 Stock 并行维护
  • inventory/services.inbound:批次商品必须带批次号(缺参报错);outbound 自动 FEFO 分摊(近效期优先,空到期日最后,先入先出兜底),分摊明细写入 StockMovement.batch_detail
  • 采购穿透:PurchaseBillLine 支持批次号/生产日期/到期日,过账写入批次账
  • 近效期预警:notify 新增 batch_expiry 规则(threshold=提前天数),按批次+当日去重,挂入 run_all_alert_checks
  • API:GET /api/v1/inventory/batches/(只读,支持 product/warehouse/in_stock 过滤)
  • 测试 9 例:批次必填、聚合一致、FEFO 跨批分摊、不足拒绝、预警去重、采购端到端、非批次回归

✅ #2 多单位换算(整件散包基础)

  • 新模型 catalog.UnitConversion(product, unit, rate):1 录入单位 = rate × 基本单位
  • catalog/services.to_base:换算服务,缺换算率抛 UnitConversionNotFound
  • sales/purchase 四个行模型新增 source_unit/source_quantity(可空,老调用零影响);quantity 恒存基本单位
  • 语义:带录入单位时 unit_price 按录入单位计价,amount = source_quantity × price;不传价时默认价 × rate
  • 测试:2 箱×24=48 出库、缺换算率报错、按箱默认价 5×24=120、老式行回归

✅ #3 开单自动取价

  • 新模型 partner.CustomerProductPrice(客户×商品专属价)
  • partner/services.quote_price 四级优先:客户专属价 → 价格等级折扣 → 最近成交价 → 默认售价;同时返回 last/min/max 历史成交参考(智慧记同款体验)
  • create_sales_bill 行不传价自动取价;API GET /api/v1/partner/price-quote/(批量,供前端预填)
  • 测试:四级优先级、历史价统计、开单自动填充、报价 API

✅ #4 最低售价 + 抹零

  • Product.min_sale_price:低于即抛 BelowMinPrice,行传 allow_below_min=True 视为审批放行
  • SalesBill.round_off:create_sales_bill(round_to=1|0.1|0.01) 向下取整抹零,净额入 total_amount,应收按净额生成;"抹零 X 元"自动追加 remark
  • core/services 抽出共享行解析(单位/价格/最低价/抹零),sales 与 purchase 语义一致
  • 测试:拒绝/放行、元/角/分三档抹零矩阵、应收净额一致性

✅ #5 信用额度落地(此前字段存在但从不校验)

  • partner/services.credit_usage:客户 open/partial 应收净占用;check_credit 服务
  • confirm_sales_bill 过账前强制校验:超限抛 CreditLimitExceeded(事务回滚,库存/应收/状态零变化);force=True 放行并写预警通知;占用 ≥90% 提前预警
  • API:GET /api/v1/partner/credit-usage/<customer_id>/(前端额度进度条数据源)
  • 测试:通过/拒绝回滚/force+通知/90%预警/无限额跳过/抹零净额口径

✅ #6 账龄分析 + 对账单 + 公开分享

  • finance/services.receivable_aging:0-30/31-60/61-90/91-180/181-365/365+ 六桶,支持 as_of 与单客户
  • customer_statement:期初(含"区间内核销旧账"的口径修正)→ 区间应收(借)/收款核销(贷) → 期末,逐行滚动余额
  • 分享:finance.StatementShare(UUID token + 过期 + 吊销);受保护 POST/GET /api/v1/finance/statements/share/;公开 GET /api/v1/open/statements/<token>/(AllowAny,不依赖租户头,过期/吊销 404)
  • 测试:六桶金额、已结清剔除、单客户过滤、期初/期末平衡、匿名访问、过期 404、吊销 404

📁 新增/变更文件

backend/
├── apps/core/services.py                       [新] 行解析/取价/最低价/抹零 共享服务
├── apps/catalog/services.py                    [新] to_base 单位换算
├── apps/catalog/models.py                      Product 批次字段/min_sale_price + UnitConversion
├── apps/inventory/models.py                    StockBatch + StockMovement.batch_detail
├── apps/inventory/services.py                  批次入库 + FEFO 出库
├── apps/partner/models.py                      CustomerProductPrice
├── apps/partner/services.py                    [新] quote_price / credit_usage / check_credit
├── apps/partner/views.py·urls.py               price-quote / credit-usage API
├── apps/sales/services.py                      取价/换算/最低价/抹零/信用额度 全接入
├── apps/purchase/services.py·models.py         批次穿透 + 行单位字段
├── apps/finance/services.py                    receivable_aging / customer_statement
├── apps/finance/models.py                      StatementShare
├── apps/finance/views.py·urls.py               账龄/对账单/分享 API + 公开端点
├── config/urls.py                              /api/v1/open/statements/<token>/ 公开路由
├── apps/notify/models.py·services.py           batch_expiry 规则 + 扫描
├── migrations ×7 app                           [新]
└── tests/test_p0_batch.py·test_p0_unit_price.py·test_p0_credit.py·test_p0_aging_statement.py  [新] 38 例

🔜 后续(未在本次范围)

  • 前端 12 页对应改造(开单页自动取价/单位选择/抹零、客户页额度进度条、账龄报表页、对账单分享按钮)
  • P1:AI 应收风险预警(notify 规则底座已就绪)、AI 开单
  • P2:套餐计费/官网/演示账套(见《差距分析与改造清单》P2)
  • 线上(192.168.5.7)镜像重建与部署