6.0 KiB
6.0 KiB
dealerhub · P0 改造实施报告(对标竞品差距清单)
依据:
docs/差距分析与改造清单.mdP0 六项 +docs/P0改造实施计划.md。 结果:六项全部落地,专项新增 38 个测试,全量回归 141 passed(原 103 + 新增 38),manage.py check0 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行不传价自动取价;APIGET /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 元"自动追加 remarkcore/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)镜像重建与部署