146 lines
3.8 KiB
Go
146 lines
3.8 KiB
Go
package repository
|
|
|
|
import (
|
|
"time"
|
|
|
|
"git.mchus.pro/mchus/quoteforge/internal/models"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
type ComponentRepository struct {
|
|
db *gorm.DB
|
|
}
|
|
|
|
func NewComponentRepository(db *gorm.DB) *ComponentRepository {
|
|
return &ComponentRepository{db: db}
|
|
}
|
|
|
|
type ComponentFilter struct {
|
|
Category string
|
|
Search string
|
|
HasPrice bool
|
|
ExcludeHidden bool
|
|
SortField string
|
|
SortDir string
|
|
}
|
|
|
|
func (r *ComponentRepository) List(filter ComponentFilter, offset, limit int) ([]models.LotMetadata, int64, error) {
|
|
var components []models.LotMetadata
|
|
var total int64
|
|
|
|
query := r.db.Model(&models.LotMetadata{}).
|
|
Preload("Lot").
|
|
Preload("Category")
|
|
|
|
if filter.Category != "" {
|
|
query = query.Joins("JOIN qt_categories ON qt_lot_metadata.category_id = qt_categories.id").
|
|
Where("qt_categories.code = ?", filter.Category)
|
|
}
|
|
if filter.Search != "" {
|
|
search := "%" + filter.Search + "%"
|
|
query = query.Where("lot_name LIKE ? OR model LIKE ?", search, search)
|
|
}
|
|
if filter.HasPrice {
|
|
query = query.Where("current_price IS NOT NULL AND current_price > 0")
|
|
}
|
|
if filter.ExcludeHidden {
|
|
query = query.Where("is_hidden = ? OR is_hidden IS NULL", false)
|
|
}
|
|
|
|
query.Count(&total)
|
|
|
|
// Apply sorting
|
|
sortDir := "ASC"
|
|
if filter.SortDir == "desc" {
|
|
sortDir = "DESC"
|
|
}
|
|
|
|
switch filter.SortField {
|
|
case "popularity_score":
|
|
query = query.Order("popularity_score " + sortDir)
|
|
case "current_price":
|
|
query = query.Order("CASE WHEN current_price IS NULL OR current_price = 0 THEN 1 ELSE 0 END").
|
|
Order("current_price " + sortDir)
|
|
case "lot_name":
|
|
query = query.Order("lot_name " + sortDir)
|
|
case "quote_count":
|
|
// Sort by quote count from lot_log table
|
|
query = query.
|
|
Select("qt_lot_metadata.*, (SELECT COUNT(*) FROM lot_log WHERE lot_log.lot = qt_lot_metadata.lot_name) as quote_count_sort").
|
|
Order("quote_count_sort " + sortDir)
|
|
default:
|
|
// Default: sort by popularity, no price goes last
|
|
query = query.
|
|
Order("CASE WHEN current_price IS NULL OR current_price = 0 THEN 1 ELSE 0 END").
|
|
Order("popularity_score DESC")
|
|
}
|
|
|
|
err := query.
|
|
Offset(offset).
|
|
Limit(limit).
|
|
Find(&components).Error
|
|
|
|
return components, total, err
|
|
}
|
|
|
|
func (r *ComponentRepository) GetByLotName(lotName string) (*models.LotMetadata, error) {
|
|
var component models.LotMetadata
|
|
err := r.db.
|
|
Preload("Lot").
|
|
Preload("Category").
|
|
Where("lot_name = ?", lotName).
|
|
First(&component).Error
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &component, nil
|
|
}
|
|
|
|
func (r *ComponentRepository) GetMultiple(lotNames []string) ([]models.LotMetadata, error) {
|
|
var components []models.LotMetadata
|
|
err := r.db.
|
|
Preload("Lot").
|
|
Preload("Category").
|
|
Where("lot_name IN ?", lotNames).
|
|
Find(&components).Error
|
|
return components, err
|
|
}
|
|
|
|
func (r *ComponentRepository) Update(component *models.LotMetadata) error {
|
|
return r.db.Save(component).Error
|
|
}
|
|
|
|
func (r *ComponentRepository) DB() *gorm.DB {
|
|
return r.db
|
|
}
|
|
|
|
func (r *ComponentRepository) Create(component *models.LotMetadata) error {
|
|
return r.db.Create(component).Error
|
|
}
|
|
|
|
func (r *ComponentRepository) IncrementRequestCount(lotName string) error {
|
|
now := time.Now()
|
|
return r.db.Model(&models.LotMetadata{}).
|
|
Where("lot_name = ?", lotName).
|
|
Updates(map[string]interface{}{
|
|
"request_count": gorm.Expr("request_count + 1"),
|
|
"last_request_date": now,
|
|
}).Error
|
|
}
|
|
|
|
// GetAllLots returns all lots from the existing lot table
|
|
func (r *ComponentRepository) GetAllLots() ([]models.Lot, error) {
|
|
var lots []models.Lot
|
|
err := r.db.Find(&lots).Error
|
|
return lots, err
|
|
}
|
|
|
|
// GetLotsWithoutMetadata returns lots that don't have qt_lot_metadata entries
|
|
func (r *ComponentRepository) GetLotsWithoutMetadata() ([]models.Lot, error) {
|
|
var lots []models.Lot
|
|
err := r.db.
|
|
Where("lot_name NOT IN (SELECT lot_name FROM qt_lot_metadata)").
|
|
Find(&lots).Error
|
|
return lots, err
|
|
}
|