Fix vendor mapping delete behavior and update docs
This commit is contained in:
@@ -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(¤t, 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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user