feat: add stock movement on backend

This commit is contained in:
2026-06-26 16:57:36 +03:00
parent 846844a1f0
commit 7b662bb618
6 changed files with 140 additions and 2 deletions
+116
View File
@@ -0,0 +1,116 @@
package handlers
import (
"fmt"
"net/http"
"github.com/gin-gonic/gin"
"gorm.io/gorm"
"fishfish/database"
"fishfish/models"
)
func StockIn(c *gin.Context) {
var input struct {
ItemID uint `json:"item_id" binding:"required"`
Quantity float64 `json:"quantity" binding:"required"`
Comment string `json:"comment"`
}
if err := c.ShouldBindJSON(&input); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "Неверные данные"})
return
}
if input.Quantity <= 0 {
c.JSON(http.StatusBadRequest, gin.H{"error": "Количество должно быть положительным"})
return
}
err := database.DB.Transaction(func(tx *gorm.DB) error {
result := tx.Model(&models.Item{}).
Where("id = ? ", input.ItemID).
Update("stock", gorm.Expr("stock + ?", input.Quantity))
if result.Error != nil {
return result.Error
}
if result.RowsAffected == 0 {
return fmt.Errorf("товар не найден")
}
movement := models.StockMovement{
ItemID: input.ItemID,
Type: "in",
Quantity: input.Quantity,
Reason: "purchase",
Comment: input.Comment,
}
if err := tx.Create(&movement).Error; err != nil {
return err
}
return nil
})
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"message": "Приход оформлен"})
}
func StockOut(c *gin.Context) {
var input struct {
ItemID uint `json:"item_id" binding:"required"`
Quantity float64 `json:"quantity" binding:"required"`
Comment string `json:"comment"`
}
if err := c.ShouldBindJSON(&input); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "Неверные данные"})
return
}
if input.Quantity <= 0 {
c.JSON(http.StatusBadRequest, gin.H{"error": "Количество должно быть положительным"})
return
}
err := database.DB.Transaction(func(tx *gorm.DB) error {
result := tx.Model(&models.Item{}).
Where("id = ? AND stock >= ? ", input.ItemID, input.Quantity).
Update("stock", gorm.Expr("stock - ?", input.Quantity))
if result.Error != nil {
return result.Error
}
if result.RowsAffected == 0 {
return fmt.Errorf("товар не найден или не достаточно товара")
}
movement := models.StockMovement{
ItemID: input.ItemID,
Type: "out",
Quantity: input.Quantity,
Reason: "sale",
Comment: input.Comment,
}
if err := tx.Create(&movement).Error; err != nil {
return err
}
return nil
})
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"message": "Уход оформлен"})
}