Fix competitor price display and pricelist item deduplication

- Render competitor prices in Pricing tab (all three row branches)
- Add footer total accumulation for competitor column
- Deduplicate local_pricelist_items via migration + unique index
- Use ON CONFLICT DO NOTHING in SaveLocalPricelistItems to prevent duplicates on concurrent sync

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Mikhail Chusavitin
2026-03-13 10:33:04 +03:00
parent 06397a6bd1
commit e2da8b4253
3 changed files with 57 additions and 9 deletions

View File

@@ -119,6 +119,11 @@ var localMigrations = []localMigration{
name: "Convert local partnumber book cache to book membership + deduplicated PN catalog",
run: migrateLocalPartnumberBookCatalog,
},
{
id: "2026_03_13_pricelist_items_dedup_unique",
name: "Deduplicate local_pricelist_items and add unique index on (pricelist_id, lot_name)",
run: deduplicatePricelistItemsAndAddUniqueIndex,
},
}
type localPartnumberCatalogRow struct {
@@ -1092,3 +1097,26 @@ func rebuildLocalPartnumberBookCatalog(tx *gorm.DB, catalog map[string]*localPar
}
return nil
}
func deduplicatePricelistItemsAndAddUniqueIndex(tx *gorm.DB) error {
// Remove duplicate (pricelist_id, lot_name) rows keeping only the row with the lowest id.
if err := tx.Exec(`
DELETE FROM local_pricelist_items
WHERE id NOT IN (
SELECT MIN(id) FROM local_pricelist_items
GROUP BY pricelist_id, lot_name
)
`).Error; err != nil {
return fmt.Errorf("deduplicate local_pricelist_items: %w", err)
}
// Add unique index to prevent future duplicates.
if err := tx.Exec(`
CREATE UNIQUE INDEX IF NOT EXISTS idx_local_pricelist_items_pricelist_lot_unique
ON local_pricelist_items(pricelist_id, lot_name)
`).Error; err != nil {
return fmt.Errorf("create unique index on local_pricelist_items: %w", err)
}
slog.Info("deduplicated local_pricelist_items and added unique index")
return nil
}