feat: world-прайслист как заглушка для отсутствующих цен
Там, где для LOT нет цены в estimate/warehouse/competitor, подставляется цена из world-прайслиста. Такие ячейки в таблицах «Цена покупки»/«Цена продажи» подсвечиваются (amber), участвуют в «Итого» и убирают красную «*». В CSV-экспорте добавлена колонка «Заглушка (world)» с перечнем столбцов, где сработал фолбэк. Добавлены Tx-версии GetLatestLocalPricelistBySource/GetLocalPricesForLots, чтобы резолв прайслистов внутри транзакции не дедлочил single-connection пул. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
498cbf5490
commit
70a3ff255f
@@ -82,6 +82,51 @@ func TestCalculatePriceLevels_UsesExplicitPricelistIDs(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestCalculatePriceLevels_WorldFallback(t *testing.T) {
|
||||
db := newPriceLevelsTestDB(t)
|
||||
repo := repository.NewPricelistRepository(db)
|
||||
service := NewQuoteService(repo, nil)
|
||||
|
||||
seedPricelistWithItem(t, repo, "estimate", "CPU_Z", 100)
|
||||
seedPricelistWithItem(t, repo, "world", "CPU_Z", 150)
|
||||
|
||||
result, err := service.CalculatePriceLevels(&PriceLevelsRequest{
|
||||
Items: []struct {
|
||||
LotName string `json:"lot_name"`
|
||||
Quantity int `json:"quantity"`
|
||||
}{
|
||||
{LotName: "CPU_Z", Quantity: 1},
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("CalculatePriceLevels returned error: %v", err)
|
||||
}
|
||||
item := result.Items[0]
|
||||
|
||||
if item.EstimatePrice == nil || *item.EstimatePrice != 100 {
|
||||
t.Fatalf("expected native estimate 100, got %#v", item.EstimatePrice)
|
||||
}
|
||||
if item.EstimateFromWorld {
|
||||
t.Fatalf("expected estimate_from_world false when native price exists")
|
||||
}
|
||||
|
||||
if item.WarehousePrice == nil || *item.WarehousePrice != 150 {
|
||||
t.Fatalf("expected world-fallback warehouse 150, got %#v", item.WarehousePrice)
|
||||
}
|
||||
if !item.WarehouseFromWorld {
|
||||
t.Fatalf("expected warehouse_from_world true")
|
||||
}
|
||||
if item.CompetitorPrice == nil || *item.CompetitorPrice != 150 {
|
||||
t.Fatalf("expected world-fallback competitor 150, got %#v", item.CompetitorPrice)
|
||||
}
|
||||
if !item.CompetitorFromWorld {
|
||||
t.Fatalf("expected competitor_from_world true")
|
||||
}
|
||||
if len(item.PriceMissing) != 0 {
|
||||
t.Fatalf("expected no price_missing after world fallback, got %#v", item.PriceMissing)
|
||||
}
|
||||
}
|
||||
|
||||
func newPriceLevelsTestDB(t *testing.T) *gorm.DB {
|
||||
t.Helper()
|
||||
db, err := gorm.Open(sqlite.Open("file::memory:?cache=shared"), &gorm.Config{})
|
||||
|
||||
Reference in New Issue
Block a user