package handlers import ( "fmt" "net/http" "github.com/gin-gonic/gin" "gorm.io/gorm" "fishfish/database" "fishfish/models" ) func CreateOrder(c *gin.Context) { userID := getUserID(c) var req struct { DeliveryAddress string `json:"delivery_address" binding:"required"` } if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "Не указан адрес доставки"}) return } var cartItems []models.CartItem if err := database.DB.Preload("Item").Where("user_id = ? ", userID).Find(&cartItems).Error; err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": "Не удалось получить корзину"}) return } if len(cartItems) == 0 { c.JSON(http.StatusBadRequest, gin.H{"error": "Корзина пуста"}) return } var order models.Order err := database.DB.Transaction(func(tx *gorm.DB) error { var total float64 var orderItems []models.OrderItem for _, cartItem := range cartItems { item := cartItem.Item result := tx.Model(&models.Item{}).Where("id = ? AND stock >= ?", item.ID, cartItem.Quantity).Update("stock", gorm.Expr("stock - ? ", cartItem.Quantity)) if result.RowsAffected == 0 { return fmt.Errorf("недостаточно товара '%s' на складе", item.Name) } itemTotal := float64(item.Price) * cartItem.Quantity total += itemTotal orderItems = append(orderItems, models.OrderItem{ ItemID: cartItem.ItemID, Quantity: cartItem.Quantity, Price: float64(item.Price), }) } order = models.Order{ UserID: userID, Status: "new", DeliveryAddress: req.DeliveryAddress, TotalPrice: total, Items: orderItems, } if err := tx.Create(&order).Error; err != nil { return err } if err := tx.Where("user_id = ? ", userID).Delete(&models.CartItem{}).Error; err != nil { return err } return nil }) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } c.JSON(http.StatusCreated, order) } func GetUserOrders(c *gin.Context) { userID := getUserID(c) var orders []models.Order if err := database.DB.Preload("Items.Item").Where("user_id = ? ", userID).Find(&orders).Error; err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": "Не удалось вывести заказы"}) return } c.JSON(http.StatusOK, orders) } func GetOrder(c *gin.Context) { userID := getUserID(c) orderID := c.Param("id") var order models.Order if err := database.DB.Preload("Items.Item").Where("id = ? AND user_id = ? ", orderID, userID).First(&order).Error; err != nil { c.JSON(http.StatusNotFound, gin.H{"error": "Заказ не найден"}) return } c.JSON(http.StatusOK, order) } func GetAllOrders(c *gin.Context) { var orders models.Order if err := database.DB.Preload("Items.Item").Find(&orders).Error; err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": "Не удалось вывести заказы"}) return } c.JSON(http.StatusOK, orders) } func UpdateOrderStatus(c *gin.Context) { orderID := c.Param("id") var req struct { Status string `json:"status" binding:"required"` } if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "Не указан статус заказа"}) return } if req.Status != "new" && req.Status != "packed" && req.Status != "delivered" && req.Status != "cancel" { c.JSON(http.StatusBadRequest, gin.H{"error": "Неверно указанный статус заказа"}) } result := database.DB.Model(&models.Order{}).Where("id = ? ", orderID).Update("status", req.Status) if result.Error != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": "Ошибка при изменении статуса заказа"}) return } if result.RowsAffected == 0 { c.JSON(http.StatusNotFound, gin.H{"error": "Заказ не найден"}) return } c.JSON(http.StatusAccepted, "Статус заказа успешно изменен") }