2025-11-17 12:17:44 +07:00

110 lines
3.7 KiB
Go

package models
import (
"time"
"gorm.io/gorm"
)
// Archive represents an archived item
type Archive struct {
ID uint `gorm:"primaryKey" json:"id"`
ItemID uint `gorm:"not null;uniqueIndex" json:"item_id"` // Original item ID
Name string `gorm:"type:varchar(100);not null" json:"name"`
CategoryID uint `gorm:"not null" json:"category_id"`
Category Category `gorm:"foreignKey:CategoryID" json:"category,omitempty"`
PhotoURL string `gorm:"type:varchar(255)" json:"photo_url"`
Location string `gorm:"type:varchar(200)" json:"location"`
Description string `gorm:"type:text" json:"description"`
DateFound time.Time `json:"date_found"`
Status string `gorm:"type:varchar(50)" json:"status"` // case_closed, expired
ReporterName string `gorm:"type:varchar(100)" json:"reporter_name"`
ReporterContact string `gorm:"type:varchar(50)" json:"reporter_contact"`
ArchivedReason string `gorm:"type:varchar(100)" json:"archived_reason"` // expired, case_closed
ClaimedBy *uint `json:"claimed_by"` // User who claimed (if applicable)
Claimer *User `gorm:"foreignKey:ClaimedBy" json:"claimer,omitempty"`
ArchivedAt time.Time `json:"archived_at"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
}
// TableName specifies the table name for Archive model
func (Archive) TableName() string {
return "archives"
}
// Archive reason constants
const (
ArchiveReasonExpired = "expired"
ArchiveReasonCaseClosed = "case_closed"
)
// BeforeCreate hook
func (a *Archive) BeforeCreate(tx *gorm.DB) error {
if a.ArchivedAt.IsZero() {
a.ArchivedAt = time.Now()
}
return nil
}
// ArchiveResponse represents archive data for API responses
type ArchiveResponse struct {
ID uint `json:"id"`
ItemID uint `json:"item_id"`
Name string `json:"name"`
Category string `json:"category"`
PhotoURL string `json:"photo_url"`
Location string `json:"location"`
DateFound time.Time `json:"date_found"`
Status string `json:"status"`
ArchivedReason string `json:"archived_reason"`
ClaimedBy string `json:"claimed_by,omitempty"`
ArchivedAt time.Time `json:"archived_at"`
}
// ToResponse converts Archive to ArchiveResponse
func (a *Archive) ToResponse() ArchiveResponse {
categoryName := ""
if a.Category.ID != 0 {
categoryName = a.Category.Name
}
claimedByName := ""
if a.Claimer != nil && a.Claimer.ID != 0 {
claimedByName = a.Claimer.Name
}
return ArchiveResponse{
ID: a.ID,
ItemID: a.ItemID,
Name: a.Name,
Category: categoryName,
PhotoURL: a.PhotoURL,
Location: a.Location,
DateFound: a.DateFound,
Status: a.Status,
ArchivedReason: a.ArchivedReason,
ClaimedBy: claimedByName,
ArchivedAt: a.ArchivedAt,
}
}
// CreateFromItem creates an Archive from an Item
func CreateFromItem(item *Item, reason string, claimedBy *uint) *Archive {
return &Archive{
ItemID: item.ID,
Name: item.Name,
CategoryID: item.CategoryID,
PhotoURL: item.PhotoURL,
Location: item.Location,
Description: item.Description,
DateFound: item.DateFound,
Status: item.Status,
ReporterName: item.ReporterName,
ReporterContact: item.ReporterContact,
ArchivedReason: reason,
ClaimedBy: claimedBy,
ArchivedAt: time.Now(),
}
}