107 lines
2.9 KiB
Go
107 lines
2.9 KiB
Go
package handlers
|
|
|
|
import (
|
|
"net/http"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"git.mchus.pro/mchus/quoteforge/internal/localdb"
|
|
"git.mchus.pro/mchus/quoteforge/internal/repository"
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
// PartnumberBooksHandler provides read-only access to local partnumber book snapshots.
|
|
type PartnumberBooksHandler struct {
|
|
localDB *localdb.LocalDB
|
|
}
|
|
|
|
func NewPartnumberBooksHandler(localDB *localdb.LocalDB) *PartnumberBooksHandler {
|
|
return &PartnumberBooksHandler{localDB: localDB}
|
|
}
|
|
|
|
// List returns all local partnumber book snapshots.
|
|
// GET /api/partnumber-books
|
|
func (h *PartnumberBooksHandler) List(c *gin.Context) {
|
|
bookRepo := repository.NewPartnumberBookRepository(h.localDB.DB())
|
|
books, err := bookRepo.ListBooks()
|
|
if err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
type bookSummary struct {
|
|
ID uint `json:"id"`
|
|
ServerID int `json:"server_id"`
|
|
Version string `json:"version"`
|
|
CreatedAt string `json:"created_at"`
|
|
IsActive bool `json:"is_active"`
|
|
ItemCount int64 `json:"item_count"`
|
|
}
|
|
|
|
summaries := make([]bookSummary, 0, len(books))
|
|
for _, b := range books {
|
|
summaries = append(summaries, bookSummary{
|
|
ID: b.ID,
|
|
ServerID: b.ServerID,
|
|
Version: b.Version,
|
|
CreatedAt: b.CreatedAt.Format("2006-01-02"),
|
|
IsActive: b.IsActive,
|
|
ItemCount: bookRepo.CountBookItems(b.ID),
|
|
})
|
|
}
|
|
|
|
c.JSON(http.StatusOK, gin.H{
|
|
"books": summaries,
|
|
"total": len(summaries),
|
|
})
|
|
}
|
|
|
|
// GetItems returns items for a partnumber book by server ID.
|
|
// GET /api/partnumber-books/:id
|
|
func (h *PartnumberBooksHandler) GetItems(c *gin.Context) {
|
|
idStr := c.Param("id")
|
|
id, err := strconv.ParseUint(idStr, 10, 64)
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid book ID"})
|
|
return
|
|
}
|
|
|
|
bookRepo := repository.NewPartnumberBookRepository(h.localDB.DB())
|
|
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
|
|
perPage, _ := strconv.Atoi(c.DefaultQuery("per_page", "100"))
|
|
search := strings.TrimSpace(c.Query("search"))
|
|
if page < 1 {
|
|
page = 1
|
|
}
|
|
if perPage < 1 || perPage > 500 {
|
|
perPage = 100
|
|
}
|
|
|
|
// Find local book by server_id
|
|
var book localdb.LocalPartnumberBook
|
|
if err := h.localDB.DB().Where("server_id = ?", id).First(&book).Error; err != nil {
|
|
c.JSON(http.StatusNotFound, gin.H{"error": "partnumber book not found"})
|
|
return
|
|
}
|
|
|
|
items, total, err := bookRepo.GetBookItemsPage(book.ID, search, page, perPage)
|
|
if err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, gin.H{
|
|
"book_id": book.ServerID,
|
|
"version": book.Version,
|
|
"is_active": book.IsActive,
|
|
"items": items,
|
|
"total": total,
|
|
"page": page,
|
|
"per_page": perPage,
|
|
"search": search,
|
|
"book_total": bookRepo.CountBookItems(book.ID),
|
|
"lot_count": bookRepo.CountDistinctLots(book.ID),
|
|
"primary_count": bookRepo.CountPrimaryItems(book.ID),
|
|
})
|
|
}
|