113 lines
3.6 KiB
Go
113 lines
3.6 KiB
Go
package repository
|
|
|
|
import (
|
|
"git.mchus.pro/mchus/quoteforge/internal/localdb"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
// PartnumberBookRepository provides read-only access to local partnumber book snapshots.
|
|
type PartnumberBookRepository struct {
|
|
db *gorm.DB
|
|
}
|
|
|
|
func NewPartnumberBookRepository(db *gorm.DB) *PartnumberBookRepository {
|
|
return &PartnumberBookRepository{db: db}
|
|
}
|
|
|
|
// GetActiveBook returns the most recently active local partnumber book.
|
|
func (r *PartnumberBookRepository) GetActiveBook() (*localdb.LocalPartnumberBook, error) {
|
|
var book localdb.LocalPartnumberBook
|
|
err := r.db.Where("is_active = 1").Order("created_at DESC, id DESC").First(&book).Error
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &book, nil
|
|
}
|
|
|
|
// GetBookItems returns all items for the given local book ID.
|
|
func (r *PartnumberBookRepository) GetBookItems(bookID uint) ([]localdb.LocalPartnumberBookItem, error) {
|
|
var items []localdb.LocalPartnumberBookItem
|
|
err := r.db.Where("book_id = ?", bookID).Find(&items).Error
|
|
return items, err
|
|
}
|
|
|
|
// GetBookItemsPage returns items for the given local book ID with optional search and pagination.
|
|
func (r *PartnumberBookRepository) GetBookItemsPage(bookID uint, search string, page, perPage int) ([]localdb.LocalPartnumberBookItem, int64, error) {
|
|
if page < 1 {
|
|
page = 1
|
|
}
|
|
if perPage < 1 {
|
|
perPage = 100
|
|
}
|
|
|
|
query := r.db.Model(&localdb.LocalPartnumberBookItem{}).Where("book_id = ?", bookID)
|
|
trimmedSearch := "%" + search + "%"
|
|
if search != "" {
|
|
query = query.Where("partnumber LIKE ? OR lot_name LIKE ?", trimmedSearch, trimmedSearch)
|
|
}
|
|
|
|
var total int64
|
|
if err := query.Count(&total).Error; err != nil {
|
|
return nil, 0, err
|
|
}
|
|
|
|
var items []localdb.LocalPartnumberBookItem
|
|
err := query.
|
|
Order("partnumber ASC, lot_name ASC, id ASC").
|
|
Offset((page - 1) * perPage).
|
|
Limit(perPage).
|
|
Find(&items).Error
|
|
return items, total, err
|
|
}
|
|
|
|
// FindLotByPartnumber looks up a partnumber in the active book and returns the matching items.
|
|
func (r *PartnumberBookRepository) FindLotByPartnumber(bookID uint, partnumber string) ([]localdb.LocalPartnumberBookItem, error) {
|
|
var items []localdb.LocalPartnumberBookItem
|
|
err := r.db.Where("book_id = ? AND partnumber = ?", bookID, partnumber).Find(&items).Error
|
|
return items, err
|
|
}
|
|
|
|
// ListBooks returns all local partnumber books ordered newest first.
|
|
func (r *PartnumberBookRepository) ListBooks() ([]localdb.LocalPartnumberBook, error) {
|
|
var books []localdb.LocalPartnumberBook
|
|
err := r.db.Order("created_at DESC, id DESC").Find(&books).Error
|
|
return books, err
|
|
}
|
|
|
|
// SaveBook saves a new partnumber book snapshot.
|
|
func (r *PartnumberBookRepository) SaveBook(book *localdb.LocalPartnumberBook) error {
|
|
return r.db.Save(book).Error
|
|
}
|
|
|
|
// SaveBookItems bulk-inserts items for a book snapshot.
|
|
func (r *PartnumberBookRepository) SaveBookItems(items []localdb.LocalPartnumberBookItem) error {
|
|
if len(items) == 0 {
|
|
return nil
|
|
}
|
|
return r.db.CreateInBatches(items, 500).Error
|
|
}
|
|
|
|
// CountBookItems returns the number of items for a given local book ID.
|
|
func (r *PartnumberBookRepository) CountBookItems(bookID uint) int64 {
|
|
var count int64
|
|
r.db.Model(&localdb.LocalPartnumberBookItem{}).Where("book_id = ?", bookID).Count(&count)
|
|
return count
|
|
}
|
|
|
|
func (r *PartnumberBookRepository) CountDistinctLots(bookID uint) int64 {
|
|
var count int64
|
|
r.db.Model(&localdb.LocalPartnumberBookItem{}).
|
|
Where("book_id = ?", bookID).
|
|
Distinct("lot_name").
|
|
Count(&count)
|
|
return count
|
|
}
|
|
|
|
func (r *PartnumberBookRepository) CountPrimaryItems(bookID uint) int64 {
|
|
var count int64
|
|
r.db.Model(&localdb.LocalPartnumberBookItem{}).
|
|
Where("book_id = ? AND is_primary_pn = ?", bookID, true).
|
|
Count(&count)
|
|
return count
|
|
}
|