update tests

This commit is contained in:
2026-03-02 11:03:59 +00:00
parent eac5dccc3c
commit a2e0a8e05c
2 changed files with 69 additions and 0 deletions
+52
View File
@@ -1240,8 +1240,35 @@ func CreateBookingHandler(w http.ResponseWriter, r *http.Request) {
if req.StartTime.Before(time.Now()) { if req.StartTime.Before(time.Now()) {
http.Error(w, "Start time cannot be in the past", http.StatusBadRequest) http.Error(w, "Start time cannot be in the past", http.StatusBadRequest)
return return
return
} }
// Validate booking fits within operating hours for regular users
var svcDuration int
if err := db.DB.QueryRow(r.Context(), `
SELECT COALESCE(SUM(duration_minutes), 0) FROM services WHERE id = ANY($1)
`, req.ServiceIDs).Scan(&svcDuration); err != nil {
log.Printf("Failed to calc duration: %v", err)
http.Error(w, "Internal server error", http.StatusInternalServerError)
return
}
weekday := int(req.StartTime.Weekday())
var closeStr string
if err := db.DB.QueryRow(r.Context(), `SELECT end_time::text FROM working_hours WHERE weekday = $1`, weekday).Scan(&closeStr); err != nil {
log.Printf("Failed to get hours: %v", err)
http.Error(w, "Could not verify hours", http.StatusInternalServerError)
return
}
endTime := req.StartTime.Add(time.Duration(svcDuration) * time.Minute)
closeTime, _ := time.Parse("15:04:05", closeStr)
if endTime.Hour() > closeTime.Hour() || (endTime.Hour() == closeTime.Hour() && endTime.Minute() > closeTime.Minute()) {
http.Error(w, "Cannot book this time - services would extend beyond closing hours", http.StatusBadRequest)
return
}
// Get created by from context (if available) // Get created by from context (if available)
var createdBy *string var createdBy *string
if creatorID, ok := r.Context().Value(mw.UserIDKey).(string); ok { if creatorID, ok := r.Context().Value(mw.UserIDKey).(string); ok {
@@ -1698,6 +1725,31 @@ func ConfirmBookingHandler(w http.ResponseWriter, r *http.Request) {
} }
} }
// Check for overlapping confirmed/in_progress/completed bookings before confirming
var bkStart time.Time
if err := db.DB.QueryRow(r.Context(), "SELECT start_time FROM bookings WHERE id = $1", bookingID).Scan(&bkStart); err != nil {
log.Printf("Failed to get start time: %v", err)
http.Error(w, "Internal server error", http.StatusInternalServerError)
return
}
var dur int
db.DB.QueryRow(r.Context(), `
SELECT COALESCE(SUM(COALESCE(bs.override_duration_minutes, s.duration_minutes)), 60)
FROM booking_services bs JOIN services s ON bs.service_id = s.id WHERE bs.booking_id = $1
`, bookingID).Scan(&dur)
newEnd := bkStart.Add(time.Duration(dur) * time.Minute)
var cnt int
db.DB.QueryRow(r.Context(), `
SELECT COUNT(*) FROM bookings WHERE id != $1 AND status IN ('confirmed','in_progress','completed') AND start_time < $3 AND start_time + (INTERVAL '1 minute' * (SELECT COALESCE(SUM(COALESCE(bs.override_duration_minutes,s.duration_minutes)),60) FROM booking_services bs JOIN services s ON bs.service_id=s.id WHERE bs.booking_id=bookings.id)) > $2
`, bookingID, bkStart, newEnd).Scan(&cnt)
if cnt > 0 {
http.Error(w, "Cannot confirm - time slot overlaps with existing booking", http.StatusConflict)
return
}
tx, err := db.DB.Begin(r.Context()) tx, err := db.DB.Begin(r.Context())
if err != nil { if err != nil {
log.Printf("Failed to start transaction: %v", err) log.Printf("Failed to start transaction: %v", err)
+17
View File
@@ -537,8 +537,25 @@ func AdminCreateBookingForUserHandler(w http.ResponseWriter, r *http.Request) {
if isClosed { if isClosed {
http.Error(w, "Cannot book during holiday hours when the salon is closed", http.StatusConflict) http.Error(w, "Cannot book during holiday hours when the salon is closed", http.StatusConflict)
return return
return
} }
// Check for overlapping confirmed/in_progress/completed bookings
var dur int
db.DB.QueryRow(r.Context(), `
SELECT COALESCE(SUM(duration_minutes), 0) FROM services WHERE id = ANY($1)
`, req.ServiceIDs).Scan(&dur)
newEnd := req.StartTime.Add(time.Duration(dur) * time.Minute)
var cnt int
db.DB.QueryRow(r.Context(), `
SELECT COUNT(*) FROM bookings WHERE status IN ('confirmed','in_progress','completed') AND start_time < $2 AND start_time + (INTERVAL '1 minute' * (SELECT COALESCE(SUM(COALESCE(bs.override_duration_minutes,s.duration_minutes)),60) FROM booking_services bs JOIN services s ON bs.service_id=s.id WHERE bs.booking_id=bookings.id)) > $1
`, req.StartTime, newEnd).Scan(&cnt)
if cnt > 0 {
http.Error(w, "Cannot create booking - time slot overlaps with existing booking", http.StatusConflict)
return
}
tx, err := db.DB.Begin(r.Context()) tx, err := db.DB.Begin(r.Context())
if err != nil { if err != nil {
log.Printf("Failed to start transaction: %v", err) log.Printf("Failed to start transaction: %v", err)