169 lines
4.3 KiB
Go
169 lines
4.3 KiB
Go
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
|
|
}
|
|
|
|
for _, oi := range order.Items {
|
|
movement := models.StockMovement{
|
|
ItemID: oi.ItemID,
|
|
Type: "out",
|
|
Quantity: oi.Quantity,
|
|
Reason: "order",
|
|
OrderID: &order.ID,
|
|
}
|
|
|
|
if err := tx.Omit("Item").Create(&movement).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": "Неверно указанный статус заказа"})
|
|
return
|
|
}
|
|
|
|
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, "Статус заказа успешно изменен")
|
|
}
|