From d9b5653502fb51a6210ff88902ee184058c5d332 Mon Sep 17 00:00:00 2001 From: NANDO9322 Date: Mon, 26 Jan 2026 16:14:10 -0300 Subject: [PATCH] fix: ajuste erros de merge --- .../internal/http/handler/handler_test.go | 149 +++++------------- .../internal/http/handler/product_handler.go | 47 ------ .../internal/repository/postgres/postgres.go | 76 ++++++++- .../internal/usecase/product_service.go | 14 +- backend-old/internal/usecase/usecase.go | 1 + backend-old/internal/usecase/usecase_test.go | 8 +- 6 files changed, 117 insertions(+), 178 deletions(-) diff --git a/backend-old/internal/http/handler/handler_test.go b/backend-old/internal/http/handler/handler_test.go index 713d337..0c11962 100644 --- a/backend-old/internal/http/handler/handler_test.go +++ b/backend-old/internal/http/handler/handler_test.go @@ -186,10 +186,6 @@ func (m *MockRepository) GetInventoryItem(ctx context.Context, id uuid.UUID) (*d return nil, errors.New("inventory item not found") } -func (m *MockRepository) UpdateInventoryItem(ctx context.Context, item *domain.InventoryItem) error { - return nil -} - func (m *MockRepository) CreateOrder(ctx context.Context, order *domain.Order) error { id, _ := uuid.NewV7() order.ID = id @@ -261,9 +257,17 @@ func (m *MockRepository) GetUserByEmail(ctx context.Context, email string) (*dom return &u, nil } } - return nil, errors.New("user not found") // Simulate repository behavior + return nil, errors.New("user not found") } +// MockPaymentGateway implements the PaymentGateway interface for testing +type MockPaymentGateway struct{} + +func (m *MockPaymentGateway) CreatePreference(ctx context.Context, order *domain.Order) (*domain.PaymentPreference, error) { + return &domain.PaymentPreference{}, nil +} + +// Restored methods func (m *MockRepository) UpdateUser(ctx context.Context, user *domain.User) error { return nil } @@ -273,6 +277,7 @@ func (m *MockRepository) DeleteUser(ctx context.Context, id uuid.UUID) error { } func (m *MockRepository) AddCartItem(ctx context.Context, item *domain.CartItem) (*domain.CartItem, error) { + item.ID = uuid.Must(uuid.NewV7()) return item, nil } @@ -292,12 +297,20 @@ func (m *MockRepository) ClearCart(ctx context.Context, buyerID uuid.UUID) error return nil } -func (m *MockRepository) CreateReview(ctx context.Context, review *domain.Review) error { +func (m *MockRepository) ReplaceCart(ctx context.Context, buyerID uuid.UUID, items []domain.CartItem) error { return nil } -func (m *MockRepository) GetCompanyRating(ctx context.Context, companyID uuid.UUID) (*domain.CompanyRating, error) { - return &domain.CompanyRating{}, nil +func (m *MockRepository) UpdateOrderItems(ctx context.Context, orderID uuid.UUID, items []domain.OrderItem, totalCents int64) error { + return nil +} + +func (m *MockRepository) GetShippingSettings(ctx context.Context, vendorID uuid.UUID) (*domain.ShippingSettings, error) { + return &domain.ShippingSettings{}, nil +} + +func (m *MockRepository) UpsertShippingSettings(ctx context.Context, settings *domain.ShippingSettings) error { + return nil } func (m *MockRepository) SellerDashboard(ctx context.Context, sellerID uuid.UUID) (*domain.SellerDashboard, error) { @@ -308,135 +321,55 @@ func (m *MockRepository) AdminDashboard(ctx context.Context, since time.Time) (* return &domain.AdminDashboard{}, nil } -func (m *MockRepository) GetShippingMethodsByVendor(ctx context.Context, vendorID uuid.UUID) ([]domain.ShippingMethod, error) { - var methods []domain.ShippingMethod - for _, method := range m.shipping { - if method.VendorID == vendorID { - methods = append(methods, method) - } - } - return methods, nil -} - -func (m *MockRepository) UpsertShippingMethods(ctx context.Context, methods []domain.ShippingMethod) error { - for _, method := range methods { - updated := false - for i, existing := range m.shipping { - if existing.VendorID == method.VendorID && existing.Type == method.Type { - m.shipping[i] = method - updated = true - break - } - } - if !updated { - m.shipping = append(m.shipping, method) - } - } +func (m *MockRepository) CreateDocument(ctx context.Context, doc *domain.CompanyDocument) error { return nil } - -func (m *MockRepository) GetShippingSettings(ctx context.Context, vendorID uuid.UUID) (*domain.ShippingSettings, error) { - if s, ok := m.shippingSettings[vendorID]; ok { - return &s, nil - } +func (m *MockRepository) ListDocuments(ctx context.Context, companyID uuid.UUID) ([]domain.CompanyDocument, error) { return nil, nil } - -func (m *MockRepository) UpsertShippingSettings(ctx context.Context, settings *domain.ShippingSettings) error { - m.shippingSettings[settings.VendorID] = *settings - return nil -} - -func (m *MockRepository) ListReviews(ctx context.Context, filter domain.ReviewFilter) ([]domain.Review, int64, error) { - return []domain.Review{}, 0, nil -} - -func (m *MockRepository) ListShipments(ctx context.Context, filter domain.ShipmentFilter) ([]domain.Shipment, int64, error) { - return []domain.Shipment{}, 0, nil -} - -// Financial Methods -func (m *MockRepository) CreateDocument(ctx context.Context, doc *domain.CompanyDocument) error { - id, _ := uuid.NewV7() - doc.ID = id - m.documents = append(m.documents, *doc) - return nil // Simulate creation -} - -func (m *MockRepository) ListDocuments(ctx context.Context, companyID uuid.UUID) ([]domain.CompanyDocument, error) { - var docs []domain.CompanyDocument - for _, doc := range m.documents { - if doc.CompanyID == companyID { - docs = append(docs, doc) - } - } - return docs, nil -} - func (m *MockRepository) RecordLedgerEntry(ctx context.Context, entry *domain.LedgerEntry) error { - id, _ := uuid.NewV7() - entry.ID = id return nil } - func (m *MockRepository) GetLedger(ctx context.Context, companyID uuid.UUID, limit, offset int) ([]domain.LedgerEntry, int64, error) { - return []domain.LedgerEntry{}, 0, nil + return nil, 0, nil } - func (m *MockRepository) GetBalance(ctx context.Context, companyID uuid.UUID) (int64, error) { - return 100000, nil // Simulate some balance + return 0, nil } - func (m *MockRepository) CreateWithdrawal(ctx context.Context, withdrawal *domain.Withdrawal) error { - id, _ := uuid.NewV7() - withdrawal.ID = id return nil } - func (m *MockRepository) ListWithdrawals(ctx context.Context, companyID uuid.UUID) ([]domain.Withdrawal, error) { - return []domain.Withdrawal{}, nil + return nil, nil } - func (m *MockRepository) GetPaymentGatewayConfig(ctx context.Context, provider string) (*domain.PaymentGatewayConfig, error) { - if cfg, ok := m.gatewayConfigs[provider]; ok { - return &cfg, nil - } - return nil, errors.New("payment gateway config not found") + return nil, nil } - func (m *MockRepository) UpsertPaymentGatewayConfig(ctx context.Context, config *domain.PaymentGatewayConfig) error { - m.gatewayConfigs[config.Provider] = *config return nil } - func (m *MockRepository) GetSellerPaymentAccount(ctx context.Context, sellerID uuid.UUID) (*domain.SellerPaymentAccount, error) { - if acc, ok := m.sellerAccounts[sellerID]; ok { - return &acc, nil - } - return nil, errors.New("seller account not found") + return nil, nil } - func (m *MockRepository) UpsertSellerPaymentAccount(ctx context.Context, account *domain.SellerPaymentAccount) error { - m.sellerAccounts[account.SellerID] = *account return nil } - -// MockPaymentGateway implements the PaymentGateway interface for testing -type MockPaymentGateway struct{} - -func (m *MockPaymentGateway) CreatePreference(ctx context.Context, order *domain.Order) (*domain.PaymentPreference, error) { - return &domain.PaymentPreference{}, nil +func (m *MockRepository) GetCompanyRating(ctx context.Context, companyID uuid.UUID) (*domain.CompanyRating, error) { + return nil, nil } - -func (m *MockPaymentGateway) ParseWebhook(ctx context.Context, payload []byte) (*domain.PaymentSplitResult, error) { - return &domain.PaymentSplitResult{}, nil -} - -func (m *MockRepository) ReplaceCart(ctx context.Context, buyerID uuid.UUID, items []domain.CartItem) error { +func (m *MockRepository) CreateReview(ctx context.Context, review *domain.Review) error { return nil } - -func (m *MockRepository) UpdateOrderItems(ctx context.Context, orderID uuid.UUID, items []domain.OrderItem, totalCents int64) error { +func (m *MockRepository) ListReviews(ctx context.Context, filter domain.ReviewFilter) ([]domain.Review, int64, error) { + return nil, 0, nil +} +func (m *MockRepository) ListShipments(ctx context.Context, filter domain.ShipmentFilter) ([]domain.Shipment, int64, error) { + return nil, 0, nil +} +func (m *MockRepository) GetShippingMethodsByVendor(ctx context.Context, vendorID uuid.UUID) ([]domain.ShippingMethod, error) { + return nil, nil +} +func (m *MockRepository) UpsertShippingMethods(ctx context.Context, methods []domain.ShippingMethod) error { return nil } diff --git a/backend-old/internal/http/handler/product_handler.go b/backend-old/internal/http/handler/product_handler.go index 9b0993b..620fa56 100644 --- a/backend-old/internal/http/handler/product_handler.go +++ b/backend-old/internal/http/handler/product_handler.go @@ -439,53 +439,6 @@ type registerInventoryRequest struct { Observations string `json:"observations"` } -type updateInventoryRequest struct { - StockQuantity int64 `json:"qtdade_estoque"` - SalePrice float64 `json:"preco_venda"` -} - -// UpdateInventoryItem updates price and stock for an existing inventory item. -func (h *Handler) UpdateInventoryItem(w http.ResponseWriter, r *http.Request) { - // Parse ID from path - idStr := r.PathValue("id") - if idStr == "" { - parts := splitPath(r.URL.Path) - if len(parts) > 0 { - idStr = parts[len(parts)-1] - } - } - if idStr == "" { - writeError(w, http.StatusBadRequest, errors.New("id is required")) - return - } - itemID, err := uuid.FromString(idStr) - if err != nil { - writeError(w, http.StatusBadRequest, errors.New("invalid id format")) - return - } - - var req updateInventoryRequest - 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.StatusUnauthorized, errors.New("unauthorized")) - return - } - - priceCents := int64(req.SalePrice * 100) - err = h.svc.UpdateInventoryItem(r.Context(), itemID, *claims.CompanyID, priceCents, req.StockQuantity) - if err != nil { - writeError(w, http.StatusInternalServerError, err) - return - } - - writeJSON(w, http.StatusOK, map[string]string{"status": "updated"}) -} - // CreateInventoryItem godoc // @Summary Adicionar item ao estoque (venda) // @Tags Estoque diff --git a/backend-old/internal/repository/postgres/postgres.go b/backend-old/internal/repository/postgres/postgres.go index baf2413..964d5ac 100644 --- a/backend-old/internal/repository/postgres/postgres.go +++ b/backend-old/internal/repository/postgres/postgres.go @@ -529,6 +529,43 @@ VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $ return tx.Commit() } +func (r *Repository) UpdateOrderItems(ctx context.Context, orderID uuid.UUID, items []domain.OrderItem, totalCents int64) error { + tx, err := r.db.BeginTxx(ctx, nil) + if err != nil { + return err + } + defer tx.Rollback() + + // 1. Update Order Total + if _, err := tx.ExecContext(ctx, "UPDATE orders SET total_cents = $1, updated_at = $2 WHERE id = $3", totalCents, time.Now().UTC(), orderID); err != nil { + return err + } + + // 2. Clear existing items (be careful with stock, caller handles logic? Caller (Service) says it handles logic) + // Assuming Service handles adjust inventory BEFORE calling this? + // Service.UpdateOrderItems impl (step 643 line 93) just calls repo. + // We just replace items here. + if _, err := tx.ExecContext(ctx, "DELETE FROM order_items WHERE order_id = $1", orderID); err != nil { + return err + } + + // 3. Insert new items + query := `INSERT INTO order_items (id, order_id, product_id, quantity, unit_cents, batch, expires_at) + VALUES (:id, :order_id, :product_id, :quantity, :unit_cents, :batch, :expires_at)` + + for _, item := range items { + if item.ID == uuid.Nil { + item.ID = uuid.Must(uuid.NewV7()) + } + item.OrderID = orderID + if _, err := tx.NamedExecContext(ctx, query, item); err != nil { + return err + } + } + + return tx.Commit() +} + func (r *Repository) ListOrders(ctx context.Context, filter domain.OrderFilter) ([]domain.Order, int64, error) { baseQuery := `FROM orders` var args []any @@ -987,6 +1024,38 @@ RETURNING id, buyer_id, product_id, quantity, unit_cents, batch, expires_at, cre return nil, errors.New("failed to persist cart item") } +// ReplaceCart clears the buyer's cart and inserts new items transactionally. +func (r *Repository) ReplaceCart(ctx context.Context, buyerID uuid.UUID, items []domain.CartItem) error { + tx, err := r.db.BeginTxx(ctx, nil) + if err != nil { + return err + } + defer tx.Rollback() + + // Clear existing cart + if _, err := tx.ExecContext(ctx, "DELETE FROM cart_items WHERE buyer_id = $1", buyerID); err != nil { + return err + } + + // Insert new items + query := `INSERT INTO cart_items (id, buyer_id, product_id, quantity, unit_cents, batch, expires_at, created_at, updated_at) + VALUES (:id, :buyer_id, :product_id, :quantity, :unit_cents, :batch, :expires_at, :created_at, :updated_at)` + + now := time.Now().UTC() + for _, item := range items { + if item.ID == uuid.Nil { + item.ID = uuid.Must(uuid.NewV7()) + } + item.CreatedAt = now + item.UpdatedAt = now + if _, err := tx.NamedExecContext(ctx, query, item); err != nil { + return err + } + } + + return tx.Commit() +} + func (r *Repository) ListCartItems(ctx context.Context, buyerID uuid.UUID) ([]domain.CartItem, error) { query := `SELECT ci.id, ci.buyer_id, ci.product_id, ci.quantity, ci.unit_cents, ci.batch, ci.expires_at, ci.created_at, ci.updated_at, p.name AS product_name @@ -1382,10 +1451,3 @@ func (r *Repository) CreateInventoryItem(ctx context.Context, item *domain.Inven _, err := r.db.NamedExecContext(ctx, query, item) return err } - -func (r *Repository) UpdateInventoryItem(ctx context.Context, item *domain.InventoryItem) error { - query := `UPDATE inventory_items SET sale_price_cents = :sale_price_cents, stock_quantity = :stock_quantity, updated_at = :updated_at WHERE id = :id AND seller_id = :seller_id` - item.UpdatedAt = time.Now().UTC() - _, err := r.db.NamedExecContext(ctx, query, item) - return err -} diff --git a/backend-old/internal/usecase/product_service.go b/backend-old/internal/usecase/product_service.go index 9163983..8cb356c 100644 --- a/backend-old/internal/usecase/product_service.go +++ b/backend-old/internal/usecase/product_service.go @@ -129,14 +129,10 @@ func (s *Service) RegisterInventoryItem(ctx context.Context, item *domain.Invent return s.repo.CreateInventoryItem(ctx, item) } -func (s *Service) UpdateInventoryItem(ctx context.Context, itemID uuid.UUID, sellerID uuid.UUID, priceCents int64, stockQuantity int64) error { - // We construct a partial item just for update - item := &domain.InventoryItem{ - ID: itemID, - SellerID: sellerID, - SalePriceCents: priceCents, - StockQuantity: stockQuantity, - } - // Future improvement: check if item exists and belongs to seller first, strict validation +func (s *Service) GetInventoryItem(ctx context.Context, id uuid.UUID) (*domain.InventoryItem, error) { + return s.repo.GetInventoryItem(ctx, id) +} + +func (s *Service) UpdateInventoryItem(ctx context.Context, item *domain.InventoryItem) error { return s.repo.UpdateInventoryItem(ctx, item) } diff --git a/backend-old/internal/usecase/usecase.go b/backend-old/internal/usecase/usecase.go index b56e86e..111045a 100644 --- a/backend-old/internal/usecase/usecase.go +++ b/backend-old/internal/usecase/usecase.go @@ -36,6 +36,7 @@ type Repository interface { AdjustInventory(ctx context.Context, productID uuid.UUID, delta int64, reason string) (*domain.InventoryItem, error) ListInventory(ctx context.Context, filter domain.InventoryFilter) ([]domain.InventoryItem, int64, error) CreateInventoryItem(ctx context.Context, item *domain.InventoryItem) error + GetInventoryItem(ctx context.Context, id uuid.UUID) (*domain.InventoryItem, error) UpdateInventoryItem(ctx context.Context, item *domain.InventoryItem) error CreateOrder(ctx context.Context, order *domain.Order) error diff --git a/backend-old/internal/usecase/usecase_test.go b/backend-old/internal/usecase/usecase_test.go index adfd1e6..b3960e8 100644 --- a/backend-old/internal/usecase/usecase_test.go +++ b/backend-old/internal/usecase/usecase_test.go @@ -194,10 +194,6 @@ func (m *MockRepository) GetInventoryItem(ctx context.Context, id uuid.UUID) (*d return nil, errors.New("not implemented in mock") } -func (m *MockRepository) UpdateInventoryItem(ctx context.Context, item *domain.InventoryItem) error { - return nil -} - func (m *MockRepository) CreateOrder(ctx context.Context, order *domain.Order) error { m.orders = append(m.orders, *order) return nil @@ -254,9 +250,7 @@ func (m *MockRepository) CreateShipment(ctx context.Context, shipment *domain.Sh func (m *MockRepository) GetShipmentByOrderID(ctx context.Context, orderID uuid.UUID) (*domain.Shipment, error) { return nil, nil } -func (m *MockRepository) UpdateShipmentStatus(ctx context.Context, id uuid.UUID, status string) error { - return nil -} + func (m *MockRepository) ListShipments(ctx context.Context, filter domain.ShipmentFilter) ([]domain.Shipment, int64, error) { return nil, 0, nil }