- Go module with Gin, GORM, JWT, excelize dependencies - Configuration loading from YAML with all settings - GORM models for users, categories, components, configurations, alerts - Repository layer for all entities - Services: auth (JWT), pricing (median/average/weighted), components, quotes, configurations, export (CSV/XLSX), alerts - Middleware: JWT auth, role-based access, CORS - HTTP handlers for all API endpoints - Main server with dependency injection and graceful shutdown Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
100 lines
2.5 KiB
Go
100 lines
2.5 KiB
Go
package repository
|
|
|
|
import (
|
|
"time"
|
|
|
|
"github.com/mchus/quoteforge/internal/models"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
type PriceRepository struct {
|
|
db *gorm.DB
|
|
}
|
|
|
|
func NewPriceRepository(db *gorm.DB) *PriceRepository {
|
|
return &PriceRepository{db: db}
|
|
}
|
|
|
|
type PricePoint struct {
|
|
Price float64
|
|
Date time.Time
|
|
}
|
|
|
|
// GetPriceHistory returns price history from lot_log for a component
|
|
func (r *PriceRepository) GetPriceHistory(lotName string, periodDays int) ([]PricePoint, error) {
|
|
var points []PricePoint
|
|
since := time.Now().AddDate(0, 0, -periodDays)
|
|
|
|
err := r.db.Model(&models.LotLog{}).
|
|
Select("price, date").
|
|
Where("lot = ? AND date >= ?", lotName, since).
|
|
Order("date DESC").
|
|
Scan(&points).Error
|
|
|
|
return points, err
|
|
}
|
|
|
|
// GetLatestPrice returns the most recent price for a component
|
|
func (r *PriceRepository) GetLatestPrice(lotName string) (*PricePoint, error) {
|
|
var point PricePoint
|
|
err := r.db.Model(&models.LotLog{}).
|
|
Select("price, date").
|
|
Where("lot = ?", lotName).
|
|
Order("date DESC").
|
|
First(&point).Error
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &point, nil
|
|
}
|
|
|
|
// GetPriceOverride returns active override for a component
|
|
func (r *PriceRepository) GetPriceOverride(lotName string) (*models.PriceOverride, error) {
|
|
var override models.PriceOverride
|
|
today := time.Now().Truncate(24 * time.Hour)
|
|
|
|
err := r.db.
|
|
Where("lot_name = ?", lotName).
|
|
Where("valid_from <= ?", today).
|
|
Where("valid_until IS NULL OR valid_until >= ?", today).
|
|
Order("valid_from DESC").
|
|
First(&override).Error
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &override, nil
|
|
}
|
|
|
|
// CreatePriceOverride creates a new price override
|
|
func (r *PriceRepository) CreatePriceOverride(override *models.PriceOverride) error {
|
|
return r.db.Create(override).Error
|
|
}
|
|
|
|
// GetPriceOverrides returns all overrides for a component
|
|
func (r *PriceRepository) GetPriceOverrides(lotName string) ([]models.PriceOverride, error) {
|
|
var overrides []models.PriceOverride
|
|
err := r.db.
|
|
Where("lot_name = ?", lotName).
|
|
Order("valid_from DESC").
|
|
Find(&overrides).Error
|
|
return overrides, err
|
|
}
|
|
|
|
// DeletePriceOverride deletes an override
|
|
func (r *PriceRepository) DeletePriceOverride(id uint) error {
|
|
return r.db.Delete(&models.PriceOverride{}, id).Error
|
|
}
|
|
|
|
// GetQuoteCount returns the number of quotes in lot_log for a period
|
|
func (r *PriceRepository) GetQuoteCount(lotName string, periodDays int) (int64, error) {
|
|
var count int64
|
|
since := time.Now().AddDate(0, 0, -periodDays)
|
|
|
|
err := r.db.Model(&models.LotLog{}).
|
|
Where("lot = ? AND date >= ?", lotName, since).
|
|
Count(&count).Error
|
|
|
|
return count, err
|
|
}
|