128 lines
3.5 KiB
Go
128 lines
3.5 KiB
Go
// internal/repositories/lost_item_repo.go
|
|
package repositories
|
|
|
|
import (
|
|
"errors"
|
|
"lost-and-found/internal/models"
|
|
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
type LostItemRepository struct {
|
|
db *gorm.DB
|
|
}
|
|
|
|
func NewLostItemRepository(db *gorm.DB) *LostItemRepository {
|
|
return &LostItemRepository{db: db}
|
|
}
|
|
|
|
// Create creates a new lost item report
|
|
func (r *LostItemRepository) Create(lostItem *models.LostItem) error {
|
|
return r.db.Create(lostItem).Error
|
|
}
|
|
|
|
// FindByID finds lost item by ID
|
|
func (r *LostItemRepository) FindByID(id uint) (*models.LostItem, error) {
|
|
var lostItem models.LostItem
|
|
err := r.db.Preload("Category").Preload("User").Preload("User.Role").First(&lostItem, id).Error
|
|
if err != nil {
|
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
return nil, errors.New("lost item not found")
|
|
}
|
|
return nil, err
|
|
}
|
|
return &lostItem, nil
|
|
}
|
|
|
|
// FindAll returns all lost items with filters
|
|
func (r *LostItemRepository) FindAll(page, limit int, status, category, search string, userID *uint) ([]models.LostItem, int64, error) {
|
|
var lostItems []models.LostItem
|
|
var total int64
|
|
|
|
query := r.db.Model(&models.LostItem{})
|
|
|
|
// Filter by user if specified
|
|
if userID != nil {
|
|
query = query.Where("user_id = ?", *userID)
|
|
}
|
|
|
|
// Apply filters
|
|
if status != "" {
|
|
query = query.Where("status = ?", status)
|
|
}
|
|
if category != "" {
|
|
query = query.Joins("JOIN categories ON categories.id = lost_items.category_id").Where("categories.slug = ?", category)
|
|
}
|
|
if search != "" {
|
|
query = query.Where("name ILIKE ? OR description ILIKE ?", "%"+search+"%", "%"+search+"%")
|
|
}
|
|
|
|
// Count total
|
|
if err := query.Count(&total).Error; err != nil {
|
|
return nil, 0, err
|
|
}
|
|
|
|
// Get paginated results
|
|
offset := (page - 1) * limit
|
|
err := query.Preload("Category").Preload("User").Preload("User.Role").
|
|
Order("date_lost DESC").
|
|
Offset(offset).Limit(limit).Find(&lostItems).Error
|
|
if err != nil {
|
|
return nil, 0, err
|
|
}
|
|
|
|
return lostItems, total, nil
|
|
}
|
|
|
|
// Update updates lost item data
|
|
func (r *LostItemRepository) Update(lostItem *models.LostItem) error {
|
|
return r.db.Save(lostItem).Error
|
|
}
|
|
|
|
// UpdateStatus updates lost item status
|
|
func (r *LostItemRepository) UpdateStatus(id uint, status string) error {
|
|
return r.db.Model(&models.LostItem{}).Where("id = ?", id).Update("status", status).Error
|
|
}
|
|
|
|
// Delete soft deletes a lost item
|
|
func (r *LostItemRepository) Delete(id uint) error {
|
|
return r.db.Delete(&models.LostItem{}, id).Error
|
|
}
|
|
|
|
// FindByUser finds lost items by user ID
|
|
func (r *LostItemRepository) FindByUser(userID uint, page, limit int) ([]models.LostItem, int64, error) {
|
|
var lostItems []models.LostItem
|
|
var total int64
|
|
|
|
query := r.db.Model(&models.LostItem{}).Where("user_id = ?", userID)
|
|
|
|
// Count total
|
|
if err := query.Count(&total).Error; err != nil {
|
|
return nil, 0, err
|
|
}
|
|
|
|
// Get paginated results
|
|
offset := (page - 1) * limit
|
|
err := query.Preload("Category").Order("date_lost DESC").
|
|
Offset(offset).Limit(limit).Find(&lostItems).Error
|
|
if err != nil {
|
|
return nil, 0, err
|
|
}
|
|
|
|
return lostItems, total, nil
|
|
}
|
|
|
|
// CountByStatus counts lost items by status
|
|
func (r *LostItemRepository) CountByStatus(status string) (int64, error) {
|
|
var count int64
|
|
err := r.db.Model(&models.LostItem{}).Where("status = ?", status).Count(&count).Error
|
|
return count, err
|
|
}
|
|
|
|
// FindActiveForMatching finds active lost items for matching
|
|
func (r *LostItemRepository) FindActiveForMatching(categoryID uint) ([]models.LostItem, error) {
|
|
var lostItems []models.LostItem
|
|
err := r.db.Where("status = ? AND category_id = ?", models.LostItemStatusActive, categoryID).
|
|
Preload("User").Find(&lostItems).Error
|
|
return lostItems, err
|
|
} |