backend-service/internal/models/booking.go

89 lines
3.1 KiB
Go
Raw Permalink Normal View History

package models
import (
"errors"
"time"
"gorm.io/gorm"
)
// BookingStatus represents the possible states of a booking
type BookingStatus string
const (
BookingStatusScheduled BookingStatus = "scheduled"
BookingStatusCompleted BookingStatus = "completed"
BookingStatusCancelled BookingStatus = "cancelled"
)
// PaymentStatus represents the possible states of a payment
type PaymentStatus string
const (
PaymentStatusPending PaymentStatus = "pending"
PaymentStatusSucceeded PaymentStatus = "succeeded"
PaymentStatusFailed PaymentStatus = "failed"
PaymentStatusRefunded PaymentStatus = "refunded"
)
// Booking represents a scheduled meeting
type Booking struct {
gorm.Model
UserID uint `json:"user_id" gorm:"not null;index" validate:"required"`
User User `json:"user" gorm:"foreignKey:UserID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE"`
ScheduledAt time.Time `json:"scheduled_at" gorm:"not null;index" validate:"required"`
Duration int `json:"duration" gorm:"default:60;check:duration > 0" validate:"min=15,max=480"` // minutes, 15min to 8hrs
Status BookingStatus `json:"status" gorm:"default:'scheduled';size:20" validate:"required,oneof=scheduled completed cancelled"`
JitsiRoomID string `json:"jitsi_room_id" gorm:"size:255;index"`
JitsiRoomURL string `json:"jitsi_room_url" gorm:"size:500"`
PaymentID string `json:"payment_id" gorm:"size:255;index"`
PaymentStatus PaymentStatus `json:"payment_status" gorm:"size:20" validate:"omitempty,oneof=pending succeeded failed refunded"`
Amount float64 `json:"amount" gorm:"type:decimal(10,2);check:amount >= 0" validate:"min=0"`
Notes string `json:"notes" gorm:"type:text"`
}
// BeforeCreate is a GORM hook that runs before creating a booking record
func (b *Booking) BeforeCreate(tx *gorm.DB) error {
// Validate that the scheduled time is in the future
if b.ScheduledAt.Before(time.Now()) {
return errors.New("booking cannot be scheduled in the past")
}
// Set default status if not provided
if b.Status == "" {
b.Status = BookingStatusScheduled
}
// Set default duration if not provided
if b.Duration == 0 {
b.Duration = 60
}
return nil
}
// BeforeUpdate is a GORM hook that runs before updating a booking record
func (b *Booking) BeforeUpdate(tx *gorm.DB) error {
// Prevent updating completed bookings
if b.Status == BookingStatusCompleted {
return errors.New("cannot modify completed bookings")
}
return nil
}
// CanBeCancelled checks if the booking can be cancelled
func (b *Booking) CanBeCancelled() bool {
return b.Status == BookingStatusScheduled && b.ScheduledAt.After(time.Now().Add(24*time.Hour))
}
// CanBeRescheduled checks if the booking can be rescheduled
func (b *Booking) CanBeRescheduled() bool {
return b.Status == BookingStatusScheduled && b.ScheduledAt.After(time.Now().Add(2*time.Hour))
}
// IsUpcoming checks if the booking is scheduled for the future
func (b *Booking) IsUpcoming() bool {
return b.Status == BookingStatusScheduled && b.ScheduledAt.After(time.Now())
}