refactor: remove CurrentPrice from local_components and transition to pricelist-based pricing
## Overview Removed the CurrentPrice and SyncedAt fields from local_components, transitioning to a pricelist-based pricing model where all prices are sourced from local_pricelist_items based on the configuration's selected pricelist. ## Changes ### Data Model Updates - **LocalComponent**: Now stores only metadata (LotName, LotDescription, Category, Model) - Removed: CurrentPrice, SyncedAt (both redundant) - Pricing is now exclusively sourced from local_pricelist_items - **LocalConfiguration**: Added pricelist selection fields - Added: WarehousePricelistID, CompetitorPricelistID - These complement the existing PricelistID (Estimate) ### Migrations - Added migration "drop_component_unused_fields" to remove CurrentPrice and SyncedAt columns - Added migration "add_warehouse_competitor_pricelists" to add new pricelist fields ### Component Sync - Removed current_price from MariaDB query - Removed CurrentPrice assignment in component creation - SyncComponentPrices now exclusively updates based on pricelist_items via quote calculation ### Quote Calculation - Added PricelistID field to QuoteRequest - Updated local-first path to use pricelist_items instead of component.CurrentPrice - Falls back to latest estimate pricelist if PricelistID not specified - Maintains offline-first behavior: local queries work without MariaDB ### Configuration Refresh - Removed fallback on component.CurrentPrice - Prices are only refreshed from local_pricelist_items - If price not found in pricelist, original price is preserved ### API Changes - Removed CurrentPrice from ComponentView - Components API no longer returns pricing information - Pricing is accessed via QuoteService or PricelistService ### Code Cleanup - Removed UpdateComponentPricesFromPricelist() method - Removed EnsureComponentPricesFromPricelists() method - Updated UnifiedRepository to remove offline pricing logic - Updated converters to remove CurrentPrice mapping ## Architecture Impact - Components = metadata store only - Prices = managed by pricelist system - Quote calculation = owns all pricing logic - Local-first behavior preserved: SQLite queries work offline, no MariaDB dependency ## Testing - Build successful - All code compiles without errors - Ready for migration testing with existing databases Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -347,7 +347,7 @@ func (s *LocalConfigurationService) RefreshPrices(uuid string, ownerUsername str
|
||||
}
|
||||
latestPricelist, latestErr := s.localDB.GetLatestLocalPricelist()
|
||||
|
||||
// Update prices for all items
|
||||
// Update prices for all items from pricelist
|
||||
updatedItems := make(localdb.LocalConfigItems, len(localCfg.Items))
|
||||
for i, item := range localCfg.Items {
|
||||
if latestErr == nil && latestPricelist != nil {
|
||||
@@ -362,20 +362,8 @@ func (s *LocalConfigurationService) RefreshPrices(uuid string, ownerUsername str
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback to current component price from local cache
|
||||
component, err := s.localDB.GetLocalComponent(item.LotName)
|
||||
if err != nil || component.CurrentPrice == nil {
|
||||
// Keep original item if component not found or no price available
|
||||
updatedItems[i] = item
|
||||
continue
|
||||
}
|
||||
|
||||
// Update item with current price from local cache
|
||||
updatedItems[i] = localdb.LocalConfigItem{
|
||||
LotName: item.LotName,
|
||||
Quantity: item.Quantity,
|
||||
UnitPrice: *component.CurrentPrice,
|
||||
}
|
||||
// Keep original item if price not found in pricelist
|
||||
updatedItems[i] = item
|
||||
}
|
||||
|
||||
// Update configuration
|
||||
@@ -672,7 +660,7 @@ func (s *LocalConfigurationService) RefreshPricesNoAuth(uuid string) (*models.Co
|
||||
}
|
||||
latestPricelist, latestErr := s.localDB.GetLatestLocalPricelist()
|
||||
|
||||
// Update prices for all items
|
||||
// Update prices for all items from pricelist
|
||||
updatedItems := make(localdb.LocalConfigItems, len(localCfg.Items))
|
||||
for i, item := range localCfg.Items {
|
||||
if latestErr == nil && latestPricelist != nil {
|
||||
@@ -687,20 +675,8 @@ func (s *LocalConfigurationService) RefreshPricesNoAuth(uuid string) (*models.Co
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback to current component price from local cache
|
||||
component, err := s.localDB.GetLocalComponent(item.LotName)
|
||||
if err != nil || component.CurrentPrice == nil {
|
||||
// Keep original item if component not found or no price available
|
||||
updatedItems[i] = item
|
||||
continue
|
||||
}
|
||||
|
||||
// Update item with current price from local cache
|
||||
updatedItems[i] = localdb.LocalConfigItem{
|
||||
LotName: item.LotName,
|
||||
Quantity: item.Quantity,
|
||||
UnitPrice: *component.CurrentPrice,
|
||||
}
|
||||
// Keep original item if price not found in pricelist
|
||||
updatedItems[i] = item
|
||||
}
|
||||
|
||||
// Update configuration
|
||||
|
||||
Reference in New Issue
Block a user