package api import ( "log" "net/http" "rrbec_server/internal/models" "rrbec_server/internal/service" "strconv" "github.com/gin-gonic/gin" ) type Handler struct { svc *service.Service } func NewHandler(svc *service.Service) *Handler { return &Handler{svc: svc} } func (h *Handler) GetProducts(c *gin.Context) { products, err := h.svc.GetProducts() if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } c.JSON(http.StatusOK, products) } func (h *Handler) CreateProduct(c *gin.Context) { var product models.Product if err := c.ShouldBindJSON(&product); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } if err := h.svc.CreateProduct(&product); err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } c.JSON(http.StatusCreated, gin.H{"message": "Product created successfully", "product": product}) } func (h *Handler) UpdateProduct(c *gin.Context) { idStr := c.Param("id") id, err := strconv.ParseUint(idStr, 10, 64) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "invalid id format"}) return } var updates map[string]interface{} if err := c.ShouldBindJSON(&updates); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } if err := h.svc.UpdateProduct(uint(id), updates); err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } c.JSON(http.StatusOK, gin.H{"message": "Product updated successfully"}) } func (h *Handler) GetMesas(c *gin.Context) { mesas, err := h.svc.GetMesas() if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } c.JSON(http.StatusOK, mesas) } func (h *Handler) GetCategories(c *gin.Context) { categories, err := h.svc.GetCategories() if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } c.JSON(http.StatusOK, categories) } func (h *Handler) CreateCategory(c *gin.Context) { var cat models.Category if err := c.ShouldBindJSON(&cat); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } if err := h.svc.CreateCategory(&cat); err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } c.JSON(http.StatusCreated, cat) } func (h *Handler) UpdateCategory(c *gin.Context) { idStr := c.Param("id") id, err := strconv.ParseUint(idStr, 10, 64) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "invalid id format"}) return } var updates map[string]interface{} if err := c.ShouldBindJSON(&updates); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } if err := h.svc.UpdateCategory(uint(id), updates); err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } c.JSON(http.StatusOK, gin.H{"message": "Category updated successfully"}) } func (h *Handler) GetTypePayments(c *gin.Context) { types, err := h.svc.GetTypePayments() if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } c.JSON(http.StatusOK, types) } func (h *Handler) GetClients(c *gin.Context) { clients, err := h.svc.GetClients() if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } c.JSON(http.StatusOK, clients) } func (h *Handler) GetOrders(c *gin.Context) { orders, err := h.svc.GetOrders() if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } c.JSON(http.StatusOK, orders) } func (h *Handler) CreateOrder(c *gin.Context) { var order models.Order if err := c.ShouldBindJSON(&order); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } if err := h.svc.CreateOrder(&order); err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } c.JSON(http.StatusCreated, order) } func (h *Handler) UpdateOrder(c *gin.Context) { idStr := c.Param("id") id, err := strconv.ParseUint(idStr, 10, 64) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "invalid id format"}) return } var updates map[string]interface{} if err := c.ShouldBindJSON(&updates); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } if err := h.svc.UpdateOrder(uint(id), updates); err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } c.JSON(http.StatusOK, gin.H{"message": "Order updated successfully"}) } func (h *Handler) SetOrderPreparing(c *gin.Context) { idStr := c.Param("id") id, err := strconv.ParseUint(idStr, 10, 64) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "invalid id format"}) return } if err := h.svc.SetOrderPreparing(uint(id)); err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } c.JSON(http.StatusOK, gin.H{"message": "Order is now preparing"}) } func (h *Handler) SetOrderFinished(c *gin.Context) { idStr := c.Param("id") id, err := strconv.ParseUint(idStr, 10, 64) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "invalid id format"}) return } if err := h.svc.SetOrderFinished(uint(id)); err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } c.JSON(http.StatusOK, gin.H{"message": "Order finished"}) } func (h *Handler) SetOrderDelivered(c *gin.Context) { idStr := c.Param("id") id, err := strconv.ParseUint(idStr, 10, 64) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "invalid id format"}) return } if err := h.svc.SetOrderDelivered(uint(id)); err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } c.JSON(http.StatusOK, gin.H{"message": "Order delivered"}) } func (h *Handler) SetOrderCanceled(c *gin.Context) { idStr := c.Param("id") id, err := strconv.ParseUint(idStr, 10, 64) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "invalid id format"}) return } if err := h.svc.SetOrderCanceled(uint(id)); err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } c.JSON(http.StatusOK, gin.H{"message": "Order canceled"}) } func (h *Handler) GetPayments(c *gin.Context) { payments, err := h.svc.GetPayments() if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } c.JSON(http.StatusOK, payments) } func (h *Handler) CreateComanda(c *gin.Context) { var comanda models.Comanda if err := c.ShouldBindJSON(&comanda); err != nil { log.Printf("DEBUG: CreateComanda bind error: %v", err) c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } log.Printf("DEBUG: CreateComanda received: MesaID=%d, UserID=%d, ClientID=%v", comanda.MesaID, comanda.UserID, comanda.ClientID) if comanda.MesaID == 0 { c.JSON(http.StatusBadRequest, gin.H{"error": "Mesa ID is required for sync consistency"}) return } if err := h.svc.CreateComanda(&comanda); err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } c.JSON(http.StatusCreated, comanda) } func (h *Handler) AddItemToComanda(c *gin.Context) { var item models.ProductComanda if err := c.ShouldBindJSON(&item); err != nil { log.Printf("DEBUG: AddItem bind error: %v", err) c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } log.Printf("DEBUG: AddItem received: ComandaID=%d, ProductID=%d", item.ComandaID, item.ProductID) if item.ComandaID == 0 || item.ProductID == 0 { c.JSON(http.StatusBadRequest, gin.H{"error": "ComandaID and ProductID are required for sync"}) return } if err := h.svc.AddItemToComandaRaw(&item); err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } c.JSON(http.StatusCreated, item) } func (h *Handler) DeleteItemFromComanda(c *gin.Context) { idStr := c.Param("id") id, err := strconv.ParseUint(idStr, 10, 64) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "invalid id format"}) return } if err := h.svc.DeleteItem(uint(id)); err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } c.JSON(http.StatusOK, gin.H{"message": "Item deleted successfully"}) } func (h *Handler) ClearComanda(c *gin.Context) { idStr := c.Param("id") id, err := strconv.ParseUint(idStr, 10, 64) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "invalid id format"}) return } if err := h.svc.ClearComanda(uint(id)); err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } c.JSON(http.StatusOK, gin.H{"message": "Comanda cleared and closed"}) } func (h *Handler) UpdateComanda(c *gin.Context) { idStr := c.Param("id") id, err := strconv.ParseUint(idStr, 10, 64) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "invalid id format"}) return } var updates map[string]interface{} if err := c.ShouldBindJSON(&updates); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } if err := h.svc.UpdateComanda(uint(id), updates); err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } c.JSON(http.StatusOK, gin.H{"message": "Comanda updated successfully"}) } func (h *Handler) PagarComanda(c *gin.Context) { idStr := c.Param("id") id, err := strconv.ParseUint(idStr, 10, 64) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "invalid id format"}) return } var rawData map[string]interface{} if err := c.ShouldBindJSON(&rawData); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } log.Printf("DEBUG: PagarComanda RAW JSON: %v", rawData) var payment models.Payment if v, ok := rawData["value"].(float64); ok { payment.Value = models.Price(v) } if v, ok := rawData["type_pay"].(float64); ok { payment.TypePayID = uint(v) } else if v, ok := rawData["id_type_pay"].(float64); ok { payment.TypePayID = uint(v) } if v, ok := rawData["client"].(float64); ok { clientId := uint(v) payment.ClientID = &clientId } else if v, ok := rawData["client_id"].(float64); ok { clientId := uint(v) payment.ClientID = &clientId } if v, ok := rawData["description"].(string); ok { payment.Description = v } status := "CLOSED" if v, ok := rawData["status"].(string); ok { status = v } if err := h.svc.PagarComanda(uint(id), &payment, status); err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } c.JSON(http.StatusOK, gin.H{"message": "Payment registered and comanda updated to " + status}) } func (h *Handler) GetComandas(c *gin.Context) { comandas, err := h.svc.GetComandas() if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } c.JSON(http.StatusOK, comandas) } func (h *Handler) GetComandaByID(c *gin.Context) { idStr := c.Param("id") id, err := strconv.ParseUint(idStr, 10, 64) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "invalid id format"}) return } comanda, err := h.svc.GetComandaByID(uint(id)) if err != nil { c.JSON(http.StatusNotFound, gin.H{"error": "comanda not found"}) return } c.JSON(http.StatusOK, comanda) } func (h *Handler) Login(c *gin.Context) { var input struct { Username string `json:"username" binding:"required"` Password string `json:"password" binding:"required"` } if err := c.ShouldBindJSON(&input); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } user, err := h.svc.Login(input.Username, input.Password) if err != nil { c.JSON(http.StatusUnauthorized, gin.H{"error": err.Error()}) return } c.JSON(http.StatusOK, gin.H{ "message": "Login successful", "user": user, }) } func (h *Handler) GetCurrentUser(c *gin.Context) { userID, exists := c.Get("userID") if !exists { c.JSON(http.StatusUnauthorized, gin.H{"error": "user not authenticated"}) return } c.JSON(http.StatusOK, gin.H{"user_id": userID}) }