package handlers import ( "net/http" "github.com/gin-gonic/gin" "github.com/google/uuid" "gitea.maison43.duckdns.org/gilles/matosbox/internal/data/ent" "gitea.maison43.duckdns.org/gilles/matosbox/internal/data/ent/lienobjetemplacement" ) type lienObjetEmplacementRequest struct { EmplacementID *string `json:"emplacement_id"` Type *string `json:"type"` } type lienObjetEmplacementUpdateRequest struct { EmplacementID *string `json:"emplacement_id"` Type *string `json:"type"` } // @Summary Lister les liens objet/emplacement // @Tags LiensEmplacements // @Produce json // @Param id path string true "ID objet" // @Param page query int false "Page" // @Param limit query int false "Limite" // @Success 200 {object} map[string]any // @Failure 400 {object} map[string]string // @Failure 500 {object} map[string]string // @Router /objets/{id}/liens_emplacements [get] func (h *Handler) ListLiensEmplacements(c *gin.Context) { objetID, err := uuid.Parse(c.Param("id")) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"erreur": "identifiant invalide"}) return } limit, offset, page := parsePagination(c.Query("page"), c.Query("limit")) query := h.client.LienObjetEmplacement.Query(). Where(lienobjetemplacement.ObjetID(objetID)) total, err := query.Count(c.Request.Context()) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"erreur": "impossible de compter les liens"}) return } items, err := query. Order(ent.Desc(lienobjetemplacement.FieldCreatedAt)). Limit(limit). Offset(offset). All(c.Request.Context()) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"erreur": "impossible de lister les liens"}) return } respondPaginated(c, items, total, page, limit) } // @Summary Creer un lien objet/emplacement // @Tags LiensEmplacements // @Accept json // @Produce json // @Param id path string true "ID objet" // @Param body body lienObjetEmplacementRequest true "Lien" // @Success 201 {object} ent.LienObjetEmplacement // @Failure 400 {object} map[string]string // @Failure 404 {object} map[string]string // @Failure 409 {object} map[string]string // @Failure 500 {object} map[string]string // @Router /objets/{id}/liens_emplacements [post] func (h *Handler) CreateLienEmplacement(c *gin.Context) { objetID, err := uuid.Parse(c.Param("id")) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"erreur": "identifiant invalide"}) return } var req lienObjetEmplacementRequest if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, gin.H{"erreur": "donnees invalides"}) return } if req.EmplacementID == nil || *req.EmplacementID == "" { c.JSON(http.StatusBadRequest, gin.H{"erreur": "emplacement_id obligatoire"}) return } emplacementID, err := uuid.Parse(*req.EmplacementID) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"erreur": "emplacement_id invalide"}) return } if _, err := h.client.Emplacement.Get(c.Request.Context(), emplacementID); err != nil { if ent.IsNotFound(err) { c.JSON(http.StatusNotFound, gin.H{"erreur": "emplacement introuvable"}) return } c.JSON(http.StatusInternalServerError, gin.H{"erreur": "impossible de charger l'emplacement"}) return } create := h.client.LienObjetEmplacement.Create(). SetObjetID(objetID). SetEmplacementID(emplacementID) typeValeur := lienobjetemplacement.TypeStocke if req.Type != nil && *req.Type != "" { parsed, ok := parseLienType(*req.Type) if !ok { c.JSON(http.StatusBadRequest, gin.H{"erreur": "type invalide"}) return } typeValeur = parsed } create.SetType(typeValeur) exists, err := h.client.LienObjetEmplacement.Query(). Where( lienobjetemplacement.ObjetID(objetID), lienobjetemplacement.EmplacementID(emplacementID), lienobjetemplacement.TypeEQ(typeValeur), ). Exist(c.Request.Context()) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"erreur": "impossible de verifier le lien"}) return } if exists { c.JSON(http.StatusConflict, gin.H{"erreur": "lien deja existant"}) return } created, err := create.Save(c.Request.Context()) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"erreur": "impossible de creer le lien"}) return } c.JSON(http.StatusCreated, created) } // @Summary Supprimer un lien objet/emplacement // @Tags LiensEmplacements // @Param id path string true "ID lien" // @Success 204 {string} string "No Content" // @Failure 400 {object} map[string]string // @Failure 404 {object} map[string]string // @Failure 500 {object} map[string]string // @Router /liens_emplacements/{id} [delete] func (h *Handler) DeleteLienEmplacement(c *gin.Context) { lienID, err := uuid.Parse(c.Param("id")) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"erreur": "identifiant invalide"}) return } if err := h.client.LienObjetEmplacement.DeleteOneID(lienID).Exec(c.Request.Context()); err != nil { if ent.IsNotFound(err) { c.JSON(http.StatusNotFound, gin.H{"erreur": "lien introuvable"}) return } c.JSON(http.StatusInternalServerError, gin.H{"erreur": "impossible de supprimer le lien"}) return } c.Status(http.StatusNoContent) } // @Summary Mettre a jour un lien objet/emplacement // @Tags LiensEmplacements // @Accept json // @Produce json // @Param id path string true "ID lien" // @Param body body lienObjetEmplacementUpdateRequest true "Mise a jour" // @Success 200 {object} ent.LienObjetEmplacement // @Failure 400 {object} map[string]string // @Failure 404 {object} map[string]string // @Failure 409 {object} map[string]string // @Failure 500 {object} map[string]string // @Router /liens_emplacements/{id} [put] func (h *Handler) UpdateLienEmplacement(c *gin.Context) { lienID, err := uuid.Parse(c.Param("id")) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"erreur": "identifiant invalide"}) return } var req lienObjetEmplacementUpdateRequest if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, gin.H{"erreur": "donnees invalides"}) return } existant, err := h.client.LienObjetEmplacement.Get(c.Request.Context(), lienID) if err != nil { if ent.IsNotFound(err) { c.JSON(http.StatusNotFound, gin.H{"erreur": "lien introuvable"}) return } c.JSON(http.StatusInternalServerError, gin.H{"erreur": "impossible de charger le lien"}) return } nouveauEmplacementID := existant.EmplacementID if req.EmplacementID != nil && *req.EmplacementID != "" { parsed, err := uuid.Parse(*req.EmplacementID) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"erreur": "emplacement_id invalide"}) return } if _, err := h.client.Emplacement.Get(c.Request.Context(), parsed); err != nil { if ent.IsNotFound(err) { c.JSON(http.StatusNotFound, gin.H{"erreur": "emplacement introuvable"}) return } c.JSON(http.StatusInternalServerError, gin.H{"erreur": "impossible de charger l'emplacement"}) return } nouveauEmplacementID = parsed } nouveauType := existant.Type if req.Type != nil && *req.Type != "" { parsed, ok := parseLienType(*req.Type) if !ok { c.JSON(http.StatusBadRequest, gin.H{"erreur": "type invalide"}) return } nouveauType = parsed } dupe, err := h.client.LienObjetEmplacement.Query(). Where( lienobjetemplacement.ObjetID(existant.ObjetID), lienobjetemplacement.EmplacementID(nouveauEmplacementID), lienobjetemplacement.TypeEQ(nouveauType), lienobjetemplacement.IDNEQ(lienID), ). Exist(c.Request.Context()) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"erreur": "impossible de verifier le lien"}) return } if dupe { c.JSON(http.StatusConflict, gin.H{"erreur": "lien deja existant"}) return } updated, err := h.client.LienObjetEmplacement.UpdateOneID(lienID). SetEmplacementID(nouveauEmplacementID). SetType(nouveauType). Save(c.Request.Context()) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"erreur": "impossible de mettre a jour le lien"}) return } c.JSON(http.StatusOK, updated) } func parseLienType(value string) (lienobjetemplacement.Type, bool) { switch value { case "stocke": return lienobjetemplacement.TypeStocke, true case "utilise_dans": return lienobjetemplacement.TypeUtiliseDans, true default: return "", false } }