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
@@ -89,6 +89,9 @@ type PriceLevelsItem struct {
|
||||
DeltaCompEstimatePct *float64 `json:"delta_comp_estimate_pct"`
|
||||
DeltaCompWhAbs *float64 `json:"delta_comp_wh_abs"`
|
||||
DeltaCompWhPct *float64 `json:"delta_comp_wh_pct"`
|
||||
EstimateFromWorld bool `json:"estimate_from_world"`
|
||||
WarehouseFromWorld bool `json:"warehouse_from_world"`
|
||||
CompetitorFromWorld bool `json:"competitor_from_world"`
|
||||
PriceMissing []string `json:"price_missing"`
|
||||
}
|
||||
|
||||
@@ -239,6 +242,29 @@ func (s *QuoteService) CalculatePriceLevels(req *PriceLevelsRequest) (*PriceLeve
|
||||
}
|
||||
}
|
||||
|
||||
var worldID uint
|
||||
if req.PricelistIDs != nil {
|
||||
if explicitID, ok := req.PricelistIDs[string(models.PricelistSourceWorld)]; ok && explicitID > 0 {
|
||||
worldID = explicitID
|
||||
}
|
||||
}
|
||||
if worldID == 0 && s.pricelistRepo != nil {
|
||||
if latest, err := s.pricelistRepo.GetLatestActiveBySource(string(models.PricelistSourceWorld)); err == nil {
|
||||
worldID = latest.ID
|
||||
}
|
||||
}
|
||||
if worldID == 0 && s.localDB != nil {
|
||||
if localPL, err := s.localDB.GetLatestLocalPricelistBySource(string(models.PricelistSourceWorld)); err == nil && localPL != nil {
|
||||
worldID = localPL.ServerID
|
||||
}
|
||||
}
|
||||
worldPrices := map[string]float64{}
|
||||
if worldID != 0 {
|
||||
if prices, err := s.lookupPricesByPricelistID(worldID, lotNames, req.NoCache); err == nil {
|
||||
worldPrices = prices
|
||||
}
|
||||
}
|
||||
|
||||
for _, reqItem := range req.Items {
|
||||
responseLotName := originalLotNames[reqItem.LotName]
|
||||
if responseLotName == "" {
|
||||
@@ -253,14 +279,26 @@ func (s *QuoteService) CalculatePriceLevels(req *PriceLevelsRequest) (*PriceLeve
|
||||
if p, ok := levelBySource[models.PricelistSourceEstimate].prices[reqItem.LotName]; ok && p > 0 {
|
||||
price := p
|
||||
item.EstimatePrice = &price
|
||||
} else if wp, ok := worldPrices[reqItem.LotName]; ok && wp > 0 {
|
||||
price := wp
|
||||
item.EstimatePrice = &price
|
||||
item.EstimateFromWorld = true
|
||||
}
|
||||
if p, ok := levelBySource[models.PricelistSourceWarehouse].prices[reqItem.LotName]; ok && p > 0 {
|
||||
price := p
|
||||
item.WarehousePrice = &price
|
||||
} else if wp, ok := worldPrices[reqItem.LotName]; ok && wp > 0 {
|
||||
price := wp
|
||||
item.WarehousePrice = &price
|
||||
item.WarehouseFromWorld = true
|
||||
}
|
||||
if p, ok := levelBySource[models.PricelistSourceCompetitor].prices[reqItem.LotName]; ok && p > 0 {
|
||||
price := p
|
||||
item.CompetitorPrice = &price
|
||||
} else if wp, ok := worldPrices[reqItem.LotName]; ok && wp > 0 {
|
||||
price := wp
|
||||
item.CompetitorPrice = &price
|
||||
item.CompetitorFromWorld = true
|
||||
}
|
||||
|
||||
if item.EstimatePrice == nil {
|
||||
|
||||
Reference in New Issue
Block a user