89 lines
3.1 KiB
Go
89 lines
3.1 KiB
Go
|
|
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())
|
||
|
|
}
|