4fd0bb8b83
- 字段重命名(旧列弃用保留,启动幂等回填 BackfillPricingColumns): 入库 unit_price/total_price/total_amount → cost_price/cost_amount/cost_total; 出库同前缀 + 新增 sale_amount(售价小计)/ sale_total(应收)/ profit_total(总利润) - 建单落三值;确认售价联动重算 sale_amount/sale_total/profit_total; 确认进价回填成本后联动重算受影响出库单利润(recalcStockOutProfit) - 出库 List/Get 对 operator/readonly 抹零成本与利润(stripStockOutCost 服务端兜底) - 兼容一版:Create/Update 接受旧 key unit_price 回落(v1.0.87 及之前客户端) - SUM 聚合/价格趋势/导入/种子工具同步切新列;测试全量改名 + 6 个新回归 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JJ1g8XV1YhhmHRzhwWEW7o
52 lines
2.5 KiB
Go
52 lines
2.5 KiB
Go
package service
|
||
|
||
import (
|
||
"log"
|
||
|
||
"gorm.io/gorm"
|
||
|
||
"github.com/wangjia/jiu/backend/internal/model"
|
||
)
|
||
|
||
// BackfillPricingColumns 2026-07 定价字段消歧的一次性数据迁移(幂等,可反复执行):
|
||
// - stock_in_items / stock_out_items:unit_price→cost_price、total_price→cost_amount
|
||
// - stock_in_orders:total_amount→cost_total;stock_out_orders:total_amount→sale_total
|
||
// - stock_out_items.sale_amount = sale_price×quantity(待定价行保持 0)
|
||
// - stock_out_orders.profit_total = Σ(sale_price>0 ? (sale_price-cost_price)×qty : 0)
|
||
//
|
||
// 只在新列为 0 且旧列非 0 时拷贝,不修改旧列(旧列观察一版后手动 DROP)。
|
||
// profit_total 以「为 0 且存在已定价明细」为待回填判据——利润恰为 0 的单重算一次
|
||
// 结果不变,幂等。全新安装(schema.sql 已无旧列)时整体跳过。
|
||
func BackfillPricingColumns(db *gorm.DB) {
|
||
// 旧列存在性守卫:四张表的旧列是同批产生的,抽查一张即可
|
||
// (model 已无 UnitPrice 字段,HasColumn 会按原始列名探测)
|
||
if !db.Migrator().HasColumn(&model.StockOutItem{}, "unit_price") {
|
||
return
|
||
}
|
||
stmts := []string{
|
||
`UPDATE stock_in_items SET cost_price = unit_price WHERE cost_price = 0 AND unit_price <> 0`,
|
||
`UPDATE stock_in_items SET cost_amount = total_price WHERE cost_amount = 0 AND total_price <> 0`,
|
||
`UPDATE stock_in_orders SET cost_total = total_amount WHERE cost_total = 0 AND total_amount <> 0`,
|
||
`UPDATE stock_out_items SET cost_price = unit_price WHERE cost_price = 0 AND unit_price <> 0`,
|
||
`UPDATE stock_out_items SET cost_amount = total_price WHERE cost_amount = 0 AND total_price <> 0`,
|
||
`UPDATE stock_out_items SET sale_amount = sale_price * quantity WHERE sale_amount = 0 AND sale_price > 0`,
|
||
`UPDATE stock_out_orders SET sale_total = total_amount WHERE sale_total = 0 AND total_amount <> 0`,
|
||
`UPDATE stock_out_orders SET profit_total = (
|
||
SELECT COALESCE(SUM(CASE WHEN i.sale_price > 0
|
||
THEN (i.sale_price - i.cost_price) * i.quantity ELSE 0 END), 0)
|
||
FROM stock_out_items i WHERE i.order_id = stock_out_orders.id
|
||
) WHERE profit_total = 0 AND EXISTS (
|
||
SELECT 1 FROM stock_out_items i2
|
||
WHERE i2.order_id = stock_out_orders.id AND i2.sale_price > 0
|
||
)`,
|
||
}
|
||
for _, q := range stmts {
|
||
res := db.Exec(q)
|
||
if res.Error != nil {
|
||
log.Printf("backfill pricing columns failed (%.60s...): %v", q, res.Error)
|
||
} else if res.RowsAffected > 0 {
|
||
log.Printf("backfill pricing: %d rows (%.60s...)", res.RowsAffected, q)
|
||
}
|
||
}
|
||
}
|