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

164 lines
4.8 KiB
Go

package models
import (
"time"
"gorm.io/gorm"
)
// Claim represents a claim for a found item
type Claim struct {
ID uint `gorm:"primaryKey" json:"id"`
ItemID uint `gorm:"not null" json:"item_id"`
Item Item `gorm:"foreignKey:ItemID" json:"item,omitempty"`
UserID uint `gorm:"not null" json:"user_id"`
User User `gorm:"foreignKey:UserID" json:"user,omitempty"`
Description string `gorm:"type:text;not null" json:"description"` // User's description of the item
ProofURL string `gorm:"type:varchar(255)" json:"proof_url"` // Optional proof photo
Contact string `gorm:"type:varchar(50);not null" json:"contact"`
Status string `gorm:"type:varchar(50);default:'pending'" json:"status"` // pending, approved, rejected
Notes string `gorm:"type:text" json:"notes"` // Manager's notes (approval/rejection reason)
VerifiedAt *time.Time `json:"verified_at"`
VerifiedBy *uint `json:"verified_by"` // Manager who verified
Verifier *User `gorm:"foreignKey:VerifiedBy" json:"verifier,omitempty"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
// Relationships
Verification *ClaimVerification `gorm:"foreignKey:ClaimID" json:"verification,omitempty"`
}
// TableName specifies the table name for Claim model
func (Claim) TableName() string {
return "claims"
}
// Claim status constants
const (
ClaimStatusPending = "pending"
ClaimStatusApproved = "approved"
ClaimStatusRejected = "rejected"
)
// BeforeCreate hook
func (c *Claim) BeforeCreate(tx *gorm.DB) error {
if c.Status == "" {
c.Status = ClaimStatusPending
}
return nil
}
// IsPending checks if claim is pending
func (c *Claim) IsPending() bool {
return c.Status == ClaimStatusPending
}
// IsApproved checks if claim is approved
func (c *Claim) IsApproved() bool {
return c.Status == ClaimStatusApproved
}
// IsRejected checks if claim is rejected
func (c *Claim) IsRejected() bool {
return c.Status == ClaimStatusRejected
}
// Approve approves the claim
func (c *Claim) Approve(verifierID uint, notes string) {
c.Status = ClaimStatusApproved
c.VerifiedBy = &verifierID
now := time.Now()
c.VerifiedAt = &now
c.Notes = notes
}
// Reject rejects the claim
func (c *Claim) Reject(verifierID uint, notes string) {
c.Status = ClaimStatusRejected
c.VerifiedBy = &verifierID
now := time.Now()
c.VerifiedAt = &now
c.Notes = notes
}
// ClaimResponse represents claim data for API responses
type ClaimResponse struct {
ID uint `json:"id"`
ItemID uint `json:"item_id"`
ItemName string `json:"item_name"`
UserID uint `json:"user_id"`
UserName string `json:"user_name"`
Description string `json:"description"`
ProofURL string `json:"proof_url"`
Contact string `json:"contact"`
Status string `json:"status"`
Notes string `json:"notes"`
MatchPercentage *float64 `json:"match_percentage,omitempty"`
VerifiedAt *time.Time `json:"verified_at"`
VerifiedBy *uint `json:"verified_by"`
VerifierName string `json:"verifier_name,omitempty"`
CreatedAt time.Time `json:"created_at"`
}
// ToResponse converts Claim to ClaimResponse
func (c *Claim) ToResponse() ClaimResponse {
itemName := ""
if c.Item.ID != 0 {
itemName = c.Item.Name
}
userName := ""
if c.User.ID != 0 {
userName = c.User.Name
}
verifierName := ""
if c.Verifier != nil && c.Verifier.ID != 0 {
verifierName = c.Verifier.Name
}
var matchPercentage *float64
if c.Verification != nil {
matchPercentage = &c.Verification.SimilarityScore
}
return ClaimResponse{
ID: c.ID,
ItemID: c.ItemID,
ItemName: itemName,
UserID: c.UserID,
UserName: userName,
Description: c.Description,
ProofURL: c.ProofURL,
Contact: c.Contact,
Status: c.Status,
Notes: c.Notes,
MatchPercentage: matchPercentage,
VerifiedAt: c.VerifiedAt,
VerifiedBy: c.VerifiedBy,
VerifierName: verifierName,
CreatedAt: c.CreatedAt,
}
}
// ClaimDetailResponse includes item description for verification
type ClaimDetailResponse struct {
ClaimResponse
ItemDescription string `json:"item_description"` // Original item description for comparison
}
// ToDetailResponse converts Claim to ClaimDetailResponse
func (c *Claim) ToDetailResponse() ClaimDetailResponse {
baseResponse := c.ToResponse()
itemDescription := ""
if c.Item.ID != 0 {
itemDescription = c.Item.Description
}
return ClaimDetailResponse{
ClaimResponse: baseResponse,
ItemDescription: itemDescription,
}
}