Add new items section to price changes modal

Track positions added to a pricelist (not present in the previous one)
and display them in a separate "Новые позиции" section in the price
changes modal on both pricelists and admin_pricing pages.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Mikhail Chusavitin
2026-03-12 11:39:47 +03:00
parent d067a5890a
commit c0fecde34e
4 changed files with 46 additions and 12 deletions

View File

@@ -116,6 +116,7 @@ func (h *PricelistHandler) Create(c *gin.Context) {
changes = &pricelist.PriceChangeSummary{
Changed: []pricelist.PriceChangeItem{},
Missing: []pricelist.PriceChangeItem{},
Added: []pricelist.PriceChangeItem{},
}
}
c.JSON(http.StatusCreated, gin.H{
@@ -182,6 +183,7 @@ func (h *PricelistHandler) CreateWithProgress(c *gin.Context) {
changes = &pricelist.PriceChangeSummary{
Changed: []pricelist.PriceChangeItem{},
Missing: []pricelist.PriceChangeItem{},
Added: []pricelist.PriceChangeItem{},
}
}

View File

@@ -51,6 +51,7 @@ type PriceChangeSummary struct {
PreviousPricelistVersion string `json:"previous_pricelist_version,omitempty"`
Changed []PriceChangeItem `json:"changed"`
Missing []PriceChangeItem `json:"missing"`
Added []PriceChangeItem `json:"added"`
}
func NewService(db *gorm.DB, repo *repository.PricelistRepository, componentRepo *repository.ComponentRepository, pricingSvc *pricing.Service) *Service {
@@ -524,7 +525,7 @@ func (s *Service) StreamItemsForExport(pricelistID uint, batchSize int, 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
return &PriceChangeSummary{Changed: []PriceChangeItem{}, Missing: []PriceChangeItem{}, Added: []PriceChangeItem{}}, nil
}
var current models.Pricelist
@@ -539,7 +540,7 @@ func (s *Service) BuildPriceChangeSummary(pricelistID uint) (*PriceChangeSummary
First(&previous).Error
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return &PriceChangeSummary{Changed: []PriceChangeItem{}, Missing: []PriceChangeItem{}}, nil
return &PriceChangeSummary{Changed: []PriceChangeItem{}, Missing: []PriceChangeItem{}, Added: []PriceChangeItem{}}, nil
}
return nil, fmt.Errorf("loading previous pricelist: %w", err)
}
@@ -568,8 +569,14 @@ func (s *Service) BuildPriceChangeSummary(pricelistID uint) (*PriceChangeSummary
curMap[strings.TrimSpace(it.LotName)] = it.Price
}
prevMap := make(map[string]float64, len(prevItems))
for _, it := range prevItems {
prevMap[strings.TrimSpace(it.LotName)] = it.Price
}
changed := make([]PriceChangeItem, 0)
missing := make([]PriceChangeItem, 0)
added := make([]PriceChangeItem, 0)
const eps = 0.000001
for _, prev := range prevItems {
lotName := strings.TrimSpace(prev.LotName)
@@ -606,10 +613,28 @@ func (s *Service) BuildPriceChangeSummary(pricelistID uint) (*PriceChangeSummary
})
}
for _, cur := range curItems {
lotName := strings.TrimSpace(cur.LotName)
if lotName == "" {
continue
}
if _, exists := prevMap[lotName]; !exists {
priceCopy := cur.Price
added = append(added, PriceChangeItem{
LotName: lotName,
OldPrice: 0,
NewPrice: &priceCopy,
Diff: nil,
ChangeType: "added",
})
}
}
return &PriceChangeSummary{
PreviousPricelistID: previous.ID,
PreviousPricelistVersion: previous.Version,
Changed: changed,
Missing: missing,
Added: added,
}, nil
}