package handler import ( "errors" "log" "net/http" "github.com/saveinmed/backend-go/internal/domain" "github.com/saveinmed/backend-go/internal/http/middleware" ) // CreateOrder godoc // @Summary Criação de pedido com split // @Tags Pedidos // @Accept json // @Produce json // @Param order body createOrderRequest true "Pedido" // @Success 201 {object} domain.Order // @Router /api/v1/orders [post] func (h *Handler) CreateOrder(w http.ResponseWriter, r *http.Request) { var req createOrderRequest if err := decodeJSON(r.Context(), r, &req); err != nil { writeError(w, http.StatusBadRequest, err) return } claims, ok := middleware.GetClaims(r.Context()) if !ok || claims.CompanyID == nil { writeError(w, http.StatusBadRequest, errors.New("missing buyer context")) return } order := &domain.Order{ BuyerID: *claims.CompanyID, SellerID: req.SellerID, Items: req.Items, Shipping: req.Shipping, PaymentMethod: domain.PaymentMethod(req.PaymentMethod.Type), } var total int64 for _, item := range req.Items { total += item.UnitCents * item.Quantity } order.TotalCents = total if err := h.svc.CreateOrder(r.Context(), order); err != nil { writeError(w, http.StatusInternalServerError, err) return } writeJSON(w, http.StatusCreated, order) } // ListOrders godoc // @Summary Listar pedidos // @Tags Pedidos // @Security BearerAuth // @Produce json // @Success 200 {array} domain.Order // @Router /api/v1/orders [get] func (h *Handler) ListOrders(w http.ResponseWriter, r *http.Request) { log.Printf("📦 [ListOrders] ========== INÍCIO ==========") log.Printf("📦 [ListOrders] URL: %s", r.URL.String()) log.Printf("📦 [ListOrders] Method: %s", r.Method) page, pageSize := parsePagination(r) log.Printf("📦 [ListOrders] Paginação: page=%d, pageSize=%d", page, pageSize) filter := domain.OrderFilter{} // Parse role query param for filtering log.Printf("🔐 [ListOrders] Obtendo requester do contexto...") requester, err := getRequester(r) if err != nil { log.Printf("❌ [ListOrders] ERRO ao obter requester: %v", err) writeError(w, http.StatusUnauthorized, err) return } log.Printf("✅ [ListOrders] Requester obtido: Role=%s, CompanyID=%v", requester.Role, requester.CompanyID) role := r.URL.Query().Get("role") log.Printf("🎭 [ListOrders] Role query param: '%s'", role) if role != "" && requester.CompanyID != nil { log.Printf("🏢 [ListOrders] CompanyID do requester: %s", *requester.CompanyID) switch role { case "buyer": filter.BuyerID = requester.CompanyID log.Printf("🛒 [ListOrders] Filtro aplicado: BuyerID=%s", *requester.CompanyID) case "seller": filter.SellerID = requester.CompanyID log.Printf("💰 [ListOrders] Filtro aplicado: SellerID=%s", *requester.CompanyID) } } else { log.Printf("⚠️ [ListOrders] Sem filtro de role aplicado. role='%s', CompanyID=%v", role, requester.CompanyID) } log.Printf("🔍 [ListOrders] Chamando svc.ListOrders com filter=%+v", filter) result, err := h.svc.ListOrders(r.Context(), filter, page, pageSize) if err != nil { log.Printf("❌ [ListOrders] ERRO no service ListOrders: %v", err) writeError(w, http.StatusInternalServerError, err) return } log.Printf("✅ [ListOrders] Sucesso! Total de pedidos: %d", result.Total) log.Printf("📦 [ListOrders] ========== FIM ==========") writeJSON(w, http.StatusOK, result) } // GetOrder godoc // @Summary Consulta pedido // @Tags Pedidos // @Security BearerAuth // @Produce json // @Param id path string true "Order ID" // @Success 200 {object} domain.Order // @Router /api/v1/orders/{id} [get] func (h *Handler) GetOrder(w http.ResponseWriter, r *http.Request) { id, err := parseUUIDFromPath(r.URL.Path) if err != nil { writeError(w, http.StatusBadRequest, err) return } order, err := h.svc.GetOrder(r.Context(), id) if err != nil { writeError(w, http.StatusNotFound, err) return } writeJSON(w, http.StatusOK, order) } // UpdateOrder godoc // @Summary Atualizar itens do pedido // @Tags Pedidos // @Security BearerAuth // @Accept json // @Produce json // @Param id path string true "Order ID" // @Param order body createOrderRequest true "Novos dados (itens)" // @Success 200 {object} domain.Order // @Router /api/v1/orders/{id} [put] func (h *Handler) UpdateOrder(w http.ResponseWriter, r *http.Request) { id, err := parseUUIDFromPath(r.URL.Path) if err != nil { writeError(w, http.StatusBadRequest, err) return } var req createOrderRequest if err := decodeJSON(r.Context(), r, &req); err != nil { writeError(w, http.StatusBadRequest, err) return } var total int64 for _, item := range req.Items { total += item.UnitCents * item.Quantity } // FIX: UpdateOrderItems expects []domain.OrderItem // req.Items is []domain.OrderItem (from dto.go definition) if err := h.svc.UpdateOrderItems(r.Context(), id, req.Items, total); err != nil { writeError(w, http.StatusInternalServerError, err) return } // Return updated order order, err := h.svc.GetOrder(r.Context(), id) if err != nil { writeJSON(w, http.StatusOK, map[string]string{"status": "updated"}) return } writeJSON(w, http.StatusOK, order) } // UpdateOrderStatus godoc // @Summary Atualiza status do pedido // @Tags Pedidos // @Security BearerAuth // @Accept json // @Produce json // @Param id path string true "Order ID" // @Param status body updateStatusRequest true "Novo status" // @Success 204 "" // @Router /api/v1/orders/{id}/status [patch] func (h *Handler) UpdateOrderStatus(w http.ResponseWriter, r *http.Request) { id, err := parseUUIDFromPath(r.URL.Path) if err != nil { writeError(w, http.StatusBadRequest, err) return } var req updateStatusRequest if err := decodeJSON(r.Context(), r, &req); err != nil { writeError(w, http.StatusBadRequest, err) return } if !isValidStatus(req.Status) { writeError(w, http.StatusBadRequest, errors.New("invalid status")) return } if err := h.svc.UpdateOrderStatus(r.Context(), id, domain.OrderStatus(req.Status)); err != nil { writeError(w, http.StatusInternalServerError, err) return } w.WriteHeader(http.StatusNoContent) } // DeleteOrder godoc // @Summary Remover pedido // @Tags Pedidos // @Security BearerAuth // @Param id path string true "Order ID" // @Success 204 "" // @Failure 400 {object} map[string]string // @Failure 404 {object} map[string]string // @Router /api/v1/orders/{id} [delete] func (h *Handler) DeleteOrder(w http.ResponseWriter, r *http.Request) { id, err := parseUUIDFromPath(r.URL.Path) if err != nil { writeError(w, http.StatusBadRequest, err) return } if err := h.svc.DeleteOrder(r.Context(), id); err != nil { writeError(w, http.StatusBadRequest, err) return } w.WriteHeader(http.StatusNoContent) }