146 lines
4.0 KiB
Go
146 lines
4.0 KiB
Go
package controllers
|
|
|
|
import (
|
|
"fmt"
|
|
"net/http"
|
|
"s-class-backend/config"
|
|
"s-class-backend/helpers" // Import helper pembuat kode acak
|
|
"s-class-backend/models"
|
|
"time"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/google/uuid"
|
|
)
|
|
|
|
type BookingInput struct {
|
|
RoomID uint `json:"room_id" binding:"required"`
|
|
StartTime time.Time `json:"start_time" binding:"required"`
|
|
EndTime time.Time `json:"end_time" binding:"required"`
|
|
Purpose string `json:"purpose" binding:"required"`
|
|
}
|
|
|
|
func CreateBooking(c *gin.Context) {
|
|
var input BookingInput
|
|
if err := c.ShouldBindJSON(&input); err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
// --- Handle UUID ---
|
|
userIDInterface, exists := c.Get("user_id")
|
|
if !exists {
|
|
c.JSON(http.StatusUnauthorized, gin.H{"error": "User ID tidak ditemukan"})
|
|
return
|
|
}
|
|
|
|
userIDStr, ok := userIDInterface.(string)
|
|
if !ok {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "Format User ID token salah"})
|
|
return
|
|
}
|
|
|
|
userID, err := uuid.Parse(userIDStr)
|
|
if err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "Gagal memproses User ID"})
|
|
return
|
|
}
|
|
|
|
// Validasi Waktu
|
|
if input.EndTime.Before(input.StartTime) {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "Waktu selesai tidak boleh lebih awal dari waktu mulai!"})
|
|
return
|
|
}
|
|
|
|
// CEK BENTROK (Overlap Check)
|
|
var count int64
|
|
config.DB.Model(&models.Booking{}).Where("room_id = ? AND status != 'Cancelled' AND ((start_time < ? AND end_time > ?) OR (start_time < ? AND end_time > ?) OR (start_time >= ? AND end_time <= ?))",
|
|
input.RoomID, input.EndTime, input.StartTime, input.EndTime, input.StartTime, input.StartTime, input.EndTime).Count(&count)
|
|
|
|
if count > 0 {
|
|
c.JSON(http.StatusConflict, gin.H{"error": "Ruangan sudah dibooking pada jam tersebut!"})
|
|
return
|
|
}
|
|
|
|
// Simpan Booking
|
|
booking := models.Booking{
|
|
UserID: userID,
|
|
RoomID: input.RoomID,
|
|
StartTime: input.StartTime,
|
|
EndTime: input.EndTime,
|
|
Purpose: input.Purpose,
|
|
Status: "Pending",
|
|
}
|
|
|
|
if err := config.DB.Create(&booking).Error; err != nil {
|
|
fmt.Println("Error DB:", err)
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, gin.H{
|
|
"message": "Booking Berhasil diajukan!",
|
|
"data": booking,
|
|
})
|
|
}
|
|
|
|
func GetUserBookings(c *gin.Context) {
|
|
var bookings []models.Booking
|
|
|
|
userID, _ := c.Get("user_id")
|
|
role, _ := c.Get("role")
|
|
|
|
if role == "admin" {
|
|
if err := config.DB.Preload("Room").Preload("User").Order("created_at desc").Find(&bookings).Error; err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
} else {
|
|
if err := config.DB.Preload("Room").Where("user_id = ?", userID).Order("created_at desc").Find(&bookings).Error; err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
}
|
|
|
|
c.JSON(http.StatusOK, gin.H{"data": bookings})
|
|
}
|
|
|
|
type UpdateStatusInput struct {
|
|
Status string `json:"status" binding:"required"`
|
|
}
|
|
|
|
// --- FUNGSI UPDATE STATUS (ADMIN) ---
|
|
func UpdateBookingStatus(c *gin.Context) {
|
|
bookingID := c.Param("id")
|
|
|
|
var booking models.Booking
|
|
if err := config.DB.First(&booking, "booking_id = ?", bookingID).Error; err != nil {
|
|
c.JSON(http.StatusNotFound, gin.H{"error": "Booking tidak ditemukan"})
|
|
return
|
|
}
|
|
|
|
var input UpdateStatusInput
|
|
if err := c.ShouldBindJSON(&input); err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
booking.Status = input.Status
|
|
|
|
// 👇 LOGIKA PEMBUATAN REDEEM CODE 👇
|
|
if input.Status == "Approved" {
|
|
// Buat kode dari helper jika sebelumnya belum punya kode
|
|
if booking.RedeemCode == "" {
|
|
booking.RedeemCode = helpers.GenerateRedeemCode()
|
|
}
|
|
} else if input.Status == "Rejected" || input.Status == "Cancelled" {
|
|
// Kosongkan kode jika peminjaman ditolak/dibatalkan
|
|
booking.RedeemCode = ""
|
|
}
|
|
|
|
config.DB.Save(&booking)
|
|
|
|
c.JSON(http.StatusOK, gin.H{
|
|
"message": "Status booking berhasil diperbarui!",
|
|
"data": booking,
|
|
})
|
|
} |