165 lines
4.8 KiB
Go
165 lines
4.8 KiB
Go
// internal/models/claim.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,
|
|
}
|
|
} |