128 lines
3.9 KiB
Go
128 lines
3.9 KiB
Go
// internal/models/notification.go
|
|
package models
|
|
|
|
import (
|
|
"time"
|
|
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
// Notification represents a notification for a user
|
|
type Notification struct {
|
|
ID uint `gorm:"primaryKey" json:"id"`
|
|
UserID uint `gorm:"not null" json:"user_id"`
|
|
User User `gorm:"foreignKey:UserID" json:"user,omitempty"`
|
|
Type string `gorm:"type:varchar(50);not null" json:"type"` // match_found, claim_approved, claim_rejected, item_expired, etc.
|
|
Title string `gorm:"type:varchar(200);not null" json:"title"`
|
|
Message string `gorm:"type:text;not null" json:"message"`
|
|
EntityType string `gorm:"type:varchar(50)" json:"entity_type"` // item, claim, match, etc.
|
|
EntityID *uint `json:"entity_id"`
|
|
IsRead bool `gorm:"default:false" json:"is_read"`
|
|
ReadAt *time.Time `json:"read_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 Notification model
|
|
func (Notification) TableName() string {
|
|
return "notifications"
|
|
}
|
|
|
|
// Notification type constants
|
|
const (
|
|
NotificationMatchFound = "match_found"
|
|
NotificationClaimApproved = "claim_approved"
|
|
NotificationClaimRejected = "claim_rejected"
|
|
NotificationItemExpired = "item_expired"
|
|
NotificationNewClaim = "new_claim"
|
|
NotificationItemReturned = "item_returned"
|
|
)
|
|
|
|
// MarkAsRead marks the notification as read
|
|
func (n *Notification) MarkAsRead() {
|
|
n.IsRead = true
|
|
now := time.Now()
|
|
n.ReadAt = &now
|
|
}
|
|
|
|
// NotificationResponse represents notification data for API responses
|
|
type NotificationResponse struct {
|
|
ID uint `json:"id"`
|
|
Type string `json:"type"`
|
|
Title string `json:"title"`
|
|
Message string `json:"message"`
|
|
EntityType string `json:"entity_type"`
|
|
EntityID *uint `json:"entity_id"`
|
|
IsRead bool `json:"is_read"`
|
|
ReadAt *time.Time `json:"read_at"`
|
|
CreatedAt time.Time `json:"created_at"`
|
|
}
|
|
|
|
// ToResponse converts Notification to NotificationResponse
|
|
func (n *Notification) ToResponse() NotificationResponse {
|
|
return NotificationResponse{
|
|
ID: n.ID,
|
|
Type: n.Type,
|
|
Title: n.Title,
|
|
Message: n.Message,
|
|
EntityType: n.EntityType,
|
|
EntityID: n.EntityID,
|
|
IsRead: n.IsRead,
|
|
ReadAt: n.ReadAt,
|
|
CreatedAt: n.CreatedAt,
|
|
}
|
|
}
|
|
|
|
// CreateNotification creates a new notification
|
|
func CreateNotification(db *gorm.DB, userID uint, notifType, title, message, entityType string, entityID *uint) error {
|
|
notification := &Notification{
|
|
UserID: userID,
|
|
Type: notifType,
|
|
Title: title,
|
|
Message: message,
|
|
EntityType: entityType,
|
|
EntityID: entityID,
|
|
}
|
|
|
|
return db.Create(notification).Error
|
|
}
|
|
|
|
// CreateMatchNotification creates a notification for match found
|
|
func CreateMatchNotification(db *gorm.DB, userID uint, itemName string, matchID uint) error {
|
|
return CreateNotification(
|
|
db,
|
|
userID,
|
|
NotificationMatchFound,
|
|
"Barang yang Mirip Ditemukan!",
|
|
"Kami menemukan barang yang mirip dengan laporan kehilangan Anda: "+itemName,
|
|
"match",
|
|
&matchID,
|
|
)
|
|
}
|
|
|
|
// CreateClaimApprovedNotification creates a notification for approved claim
|
|
func CreateClaimApprovedNotification(db *gorm.DB, userID uint, itemName string, claimID uint) error {
|
|
return CreateNotification(
|
|
db,
|
|
userID,
|
|
NotificationClaimApproved,
|
|
"Klaim Disetujui!",
|
|
"Klaim Anda untuk barang '"+itemName+"' telah disetujui. Silakan ambil barang di tempat yang ditentukan.",
|
|
"claim",
|
|
&claimID,
|
|
)
|
|
}
|
|
|
|
// CreateClaimRejectedNotification creates a notification for rejected claim
|
|
func CreateClaimRejectedNotification(db *gorm.DB, userID uint, itemName, reason string, claimID uint) error {
|
|
return CreateNotification(
|
|
db,
|
|
userID,
|
|
NotificationClaimRejected,
|
|
"Klaim Ditolak",
|
|
"Klaim Anda untuk barang '"+itemName+"' ditolak. Alasan: "+reason,
|
|
"claim",
|
|
&claimID,
|
|
)
|
|
} |