mirror of
https://github.com/serty2005/rmser.git
synced 2026-02-04 19:02:33 -06:00
318 lines
8.7 KiB
Go
318 lines
8.7 KiB
Go
package handlers
|
|
|
|
import (
|
|
"net/http"
|
|
"time"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/google/uuid"
|
|
"github.com/shopspring/decimal"
|
|
"go.uber.org/zap"
|
|
|
|
"rmser/internal/services/drafts"
|
|
"rmser/pkg/logger"
|
|
)
|
|
|
|
type DraftsHandler struct {
|
|
service *drafts.Service
|
|
}
|
|
|
|
func NewDraftsHandler(service *drafts.Service) *DraftsHandler {
|
|
return &DraftsHandler{service: service}
|
|
}
|
|
|
|
// GetDraft
|
|
func (h *DraftsHandler) GetDraft(c *gin.Context) {
|
|
userID := c.MustGet("userID").(uuid.UUID)
|
|
idStr := c.Param("id")
|
|
id, err := uuid.Parse(idStr)
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid id"})
|
|
return
|
|
}
|
|
|
|
draft, err := h.service.GetDraft(id, userID)
|
|
if err != nil {
|
|
c.JSON(http.StatusNotFound, gin.H{"error": "draft not found"})
|
|
return
|
|
}
|
|
c.JSON(http.StatusOK, draft)
|
|
}
|
|
|
|
// GetDictionaries (бывший GetStores)
|
|
func (h *DraftsHandler) GetDictionaries(c *gin.Context) {
|
|
userID := c.MustGet("userID").(uuid.UUID)
|
|
|
|
data, err := h.service.GetDictionaries(userID)
|
|
if err != nil {
|
|
logger.Log.Error("GetDictionaries error", zap.Error(err))
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
c.JSON(http.StatusOK, data)
|
|
}
|
|
|
|
// GetStores - устаревший метод для обратной совместимости
|
|
// Возвращает массив складов
|
|
func (h *DraftsHandler) GetStores(c *gin.Context) {
|
|
userID := c.MustGet("userID").(uuid.UUID)
|
|
|
|
// Используем логику из GetDictionaries, но возвращаем только stores
|
|
dict, err := h.service.GetDictionaries(userID)
|
|
if err != nil {
|
|
logger.Log.Error("GetStores error", zap.Error(err))
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
// dict["stores"] уже содержит []catalog.Store
|
|
c.JSON(http.StatusOK, dict["stores"])
|
|
}
|
|
|
|
// UpdateItemDTO
|
|
type UpdateItemDTO struct {
|
|
ProductID *string `json:"product_id"`
|
|
ContainerID *string `json:"container_id"`
|
|
Quantity float64 `json:"quantity"`
|
|
Price float64 `json:"price"`
|
|
}
|
|
|
|
// AddDraftItem - POST /api/drafts/:id/items
|
|
func (h *DraftsHandler) AddDraftItem(c *gin.Context) {
|
|
draftID, err := uuid.Parse(c.Param("id"))
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid draft id"})
|
|
return
|
|
}
|
|
|
|
item, err := h.service.AddItem(draftID)
|
|
if err != nil {
|
|
logger.Log.Error("Failed to add item", zap.Error(err))
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, item)
|
|
}
|
|
|
|
// DeleteDraftItem - DELETE /api/drafts/:id/items/:itemId
|
|
func (h *DraftsHandler) DeleteDraftItem(c *gin.Context) {
|
|
draftID, err := uuid.Parse(c.Param("id"))
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid draft id"})
|
|
return
|
|
}
|
|
itemID, err := uuid.Parse(c.Param("itemId"))
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid item id"})
|
|
return
|
|
}
|
|
|
|
newTotal, err := h.service.DeleteItem(draftID, itemID)
|
|
if err != nil {
|
|
logger.Log.Error("Failed to delete item", zap.Error(err))
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, gin.H{
|
|
"status": "deleted",
|
|
"id": itemID.String(),
|
|
"total_sum": newTotal,
|
|
})
|
|
}
|
|
|
|
func (h *DraftsHandler) UpdateItem(c *gin.Context) {
|
|
// userID := c.MustGet("userID").(uuid.UUID) // Пока не используется в UpdateItem, но можно добавить проверку владельца
|
|
draftID, _ := uuid.Parse(c.Param("id"))
|
|
itemID, _ := uuid.Parse(c.Param("itemId"))
|
|
|
|
var req UpdateItemDTO
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
var pID *uuid.UUID
|
|
if req.ProductID != nil && *req.ProductID != "" {
|
|
if uid, err := uuid.Parse(*req.ProductID); err == nil {
|
|
pID = &uid
|
|
}
|
|
}
|
|
|
|
var cID *uuid.UUID
|
|
if req.ContainerID != nil && *req.ContainerID != "" {
|
|
if uid, err := uuid.Parse(*req.ContainerID); err == nil {
|
|
cID = &uid
|
|
}
|
|
}
|
|
|
|
qty := decimal.NewFromFloat(req.Quantity)
|
|
price := decimal.NewFromFloat(req.Price)
|
|
|
|
if err := h.service.UpdateItem(draftID, itemID, pID, cID, qty, price); err != nil {
|
|
logger.Log.Error("Failed to update item", zap.Error(err))
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, gin.H{"status": "updated"})
|
|
}
|
|
|
|
type CommitRequestDTO struct {
|
|
DateIncoming string `json:"date_incoming"` // YYYY-MM-DD
|
|
StoreID string `json:"store_id"`
|
|
SupplierID string `json:"supplier_id"`
|
|
Comment string `json:"comment"`
|
|
}
|
|
|
|
func (h *DraftsHandler) CommitDraft(c *gin.Context) {
|
|
userID := c.MustGet("userID").(uuid.UUID)
|
|
draftID, err := uuid.Parse(c.Param("id"))
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid draft id"})
|
|
return
|
|
}
|
|
|
|
var req CommitRequestDTO
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
date, err := time.Parse("2006-01-02", req.DateIncoming)
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid date format"})
|
|
return
|
|
}
|
|
storeID, err := uuid.Parse(req.StoreID)
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid store id"})
|
|
return
|
|
}
|
|
supplierID, err := uuid.Parse(req.SupplierID)
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid supplier id"})
|
|
return
|
|
}
|
|
|
|
if err := h.service.UpdateDraftHeader(draftID, &storeID, &supplierID, date, req.Comment); err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to update header: " + err.Error()})
|
|
return
|
|
}
|
|
|
|
docNum, err := h.service.CommitDraft(draftID, userID)
|
|
if err != nil {
|
|
logger.Log.Error("Commit failed", zap.Error(err))
|
|
c.JSON(http.StatusBadGateway, gin.H{"error": "RMS error: " + err.Error()})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, gin.H{"status": "completed", "document_number": docNum})
|
|
}
|
|
|
|
type AddContainerRequestDTO struct {
|
|
ProductID string `json:"product_id" binding:"required"`
|
|
Name string `json:"name" binding:"required"`
|
|
Count float64 `json:"count" binding:"required,gt=0"`
|
|
}
|
|
|
|
func (h *DraftsHandler) AddContainer(c *gin.Context) {
|
|
userID := c.MustGet("userID").(uuid.UUID)
|
|
|
|
var req AddContainerRequestDTO
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
pID, err := uuid.Parse(req.ProductID)
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid product_id"})
|
|
return
|
|
}
|
|
|
|
countDec := decimal.NewFromFloat(req.Count)
|
|
|
|
newID, err := h.service.CreateProductContainer(userID, pID, req.Name, countDec)
|
|
if err != nil {
|
|
logger.Log.Error("Failed to create container", zap.Error(err))
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, gin.H{"status": "created", "container_id": newID.String()})
|
|
}
|
|
|
|
type DraftListItemDTO struct {
|
|
ID string `json:"id"`
|
|
DocumentNumber string `json:"document_number"`
|
|
DateIncoming string `json:"date_incoming"`
|
|
Status string `json:"status"`
|
|
ItemsCount int `json:"items_count"`
|
|
TotalSum float64 `json:"total_sum"`
|
|
StoreName string `json:"store_name"`
|
|
CreatedAt string `json:"created_at"`
|
|
}
|
|
|
|
func (h *DraftsHandler) GetDrafts(c *gin.Context) {
|
|
userID := c.MustGet("userID").(uuid.UUID)
|
|
list, err := h.service.GetActiveDrafts(userID)
|
|
if err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
response := make([]DraftListItemDTO, 0, len(list))
|
|
for _, d := range list {
|
|
var totalSum decimal.Decimal
|
|
for _, item := range d.Items {
|
|
if !item.Sum.IsZero() {
|
|
totalSum = totalSum.Add(item.Sum)
|
|
} else {
|
|
totalSum = totalSum.Add(item.Quantity.Mul(item.Price))
|
|
}
|
|
}
|
|
sumFloat, _ := totalSum.Float64()
|
|
|
|
dateStr := ""
|
|
if d.DateIncoming != nil {
|
|
dateStr = d.DateIncoming.Format("2006-01-02")
|
|
}
|
|
storeName := ""
|
|
if d.Store != nil {
|
|
storeName = d.Store.Name
|
|
}
|
|
|
|
response = append(response, DraftListItemDTO{
|
|
ID: d.ID.String(),
|
|
DocumentNumber: d.DocumentNumber,
|
|
DateIncoming: dateStr,
|
|
Status: d.Status,
|
|
ItemsCount: len(d.Items),
|
|
TotalSum: sumFloat,
|
|
StoreName: storeName,
|
|
CreatedAt: d.CreatedAt.Format(time.RFC3339),
|
|
})
|
|
}
|
|
c.JSON(http.StatusOK, response)
|
|
}
|
|
|
|
func (h *DraftsHandler) DeleteDraft(c *gin.Context) {
|
|
// userID := c.MustGet("userID").(uuid.UUID) // Можно добавить проверку владельца
|
|
idStr := c.Param("id")
|
|
id, err := uuid.Parse(idStr)
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid id"})
|
|
return
|
|
}
|
|
|
|
newStatus, err := h.service.DeleteDraft(id)
|
|
if err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, gin.H{"status": newStatus, "id": id.String()})
|
|
}
|