Optimize task retention from 5 minutes to 30 seconds to reduce polling overhead since toast notifications are shown only once. Add conditional warehouse pricelist creation via checkbox. Fix category storage in warehouse pricelists to properly load from lot table. Replace SSE with task polling for all long operations. Add comprehensive logging for debugging while minimizing noise from polling endpoints. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
93 lines
3.7 KiB
Go
93 lines
3.7 KiB
Go
package models
|
|
|
|
import (
|
|
"time"
|
|
)
|
|
|
|
type PricelistSource string
|
|
|
|
const (
|
|
PricelistSourceEstimate PricelistSource = "estimate"
|
|
PricelistSourceWarehouse PricelistSource = "warehouse"
|
|
PricelistSourceCompetitor PricelistSource = "competitor"
|
|
)
|
|
|
|
func (s PricelistSource) IsValid() bool {
|
|
switch s {
|
|
case PricelistSourceEstimate, PricelistSourceWarehouse, PricelistSourceCompetitor:
|
|
return true
|
|
default:
|
|
return false
|
|
}
|
|
}
|
|
|
|
func NormalizePricelistSource(source string) PricelistSource {
|
|
switch PricelistSource(source) {
|
|
case PricelistSourceWarehouse:
|
|
return PricelistSourceWarehouse
|
|
case PricelistSourceCompetitor:
|
|
return PricelistSourceCompetitor
|
|
default:
|
|
return PricelistSourceEstimate
|
|
}
|
|
}
|
|
|
|
// Pricelist represents a versioned snapshot of prices
|
|
type Pricelist struct {
|
|
ID uint `gorm:"primaryKey" json:"id"`
|
|
Source string `gorm:"size:20;not null;default:'estimate';uniqueIndex:idx_qt_pricelists_source_version,priority:1;index:idx_qt_pricelists_source_created_at,priority:1" json:"source"`
|
|
Version string `gorm:"size:20;not null;uniqueIndex:idx_qt_pricelists_source_version,priority:2" json:"version"` // Format: YYYY-MM-DD-NNN
|
|
Notification string `gorm:"size:500" json:"notification"` // Notification shown in configurator
|
|
CreatedAt time.Time `gorm:"index:idx_qt_pricelists_source_created_at,priority:2,sort:desc" json:"created_at"`
|
|
CreatedBy string `gorm:"size:100" json:"created_by"`
|
|
IsActive bool `gorm:"default:true" json:"is_active"`
|
|
UsageCount int `gorm:"default:0" json:"usage_count"`
|
|
ExpiresAt *time.Time `json:"expires_at"`
|
|
ItemCount int `gorm:"-" json:"item_count,omitempty"` // Virtual field for display
|
|
}
|
|
|
|
func (Pricelist) TableName() string {
|
|
return "qt_pricelists"
|
|
}
|
|
|
|
// PricelistItem represents a single item in a pricelist
|
|
type PricelistItem struct {
|
|
ID uint `gorm:"primaryKey" json:"id"`
|
|
PricelistID uint `gorm:"not null;index:idx_pricelist_lot" json:"pricelist_id"`
|
|
LotName string `gorm:"size:255;not null;index:idx_pricelist_lot" json:"lot_name"`
|
|
LotCategory *string `gorm:"column:lot_category;size:50" json:"category,omitempty"`
|
|
Price float64 `gorm:"type:decimal(12,2);not null" json:"price"`
|
|
PriceMethod string `gorm:"size:20" json:"price_method"`
|
|
|
|
// Price calculation settings (snapshot from qt_lot_metadata)
|
|
PricePeriodDays int `gorm:"default:90" json:"price_period_days"`
|
|
PriceCoefficient float64 `gorm:"type:decimal(5,2);default:0" json:"price_coefficient"`
|
|
ManualPrice *float64 `gorm:"type:decimal(12,2)" json:"manual_price,omitempty"`
|
|
MetaPrices string `gorm:"size:1000" json:"meta_prices,omitempty"`
|
|
|
|
// Virtual fields for display (not stored in qt_pricelist_items table)
|
|
// LotDescription is populated via JOIN in SQL queries
|
|
// AvailableQty and Partnumbers are populated programmatically for warehouse pricelists
|
|
LotDescription string `gorm:"-" json:"lot_description,omitempty"`
|
|
AvailableQty *float64 `gorm:"-" json:"available_qty,omitempty"`
|
|
Partnumbers []string `gorm:"-" json:"partnumbers,omitempty"`
|
|
}
|
|
|
|
func (PricelistItem) TableName() string {
|
|
return "qt_pricelist_items"
|
|
}
|
|
|
|
// PricelistSummary is used for list views
|
|
type PricelistSummary struct {
|
|
ID uint `json:"id"`
|
|
Source string `json:"source"`
|
|
Version string `json:"version"`
|
|
Notification string `json:"notification"`
|
|
CreatedAt time.Time `json:"created_at"`
|
|
CreatedBy string `json:"created_by"`
|
|
IsActive bool `json:"is_active"`
|
|
UsageCount int `json:"usage_count"`
|
|
ExpiresAt *time.Time `json:"expires_at"`
|
|
ItemCount int64 `json:"item_count"`
|
|
}
|