From d1fa3aca680b7b70f2fb39d5deef5953094c8d3f Mon Sep 17 00:00:00 2001 From: colesm Date: Thu, 9 Oct 2025 15:16:08 +0200 Subject: [PATCH] MAJ Mathilde --- .../DTO/Product/Request/CreateProductDto.cs | 27 ++++- .../DTO/Product/Request/UpdateProductDto.cs | 26 ++-- .../DTO/Product/Response/GetProductDto.cs | 32 +++-- .../DTO/Supplier/Request/CreateSupplierDto.cs | 9 ++ .../DTO/Supplier/Request/UpdateSupplierDto.cs | 2 + .../DTO/Supplier/Response/GetSupplierDto.cs | 14 ++- .../Warehouse/Request/CreateWarehouseDto.cs | 17 ++- .../Warehouse/Request/UpdateWarehouseDto.cs | 20 +++- .../DTO/Warehouse/Response/GetWarehouseDto.cs | 21 +++- .../Product/CreateProductEndpoint.cs | 77 +++++++++--- .../Product/DeleteProductEndpoint.cs | 38 ++++-- .../Product/GetAllProductsEndpoint.cs | 69 +++++++---- .../Endpoints/Product/GetProductEndpoint.cs | 44 +++++-- .../Product/UpdateProductEndpoint.cs | 111 ++++++++++++++---- .../Supplier/CreateSupplierEndpoint.cs | 34 ++++-- .../Supplier/DeleteSupplierEndpoint.cs | 20 +++- .../Supplier/GetAllSupplierEndpoint.cs | 36 ++++-- .../Endpoints/Supplier/GetSupplierEndpoint.cs | 23 ++-- .../Supplier/UpdateSupplierEndpoint.cs | 36 ++++-- .../Warehouse/CreateWarehouseEndpoint.cs | 34 ++++-- .../Warehouse/DeleteWarehouseEndpoint.cs | 29 +++-- .../Warehouse/GetAllWarehouseEndpoint.cs | 41 ++++--- .../Warehouse/GetWarehouseEndpoint.cs | 27 +++-- .../Warehouse/UpdateWarehouseEndpoint.cs | 52 ++++++-- 24 files changed, 628 insertions(+), 211 deletions(-) diff --git a/PyroFetes/DTO/Product/Request/CreateProductDto.cs b/PyroFetes/DTO/Product/Request/CreateProductDto.cs index a704c38..f5fbd90 100644 --- a/PyroFetes/DTO/Product/Request/CreateProductDto.cs +++ b/PyroFetes/DTO/Product/Request/CreateProductDto.cs @@ -1,6 +1,4 @@ -using PyroFetes.Models; - -namespace PyroFetes.DTO.Product.Request; +namespace API.DTO.Product.Request; public class CreateProductDto { @@ -11,11 +9,28 @@ public class CreateProductDto public int ApprovalNumber { get; set; } public decimal Weight { get; set; } public decimal Nec { get; set; } - public decimal SellingPrice {get; set;} + public decimal SellingPrice { get; set; } public string? Image { get; set; } public string? Link { get; set; } - + public int ClassificationId { get; set;} public int ProductCategoryId { get; set; } - + + // Liste des fournisseurs liés au produit + public List? Suppliers { get; set; } + + // Liste des entrepôts liés au produit (ajoutée ici) + public List? Warehouses { get; set; } +} + +public class ProductSupplierPriceDto +{ + public int SupplierId { get; set; } + public decimal SellingPrice { get; set; } +} + +public class CreateProductWarehouseDto +{ + public int WarehouseId { get; set; } + public int Quantity { get; set; } } \ No newline at end of file diff --git a/PyroFetes/DTO/Product/Request/UpdateProductDto.cs b/PyroFetes/DTO/Product/Request/UpdateProductDto.cs index 1bc96a4..6cb7742 100644 --- a/PyroFetes/DTO/Product/Request/UpdateProductDto.cs +++ b/PyroFetes/DTO/Product/Request/UpdateProductDto.cs @@ -1,20 +1,32 @@ -using PyroFetes.Models; - -namespace PyroFetes.DTO.Product.Request; +namespace API.DTO.Product.Request; public class UpdateProductDto { public int Id { get; set; } - public int Reference { get; set; } + public int References { get; set; } public string? Name { get; set; } public decimal Duration { get; set; } public decimal Caliber { get; set; } public int ApprovalNumber { get; set; } public decimal Weight { get; set; } public decimal Nec { get; set; } - public decimal SellingPrice {get; set;} + public decimal SellingPrice { get; set; } public string? Image { get; set; } public string? Link { get; set; } - public int ClassificationId { get; set;} + public int ClassificationId { get; set; } public int ProductCategoryId { get; set; } -} \ No newline at end of file + + // Liste des fournisseurs associés + public List Suppliers { get; set; } + + // Liste des entrepôts associés (corrigé ici) + public List Warehouses { get; set; } +} + +// DTO pour la mise à jour des entrepôts liés +public class UpdateProductWarehouseDto +{ + public int WarehouseId { get; set; } + public int Quantity { get; set; } + +} diff --git a/PyroFetes/DTO/Product/Response/GetProductDto.cs b/PyroFetes/DTO/Product/Response/GetProductDto.cs index dbfed6a..337fc4a 100644 --- a/PyroFetes/DTO/Product/Response/GetProductDto.cs +++ b/PyroFetes/DTO/Product/Response/GetProductDto.cs @@ -1,6 +1,6 @@ -using PyroFetes.Models; +using API.DTO.Product.Request; -namespace PyroFetes.DTO.Product.Response; +namespace API.DTO.Product.Response; public class GetProductDto { @@ -12,12 +12,30 @@ public class GetProductDto public int ApprovalNumber { get; set; } public decimal Weight { get; set; } public decimal Nec { get; set; } - public decimal SellingPrice {get; set;} + public decimal SellingPrice { get; set; } public string? Image { get; set; } public string? Link { get; set; } - public int ClassificationId { get; set;} - public string? ClassificationLabel { get; set; } + public int ClassificationId { get; set; } public int ProductCategoryId { get; set; } - public string? ProductCategoryLabel { get; set; } - + + // Liste des fournisseurs liés avec leur prix de vente + public List Suppliers { get; set; } + + public List Warehouses { get; set; } = new(); +} + + +public class GetProductSupplierDto +{ + public int SupplierId { get; set; } + public string SupplierName { get; set; } = string.Empty; + public decimal SellingPrice { get; set; } + +} + +public class GetProductWarehouseDto +{ + public int WarehouseId { get; set; } + public string WarehouseName { get; set; } = string.Empty; + public int Quantity { get; set; } } \ No newline at end of file diff --git a/PyroFetes/DTO/Supplier/Request/CreateSupplierDto.cs b/PyroFetes/DTO/Supplier/Request/CreateSupplierDto.cs index 25a94a4..3e6525c 100644 --- a/PyroFetes/DTO/Supplier/Request/CreateSupplierDto.cs +++ b/PyroFetes/DTO/Supplier/Request/CreateSupplierDto.cs @@ -8,4 +8,13 @@ public class CreateSupplierDto public string Adress { get; set; } public int ZipCode { get; set; } public string City { get; set; } + + // Produits que ce fournisseur fournit + public List? Products { get; set; } +} + +public class SupplierProductPriceDto +{ + public int ProductId { get; set; } + public decimal SellingPrice { get; set; } } \ No newline at end of file diff --git a/PyroFetes/DTO/Supplier/Request/UpdateSupplierDto.cs b/PyroFetes/DTO/Supplier/Request/UpdateSupplierDto.cs index 20ae5f0..0c9bb80 100644 --- a/PyroFetes/DTO/Supplier/Request/UpdateSupplierDto.cs +++ b/PyroFetes/DTO/Supplier/Request/UpdateSupplierDto.cs @@ -9,4 +9,6 @@ public class UpdateSupplierDto public string Adress { get; set; } public int ZipCode { get; set; } public string City { get; set; } + + public List? Products { get; set; } } \ No newline at end of file diff --git a/PyroFetes/DTO/Supplier/Response/GetSupplierDto.cs b/PyroFetes/DTO/Supplier/Response/GetSupplierDto.cs index ddc2365..bf24cff 100644 --- a/PyroFetes/DTO/Supplier/Response/GetSupplierDto.cs +++ b/PyroFetes/DTO/Supplier/Response/GetSupplierDto.cs @@ -1,4 +1,6 @@ -namespace API.DTO.Supplier.Response; +using API.DTO.Supplier.Request; + +namespace API.DTO.Supplier.Response; public class GetSupplierDto { @@ -9,4 +11,14 @@ public class GetSupplierDto public string Adress { get; set; } public int ZipCode { get; set; } public string City { get; set; } + + // Liste des produits liés avec leur prix fournisseur + public List Products { get; set; } +} + +public class GetSupplierProductDto +{ + public int ProductId { get; set; } + public string ProductName { get; set; } = string.Empty; + public decimal SellingPrice { get; set; } } \ No newline at end of file diff --git a/PyroFetes/DTO/Warehouse/Request/CreateWarehouseDto.cs b/PyroFetes/DTO/Warehouse/Request/CreateWarehouseDto.cs index 9f2e7cb..36563c2 100644 --- a/PyroFetes/DTO/Warehouse/Request/CreateWarehouseDto.cs +++ b/PyroFetes/DTO/Warehouse/Request/CreateWarehouseDto.cs @@ -2,11 +2,20 @@ public class CreateWarehouseDto { - public string Name {get; set;} - public int MaxWeight {get; set;} - public int Current {get; set;} - public int MinWeight {get; set;} + public string Name { get; set; } + public int MaxWeight { get; set; } + public int Current { get; set; } + public int MinWeight { get; set; } public string Adress { get; set; } public int ZipCode { get; set; } public string City { get; set; } + + // Liste des produits à stocker dans cet entrepôt + public List? Products { get; set; } } + +public class CreateWarehouseProductDto +{ + public int ProductId { get; set; } + public int Quantity { get; set; } +} \ No newline at end of file diff --git a/PyroFetes/DTO/Warehouse/Request/UpdateWarehouseDto.cs b/PyroFetes/DTO/Warehouse/Request/UpdateWarehouseDto.cs index a154737..3e843d5 100644 --- a/PyroFetes/DTO/Warehouse/Request/UpdateWarehouseDto.cs +++ b/PyroFetes/DTO/Warehouse/Request/UpdateWarehouseDto.cs @@ -1,13 +1,21 @@ -namespace API.DTO.Warehouse.Request; +namespace API.DTO.Warehouse.Request; public class UpdateWarehouseDto { - public int Id {get; set;} - public string Name {get; set;} - public int MaxWeight {get; set;} - public int Current {get; set;} - public int MinWeight {get; set;} + public int Id { get; set; } + public string Name { get; set; } + public int MaxWeight { get; set; } + public int Current { get; set; } + public int MinWeight { get; set; } public string Adress { get; set; } public int ZipCode { get; set; } public string City { get; set; } + + public List? Products { get; set; } +} + +public class UpdateWarehouseProductDto +{ + public int ProductId { get; set; } + public int Quantity { get; set; } } \ No newline at end of file diff --git a/PyroFetes/DTO/Warehouse/Response/GetWarehouseDto.cs b/PyroFetes/DTO/Warehouse/Response/GetWarehouseDto.cs index 77df53c..3af0328 100644 --- a/PyroFetes/DTO/Warehouse/Response/GetWarehouseDto.cs +++ b/PyroFetes/DTO/Warehouse/Response/GetWarehouseDto.cs @@ -1,13 +1,22 @@ -namespace API.DTO.Warehouse.Response; +namespace API.DTO.Warehouse.Response; public class GetWarehouseDto { - public int Id {get; set;} - public string Name {get; set;} - public int MaxWeight {get; set;} - public int Current {get; set;} - public int MinWeight {get; set;} + public int Id { get; set; } + public string Name { get; set; } + public int MaxWeight { get; set; } + public int Current { get; set; } + public int MinWeight { get; set; } public string Adress { get; set; } public int ZipCode { get; set; } public string City { get; set; } + + public List? Products { get; set; } +} + +public class WarehouseProductDto +{ + public int ProductId { get; set; } + public string? ProductName { get; set; } + public int Quantity { get; set; } } \ No newline at end of file diff --git a/PyroFetes/Endpoints/Product/CreateProductEndpoint.cs b/PyroFetes/Endpoints/Product/CreateProductEndpoint.cs index 5a30b83..3e0e92c 100644 --- a/PyroFetes/Endpoints/Product/CreateProductEndpoint.cs +++ b/PyroFetes/Endpoints/Product/CreateProductEndpoint.cs @@ -1,10 +1,13 @@ -using FastEndpoints; -using PyroFetes.DTO.Product.Request; -using PyroFetes.DTO.Product.Response; +using API.DTO.Product.Request; +using API.DTO.Product.Response; +using FastEndpoints; +using Microsoft.EntityFrameworkCore; +using PyroFetes.Models; namespace PyroFetes.Endpoints.Product; -public class CreateProductEndpoint(PyroFetesDbContext pyrofetesdbcontext) : Endpoint +public class CreateProductEndpoint(PyroFetesDbContext db) + : Endpoint { public override void Configure() { @@ -14,7 +17,7 @@ public class CreateProductEndpoint(PyroFetesDbContext pyrofetesdbcontext) : Endp public override async Task HandleAsync(CreateProductDto req, CancellationToken ct) { - Models.Product product = new () + var product = new Models.Product { References = req.References, Name = req.Name!, @@ -29,13 +32,48 @@ public class CreateProductEndpoint(PyroFetesDbContext pyrofetesdbcontext) : Endp ProductCategoryId = req.ProductCategoryId, ClassificationId = req.ClassificationId }; - - pyrofetesdbcontext.Products.Add(product); - await pyrofetesdbcontext.SaveChangesAsync(ct); - - Console.WriteLine("Product créé avec succès !"); - GetProductDto responseDto = new () + db.Products.Add(product); + await db.SaveChangesAsync(ct); + + // Ajout des fournisseurs liés + if (req.Suppliers is not null && req.Suppliers.Any()) + { + foreach (var s in req.Suppliers) + { + var price = new Price + { + ProductId = product.Id, + SupplierId = s.SupplierId, + SellingPrice = s.SellingPrice + }; + db.Prices.Add(price); + } + await db.SaveChangesAsync(ct); + } + + // Ajout des entrepôts liés + if (req.Warehouses is not null && req.Warehouses.Any()) + { + foreach (var w in req.Warehouses) + { + var exists = await db.Warehouses.AnyAsync(x => x.Id == w.WarehouseId, ct); + if (!exists) + continue; // sécurité : on ignore les warehouses inexistants + + var warehouseProduct = new WarehouseProduct + { + ProductId = product.Id, + WarehouseId = w.WarehouseId, + Quantity = w.Quantity + }; + db.WarehouseProducts.Add(warehouseProduct); + } + await db.SaveChangesAsync(ct); + } + + // Construction de la réponse + var response = new GetProductDto { Id = product.Id, Reference = req.References, @@ -49,9 +87,20 @@ public class CreateProductEndpoint(PyroFetesDbContext pyrofetesdbcontext) : Endp Image = req.Image, Link = req.Link, ProductCategoryId = req.ProductCategoryId, - ClassificationId = req.ClassificationId + ClassificationId = req.ClassificationId, + Suppliers = req.Suppliers?.Select(s => new ProductSupplierPriceDto + { + SupplierId = s.SupplierId, + SellingPrice = s.SellingPrice + }).ToList() ?? new(), + Warehouses = req.Warehouses?.Select(w => new GetProductWarehouseDto + { + WarehouseId = w.WarehouseId, + Quantity = w.Quantity, + WarehouseName = db.Warehouses.FirstOrDefault(x => x.Id == w.WarehouseId)?.Name ?? string.Empty + }).ToList() ?? new() }; - await Send.OkAsync(responseDto, ct); + await Send.OkAsync(response, ct); } -} \ No newline at end of file +} diff --git a/PyroFetes/Endpoints/Product/DeleteProductEndpoint.cs b/PyroFetes/Endpoints/Product/DeleteProductEndpoint.cs index cf425ea..f400abe 100644 --- a/PyroFetes/Endpoints/Product/DeleteProductEndpoint.cs +++ b/PyroFetes/Endpoints/Product/DeleteProductEndpoint.cs @@ -1,5 +1,6 @@ using FastEndpoints; using Microsoft.EntityFrameworkCore; +using PyroFetes.Models; namespace PyroFetes.Endpoints.Product; @@ -8,29 +9,50 @@ public class DeleteProductRequest public int Id { get; set; } } -public class DeleteProductEndpoint(PyroFetesDbContext pyrofetesdbcontext) : Endpoint +public class DeleteProductEndpoint(PyroFetesDbContext db) : Endpoint { public override void Configure() { Delete("/api/products/{@id}", x => new { x.Id }); AllowAnonymous(); } - + public override async Task HandleAsync(DeleteProductRequest req, CancellationToken ct) { - Models.Product? productToDelete = await pyrofetesdbcontext - .Products - .SingleOrDefaultAsync(p => p.Id == req.Id, cancellationToken: ct); + // Récupérer le produit + var productToDelete = await db.Products + .SingleOrDefaultAsync(p => p.Id == req.Id, ct); - if (productToDelete == null) + if (productToDelete is null) { Console.WriteLine($"Aucun produit avec l'ID {req.Id} trouvé."); await Send.NotFoundAsync(ct); return; } - pyrofetesdbcontext.Products.Remove(productToDelete); - await pyrofetesdbcontext.SaveChangesAsync(ct); + // Supprimer les liaisons Price + var relatedPrices = await db.Prices + .Where(p => p.ProductId == req.Id) + .ToListAsync(ct); + if (relatedPrices.Any()) + { + db.Prices.RemoveRange(relatedPrices); + } + + // Supprimer les liaisons WarehouseProduct + var relatedWarehouseProducts = await db.WarehouseProducts + .Where(wp => wp.ProductId == req.Id) + .ToListAsync(ct); + if (relatedWarehouseProducts.Any()) + { + db.WarehouseProducts.RemoveRange(relatedWarehouseProducts); + } + + // Supprimer le produit + db.Products.Remove(productToDelete); + + await db.SaveChangesAsync(ct); + Console.WriteLine($"Produit {req.Id}, ses prix et ses entrepôts liés ont été supprimés avec succès."); await Send.NoContentAsync(ct); } diff --git a/PyroFetes/Endpoints/Product/GetAllProductsEndpoint.cs b/PyroFetes/Endpoints/Product/GetAllProductsEndpoint.cs index ee81ef9..dcb89fd 100644 --- a/PyroFetes/Endpoints/Product/GetAllProductsEndpoint.cs +++ b/PyroFetes/Endpoints/Product/GetAllProductsEndpoint.cs @@ -1,10 +1,13 @@ -using FastEndpoints; +using API.DTO.Product.Request; +using API.DTO.Product.Response; +using FastEndpoints; using Microsoft.EntityFrameworkCore; -using PyroFetes.DTO.Product.Response; +using PyroFetes.Models; namespace PyroFetes.Endpoints.Product; -public class GetAllProductsEndpoint(PyroFetesDbContext pyrofetesdbcontext) : EndpointWithoutRequest> +public class GetAllProductsEndpoint(PyroFetesDbContext db) + : EndpointWithoutRequest> { public override void Configure() { @@ -14,27 +17,45 @@ public class GetAllProductsEndpoint(PyroFetesDbContext pyrofetesdbcontext) : End public override async Task HandleAsync(CancellationToken ct) { - List responseDto = await pyrofetesdbcontext.Products - .Select(p => new GetProductDto() - { - Id = p.Id, - Reference = p.References, - Name = p.Name, - Duration = p.Duration, - Caliber = p.Caliber, - ApprovalNumber = p.ApprovalNumber, - Weight = p.Weight, - Nec = p.Nec, - SellingPrice = p.SellingPrice, - Image = p.Image, - Link = p.Link, - ClassificationId = p.ClassificationId, - ClassificationLabel = p.Classification!.Label, - ProductCategoryId = p.ProductCategoryId, - ProductCategoryLabel = p.ProductCategory!.Label, - } - ).ToListAsync(ct); + // Inclure toutes les relations nécessaires : Prices + WarehouseProducts + Warehouse + var products = await db.Products + .Include(p => p.Prices) + .Include(p => p.WarehouseProducts) + .ThenInclude(wp => wp.Warehouse) + .ToListAsync(ct); + + var responseDto = products.Select(p => new GetProductDto + { + Id = p.Id, + Reference = p.References, + Name = p.Name, + Duration = p.Duration, + Caliber = p.Caliber, + ApprovalNumber = p.ApprovalNumber, + Weight = p.Weight, + Nec = p.Nec, + SellingPrice = p.SellingPrice, + Image = p.Image, + Link = p.Link, + ClassificationId = p.ClassificationId, + ProductCategoryId = p.ProductCategoryId, + + // Liste des fournisseurs liés via Price + Suppliers = p.Prices.Select(pr => new ProductSupplierPriceDto + { + SupplierId = pr.SupplierId, + SellingPrice = pr.SellingPrice + }).ToList(), + + // Liste des entrepôts via WarehouseProduct + Warehouses = p.WarehouseProducts.Select(wp => new GetProductWarehouseDto + { + WarehouseId = wp.WarehouseId, + WarehouseName = wp.Warehouse?.Name ?? string.Empty, + Quantity = wp.Quantity + }).ToList() + }).ToList(); await Send.OkAsync(responseDto, ct); } -} +} \ No newline at end of file diff --git a/PyroFetes/Endpoints/Product/GetProductEndpoint.cs b/PyroFetes/Endpoints/Product/GetProductEndpoint.cs index df4b64f..db3baf7 100644 --- a/PyroFetes/Endpoints/Product/GetProductEndpoint.cs +++ b/PyroFetes/Endpoints/Product/GetProductEndpoint.cs @@ -1,6 +1,8 @@ -using FastEndpoints; +using API.DTO.Product.Request; +using API.DTO.Product.Response; +using FastEndpoints; using Microsoft.EntityFrameworkCore; -using PyroFetes.DTO.Product.Response; +using PyroFetes.Models; namespace PyroFetes.Endpoints.Product; @@ -9,20 +11,23 @@ public class GetProductRequest public int Id { get; set; } } - -public class GetProductEndpoint(PyroFetesDbContext pyrofetesdbcontext) :Endpoint +public class GetProductEndpoint(PyroFetesDbContext db) + : Endpoint { public override void Configure() { - Get("/api/product/{@id}", x => new { x.Id }); + Get("/api/products/{@id}", x => new { x.Id }); AllowAnonymous(); } public override async Task HandleAsync(GetProductRequest req, CancellationToken ct) { - Models.Product? product = await pyrofetesdbcontext - .Products.Include(product => product.Classification).Include(product => product.ProductCategory) - .SingleOrDefaultAsync(p => p.Id == req.Id, cancellationToken: ct); + // Inclure toutes les relations : Prices + WarehouseProducts + Warehouse + var product = await db.Products + .Include(p => p.Prices) + .Include(p => p.WarehouseProducts) + .ThenInclude(wp => wp.Warehouse) + .SingleOrDefaultAsync(p => p.Id == req.Id, ct); if (product == null) { @@ -31,7 +36,7 @@ public class GetProductEndpoint(PyroFetesDbContext pyrofetesdbcontext) :Endpoint return; } - GetProductDto responseDto = new() + var responseDto = new GetProductDto { Id = product.Id, Reference = product.References, @@ -45,11 +50,24 @@ public class GetProductEndpoint(PyroFetesDbContext pyrofetesdbcontext) :Endpoint Image = product.Image, Link = product.Link, ClassificationId = product.ClassificationId, - ClassificationLabel = product.Classification!.Label, - ProductCategoryId = product.ProductCategoryId, - ProductCategoryLabel = product.ProductCategory!.Label, + ProductCategoryId = product.ProductCategoryId, + + // Fournisseurs liés via Price + Suppliers = product.Prices.Select(pr => new ProductSupplierPriceDto + { + SupplierId = pr.SupplierId, + SellingPrice = pr.SellingPrice + }).ToList(), + + // Entrepôts liés via WarehouseProduct + Warehouses = product.WarehouseProducts.Select(wp => new GetProductWarehouseDto + { + WarehouseId = wp.WarehouseId, + WarehouseName = wp.Warehouse?.Name ?? string.Empty, + Quantity = wp.Quantity + }).ToList() }; await Send.OkAsync(responseDto, ct); } -} +} \ No newline at end of file diff --git a/PyroFetes/Endpoints/Product/UpdateProductEndpoint.cs b/PyroFetes/Endpoints/Product/UpdateProductEndpoint.cs index 2512e9c..15ed7fe 100644 --- a/PyroFetes/Endpoints/Product/UpdateProductEndpoint.cs +++ b/PyroFetes/Endpoints/Product/UpdateProductEndpoint.cs @@ -1,47 +1,88 @@ -using FastEndpoints; +using API.DTO.Product.Request; +using API.DTO.Product.Response; +using FastEndpoints; using Microsoft.EntityFrameworkCore; -using PyroFetes.DTO.Product.Request; -using PyroFetes.DTO.Product.Response; +using PyroFetes.Models; namespace PyroFetes.Endpoints.Product; -public class UpdateProductEndpoint(PyroFetesDbContext pyrofetesdbcontext) :Endpoint +// Endpoint permettant de mettre à jour un produit existant +public class UpdateProductEndpoint(PyroFetesDbContext db) + : Endpoint { public override void Configure() { + // Route HTTP PUT avec un paramètre d'identifiant dans l'URL Put("/api/products/{@id}", x => new { x.Id }); + + // Autorise les requêtes anonymes (sans authentification) AllowAnonymous(); } public override async Task HandleAsync(UpdateProductDto req, CancellationToken ct) { - Models.Product? productToEdit = await pyrofetesdbcontext - .Products - .SingleOrDefaultAsync(p => p.Id == req.Id, cancellationToken: ct); + // Recherche du produit à mettre à jour, en incluant les relations Prices et WarehouseProducts + var product = await db.Products + .Include(p => p.Prices) + .Include(p => p.WarehouseProducts) + .SingleOrDefaultAsync(p => p.Id == req.Id, ct); - if (productToEdit == null) + // Si le produit n'existe pas, on retourne une réponse 404 + if (product is null) { - Console.WriteLine($"Aucun produit avec l'ID {req.Id} trouvé."); await Send.NotFoundAsync(ct); return; } - productToEdit.References = req.Reference; - productToEdit.Name = req.Name; - productToEdit.Duration = req.Duration; - productToEdit.Caliber = req.Caliber; - productToEdit.ApprovalNumber = req.ApprovalNumber; - productToEdit.Weight = req.Weight; - productToEdit.Nec = req.Nec; - productToEdit.SellingPrice = req.SellingPrice; - productToEdit.Image = req.Image; - productToEdit.Link = req.Link; - await pyrofetesdbcontext.SaveChangesAsync(ct); + // Mise à jour des propriétés principales du produit + product.References = req.References; + product.Name = req.Name; + product.Duration = req.Duration; + product.Caliber = req.Caliber; + product.ApprovalNumber = req.ApprovalNumber; + product.Weight = req.Weight; + product.Nec = req.Nec; + product.SellingPrice = req.SellingPrice; + product.Image = req.Image; + product.Link = req.Link; + product.ClassificationId = req.ClassificationId; + product.ProductCategoryId = req.ProductCategoryId; - GetProductDto responseDto = new() + // Mise à jour des prix fournisseurs associés + // On supprime les anciens enregistrements pour les remplacer + db.Prices.RemoveRange(product.Prices); + foreach (var s in req.Suppliers) { - Id = req.Id, - Reference = req.Reference, + db.Prices.Add(new Price + { + ProductId = product.Id, + SupplierId = s.SupplierId, + SellingPrice = s.SellingPrice + }); + } + + // Mise à jour des entrepôts associés + // On supprime les anciens liens avant d'ajouter les nouveaux + db.WarehouseProducts.RemoveRange(product.WarehouseProducts); + foreach (var w in req.Warehouses) + { + db.WarehouseProducts.Add(new WarehouseProduct + { + ProductId = product.Id, + WarehouseId = w.WarehouseId, + Quantity = w.Quantity + }); + } + + // Sauvegarde des modifications dans la base de données + await db.SaveChangesAsync(ct); + + // Construction de la réponse renvoyée au client + // On reconstruit les listes Suppliers et Warehouses au bon format de DTO + var response = new GetProductDto + { + Id = product.Id, + Reference = req.References, Name = req.Name, Duration = req.Duration, Caliber = req.Caliber, @@ -50,9 +91,27 @@ public class UpdateProductEndpoint(PyroFetesDbContext pyrofetesdbcontext) :Endpo Nec = req.Nec, SellingPrice = req.SellingPrice, Image = req.Image, - Link = req.Link + Link = req.Link, + ClassificationId = req.ClassificationId, + ProductCategoryId = req.ProductCategoryId, + + // Mapping des fournisseurs pour la réponse + Suppliers = req.Suppliers.Select(s => new ProductSupplierPriceDto + { + SupplierId = s.SupplierId, + SellingPrice = s.SellingPrice + }).ToList(), + + // Mapping des entrepôts pour la réponse + Warehouses = req.Warehouses.Select(w => new GetProductWarehouseDto + { + WarehouseId = w.WarehouseId, + Quantity = w.Quantity, + WarehouseName = db.Warehouses.FirstOrDefault(x => x.Id == w.WarehouseId)?.Name ?? string.Empty + }).ToList() }; - await Send.OkAsync(responseDto, ct); + // Envoi de la réponse HTTP 200 avec les données du produit mis à jour + await Send.OkAsync(response, ct); } -} \ No newline at end of file +} diff --git a/PyroFetes/Endpoints/Supplier/CreateSupplierEndpoint.cs b/PyroFetes/Endpoints/Supplier/CreateSupplierEndpoint.cs index 761eb4a..d87755a 100644 --- a/PyroFetes/Endpoints/Supplier/CreateSupplierEndpoint.cs +++ b/PyroFetes/Endpoints/Supplier/CreateSupplierEndpoint.cs @@ -1,10 +1,13 @@ using API.DTO.Supplier.Request; using API.DTO.Supplier.Response; using FastEndpoints; +using Microsoft.EntityFrameworkCore; +using PyroFetes.Models; namespace PyroFetes.Endpoints.Supplier; -public class CreateSupplierEndpoint(PyroFetesDbContext pyrofetesdbcontext) : Endpoint +public class CreateSupplierEndpoint(PyroFetesDbContext pyrofetesdbcontext) + : Endpoint { public override void Configure() { @@ -14,8 +17,7 @@ public class CreateSupplierEndpoint(PyroFetesDbContext pyrofetesdbcontext) : End public override async Task HandleAsync(CreateSupplierDto req, CancellationToken ct) { - // Création d'un nouvel objet Supplier - Models.Supplier supplier = new() + var supplier = new Models.Supplier { Name = req.Name, Email = req.Email, @@ -24,15 +26,27 @@ public class CreateSupplierEndpoint(PyroFetesDbContext pyrofetesdbcontext) : End ZipCode = req.ZipCode, City = req.City }; - - // Ajout à la base et sauvegarde + pyrofetesdbcontext.Suppliers.Add(supplier); await pyrofetesdbcontext.SaveChangesAsync(ct); - - Console.WriteLine("Fournisseur créé avec succès !"); - // Préparation de la réponse - GetSupplierDto responseDto = new() + // Ajout des liaisons Price si produits renseignés + if (req.Products is not null && req.Products.Any()) + { + foreach (var p in req.Products) + { + var price = new Price + { + SupplierId = supplier.Id, + ProductId = p.ProductId, + SellingPrice = p.SellingPrice + }; + pyrofetesdbcontext.Prices.Add(price); + } + await pyrofetesdbcontext.SaveChangesAsync(ct); + } + + var response = new GetSupplierDto { Id = supplier.Id, Name = supplier.Name, @@ -43,6 +57,6 @@ public class CreateSupplierEndpoint(PyroFetesDbContext pyrofetesdbcontext) : End City = supplier.City }; - await Send.OkAsync(responseDto, ct); + await Send.OkAsync(response, ct); } } \ No newline at end of file diff --git a/PyroFetes/Endpoints/Supplier/DeleteSupplierEndpoint.cs b/PyroFetes/Endpoints/Supplier/DeleteSupplierEndpoint.cs index dbeb8db..e9735dc 100644 --- a/PyroFetes/Endpoints/Supplier/DeleteSupplierEndpoint.cs +++ b/PyroFetes/Endpoints/Supplier/DeleteSupplierEndpoint.cs @@ -1,5 +1,6 @@ using FastEndpoints; using Microsoft.EntityFrameworkCore; +using PyroFetes.Models; namespace PyroFetes.Endpoints.Supplier; @@ -18,19 +19,32 @@ public class DeleteSupplierEndpoint(PyroFetesDbContext pyrofetesdbcontext) : End public override async Task HandleAsync(DeleteSupplierRequest req, CancellationToken ct) { - Models.Supplier? supplierToDelete = await pyrofetesdbcontext + var supplierToDelete = await pyrofetesdbcontext .Suppliers - .SingleOrDefaultAsync(s => s.Id == req.Id, cancellationToken: ct); + .SingleOrDefaultAsync(s => s.Id == req.Id, ct); - if (supplierToDelete == null) + if (supplierToDelete is null) { Console.WriteLine($"Aucun fournisseur avec l'ID {req.Id} trouvé."); await Send.NotFoundAsync(ct); return; } + // Supprimer les liaisons Price avant le fournisseur + var relatedPrices = await pyrofetesdbcontext.Prices + .Where(p => p.SupplierId == req.Id) + .ToListAsync(ct); + + if (relatedPrices.Any()) + { + pyrofetesdbcontext.Prices.RemoveRange(relatedPrices); + } + + // Supprimer le fournisseur pyrofetesdbcontext.Suppliers.Remove(supplierToDelete); + await pyrofetesdbcontext.SaveChangesAsync(ct); + Console.WriteLine($"Fournisseur {req.Id} et ses prix liés supprimés avec succès."); await Send.NoContentAsync(ct); } diff --git a/PyroFetes/Endpoints/Supplier/GetAllSupplierEndpoint.cs b/PyroFetes/Endpoints/Supplier/GetAllSupplierEndpoint.cs index 51df593..674e93b 100644 --- a/PyroFetes/Endpoints/Supplier/GetAllSupplierEndpoint.cs +++ b/PyroFetes/Endpoints/Supplier/GetAllSupplierEndpoint.cs @@ -1,10 +1,13 @@ using API.DTO.Supplier.Response; +using API.DTO.Supplier.Request; using FastEndpoints; using Microsoft.EntityFrameworkCore; +using PyroFetes.Models; namespace PyroFetes.Endpoints.Supplier; -public class GetAllSuppliersEndpoint(PyroFetesDbContext pyrofetesdbcontext) : EndpointWithoutRequest> +public class GetAllSuppliersEndpoint(PyroFetesDbContext pyrofetesdbcontext) + : EndpointWithoutRequest> { public override void Configure() { @@ -14,19 +17,28 @@ public class GetAllSuppliersEndpoint(PyroFetesDbContext pyrofetesdbcontext) : En public override async Task HandleAsync(CancellationToken ct) { - List responseDto = await pyrofetesdbcontext.Suppliers - .Select(s => new GetSupplierDto - { - Id = s.Id, - Name = s.Name!, - Email = s.Email!, - PhoneNumber = s.Phone!, - Adress = s.Address!, - ZipCode = s.ZipCode, - City = s.City! - }) + var suppliers = await pyrofetesdbcontext.Suppliers + .Include(s => s.Prices) .ToListAsync(ct); + var responseDto = suppliers.Select(s => new GetSupplierDto + { + Id = s.Id, + Name = s.Name!, + Email = s.Email!, + PhoneNumber = s.Phone!, + Adress = s.Address!, + ZipCode = s.ZipCode, + City = s.City!, + + // 🔹 Liste des produits liés via Price + Products = s.Prices.Select(pr => new SupplierProductPriceDto + { + ProductId = pr.ProductId, + SellingPrice = pr.SellingPrice + }).ToList() + }).ToList(); + await Send.OkAsync(responseDto, ct); } } \ No newline at end of file diff --git a/PyroFetes/Endpoints/Supplier/GetSupplierEndpoint.cs b/PyroFetes/Endpoints/Supplier/GetSupplierEndpoint.cs index 878e8ba..f4a498a 100644 --- a/PyroFetes/Endpoints/Supplier/GetSupplierEndpoint.cs +++ b/PyroFetes/Endpoints/Supplier/GetSupplierEndpoint.cs @@ -1,4 +1,5 @@ -using API.DTO.Supplier.Response; +using API.DTO.Supplier.Request; +using API.DTO.Supplier.Response; using FastEndpoints; using Microsoft.EntityFrameworkCore; @@ -9,7 +10,8 @@ public class GetSupplierRequest public int Id { get; set; } } -public class GetSupplierEndpoint(PyroFetesDbContext pyrofetesdbcontext) : Endpoint +public class GetSupplierEndpoint(PyroFetesDbContext pyrofetesdbcontext) + : Endpoint { public override void Configure() { @@ -19,9 +21,9 @@ public class GetSupplierEndpoint(PyroFetesDbContext pyrofetesdbcontext) : Endpoi public override async Task HandleAsync(GetSupplierRequest req, CancellationToken ct) { - Models.Supplier? supplier = await pyrofetesdbcontext - .Suppliers - .SingleOrDefaultAsync(s => s.Id == req.Id, cancellationToken: ct); + var supplier = await pyrofetesdbcontext.Suppliers + .Include(s => s.Prices) + .SingleOrDefaultAsync(s => s.Id == req.Id, ct); if (supplier == null) { @@ -30,7 +32,7 @@ public class GetSupplierEndpoint(PyroFetesDbContext pyrofetesdbcontext) : Endpoi return; } - GetSupplierDto responseDto = new() + var responseDto = new GetSupplierDto { Id = supplier.Id, Name = supplier.Name!, @@ -38,7 +40,14 @@ public class GetSupplierEndpoint(PyroFetesDbContext pyrofetesdbcontext) : Endpoi PhoneNumber = supplier.Phone!, Adress = supplier.Address!, ZipCode = supplier.ZipCode, - City = supplier.City! + City = supplier.City!, + + // Produits liés + Products = supplier.Prices.Select(p => new SupplierProductPriceDto + { + ProductId = p.ProductId, + SellingPrice = p.SellingPrice + }).ToList() }; await Send.OkAsync(responseDto, ct); diff --git a/PyroFetes/Endpoints/Supplier/UpdateSupplierEndpoint.cs b/PyroFetes/Endpoints/Supplier/UpdateSupplierEndpoint.cs index e835fce..ce5b8ca 100644 --- a/PyroFetes/Endpoints/Supplier/UpdateSupplierEndpoint.cs +++ b/PyroFetes/Endpoints/Supplier/UpdateSupplierEndpoint.cs @@ -2,6 +2,7 @@ using API.DTO.Supplier.Response; using FastEndpoints; using Microsoft.EntityFrameworkCore; +using PyroFetes.Models; namespace PyroFetes.Endpoints.Supplier; @@ -15,18 +16,16 @@ public class UpdateSupplierEndpoint(PyroFetesDbContext pyrofetesdbcontext) : End public override async Task HandleAsync(UpdateSupplierDto req, CancellationToken ct) { - Models.Supplier? supplierToEdit = await pyrofetesdbcontext + var supplierToEdit = await pyrofetesdbcontext .Suppliers - .SingleOrDefaultAsync(s => s.Id == req.Id, cancellationToken: ct); + .Include(s => s.Prices) + .SingleOrDefaultAsync(s => s.Id == req.Id, ct); - if (supplierToEdit == null) + if (supplierToEdit is null) { - Console.WriteLine($"Aucun fournisseur avec l'ID {req.Id} trouvé."); await Send.NotFoundAsync(ct); return; } - - // Mise à jour des propriétés supplierToEdit.Name = req.Name; supplierToEdit.Email = req.Email; supplierToEdit.Phone = req.PhoneNumber; @@ -34,9 +33,28 @@ public class UpdateSupplierEndpoint(PyroFetesDbContext pyrofetesdbcontext) : End supplierToEdit.ZipCode = req.ZipCode; supplierToEdit.City = req.City; + if (req.Products is not null) + { + // Supprimer les anciennes liaisons + var existingPrices = pyrofetesdbcontext.Prices + .Where(p => p.SupplierId == supplierToEdit.Id); + pyrofetesdbcontext.Prices.RemoveRange(existingPrices); + + // Ajouter les nouvelles liaisons + foreach (var p in req.Products) + { + pyrofetesdbcontext.Prices.Add(new Price + { + SupplierId = supplierToEdit.Id, + ProductId = p.ProductId, + SellingPrice = p.SellingPrice + }); + } + } + await pyrofetesdbcontext.SaveChangesAsync(ct); - GetSupplierDto responseDto = new() + var response = new GetSupplierDto { Id = supplierToEdit.Id, Name = supplierToEdit.Name, @@ -47,6 +65,6 @@ public class UpdateSupplierEndpoint(PyroFetesDbContext pyrofetesdbcontext) : End City = supplierToEdit.City }; - await Send.OkAsync(responseDto, ct); + await Send.OkAsync(response, ct); } -} \ No newline at end of file +} diff --git a/PyroFetes/Endpoints/Warehouse/CreateWarehouseEndpoint.cs b/PyroFetes/Endpoints/Warehouse/CreateWarehouseEndpoint.cs index 2c46f85..e6ff638 100644 --- a/PyroFetes/Endpoints/Warehouse/CreateWarehouseEndpoint.cs +++ b/PyroFetes/Endpoints/Warehouse/CreateWarehouseEndpoint.cs @@ -1,10 +1,12 @@ using API.DTO.Warehouse.Request; using API.DTO.Warehouse.Response; using FastEndpoints; +using PyroFetes.Models; namespace PyroFetes.Endpoints.Warehouse; -public class CreateWarehouseEndpoint(PyroFetesDbContext pyrofetesdbcontext) : Endpoint +public class CreateWarehouseEndpoint(PyroFetesDbContext db) + : Endpoint { public override void Configure() { @@ -14,7 +16,7 @@ public class CreateWarehouseEndpoint(PyroFetesDbContext pyrofetesdbcontext) : En public override async Task HandleAsync(CreateWarehouseDto req, CancellationToken ct) { - Models.Warehouse warehouse = new() + var warehouse = new Models.Warehouse { Name = req.Name, MaxWeight = req.MaxWeight, @@ -24,13 +26,27 @@ public class CreateWarehouseEndpoint(PyroFetesDbContext pyrofetesdbcontext) : En ZipCode = req.ZipCode, City = req.City }; - - pyrofetesdbcontext.Warehouses.Add(warehouse); - await pyrofetesdbcontext.SaveChangesAsync(ct); - - Console.WriteLine("Entrepôt créé avec succès !"); - GetWarehouseDto responseDto = new() + db.Warehouses.Add(warehouse); + await db.SaveChangesAsync(ct); + + // 🔹 Ajout des produits liés à cet entrepôt + if (req.Products is not null && req.Products.Any()) + { + foreach (var p in req.Products) + { + var warehouseProduct = new WarehouseProduct + { + WarehouseId = warehouse.Id, + ProductId = p.ProductId, + Quantity = p.Quantity + }; + db.WarehouseProducts.Add(warehouseProduct); + } + await db.SaveChangesAsync(ct); + } + + var response = new GetWarehouseDto { Id = warehouse.Id, Name = warehouse.Name, @@ -42,6 +58,6 @@ public class CreateWarehouseEndpoint(PyroFetesDbContext pyrofetesdbcontext) : En City = warehouse.City }; - await Send.OkAsync(responseDto, ct); + await Send.OkAsync(response, ct); } } \ No newline at end of file diff --git a/PyroFetes/Endpoints/Warehouse/DeleteWarehouseEndpoint.cs b/PyroFetes/Endpoints/Warehouse/DeleteWarehouseEndpoint.cs index 758096b..c2e131e 100644 --- a/PyroFetes/Endpoints/Warehouse/DeleteWarehouseEndpoint.cs +++ b/PyroFetes/Endpoints/Warehouse/DeleteWarehouseEndpoint.cs @@ -1,5 +1,6 @@ using FastEndpoints; using Microsoft.EntityFrameworkCore; +using PyroFetes.Models; namespace PyroFetes.Endpoints.Warehouse; @@ -8,18 +9,20 @@ public class DeleteWarehouseRequest public int Id { get; set; } } -public class DeleteWarehouseEndpoint(PyroFetesDbContext pyrofetesdbcontext) : Endpoint +public class DeleteWarehouseEndpoint(PyroFetesDbContext db) : Endpoint { public override void Configure() { - Delete("/api/warehouse/{@id}", x => new { x.Id }); + // L’annotation correcte du paramètre est {id}, pas {@id} + Delete("/api/warehouse/{id}", x => new { x.Id }); AllowAnonymous(); } - + public override async Task HandleAsync(DeleteWarehouseRequest req, CancellationToken ct) { - Models.Warehouse? warehouseToDelete = await pyrofetesdbcontext - .Warehouses + // On charge aussi les WarehouseProducts liés pour les supprimer proprement + var warehouseToDelete = await db.Warehouses + .Include(w => w.WarehouseProducts) .SingleOrDefaultAsync(w => w.Id == req.Id, cancellationToken: ct); if (warehouseToDelete == null) @@ -29,9 +32,21 @@ public class DeleteWarehouseEndpoint(PyroFetesDbContext pyrofetesdbcontext) : En return; } - pyrofetesdbcontext.Warehouses.Remove(warehouseToDelete); - await pyrofetesdbcontext.SaveChangesAsync(ct); + // 🔹 Suppression des relations WarehouseProduct avant l'entrepôt + var relatedWarehouseProducts = await db.WarehouseProducts + .Where(wp => wp.WarehouseId == req.Id) + .ToListAsync(ct); + if (relatedWarehouseProducts.Any()) + { + db.WarehouseProducts.RemoveRange(relatedWarehouseProducts); + } + + // 🔹 Suppression de l’entrepôt + db.Warehouses.Remove(warehouseToDelete); + await db.SaveChangesAsync(ct); + + Console.WriteLine($"Entrepôt {warehouseToDelete.Name} (ID {req.Id}) supprimé avec succès."); await Send.NoContentAsync(ct); } } \ No newline at end of file diff --git a/PyroFetes/Endpoints/Warehouse/GetAllWarehouseEndpoint.cs b/PyroFetes/Endpoints/Warehouse/GetAllWarehouseEndpoint.cs index 0d98e6f..2c7cdb8 100644 --- a/PyroFetes/Endpoints/Warehouse/GetAllWarehouseEndpoint.cs +++ b/PyroFetes/Endpoints/Warehouse/GetAllWarehouseEndpoint.cs @@ -1,10 +1,13 @@ using API.DTO.Warehouse.Response; +using API.DTO.Warehouse.Request; using FastEndpoints; using Microsoft.EntityFrameworkCore; +using PyroFetes.Models; namespace PyroFetes.Endpoints.Warehouse; -public class GetAllWarehouseEndpoint(PyroFetesDbContext pyrofetesdbcontext) : EndpointWithoutRequest> +public class GetAllWarehouseEndpoint(PyroFetesDbContext db) + : EndpointWithoutRequest> { public override void Configure() { @@ -14,20 +17,30 @@ public class GetAllWarehouseEndpoint(PyroFetesDbContext pyrofetesdbcontext) : En public override async Task HandleAsync(CancellationToken ct) { - List responseDto = await pyrofetesdbcontext.Warehouses - .Select(w => new GetWarehouseDto - { - Id = w.Id, - Name = w.Name, - MaxWeight = w.MaxWeight, - Current = w.Current, - MinWeight = w.MinWeight, - Adress = w.Address, - ZipCode = w.ZipCode, - City = w.City - }) + // 🔹 On inclut les relations avec WarehouseProducts et Product + var warehouses = await db.Warehouses + .Include(w => w.WarehouseProducts) + .ThenInclude(wp => wp.Product) .ToListAsync(ct); - await Send.OkAsync(responseDto, ct); + var response = warehouses.Select(w => new GetWarehouseDto + { + Id = w.Id, + Name = w.Name, + MaxWeight = w.MaxWeight, + Current = w.Current, + MinWeight = w.MinWeight, + Adress = w.Address, + ZipCode = w.ZipCode, + City = w.City, + Products = w.WarehouseProducts.Select(wp => new WarehouseProductDto + { + ProductId = wp.ProductId, + ProductName = wp.Product?.Name, + Quantity = wp.Quantity + }).ToList() + }).ToList(); + + await Send.OkAsync(response, ct); } } \ No newline at end of file diff --git a/PyroFetes/Endpoints/Warehouse/GetWarehouseEndpoint.cs b/PyroFetes/Endpoints/Warehouse/GetWarehouseEndpoint.cs index b24e007..1744bac 100644 --- a/PyroFetes/Endpoints/Warehouse/GetWarehouseEndpoint.cs +++ b/PyroFetes/Endpoints/Warehouse/GetWarehouseEndpoint.cs @@ -1,6 +1,7 @@ using API.DTO.Warehouse.Response; using FastEndpoints; using Microsoft.EntityFrameworkCore; +using PyroFetes.Models; namespace PyroFetes.Endpoints.Warehouse; @@ -9,28 +10,32 @@ public class GetWarehouseRequest public int Id { get; set; } } -public class GetWarehouseEndpoint(PyroFetesDbContext pyrofetesdbcontext) : Endpoint +public class GetWarehouseEndpoint(PyroFetesDbContext db) + : Endpoint { public override void Configure() { - Get("/api/warehouses/{@id}", x => new { x.Id }); + // Pas de "@id" ici, juste {id} + Get("/api/warehouses/{id}", x => new { x.Id }); AllowAnonymous(); } public override async Task HandleAsync(GetWarehouseRequest req, CancellationToken ct) { - Models.Warehouse? warehouse = await pyrofetesdbcontext - .Warehouses + // 🔹 Inclut les produits associés à cet entrepôt + var warehouse = await db.Warehouses + .Include(w => w.WarehouseProducts) + .ThenInclude(wp => wp.Product) .SingleOrDefaultAsync(w => w.Id == req.Id, cancellationToken: ct); if (warehouse == null) { - Console.WriteLine($"Aucun entrepôt avec l'ID {req.Id} trouvé."); + Console.WriteLine($" Aucun entrepôt avec l'ID {req.Id} trouvé."); await Send.NotFoundAsync(ct); return; } - GetWarehouseDto responseDto = new() + var response = new GetWarehouseDto { Id = warehouse.Id, Name = warehouse.Name!, @@ -39,9 +44,15 @@ public class GetWarehouseEndpoint(PyroFetesDbContext pyrofetesdbcontext) : Endpo MinWeight = warehouse.MinWeight, Adress = warehouse.Address!, ZipCode = warehouse.ZipCode, - City = warehouse.City! + City = warehouse.City!, + Products = warehouse.WarehouseProducts.Select(wp => new WarehouseProductDto + { + ProductId = wp.ProductId, + ProductName = wp.Product?.Name, + Quantity = wp.Quantity + }).ToList() }; - await Send.OkAsync(responseDto, ct); + await Send.OkAsync(response, ct); } } \ No newline at end of file diff --git a/PyroFetes/Endpoints/Warehouse/UpdateWarehouseEndpoint.cs b/PyroFetes/Endpoints/Warehouse/UpdateWarehouseEndpoint.cs index 0864bd6..7f3afc5 100644 --- a/PyroFetes/Endpoints/Warehouse/UpdateWarehouseEndpoint.cs +++ b/PyroFetes/Endpoints/Warehouse/UpdateWarehouseEndpoint.cs @@ -2,21 +2,25 @@ using API.DTO.Warehouse.Response; using FastEndpoints; using Microsoft.EntityFrameworkCore; +using PyroFetes.Models; namespace PyroFetes.Endpoints.Warehouse; -public class UpdateWarehouseEndpoint(PyroFetesDbContext pyrofetesdbcontext) : Endpoint +public class UpdateWarehouseEndpoint(PyroFetesDbContext db) + : Endpoint { public override void Configure() { - Put("/api/warehouses/{@id}", x => new { x.Id }); + // Utilise {id} plutôt que {@id} + Put("/api/warehouses/{id}", x => new { x.Id }); AllowAnonymous(); } public override async Task HandleAsync(UpdateWarehouseDto req, CancellationToken ct) { - Models.Warehouse? warehouseToEdit = await pyrofetesdbcontext - .Warehouses + // 🔹 On inclut les produits existants pour pouvoir les modifier + var warehouseToEdit = await db.Warehouses + .Include(w => w.WarehouseProducts) .SingleOrDefaultAsync(w => w.Id == req.Id, cancellationToken: ct); if (warehouseToEdit == null) @@ -26,7 +30,7 @@ public class UpdateWarehouseEndpoint(PyroFetesDbContext pyrofetesdbcontext) : En return; } - // Mise à jour des champs + // 🔹 Mise à jour des champs de base warehouseToEdit.Name = req.Name; warehouseToEdit.MaxWeight = req.MaxWeight; warehouseToEdit.Current = req.Current; @@ -35,9 +39,30 @@ public class UpdateWarehouseEndpoint(PyroFetesDbContext pyrofetesdbcontext) : En warehouseToEdit.ZipCode = req.ZipCode; warehouseToEdit.City = req.City; - await pyrofetesdbcontext.SaveChangesAsync(ct); + // 🔹 Gestion des produits associés + if (req.Products is not null) + { + // On supprime les anciens liens pour recréer proprement + var existingLinks = warehouseToEdit.WarehouseProducts.ToList(); + if (existingLinks.Any()) + db.WarehouseProducts.RemoveRange(existingLinks); - GetWarehouseDto responseDto = new() + foreach (var p in req.Products) + { + var newLink = new WarehouseProduct + { + WarehouseId = warehouseToEdit.Id, + ProductId = p.ProductId, + Quantity = p.Quantity + }; + db.WarehouseProducts.Add(newLink); + } + } + + await db.SaveChangesAsync(ct); + + // 🔹 On renvoie la version mise à jour + var response = new GetWarehouseDto { Id = warehouseToEdit.Id, Name = warehouseToEdit.Name, @@ -46,9 +71,16 @@ public class UpdateWarehouseEndpoint(PyroFetesDbContext pyrofetesdbcontext) : En MinWeight = warehouseToEdit.MinWeight, Adress = warehouseToEdit.Address, ZipCode = warehouseToEdit.ZipCode, - City = warehouseToEdit.City + City = warehouseToEdit.City, + Products = warehouseToEdit.WarehouseProducts.Select(wp => new WarehouseProductDto + { + ProductId = wp.ProductId, + ProductName = wp.Product?.Name, + Quantity = wp.Quantity + }).ToList() }; - await Send.OkAsync(responseDto, ct); + Console.WriteLine($"Entrepôt {warehouseToEdit.Name} mis à jour avec succès."); + await Send.OkAsync(response, ct); } -} \ No newline at end of file +}