Fix vendor mapping delete behavior and update docs

This commit is contained in:
Mikhail Chusavitin
2026-02-25 19:06:28 +03:00
parent a4457a0a28
commit 63454554c1
10 changed files with 497 additions and 99 deletions

View File

@@ -38,6 +38,21 @@ type CreateItemInput struct {
Category string
}
type PriceChangeItem struct {
LotName string `json:"lot_name"`
OldPrice float64 `json:"old_price"`
NewPrice *float64 `json:"new_price,omitempty"`
Diff *float64 `json:"diff,omitempty"`
ChangeType string `json:"change_type"` // increased, decreased, missing
}
type PriceChangeSummary struct {
PreviousPricelistID uint `json:"previous_pricelist_id,omitempty"`
PreviousPricelistVersion string `json:"previous_pricelist_version,omitempty"`
Changed []PriceChangeItem `json:"changed"`
Missing []PriceChangeItem `json:"missing"`
}
func NewService(db *gorm.DB, repo *repository.PricelistRepository, componentRepo *repository.ComponentRepository, pricingSvc *pricing.Service) *Service {
return &Service{
repo: repo,
@@ -505,3 +520,96 @@ func (s *Service) StreamItemsForExport(pricelistID uint, batchSize int, callback
}
return s.repo.StreamItemsForExport(pricelistID, batchSize, callback)
}
// BuildPriceChangeSummary compares a newly created pricelist with the previous pricelist of the same source.
func (s *Service) BuildPriceChangeSummary(pricelistID uint) (*PriceChangeSummary, error) {
if s.db == nil {
return &PriceChangeSummary{Changed: []PriceChangeItem{}, Missing: []PriceChangeItem{}}, nil
}
var current models.Pricelist
if err := s.db.Select("id", "source", "created_at").First(&current, pricelistID).Error; err != nil {
return nil, fmt.Errorf("loading current pricelist: %w", err)
}
var previous models.Pricelist
err := s.db.Select("id", "version").
Where("source = ? AND id <> ?", current.Source, current.ID).
Order("created_at DESC, id DESC").
First(&previous).Error
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return &PriceChangeSummary{Changed: []PriceChangeItem{}, Missing: []PriceChangeItem{}}, nil
}
return nil, fmt.Errorf("loading previous pricelist: %w", err)
}
type row struct {
LotName string
Price float64
}
var prevItems []row
var curItems []row
if err := s.db.Model(&models.PricelistItem{}).
Select("lot_name", "price").
Where("pricelist_id = ?", previous.ID).
Find(&prevItems).Error; err != nil {
return nil, fmt.Errorf("loading previous pricelist items: %w", err)
}
if err := s.db.Model(&models.PricelistItem{}).
Select("lot_name", "price").
Where("pricelist_id = ?", current.ID).
Find(&curItems).Error; err != nil {
return nil, fmt.Errorf("loading current pricelist items: %w", err)
}
curMap := make(map[string]float64, len(curItems))
for _, it := range curItems {
curMap[strings.TrimSpace(it.LotName)] = it.Price
}
changed := make([]PriceChangeItem, 0)
missing := make([]PriceChangeItem, 0)
const eps = 0.000001
for _, prev := range prevItems {
lotName := strings.TrimSpace(prev.LotName)
if lotName == "" {
continue
}
newPrice, ok := curMap[lotName]
if !ok {
missing = append(missing, PriceChangeItem{
LotName: lotName,
OldPrice: prev.Price,
NewPrice: nil,
Diff: nil,
ChangeType: "missing",
})
continue
}
diff := newPrice - prev.Price
if diff > -eps && diff < eps {
continue
}
newPriceCopy := newPrice
diffCopy := diff
changeType := "increased"
if diff < 0 {
changeType = "decreased"
}
changed = append(changed, PriceChangeItem{
LotName: lotName,
OldPrice: prev.Price,
NewPrice: &newPriceCopy,
Diff: &diffCopy,
ChangeType: changeType,
})
}
return &PriceChangeSummary{
PreviousPricelistID: previous.ID,
PreviousPricelistVersion: previous.Version,
Changed: changed,
Missing: missing,
}, nil
}