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, } }