forked from sanchezvem/pyrofetes-backend
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 3c32baac57 |
@@ -1,7 +1,7 @@
|
||||
namespace PyroFetes.DTO.Login.Request;
|
||||
namespace PyroFetes.DTO.Login.Request;
|
||||
|
||||
public class ConnectLoginDto
|
||||
{
|
||||
public string? Name { get; set; }
|
||||
public string? Username { get; set; }
|
||||
public string? Password { get; set; }
|
||||
}
|
||||
@@ -1,24 +1,8 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
// Nécessaire pour les validations
|
||||
|
||||
namespace PyroFetes.DTO.Login.Request;
|
||||
namespace PyroFetes.DTO.Login.Request;
|
||||
|
||||
public class CreateLoginDto
|
||||
{
|
||||
[Required(ErrorMessage = "Le nom est requis.")]
|
||||
[StringLength(50, MinimumLength = 3, ErrorMessage = "L'identifiant doit faire entre 3 et 50 caractères.")]
|
||||
public string Name { get; set; } = string.Empty;
|
||||
|
||||
[Required(ErrorMessage = "L'emil est requis.")]
|
||||
[StringLength(50, MinimumLength = 3)]
|
||||
public string Email { get; set; } = string.Empty;
|
||||
|
||||
[Required(ErrorMessage = "Le mot de passe est requis.")]
|
||||
[MinLength(6, ErrorMessage = "Le mot de passe doit contenir au moins 6 caractères.")]
|
||||
public string Password { get; set; } = string.Empty;
|
||||
|
||||
// Ajout du champ Rôle (Optionnel, par défaut "User")
|
||||
// Cela te permet d'envoyer "Admin" via Swagger
|
||||
public string Fonction { get; set; } = "User";
|
||||
public string? Username { get; set; }
|
||||
public string? FullName { get; set; }
|
||||
public string? Password { get; set; }
|
||||
}
|
||||
@@ -1,8 +1,9 @@
|
||||
namespace PyroFetes.DTO.Login.Request;
|
||||
namespace PyroFetes.DTO.Login.Request;
|
||||
|
||||
public class UpdateLoginDto
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string? Name { get; set; }
|
||||
public string? Username { get; set; }
|
||||
public string? FullName { get; set; }
|
||||
public string? Password { get; set; }
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace PyroFetes.DTO.Login.Response;
|
||||
namespace PyroFetes.DTO.Login.Response;
|
||||
|
||||
public class GetLoginConnectDto
|
||||
{
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
namespace PyroFetes.DTO.Login.Response;
|
||||
namespace PyroFetes.DTO.Login.Response;
|
||||
|
||||
public class GetLoginDto
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string? Name { get; set; } = string.Empty;
|
||||
public string? Email { get; set; } = string.Empty;
|
||||
public string? Password { get; set; } = string.Empty;
|
||||
public string? Fonction { get; set; } = string.Empty;
|
||||
public string? Username { get; set; }
|
||||
public string? FullName { get; set; }
|
||||
public string? Password { get; set; }
|
||||
public string? Salt { get; set; }
|
||||
}
|
||||
@@ -1,23 +1,19 @@
|
||||
using PyroFetes.Models;
|
||||
|
||||
// Assure-toi d'importer tes enums
|
||||
|
||||
namespace PyroFetes.DTO.Movement.Request
|
||||
// Définition de l'espace de noms pour les DTO utilisés dans les requêtes liées aux mouvements
|
||||
namespace API.DTO.Movement.Request
|
||||
{
|
||||
// DTO utilisé pour créer un nouveau mouvement
|
||||
public class CreateMovementDto
|
||||
{
|
||||
public int ProductId { get; set; }
|
||||
// Date à laquelle le mouvement est enregistré
|
||||
public DateTime Date { get; set; }
|
||||
|
||||
public MovementType Type { get; set; }
|
||||
|
||||
public int Quantity { get; set; }
|
||||
|
||||
public DateTime Date { get; set; } = DateTime.Now;
|
||||
// Date et heure de début du mouvement
|
||||
public DateTime Start { get; set; }
|
||||
|
||||
// Date et heure d'arrivée prévue du mouvement
|
||||
public DateTime Arrival { get; set; }
|
||||
|
||||
public int? SourceWarehouseId { get; set; }
|
||||
public int? DestinationWarehouseId { get; set; }
|
||||
|
||||
// Quantité de matériaux ou objets impliqués dans le mouvement
|
||||
public int Quantity { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,7 @@ namespace PyroFetes.DTO.Product.Request
|
||||
public class CreateProductDto
|
||||
{
|
||||
// Référence interne du produit
|
||||
public string? Reference { get; set; }
|
||||
public int References { get; set; }
|
||||
|
||||
// Nom du produit
|
||||
public string? Name { get; set; }
|
||||
@@ -15,10 +15,10 @@ namespace PyroFetes.DTO.Product.Request
|
||||
public decimal Duration { get; set; }
|
||||
|
||||
// Calibre du produit
|
||||
public int Caliber { get; set; }
|
||||
public decimal Caliber { get; set; }
|
||||
|
||||
// Numéro d’homologation
|
||||
public string? ApprovalNumber { get; set; }
|
||||
public int ApprovalNumber { get; set; }
|
||||
|
||||
// Poids du produit
|
||||
public decimal Weight { get; set; }
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace PyroFetes.DTO.Product.Request
|
||||
public int Id { get; set; }
|
||||
|
||||
// Référence interne du produit
|
||||
public string? Reference { get; set; }
|
||||
public int References { get; set; }
|
||||
|
||||
// Nom du produit
|
||||
public string? Name { get; set; }
|
||||
@@ -18,10 +18,10 @@ namespace PyroFetes.DTO.Product.Request
|
||||
public decimal Duration { get; set; }
|
||||
|
||||
// Calibre du produit
|
||||
public int Caliber { get; set; }
|
||||
public decimal Caliber { get; set; }
|
||||
|
||||
// Numéro d’homologation
|
||||
public string? ApprovalNumber { get; set; }
|
||||
public int ApprovalNumber { get; set; }
|
||||
|
||||
// Poids du produit
|
||||
public decimal Weight { get; set; }
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace PyroFetes.DTO.Product.Response
|
||||
public int Id { get; set; }
|
||||
|
||||
// Référence interne du produit
|
||||
public string? Reference { get; set; }
|
||||
public int Reference { get; set; }
|
||||
|
||||
// Nom du produit
|
||||
public string? Name { get; set; }
|
||||
@@ -19,10 +19,10 @@ namespace PyroFetes.DTO.Product.Response
|
||||
public decimal Duration { get; set; }
|
||||
|
||||
// Calibre du produit
|
||||
public int Caliber { get; set; }
|
||||
public decimal Caliber { get; set; }
|
||||
|
||||
// Numéro d’homologation
|
||||
public string? ApprovalNumber { get; set; }
|
||||
public int ApprovalNumber { get; set; }
|
||||
|
||||
// Poids du produit
|
||||
public decimal Weight { get; set; }
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
namespace PyroFetes.DTO.Refrresh.Request;
|
||||
|
||||
public class RefreshTokenDto
|
||||
{
|
||||
public string? Token { get; set; }
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
namespace PyroFetes.DTO.Refrresh.Response;
|
||||
|
||||
public class GetRefreshDto
|
||||
{
|
||||
public string? Token { get; set; }
|
||||
}
|
||||
@@ -4,22 +4,22 @@
|
||||
public class CreateSupplierDto
|
||||
{
|
||||
// Nom du fournisseur
|
||||
public string? Name { get; set; }
|
||||
public string Name { get; set; }
|
||||
|
||||
// Email du fournisseur
|
||||
public string? Email { get; set; }
|
||||
public string Email { get; set; }
|
||||
|
||||
// Numéro de téléphone du fournisseur
|
||||
public string? PhoneNumber { get; set; }
|
||||
public string PhoneNumber { get; set; }
|
||||
|
||||
// Adresse du fournisseur
|
||||
public string? Adress { get; set; }
|
||||
public string Adress { get; set; }
|
||||
|
||||
// Code postal de l'adresse
|
||||
public string? ZipCode { get; set; }
|
||||
public int ZipCode { get; set; }
|
||||
|
||||
// Ville de l'adresse
|
||||
public string? City { get; set; }
|
||||
public string City { get; set; }
|
||||
|
||||
// Liste des produits fournis par ce fournisseur dans la classe SupplierProductPriceDto
|
||||
public List<SupplierProductPriceDto>? Products { get; set; }
|
||||
|
||||
@@ -7,22 +7,22 @@
|
||||
public int Id { get; set; }
|
||||
|
||||
// Nom du fournisseur
|
||||
public string? Name { get; set; }
|
||||
public string Name { get; set; }
|
||||
|
||||
// Email du fournisseur
|
||||
public string? Email { get; set; }
|
||||
public string Email { get; set; }
|
||||
|
||||
// Numéro de téléphone du fournisseur
|
||||
public string? PhoneNumber { get; set; }
|
||||
public string PhoneNumber { get; set; }
|
||||
|
||||
// Adresse du fournisseur
|
||||
public string? Adress { get; set; }
|
||||
public string Adress { get; set; }
|
||||
|
||||
// Code postal de l'adresse
|
||||
public string? ZipCode { get; set; }
|
||||
public int ZipCode { get; set; }
|
||||
|
||||
// Ville de l'adresse
|
||||
public string? City { get; set; }
|
||||
public string City { get; set; }
|
||||
|
||||
// Liste des produits fournis par ce fournisseur relié à la classe SupplierProductPriceDto
|
||||
public List<SupplierProductPriceDto>? Products { get; set; }
|
||||
|
||||
@@ -9,22 +9,22 @@ namespace PyroFetes.DTO.Supplier.Response
|
||||
public int Id { get; set; }
|
||||
|
||||
// Nom du fournisseur
|
||||
public string? Name { get; set; }
|
||||
public string Name { get; set; }
|
||||
|
||||
// Email du fournisseur
|
||||
public string? Email { get; set; }
|
||||
public string Email { get; set; }
|
||||
|
||||
// Numéro de téléphone
|
||||
public string? PhoneNumber { get; set; }
|
||||
public string PhoneNumber { get; set; }
|
||||
|
||||
// Adresse du fournisseur
|
||||
public string? Adress { get; set; }
|
||||
public string Adress { get; set; }
|
||||
|
||||
// Code postal
|
||||
public string? ZipCode { get; set; }
|
||||
public int ZipCode { get; set; }
|
||||
|
||||
// Ville
|
||||
public string? City { get; set; }
|
||||
public string City { get; set; }
|
||||
|
||||
// Liste des produits fournis par la classe SupplierProductPriceDto
|
||||
public List<SupplierProductPriceDto> Products { get; set; } = new();
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
public class CreateWarehouseDto
|
||||
{
|
||||
// Nom de l'entrepôt
|
||||
public string? Name { get; set; }
|
||||
public string Name { get; set; }
|
||||
|
||||
// Poids maximal que l'entrepôt peut contenir
|
||||
public int MaxWeight { get; set; }
|
||||
@@ -16,13 +16,13 @@
|
||||
public int MinWeight { get; set; }
|
||||
|
||||
// Adresse de l'entrepôt
|
||||
public string? Adress { get; set; }
|
||||
public string Adress { get; set; }
|
||||
|
||||
// Code postal
|
||||
public string? ZipCode { get; set; }
|
||||
public int ZipCode { get; set; }
|
||||
|
||||
// Ville
|
||||
public string? City { get; set; }
|
||||
public string City { get; set; }
|
||||
|
||||
// Liste des produits à stocker dans cet entrepôt venant de la classe en dessous
|
||||
public List<CreateWarehouseProductDto>? Products { get; set; }
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
public int Id { get; set; }
|
||||
|
||||
// Nom de l'entrepôt
|
||||
public string? Name { get; set; }
|
||||
public string Name { get; set; }
|
||||
|
||||
// Poids maximal que l'entrepôt peut contenir
|
||||
public int MaxWeight { get; set; }
|
||||
@@ -19,13 +19,13 @@
|
||||
public int MinWeight { get; set; }
|
||||
|
||||
// Adresse de l'entrepôt
|
||||
public string? Adress { get; set; }
|
||||
public string Adress { get; set; }
|
||||
|
||||
// Code postal
|
||||
public string? ZipCode { get; set; }
|
||||
public int ZipCode { get; set; }
|
||||
|
||||
// Ville
|
||||
public string? City { get; set; }
|
||||
public string City { get; set; }
|
||||
|
||||
// Liste des produits à mettre à jour dans cet entrepôt
|
||||
public List<UpdateWarehouseProductDto>? Products { get; set; }
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
public int Id { get; set; }
|
||||
|
||||
// Nom de l'entrepôt
|
||||
public string? Name { get; set; }
|
||||
public string Name { get; set; }
|
||||
|
||||
// Poids maximal que l'entrepôt peut contenir
|
||||
public int MaxWeight { get; set; }
|
||||
@@ -19,13 +19,13 @@
|
||||
public int MinWeight { get; set; }
|
||||
|
||||
// Adresse de l'entrepôt
|
||||
public string? Adress { get; set; }
|
||||
public string Adress { get; set; }
|
||||
|
||||
// Code postal
|
||||
public string? ZipCode { get; set; }
|
||||
public int ZipCode { get; set; }
|
||||
|
||||
// Ville
|
||||
public string? City { get; set; }
|
||||
public string City { get; set; }
|
||||
|
||||
// Liste des produits stockés dans l'entrepôt
|
||||
public List<WarehouseProductDto>? Products { get; set; }
|
||||
|
||||
@@ -4,31 +4,32 @@ using PyroFetes.DTO.Brand.Request;
|
||||
|
||||
namespace PyroFetes.Endpoints.Brand;
|
||||
|
||||
public class CreateBrandEndpoint(PyroFetesDbContext pyrofetesdbcontext) : Endpoint<CreateBrandDto, GetBrandDto>
|
||||
public class CreateBrandEndpoint(PyroFetesDbContext pyrofetesdbcontext) : Endpoint<CreateBrandDto, GetBrandDto> //Instanciation d'une connexion à la bdd dans un endpoint, utilise l'élément de requête CreateBrandDto et l'élement de réponse GetBrandDto
|
||||
{
|
||||
public override void Configure()
|
||||
public override void Configure() //Configuration de l'endpoint
|
||||
{
|
||||
Post("/brands");
|
||||
Post("/api/brands"); //Créer une marque
|
||||
AllowAnonymous(); //Autorise l'accès sans authentification
|
||||
}
|
||||
|
||||
public override async Task HandleAsync(CreateBrandDto req, CancellationToken ct)
|
||||
public override async Task HandleAsync(CreateBrandDto req, CancellationToken ct)
|
||||
{
|
||||
|
||||
Models.Brand brand = new ()
|
||||
Models.Brand brand = new () //Création d'un nom rentré par l'utilisateur
|
||||
{
|
||||
Name = req.Name
|
||||
};
|
||||
|
||||
pyrofetesdbcontext.Brands.Add(brand);
|
||||
await pyrofetesdbcontext.SaveChangesAsync(ct);
|
||||
pyrofetesdbcontext.Brands.Add(brand); //Ajout de la marque à la bdd
|
||||
await pyrofetesdbcontext.SaveChangesAsync(ct); //Sauvegarde de la marque dans la bdd
|
||||
|
||||
Console.WriteLine("Marque créé avec succès !");
|
||||
|
||||
GetBrandDto responseDto = new ()
|
||||
GetBrandDto responseDto = new () //Renvoie le nom
|
||||
{
|
||||
Name = req.Name
|
||||
Name = req.Name
|
||||
};
|
||||
|
||||
await Send.OkAsync(responseDto, ct);
|
||||
await Send.OkAsync(responseDto, ct); //Réponse au client
|
||||
}
|
||||
}
|
||||
@@ -5,33 +5,34 @@ namespace PyroFetes.Endpoints.Brand;
|
||||
|
||||
public class DeleteBrandRequest
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public int Id { get; set; } //Création d'un Id
|
||||
}
|
||||
|
||||
public class DeleteBrandEndpoint(PyroFetesDbContext pyrofetesdbcontext) : Endpoint<DeleteBrandRequest>
|
||||
public class DeleteBrandEndpoint(PyroFetesDbContext pyrofetesdbcontext) : Endpoint<DeleteBrandRequest> //Instanciation d'une connexion à la bdd dans un endpoint, utilise l'élément de requête DeleteBrandDto.
|
||||
{
|
||||
public override void Configure()
|
||||
public override void Configure() //Configuration de l'endpoint
|
||||
{
|
||||
Delete("/brands/{@id}", x => new { x.Id });
|
||||
Delete("/api/brands/{@id}", x => new { x.Id }); //Supprime une marque
|
||||
AllowAnonymous(); //Autorise l'accès sans authentification
|
||||
}
|
||||
|
||||
public override async Task HandleAsync(DeleteBrandRequest req, CancellationToken ct)
|
||||
{
|
||||
|
||||
Models.Brand? brandToDelete = await pyrofetesdbcontext
|
||||
.Brands
|
||||
.SingleOrDefaultAsync(a => a.Id == req.Id, cancellationToken: ct);
|
||||
Models.Brand? brandToDelete = await pyrofetesdbcontext //Récupère une marque dans la bdd et le stocke dans brandToDelete
|
||||
.Brands //Recherche la couleur dans la table Colors
|
||||
.SingleOrDefaultAsync(a => a.Id == req.Id, cancellationToken: ct); //Recherche une couleur dont l'id correspond à req.Id
|
||||
|
||||
if (brandToDelete == null)
|
||||
{
|
||||
Console.WriteLine($"Aucune marque avec l'ID {req.Id} trouvé.");
|
||||
await Send.NotFoundAsync(ct);
|
||||
return;
|
||||
await Send.NotFoundAsync(ct); //Renvoie une erreur 404
|
||||
return; //Arrêt de la méthode
|
||||
}
|
||||
|
||||
pyrofetesdbcontext.Brands.Remove(brandToDelete);
|
||||
await pyrofetesdbcontext.SaveChangesAsync(ct);
|
||||
pyrofetesdbcontext.Brands.Remove(brandToDelete); //Supprime la marque de la bdd
|
||||
await pyrofetesdbcontext.SaveChangesAsync(ct); //Sauvegarde de la marque dans la bdd
|
||||
|
||||
await Send.NoContentAsync(ct);
|
||||
await Send.NoContentAsync(ct); //Renvoie une réponse réussite 204
|
||||
}
|
||||
}
|
||||
@@ -8,20 +8,21 @@ public class GetAllBrandsEndpoint(PyroFetesDbContext pyrofetesdbcontext) : Endpo
|
||||
{
|
||||
public override void Configure()
|
||||
{
|
||||
Get("/brands");
|
||||
Get("/api/brands"); //Endpoint qui affiche toutes les marques
|
||||
AllowAnonymous(); //Autorise l'accès sans authentification
|
||||
}
|
||||
|
||||
public override async Task HandleAsync(CancellationToken ct)
|
||||
{
|
||||
|
||||
List<GetBrandDto> responseDto = await pyrofetesdbcontext.Brands
|
||||
.Select(a => new GetBrandDto
|
||||
List<GetBrandDto> responseDto = await pyrofetesdbcontext.Brands //Création d'une liste qui récupère toutes les marques dans la bdd
|
||||
.Select(a => new GetBrandDto //Sélectionne dans la liste chaque marque
|
||||
{
|
||||
Id = a.Id,
|
||||
Name = a.Name,
|
||||
Id = a.Id, //Affiche l'id
|
||||
Name = a.Name, //Affiche le nom
|
||||
}
|
||||
).ToListAsync(ct);
|
||||
).ToListAsync(ct); //Retourne la liste de marque
|
||||
|
||||
await Send.OkAsync(responseDto, ct);
|
||||
await Send.OkAsync(responseDto, ct); //Envoie de la réponse réussite 200 au client
|
||||
}
|
||||
}
|
||||
@@ -13,29 +13,30 @@ public class GetBrandEndpoint(PyroFetesDbContext pyrofetesdbcontext) :Endpoint<G
|
||||
{
|
||||
public override void Configure()
|
||||
{
|
||||
Get("/brands/{@id}", x => new { x.Id });
|
||||
Get("/api/brands/{@id}", x => new { x.Id }); //endpoint qui affiche la marque en fonction de l'id
|
||||
AllowAnonymous(); //Autorise l'accès sans authentification
|
||||
}
|
||||
|
||||
public override async Task HandleAsync(GetBrandRequest req, CancellationToken ct)
|
||||
{
|
||||
|
||||
Models.Brand? brand = await pyrofetesdbcontext
|
||||
.Brands
|
||||
.SingleOrDefaultAsync(a => a.Id == req.Id, cancellationToken: ct);
|
||||
Models.Brand? brand = await pyrofetesdbcontext //Récupère la table marque dans la bdd
|
||||
.Brands
|
||||
.SingleOrDefaultAsync(a => a.Id == req.Id, cancellationToken: ct); //récupère l'id
|
||||
|
||||
if (brand == null)
|
||||
{
|
||||
Console.WriteLine($"Aucune marque avec l'ID {req.Id} trouvé.");
|
||||
await Send.NotFoundAsync(ct);
|
||||
return;
|
||||
await Send.NotFoundAsync(ct); //Renvoie une erreur 404
|
||||
return; //Arrêt de la méthode
|
||||
}
|
||||
|
||||
GetBrandDto responseDto = new()
|
||||
GetBrandDto responseDto = new() //renvoie l'id et le nom
|
||||
{
|
||||
Id = req.Id,
|
||||
Name = brand.Name
|
||||
Id = req.Id, //Affiche l'id
|
||||
Name = brand.Name //Affiche le nom
|
||||
};
|
||||
|
||||
await Send.OkAsync(responseDto, ct);
|
||||
await Send.OkAsync(responseDto, ct); //Envoie de la réponse réussite 200 au client
|
||||
}
|
||||
}
|
||||
@@ -8,26 +8,27 @@ public class UpdateBrandEndpoint(PyroFetesDbContext pyrofetesdbcontext) : Endpoi
|
||||
{
|
||||
public override void Configure()
|
||||
{
|
||||
Put("/brands/{Id}");
|
||||
Put("/api/brands/{Id}"); //Met à jour la marque en fonction de l'id
|
||||
AllowAnonymous(); //Autorise l'accès sans authentification
|
||||
}
|
||||
|
||||
public override async Task HandleAsync(UpdateBrandDto req, CancellationToken ct)
|
||||
{
|
||||
|
||||
Models.Brand brand = new()
|
||||
Models.Brand brand = new() //Met à jour la marque
|
||||
{
|
||||
Name = req.Name
|
||||
};
|
||||
pyrofetesdbcontext.Add(brand);
|
||||
await pyrofetesdbcontext.SaveChangesAsync(ct);
|
||||
pyrofetesdbcontext.Add(brand); //ajoute la marque dans la bdd
|
||||
await pyrofetesdbcontext.SaveChangesAsync(ct); //Sauvegarde les changements
|
||||
|
||||
GetBrandDto response = new()
|
||||
GetBrandDto response = new() //renvoie l'id et le nom
|
||||
{
|
||||
Id = req.Id,
|
||||
Name = req.Name
|
||||
};
|
||||
|
||||
await Send.OkAsync(response, ct);
|
||||
await Send.OkAsync(response, ct); //Envoie de la réponse réussite 200 au client
|
||||
|
||||
}
|
||||
}
|
||||
@@ -4,31 +4,32 @@ using FastEndpoints;
|
||||
|
||||
namespace PyroFetes.Endpoints.Classification;
|
||||
|
||||
public class CreateClassificationEndpoint(PyroFetesDbContext pyrofetesdbcontext) : Endpoint<CreateClassificationDto, GetClassificationDto>
|
||||
public class CreateClassificationEndpoint(PyroFetesDbContext pyrofetesdbcontext) : Endpoint<CreateClassificationDto, GetClassificationDto> //Instanciation d'une connexion à la bdd dans un endpoint, utilise l'élément de requête CreateClassificationDto et l'élement de réponse GetClassificationDto
|
||||
{
|
||||
public override void Configure()
|
||||
public override void Configure() //Configuration de l'endpoint
|
||||
{
|
||||
Post("/classifications");
|
||||
Post("/api/classifications"); //Créer une classification
|
||||
AllowAnonymous(); //Autorise l'accès sans authentification
|
||||
}
|
||||
|
||||
public override async Task HandleAsync(CreateClassificationDto req, CancellationToken ct)
|
||||
{
|
||||
|
||||
Models.Classification classification = new ()
|
||||
Models.Classification classification = new () //Création d'un label rentré par l'utilisateur
|
||||
{
|
||||
Label = req.Label
|
||||
};
|
||||
|
||||
pyrofetesdbcontext.Classifications.Add(classification);
|
||||
await pyrofetesdbcontext.SaveChangesAsync(ct);
|
||||
pyrofetesdbcontext.Classifications.Add(classification); //Ajout de la classification à la bdd
|
||||
await pyrofetesdbcontext.SaveChangesAsync(ct); //Sauvegarde de la classification dans la bdd
|
||||
|
||||
Console.WriteLine("Classification créée avec succès !");
|
||||
|
||||
GetClassificationDto responseDto = new ()
|
||||
GetClassificationDto responseDto = new () //Renvoie le label de la classification
|
||||
{
|
||||
Label = req.Label
|
||||
};
|
||||
|
||||
await Send.OkAsync(responseDto, ct);
|
||||
await Send.OkAsync(responseDto, ct); //Réponse au client
|
||||
}
|
||||
}
|
||||
@@ -12,26 +12,27 @@ public class DeleteClassificationEndpoint(PyroFetesDbContext libraryDbContext) :
|
||||
{
|
||||
public override void Configure()
|
||||
{
|
||||
Delete("/classifications/{@id}", x => new { x.Id });
|
||||
Delete("/api/classifications/{@id}", x => new { x.Id }); //Supprime une classification en fonction de l'id
|
||||
AllowAnonymous(); //Autorise l'accès sans authentification
|
||||
}
|
||||
|
||||
public override async Task HandleAsync(DeleteClassificationRequest req, CancellationToken ct)
|
||||
{
|
||||
|
||||
Models.Classification? classificationToDelete = await libraryDbContext
|
||||
.Classifications
|
||||
.SingleOrDefaultAsync(a => a.Id == req.Id, cancellationToken: ct);
|
||||
Models.Classification? classificationToDelete = await libraryDbContext //Récupère une classification dans la bdd et le stocke dans classificationToDelete
|
||||
.Classifications //Recherche la classification dans la table Classifications
|
||||
.SingleOrDefaultAsync(a => a.Id == req.Id, cancellationToken: ct); //Recherche une classification dont l'id correspond à req.Id
|
||||
|
||||
if (classificationToDelete == null)
|
||||
{
|
||||
Console.WriteLine($"Aucune classification avec l'ID {req.Id} trouvé.");
|
||||
await Send.NotFoundAsync(ct);
|
||||
return;
|
||||
await Send.NotFoundAsync(ct); //Renvoie une erreur 404
|
||||
return; //Arrêt de la méthode
|
||||
}
|
||||
|
||||
libraryDbContext.Classifications.Remove(classificationToDelete);
|
||||
await libraryDbContext.SaveChangesAsync(ct);
|
||||
libraryDbContext.Classifications.Remove(classificationToDelete); //Supprime la classification dans la bdd
|
||||
await libraryDbContext.SaveChangesAsync(ct); //Sauvegarde de la classification dans la bdd
|
||||
|
||||
await Send.NoContentAsync(ct);
|
||||
await Send.NoContentAsync(ct); //Renvoie une réponse réussite 204
|
||||
}
|
||||
}
|
||||
@@ -8,20 +8,21 @@ public class GetAllClassificationsEndpoint(PyroFetesDbContext pyrofetesdbcontext
|
||||
{
|
||||
public override void Configure()
|
||||
{
|
||||
Get("/classifications");
|
||||
Get("/api/classifications"); //Endpoint qui affiche toutes les classifications
|
||||
AllowAnonymous(); //Autorise l'accès sans authentification
|
||||
}
|
||||
|
||||
public override async Task HandleAsync(CancellationToken ct)
|
||||
{
|
||||
|
||||
List<GetClassificationDto> responseDto = await pyrofetesdbcontext.Classifications
|
||||
.Select(a => new GetClassificationDto
|
||||
List<GetClassificationDto> responseDto = await pyrofetesdbcontext.Classifications //Création d'une liste qui récupère toutes les classifications dans la bdd
|
||||
.Select(a => new GetClassificationDto //Sélectionne dans la liste chaque classification
|
||||
{
|
||||
Id = a.Id,
|
||||
Label = a.Label,
|
||||
Id = a.Id, //Récupère l'id
|
||||
Label = a.Label, //Récupère le label
|
||||
}
|
||||
).ToListAsync(ct);
|
||||
).ToListAsync(ct); //Retourne la liste de classification
|
||||
|
||||
await Send.OkAsync(responseDto, ct);
|
||||
await Send.OkAsync(responseDto, ct); //Envoie de la réponse réussite 200 au client
|
||||
}
|
||||
}
|
||||
@@ -13,29 +13,30 @@ public class GetClassificationEndpoint(PyroFetesDbContext pyrofetesdbcontext) :E
|
||||
{
|
||||
public override void Configure()
|
||||
{
|
||||
Get("/classifications/{@id}", x => new { x.Id });
|
||||
Get("/api/classifications/{@id}", x => new { x.Id }); //endpoint qui affiche la classification en fonction de l'id
|
||||
AllowAnonymous(); //Autorise l'accès sans authentification
|
||||
}
|
||||
|
||||
public override async Task HandleAsync(GetClassificationRequest req, CancellationToken ct)
|
||||
{
|
||||
|
||||
Models.Classification? classification = await pyrofetesdbcontext
|
||||
Models.Classification? classification = await pyrofetesdbcontext //Récupère la table marque dans la bdd
|
||||
.Classifications
|
||||
.SingleOrDefaultAsync(a => a.Id == req.Id, cancellationToken: ct);
|
||||
.SingleOrDefaultAsync(a => a.Id == req.Id, cancellationToken: ct); //récupère l'id
|
||||
|
||||
if (classification == null)
|
||||
{
|
||||
Console.WriteLine($"Aucune classification avec l'ID {req.Id} trouvé.");
|
||||
await Send.NotFoundAsync(ct);
|
||||
return;
|
||||
await Send.NotFoundAsync(ct); //Renvoie une erreur 404
|
||||
return; //Arrêt de la méthode
|
||||
}
|
||||
|
||||
GetClassificationDto responseDto = new()
|
||||
{
|
||||
Id = req.Id,
|
||||
Label = classification.Label
|
||||
Id = req.Id, //Affiche l'id
|
||||
Label = classification.Label //Affiche le nom
|
||||
};
|
||||
|
||||
await Send.OkAsync(responseDto, ct);
|
||||
await Send.OkAsync(responseDto, ct); //Envoie de la réponse réussite 200 au client
|
||||
}
|
||||
}
|
||||
@@ -8,26 +8,27 @@ public class UpdateClassificationEndpoint(PyroFetesDbContext pyrofetesdbcontext)
|
||||
{
|
||||
public override void Configure()
|
||||
{
|
||||
Put("/classifications");
|
||||
Put("/api/classifications"); //Met à jour la classification en fonction de l'id
|
||||
AllowAnonymous(); //Autorise l'accès sans authentification
|
||||
}
|
||||
|
||||
public override async Task HandleAsync(UpdateClassificationDto req, CancellationToken ct)
|
||||
{
|
||||
|
||||
Models.Classification classification = new()
|
||||
Models.Classification classification = new() //Met à jour la classification
|
||||
{
|
||||
Label = req.Label
|
||||
};
|
||||
pyrofetesdbcontext.Add(classification);
|
||||
await pyrofetesdbcontext.SaveChangesAsync(ct);
|
||||
pyrofetesdbcontext.Add(classification); //ajoute la classification dans la bdd
|
||||
await pyrofetesdbcontext.SaveChangesAsync(ct); //Sauvegarde les changements
|
||||
|
||||
GetClassificationDto response = new()
|
||||
GetClassificationDto response = new() //renvoie l'id et le nom
|
||||
{
|
||||
Id = req.Id,
|
||||
Label = req.Label
|
||||
};
|
||||
|
||||
await Send.OkAsync(response, ct);
|
||||
await Send.OkAsync(response, ct); //Envoie de la réponse réussite 200 au client
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,19 +1,21 @@
|
||||
using API.DTO.Color.Request;
|
||||
using API.DTO.Color.Response;
|
||||
using FastEndpoints;
|
||||
using PyroFetes;
|
||||
|
||||
namespace PyroFetes.Endpoints.Color;
|
||||
namespace API.Endpoints.Color;
|
||||
|
||||
public class CreateColorEndpoint(PyroFetesDbContext pyroFetesDbContext) : Endpoint<CreateColorDto, GetColorDto> //Instanciation d'une connexion à la bdd dans un endpoint, utilise l'élément de requête CreateColorDto et l'élement de réponse GetColorDto
|
||||
{
|
||||
public override void Configure() //Configuration de l'endpoint
|
||||
{
|
||||
Post("/colors"); //Création d'un endpoint pour créer une couleur avec les données de CreateColorDto
|
||||
Post("Api/colors"); //Création d'un endpoint pour créer une couleur avec les données de CreateColorDto
|
||||
AllowAnonymous(); //Laisser passer les requêtes non authentifiées
|
||||
}
|
||||
|
||||
public override async Task HandleAsync(CreateColorDto req, CancellationToken ct) //La méthode HandleAsync est appelée lorsqu'une requête est envoyée à l'endpoint
|
||||
{
|
||||
PyroFetes.Models.Color color = new()
|
||||
PyroFetes.Models.Color color = new() //Création d'un label rentré par l'utilisateur
|
||||
{
|
||||
Label = req.Label,
|
||||
};
|
||||
|
||||
@@ -3,34 +3,35 @@ using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace PyroFetes.Endpoints.Color;
|
||||
|
||||
public class DeleteColorRequest
|
||||
public class DeleteColorRequest //Création d'une classe DeleteColorRequest
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public int Id { get; set; } //Création d'un Id
|
||||
}
|
||||
|
||||
public class DeleteColorEndpoint(PyroFetesDbContext pyrofetesdbcontext) : Endpoint<DeleteColorRequest>
|
||||
public class DeleteColorEndpoint(PyroFetesDbContext pyrofetesdbcontext) : Endpoint<DeleteColorRequest> //Instanciation d'une connexion à la bdd dans un endpoint, utilise l'élément de requête DeleteColorDto.
|
||||
{
|
||||
public override void Configure()
|
||||
public override void Configure() //Configuration de l'endpoint
|
||||
{
|
||||
Delete("/colors/{@id}", x => new { x.Id });
|
||||
Delete("Api/colors/{@id}", x => new { x.Id }); //endpoint qui supprime une couleur grâce à son id
|
||||
AllowAnonymous(); //Ignorer les requêtes non authentifiées
|
||||
}
|
||||
|
||||
public override async Task HandleAsync(DeleteColorRequest req, CancellationToken ct)
|
||||
public override async Task HandleAsync(DeleteColorRequest req, CancellationToken ct) //Méthode asynchrone qui traite la suppression de la couleur
|
||||
{
|
||||
Models.Color? colorToDelete = await pyrofetesdbcontext
|
||||
.Colors
|
||||
.SingleOrDefaultAsync(a => a.Id == req.Id, cancellationToken: ct);
|
||||
Models.Color? colorToDelete = await pyrofetesdbcontext //Récupère une couleur dans la bdd et le stocke dans colorToDelete
|
||||
.Colors //Recherche la couleur dans la table Colors
|
||||
.SingleOrDefaultAsync(a => a.Id == req.Id, cancellationToken: ct); //Recherche une couleur dont l'id correspond à req.Id
|
||||
|
||||
if (colorToDelete == null)
|
||||
if (colorToDelete == null) //Si la couleur n'est pas trouvé
|
||||
{
|
||||
Console.WriteLine($"Aucune couleur avec l'ID {req.Id} trouvé.");
|
||||
await Send.NotFoundAsync(ct);
|
||||
return;
|
||||
await Send.NotFoundAsync(ct); //Renvoie une erreur 404
|
||||
return; //Arrêt de la méthode
|
||||
}
|
||||
|
||||
pyrofetesdbcontext.Colors.Remove(colorToDelete);
|
||||
await pyrofetesdbcontext.SaveChangesAsync(ct);
|
||||
pyrofetesdbcontext.Colors.Remove(colorToDelete); //Supprime la couleur dans la bdd
|
||||
await pyrofetesdbcontext.SaveChangesAsync(ct); //Sauvegarde les changements effectués dans la bdd
|
||||
|
||||
await Send.NoContentAsync(ct);
|
||||
await Send.NoContentAsync(ct); //Renvoie une réponse réussite 204
|
||||
}
|
||||
}
|
||||
@@ -6,20 +6,21 @@ namespace PyroFetes.Endpoints.Color;
|
||||
|
||||
public class GetAllColorsEndpoint(PyroFetesDbContext pyrofetesdbcontext) : EndpointWithoutRequest<List<GetColorDto>>
|
||||
{
|
||||
public override void Configure()
|
||||
public override void Configure() //Configuration de l'endpoint
|
||||
{
|
||||
Get("/colors");
|
||||
Get("Api/colors"); //Endpoint qui affiche toutes les couleurs
|
||||
AllowAnonymous(); //Ignorer les requêtes non authentifiées
|
||||
}
|
||||
|
||||
public override async Task HandleAsync(CancellationToken ct)
|
||||
{
|
||||
List<GetColorDto> responseDto = await pyrofetesdbcontext.Colors
|
||||
.Select(a => new GetColorDto
|
||||
List<GetColorDto> responseDto = await pyrofetesdbcontext.Colors //Création d'une liste qui récupère toutes les couleurs dans la bdd
|
||||
.Select(a => new GetColorDto //Sélectionne dans la liste chaque couleur
|
||||
{
|
||||
Id = a.Id,
|
||||
Label = a.Label,
|
||||
Id = a.Id, //Récupère l'id
|
||||
Label = a.Label, //Récupère le label
|
||||
}
|
||||
).ToListAsync(ct);
|
||||
await Send.OkAsync(responseDto, ct);
|
||||
).ToListAsync(ct); //Retourne la liste de couleur
|
||||
await Send.OkAsync(responseDto, ct); //Envoie de la réponse réussite 200 au client
|
||||
}
|
||||
}
|
||||
@@ -11,30 +11,30 @@ public class GetColorRequest
|
||||
|
||||
public class GetColorEndpoint(PyroFetesDbContext pyrofetesdbcontext) : Endpoint<GetColorRequest, GetColorDto>
|
||||
{
|
||||
public override void Configure()
|
||||
public override void Configure()
|
||||
{
|
||||
Get("/colors/{@id}", x => new { x.Id});
|
||||
Get("Api/colors/{@id}", x => new { x.Id}); //endpoint qui récupère une couleur grâce à son id
|
||||
AllowAnonymous(); //Autorise l'accès sans authentification
|
||||
}
|
||||
|
||||
public override async Task HandleAsync(GetColorRequest req, CancellationToken ct)
|
||||
public override async Task HandleAsync(GetColorRequest req, CancellationToken ct) //Méthode asynchrone qui traite la récupération de la couleur
|
||||
{
|
||||
Models.Color? color = await pyrofetesdbcontext
|
||||
.Colors
|
||||
.SingleOrDefaultAsync(x => x.Id == req.Id, cancellationToken: ct);
|
||||
Models.Color? color = await pyrofetesdbcontext //Récupère une couleur dans la bdd et le stocke dans color
|
||||
.Colors //Recherche la couleur dans la table Colors
|
||||
.SingleOrDefaultAsync(x => x.Id == req.Id, cancellationToken: ct); //Recherche une couleur dont l'id correspond à req.Id
|
||||
|
||||
if (color == null)
|
||||
if (color == null) //Si la couleur n'est pas trouvé
|
||||
{
|
||||
Console.WriteLine("Aucune couleur avec l'ID {req.Id} trouvé.");
|
||||
await Send.NotFoundAsync(ct);
|
||||
return;
|
||||
Console.WriteLine("Aucune couleur avec l'ID {req.Id} trouvé."); //Affiche aucune couleur avec l'id ... trouvé
|
||||
await Send.NotFoundAsync(ct); //Renvoie une erreur 404
|
||||
return; //Arrêt de la méthode
|
||||
}
|
||||
|
||||
GetColorDto responseDto = new()
|
||||
GetColorDto responseDto = new() //Constuire l'objet de réponse pour retourner les informations à l'utilisateur
|
||||
{
|
||||
Id = color.Id,
|
||||
Label = color.Label,
|
||||
Id = color.Id, //Affiche l'id lors de la réponse
|
||||
Label = color.Label, //Affiche le label lors de la réponse
|
||||
};
|
||||
await Send.OkAsync(responseDto, ct);
|
||||
|
||||
await Send.OkAsync(responseDto, ct); //Envoie de la réponse réussite 200 au client
|
||||
}
|
||||
}
|
||||
@@ -7,33 +7,34 @@ namespace PyroFetes.Endpoints.Color;
|
||||
|
||||
public class UpdateColorEndpoint(PyroFetesDbContext pyrofetesdbcontext) : Endpoint<UpdateColorDto, GetColorDto>
|
||||
{
|
||||
public override void Configure()
|
||||
public override void Configure() //Configuration de l'endpoint
|
||||
{
|
||||
Put("/colors/{@id}", x => new { x.Id });
|
||||
Put("Api/colors/{@id}", x => new { x.Id }); //Création d'un endpoint qui modifie la couleur grâce à son id
|
||||
AllowAnonymous(); //Ignorer les requêtes non authentifiées
|
||||
}
|
||||
|
||||
public override async Task HandleAsync(UpdateColorDto req, CancellationToken ct)
|
||||
{
|
||||
Models.Color? colorToEdit = await pyrofetesdbcontext
|
||||
.Colors
|
||||
.SingleOrDefaultAsync(x => x.Id == req.Id, cancellationToken: ct);
|
||||
Models.Color? colorToEdit = await pyrofetesdbcontext //Récupère une couleur dans la bdd et le stocke dans colorToEdit
|
||||
.Colors //Recherche la couleur dans la table Colors
|
||||
.SingleOrDefaultAsync(x => x.Id == req.Id, cancellationToken: ct); //Recherche une couleur dont l'id correspond à req.Id
|
||||
|
||||
if (colorToEdit == null)
|
||||
if (colorToEdit == null) //Si la couleur n'est pas trouvé
|
||||
{
|
||||
Console.WriteLine("Aucune couleur avec l'id {req.Id} trouvé.");
|
||||
await Send.NotFoundAsync(ct);
|
||||
return;
|
||||
Console.WriteLine("Aucune couleur avec l'id {req.Id} trouvé."); //Afficher aucune couleur avec l'id ... trouvé
|
||||
await Send.NotFoundAsync(ct); //Renvoie une erreur 404
|
||||
return; //Arrêt de la méthode
|
||||
|
||||
}
|
||||
colorToEdit.Label = req.Label;
|
||||
await pyrofetesdbcontext.SaveChangesAsync(ct);
|
||||
colorToEdit.Label = req.Label; //Modification du label
|
||||
await pyrofetesdbcontext.SaveChangesAsync(ct); //Sauvegarde les changements effectués dans la bdd
|
||||
|
||||
GetColorDto responseDto = new()
|
||||
GetColorDto responseDto = new() //Constuire l'objet de réponse pour retourner l'id et le label de la nouvelle couleur
|
||||
{
|
||||
Id = req.Id,
|
||||
Label = req.Label,
|
||||
Id = req.Id, //Affiche l'id
|
||||
Label = req.Label, //Affiche le label
|
||||
};
|
||||
await Send.OkAsync(responseDto, ct);
|
||||
await Send.OkAsync(responseDto, ct); //Envoie de la réponse réussite 200 au client
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -4,30 +4,31 @@ using FastEndpoints;
|
||||
|
||||
namespace PyroFetes.Endpoints.Effect;
|
||||
|
||||
public class CreateEffectEndpoint(PyroFetesDbContext pyrofetesdbcontext) : Endpoint<CreateEffectDto, GetEffectDto>
|
||||
public class CreateEffectEndpoint(PyroFetesDbContext pyrofetesdbcontext) : Endpoint<CreateEffectDto, GetEffectDto> //Instanciation d'une connexion à la bdd dans un endpoint, utilise l'élément de requête CreateEffectDto et l'élement de réponse GetEffectDto
|
||||
{
|
||||
public override void Configure()
|
||||
public override void Configure() //Configuration de l'endpoint
|
||||
{
|
||||
Post("/effects");
|
||||
Post("Api/effects"); //Créer un effet
|
||||
AllowAnonymous(); //Autorise l'accès sans authentification
|
||||
}
|
||||
|
||||
public override async Task HandleAsync(CreateEffectDto req, CancellationToken ct)
|
||||
{
|
||||
Models.Effect effect = new()
|
||||
Models.Effect effect = new() //Création d'un label rentré par l'utilisateur
|
||||
{
|
||||
Label = req.Label,
|
||||
};
|
||||
|
||||
pyrofetesdbcontext.Effects.Add(effect);
|
||||
await pyrofetesdbcontext.SaveChangesAsync(ct);
|
||||
Console.WriteLine("Effect added");
|
||||
pyrofetesdbcontext.Effects.Add(effect); //Ajoute effect à la bdd
|
||||
await pyrofetesdbcontext.SaveChangesAsync(ct); //Sauvegarde les changements effectués dans la bdd
|
||||
Console.WriteLine("Effect added"); //Affiche Effect added si réussi
|
||||
|
||||
GetEffectDto responseDto = new()
|
||||
GetEffectDto responseDto = new() //Constuire l'objet de réponse pour retourner id et label à l'utilisateur
|
||||
{
|
||||
Id = effect.Id,
|
||||
Label = req.Label,
|
||||
Id = effect.Id, //Affiche l'id lors de la réponse
|
||||
Label = req.Label, //Affiche le label lors de la réponse
|
||||
};
|
||||
|
||||
await Send.OkAsync(responseDto, ct);
|
||||
await Send.OkAsync(responseDto, ct); //Envoie de la réponse réussite 200 au client
|
||||
}
|
||||
}
|
||||
@@ -9,27 +9,28 @@ public class DeleteEffectRequest
|
||||
}
|
||||
public class DeleteEffectEndpoint(PyroFetesDbContext pyrofetesdbcontext) : Endpoint<DeleteEffectRequest>
|
||||
{
|
||||
public override void Configure()
|
||||
public override void Configure() //Configuration de l'endpoint
|
||||
{
|
||||
Delete("/effects/{@id}", x => new { x.Id });
|
||||
Delete("Api/effects/{@id}", x => new { x.Id }); //Création d'un endpoint qui supprime un effet grâce à son id
|
||||
AllowAnonymous(); //Ignorer les requêtes non authentifiées
|
||||
}
|
||||
|
||||
public override async Task HandleAsync(DeleteEffectRequest req, CancellationToken ct)
|
||||
public override async Task HandleAsync(DeleteEffectRequest req, CancellationToken ct) //Méthode asynchrone qui traite la suppression de l'effet
|
||||
{
|
||||
Models.Effect? effectToDelete = await pyrofetesdbcontext
|
||||
.Effects
|
||||
.SingleOrDefaultAsync(a => a.Id == req.Id, cancellationToken: ct);
|
||||
Models.Effect? effectToDelete = await pyrofetesdbcontext //Récupère un effet dans la bdd et le stocke dans effectToDelete
|
||||
.Effects //Recherche la couleur dans la table Colors
|
||||
.SingleOrDefaultAsync(a => a.Id == req.Id, cancellationToken: ct); //Recherche un effet dont l'id correspond à req.Id
|
||||
|
||||
if (effectToDelete == null)
|
||||
if (effectToDelete == null) //Si l'effet n'est pas trouvé
|
||||
{
|
||||
Console.WriteLine($"Aucun effet avec l'ID {req.Id} trouvé.");
|
||||
await Send.NotFoundAsync(ct);
|
||||
return;
|
||||
Console.WriteLine($"Aucun effet avec l'ID {req.Id} trouvé."); //Afficher aucun effet avec l'id ... trouvé
|
||||
await Send.NotFoundAsync(ct); //Renvoie une erreur 404
|
||||
return; //Arrêt de la méthode
|
||||
}
|
||||
|
||||
pyrofetesdbcontext.Effects.Remove(effectToDelete);
|
||||
await pyrofetesdbcontext.SaveChangesAsync(ct);
|
||||
pyrofetesdbcontext.Effects.Remove(effectToDelete); //Supprime l'effet dans la bdd
|
||||
await pyrofetesdbcontext.SaveChangesAsync(ct); //Sauvegarde les changements effectués dans la bdd
|
||||
|
||||
await Send.NoContentAsync(ct);
|
||||
await Send.NoContentAsync(ct); //Renvoie une réponse réussite 204
|
||||
}
|
||||
}
|
||||
@@ -6,21 +6,22 @@ namespace PyroFetes.Endpoints.Effect;
|
||||
|
||||
public class GetAllEffectsEndpoint(PyroFetesDbContext pyrofetesdbcontext) : EndpointWithoutRequest<List<GetEffectDto>>
|
||||
{
|
||||
public override void Configure()
|
||||
public override void Configure() //Configuration de l'endpoint
|
||||
{
|
||||
Get("/effects");
|
||||
Get("Api/effects"); //Création d'un endpoint pour récupérer tous les effets grâce à la liste
|
||||
AllowAnonymous(); //Ignorer les requêtes non authentifiées
|
||||
}
|
||||
|
||||
public override async Task HandleAsync(CancellationToken ct)
|
||||
{
|
||||
List<GetEffectDto> responseDto = await pyrofetesdbcontext.Effects
|
||||
.Select(a => new GetEffectDto
|
||||
List<GetEffectDto> responseDto = await pyrofetesdbcontext.Effects //Création d'une liste qui récupère tous les effets de la bdd
|
||||
.Select(a => new GetEffectDto //Sélectionne dans la liste chaque effet
|
||||
{
|
||||
Id = a.Id,
|
||||
Label = a.Label,
|
||||
Id = a.Id, //Récupère l'id
|
||||
Label = a.Label, //Récupère le label
|
||||
}
|
||||
).ToListAsync(ct);
|
||||
).ToListAsync(ct); //Retourne la liste de effet
|
||||
|
||||
await Send.OkAsync(responseDto, ct);
|
||||
await Send.OkAsync(responseDto, ct); //Envoie de la réponse réussite 200 au client
|
||||
}
|
||||
}
|
||||
@@ -11,30 +11,31 @@ public class GetEffectRequest
|
||||
|
||||
public class GetEffectEndpoint(PyroFetesDbContext pyrofetesdbcontext) : Endpoint<GetEffectRequest, GetEffectDto>
|
||||
{
|
||||
public override void Configure()
|
||||
public override void Configure() //Configuration de l'endpoint
|
||||
{
|
||||
Get("/effects/{@id}", x => new { x.Id });
|
||||
Get("Api/effects/{@id}", x => new { x.Id }); //Création d'un endpoint qui récupère un effet grâce à son id
|
||||
AllowAnonymous(); //Ignorer les requêtes non authentifiées
|
||||
}
|
||||
|
||||
public override async Task HandleAsync(GetEffectRequest req, CancellationToken ct)
|
||||
public override async Task HandleAsync(GetEffectRequest req, CancellationToken ct) //Méthode asynchrone qui traite la récupération de l'effet
|
||||
{
|
||||
Models.Effect? effect = await pyrofetesdbcontext
|
||||
.Effects
|
||||
.SingleOrDefaultAsync(x => x.Id == req.Id, cancellationToken: ct);
|
||||
Models.Effect? effect = await pyrofetesdbcontext //Récupère un effet dans la bdd et le stocke dans effect
|
||||
.Effects //Recherche l'effet dans la table Effects
|
||||
.SingleOrDefaultAsync(x => x.Id == req.Id, cancellationToken: ct); //Recherche un effet dont l'id correspond à req.Id
|
||||
|
||||
if (effect == null)
|
||||
if (effect == null) //Si l'effet n'est pas trouvé
|
||||
{
|
||||
Console.WriteLine("Aucun effet avec l'ID {req.Id} trouvé.");
|
||||
await Send.NotFoundAsync(ct);
|
||||
return;
|
||||
Console.WriteLine("Aucun effet avec l'ID {req.Id} trouvé."); //Afficher aucun effet avec l'id ... trouvé
|
||||
await Send.NotFoundAsync(ct); //Renvoie une erreur 404
|
||||
return; //Arrêt de la méthode
|
||||
}
|
||||
|
||||
GetEffectDto responseDto = new()
|
||||
GetEffectDto responseDto = new() //Constuire l'objet de réponse pour retourner id et label à l'utilisateur
|
||||
{
|
||||
Id = effect.Id,
|
||||
Label = effect.Label,
|
||||
Id = effect.Id, //Affiche l'id lors de la réponse
|
||||
Label = effect.Label, //Affiche le label lors de la réponse
|
||||
};
|
||||
await Send.OkAsync(responseDto, ct);
|
||||
|
||||
await Send.OkAsync(responseDto, ct); //Envoie de la réponse réussite 200 au client
|
||||
|
||||
}
|
||||
}
|
||||
@@ -7,34 +7,32 @@ namespace PyroFetes.Endpoints.Effect;
|
||||
|
||||
public class UpdateEffectEndpoint(PyroFetesDbContext pyrofetesdbcontext) : Endpoint<UpdateEffectDto, GetEffectDto>
|
||||
{
|
||||
public override void Configure()
|
||||
public override void Configure() //Configuration de l'endpoint
|
||||
{
|
||||
Put("/effects/{@id}", x => new { x.Id });
|
||||
}
|
||||
Put("Api/effects/{@id}", x => new { x.Id }); //Création d'un endpoint qui modifie un effet grâce à son id
|
||||
AllowAnonymous(); //Ignorer les requêtes non authentifiées
|
||||
}
|
||||
|
||||
public override async Task HandleAsync(UpdateEffectDto req, CancellationToken ct)
|
||||
{
|
||||
Models.Effect? effectToEdit = await pyrofetesdbcontext
|
||||
.Effects
|
||||
.SingleOrDefaultAsync(x => x.Id == req.Id, cancellationToken: ct);
|
||||
Models.Effect? effectToEdit = await pyrofetesdbcontext //Récupère un effet dans la bdd et le stocke dans effectToEdit
|
||||
.Effects //Recherche l'effet dans la table Effects
|
||||
.SingleOrDefaultAsync(x => x.Id == req.Id, cancellationToken: ct); //Recherche un effet dont l'id correspond à req.Id
|
||||
|
||||
if (effectToEdit == null)
|
||||
if (effectToEdit == null) //Si l'effet n'est pas trouvé
|
||||
{
|
||||
Console.WriteLine("Aucun effet avec l'id {req.Id} trouvé.");
|
||||
await Send.NotFoundAsync(ct);
|
||||
return;
|
||||
|
||||
Console.WriteLine($"Aucun effet avec l'id {req.Id} trouvé."); //Afficher qu'aucun effet avec l'id ... n'a été trouvé
|
||||
await Send.NotFoundAsync(ct); //Renvoie une erreur 404
|
||||
return; //Arrêt de la méthode
|
||||
}
|
||||
effectToEdit.Label = req.Label;
|
||||
await pyrofetesdbcontext.SaveChangesAsync(ct);
|
||||
effectToEdit.Label = req.Label; //Modification du label de l'effet
|
||||
await pyrofetesdbcontext.SaveChangesAsync(ct); //Sauvegarde les changements effectués dans la base de données
|
||||
|
||||
GetEffectDto responseDto = new()
|
||||
GetEffectDto responseDto = new() //Construire l'objet de réponse pour retourner l'id et le label de l'effet modifié
|
||||
{
|
||||
Id = req.Id,
|
||||
Label = req.Label,
|
||||
Id = req.Id, //Inclut l'id dans la réponse
|
||||
Label = req.Label, //Inclut le label dans la réponse
|
||||
};
|
||||
await Send.OkAsync(responseDto, ct);
|
||||
|
||||
await Send.OkAsync(responseDto, ct); //Envoie une réponse 200 OK avec l'objet de réponse
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,53 +1,44 @@
|
||||
using FastEndpoints;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using PasswordGenerator;
|
||||
using PyroFetes.DTO.Login.Request;
|
||||
using PyroFetes.DTO.Login.Request;
|
||||
using PyroFetes.DTO.Login.Response;
|
||||
using PasswordGenerator;
|
||||
|
||||
namespace PyroFetes.Endpoints.Login;
|
||||
using FastEndpoints;
|
||||
|
||||
public class CreateLoginEndpoint(PyroFetesDbContext database) : Endpoint<CreateLoginDto, GetLoginDto>
|
||||
public class CreateLoginEndpoint(PyroFetesDbContext database) : Endpoint<CreateLoginDto, GetLoginDto> //Instanciation d'une connexion à la bdd dans un endpoint, utilise l'élément de requête CreateLoginDto et l'élement de réponse GetLoginDto
|
||||
{
|
||||
public override void Configure()
|
||||
public override void Configure() //Configuration de l'endpoint
|
||||
{
|
||||
Post("/logins");
|
||||
//Roles("Admin");
|
||||
AllowAnonymous();
|
||||
Post("/api/logins"); //Créer un login
|
||||
AllowAnonymous(); //Autorise l'accès sans authentification
|
||||
}
|
||||
|
||||
public override async Task HandleAsync(CreateLoginDto req, CancellationToken ct)
|
||||
{
|
||||
bool exists = await database.Users.AnyAsync(x => x.Name == req.Name, ct);
|
||||
if (exists)
|
||||
{
|
||||
AddError("Ce nom d'utilisateur est déjà utilisé.");
|
||||
await Send.ErrorsAsync(400, ct);
|
||||
return;
|
||||
}
|
||||
|
||||
string? salt = new Password().IncludeLowercase().IncludeUppercase().IncludeNumeric().LengthRequired(24).Next();
|
||||
|
||||
Models.User login = new Models.User()
|
||||
var login = new Models.Login() //Création d'un nom, prénom, mot de passe et un salt rentré par l'utilisateur
|
||||
{
|
||||
Name = req.Name,
|
||||
Email = req.Email,
|
||||
Username = req.Username,
|
||||
FullName = req.FullName,
|
||||
Password = BCrypt.Net.BCrypt.HashPassword(req.Password + salt),
|
||||
Salt = salt,
|
||||
|
||||
Fonction = string.IsNullOrEmpty(req.Fonction) ? "User" : req.Fonction
|
||||
Salt = salt
|
||||
};
|
||||
|
||||
database.Users.Add(login);
|
||||
await database.SaveChangesAsync(ct);
|
||||
database.Logins.Add(login); //Ajout du login à la bdd
|
||||
|
||||
GetLoginDto responseDto = new()
|
||||
await database.SaveChangesAsync(ct); //Sauvegarde du login dans la bdd
|
||||
// Pour renvoyer une erreur : Send.StringAsync("Le message d'erreur", 400);
|
||||
|
||||
GetLoginDto responseDto = new() //renvoie l'id, nom, prénom, mot de passe et un salt
|
||||
{
|
||||
Id = login.Id,
|
||||
Name = login.Name,
|
||||
Email = login.Email,
|
||||
Fonction = login.Fonction
|
||||
Username = login.Username,
|
||||
FullName = login.FullName,
|
||||
Password = login.Password,
|
||||
Salt = login.Salt
|
||||
};
|
||||
|
||||
await Send.OkAsync(responseDto, ct);
|
||||
await Send.OkAsync(responseDto, ct); //Réponse au client
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
using PyroFetes.DTO.Login.Request;
|
||||
using PyroFetes.DTO.Login.Response;
|
||||
using FastEndpoints;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
@@ -12,13 +14,12 @@ public class DeleteLoginEndpoint(PyroFetesDbContext database) : Endpoint<DeleteL
|
||||
{
|
||||
public override void Configure()
|
||||
{
|
||||
Delete("/logins/{@Id}", x => new {x.Id});
|
||||
AllowAnonymous();
|
||||
Delete("/api/logins/{@Id}", x => new {x.Id});
|
||||
}
|
||||
|
||||
public override async Task HandleAsync(DeleteLoginRequest req, CancellationToken ct)
|
||||
{
|
||||
Models.User? login = await database.Users.SingleOrDefaultAsync(x => x.Id == req.Id, ct);
|
||||
var login = await database.Logins.SingleOrDefaultAsync(x => x.Id == req.Id, ct);
|
||||
|
||||
if (login == null)
|
||||
{
|
||||
@@ -26,7 +27,7 @@ public class DeleteLoginEndpoint(PyroFetesDbContext database) : Endpoint<DeleteL
|
||||
return;
|
||||
}
|
||||
|
||||
database.Users.Remove(login);
|
||||
database.Logins.Remove(login);
|
||||
await database.SaveChangesAsync(ct);
|
||||
|
||||
await Send.NoContentAsync(ct);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using PyroFetes.DTO.Login.Response;
|
||||
using FastEndpoints;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using PyroFetes.DTO.Login.Response;
|
||||
using PyroFetes;
|
||||
|
||||
namespace PyroFetes.Endpoints.Login;
|
||||
|
||||
@@ -8,19 +9,19 @@ public class GetAllLoginEndpoint(PyroFetesDbContext database) : EndpointWithoutR
|
||||
{
|
||||
public override void Configure()
|
||||
{
|
||||
Get("/logins");
|
||||
AllowAnonymous();
|
||||
Get("/api/logins");
|
||||
}
|
||||
|
||||
public override async Task HandleAsync(CancellationToken ct)
|
||||
{
|
||||
List<GetLoginDto> logins = await database.Users
|
||||
var logins = await database.Logins
|
||||
.Select(login => new GetLoginDto()
|
||||
{
|
||||
Id = login.Id,
|
||||
Name = login.Name,
|
||||
Username = login.Username,
|
||||
FullName = login.FullName,
|
||||
Password = login.Password,
|
||||
Fonction = login.Fonction
|
||||
Salt = login.Salt
|
||||
})
|
||||
.ToListAsync(ct);
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using PyroFetes.DTO.Login.Response;
|
||||
using FastEndpoints;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using PyroFetes.DTO.Login.Response;
|
||||
|
||||
namespace PyroFetes.Endpoints.Login;
|
||||
|
||||
@@ -13,13 +13,12 @@ public class GetLoginEndpoint(PyroFetesDbContext database) : Endpoint<GetLoginRe
|
||||
{
|
||||
public override void Configure()
|
||||
{
|
||||
Get("/logins/{@Id}", x => new {x.Id});
|
||||
AllowAnonymous();
|
||||
Get("/api/logins/{@Id}", x => new {x.Id});
|
||||
}
|
||||
|
||||
public override async Task HandleAsync(GetLoginRequest req, CancellationToken ct)
|
||||
{
|
||||
Models.User? login = await database.Users
|
||||
var login = await database.Logins
|
||||
.SingleOrDefaultAsync(x => x.Id == req.Id, ct);
|
||||
|
||||
if (login == null)
|
||||
@@ -31,8 +30,10 @@ public class GetLoginEndpoint(PyroFetesDbContext database) : Endpoint<GetLoginRe
|
||||
GetLoginDto responseDto = new()
|
||||
{
|
||||
Id = login.Id,
|
||||
Name = login.Name,
|
||||
Fonction = login.Fonction
|
||||
Username = login.Username,
|
||||
FullName = login.FullName,
|
||||
Password = login.Password,
|
||||
Salt = login.Salt
|
||||
};
|
||||
|
||||
await Send.OkAsync(responseDto, ct);
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
using PyroFetes.DTO.Login.Request;
|
||||
using PyroFetes.DTO.Login.Response;
|
||||
using FastEndpoints;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using PasswordGenerator;
|
||||
using PyroFetes.DTO.Login.Request;
|
||||
using PyroFetes.DTO.Login.Response;
|
||||
|
||||
namespace PyroFetes.Endpoints.Login;
|
||||
|
||||
@@ -10,13 +10,12 @@ public class UpdateLoginEndpoint(PyroFetesDbContext database) : Endpoint<UpdateL
|
||||
{
|
||||
public override void Configure()
|
||||
{
|
||||
Put("/logins/{@Id}", x => new {x.Id});
|
||||
AllowAnonymous();
|
||||
Put("/api/logins/{@Id}", x => new {x.Id});
|
||||
}
|
||||
|
||||
public override async Task HandleAsync(UpdateLoginDto req, CancellationToken ct)
|
||||
{
|
||||
Models.User? login = await database.Users.SingleOrDefaultAsync(x => x.Id == req.Id, ct);
|
||||
var login = await database.Logins.SingleOrDefaultAsync(x => x.Id == req.Id, ct);
|
||||
|
||||
if (login == null)
|
||||
{
|
||||
@@ -26,7 +25,8 @@ public class UpdateLoginEndpoint(PyroFetesDbContext database) : Endpoint<UpdateL
|
||||
|
||||
string? salt = new Password().IncludeLowercase().IncludeUppercase().IncludeNumeric().LengthRequired(24).Next();
|
||||
|
||||
login.Name = req.Name;
|
||||
login.Username = req.Username;
|
||||
login.FullName = req.FullName;
|
||||
login.Password = BCrypt.Net.BCrypt.HashPassword(req.Password + salt);
|
||||
login.Salt = salt;
|
||||
await database.SaveChangesAsync(ct);
|
||||
@@ -34,8 +34,10 @@ public class UpdateLoginEndpoint(PyroFetesDbContext database) : Endpoint<UpdateL
|
||||
GetLoginDto responseDto = new()
|
||||
{
|
||||
Id = login.Id,
|
||||
Name = login.Name,
|
||||
Fonction = login.Fonction
|
||||
Username = login.Username,
|
||||
FullName = login.FullName,
|
||||
Password = login.Password,
|
||||
Salt = login.Salt
|
||||
};
|
||||
|
||||
await Send.OkAsync(responseDto, ct);
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
using FastEndpoints;
|
||||
using PyroFetes.DTO.Login.Request;
|
||||
using FastEndpoints.Security;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using PyroFetes.DTO.Login.Request;
|
||||
using PyroFetes.DTO.Login.Response;
|
||||
using FastEndpoints;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using PyroFetes;
|
||||
|
||||
namespace PyroFetes.Endpoints.Login;
|
||||
|
||||
@@ -10,13 +11,13 @@ public class UserLoginEndpoint(PyroFetesDbContext database) : Endpoint<ConnectLo
|
||||
{
|
||||
public override void Configure()
|
||||
{
|
||||
Post("/login");
|
||||
Post("/api/login");
|
||||
AllowAnonymous();
|
||||
}
|
||||
|
||||
public override async Task HandleAsync(ConnectLoginDto req, CancellationToken ct)
|
||||
{
|
||||
Models.User? login = await database.Users.SingleOrDefaultAsync(x => x.Name == req.Name, ct);
|
||||
var login = await database.Logins.SingleOrDefaultAsync(x => x.Username == req.Username, ct);
|
||||
|
||||
if (login == null)
|
||||
{
|
||||
@@ -26,13 +27,14 @@ public class UserLoginEndpoint(PyroFetesDbContext database) : Endpoint<ConnectLo
|
||||
|
||||
if (BCrypt.Net.BCrypt.Verify(req.Password + login.Salt, login.Password))
|
||||
{
|
||||
string jwtToken = JwtBearer.CreateToken(
|
||||
var jwtToken = JwtBearer.CreateToken(
|
||||
o =>
|
||||
{
|
||||
o.SigningKey = "ThisIsASuperSecretJwtKeyThatIsAtLeast32CharsLong";
|
||||
o.ExpireAt = DateTime.UtcNow.AddMinutes(15);
|
||||
if (login.Fonction != null) o.User.Roles.Add(login.Fonction);
|
||||
o.User.Claims.Add(("Username", login.Name)!);
|
||||
if (login.Role != null) o.User.Roles.Add(login.Role);
|
||||
o.User.Claims.Add(("Username", login.Username)!);
|
||||
o.User.Claims.Add(("FullName", login.FullName)!);
|
||||
o.User["UserId"] = "001";
|
||||
});
|
||||
|
||||
|
||||
@@ -4,33 +4,34 @@ using FastEndpoints;
|
||||
|
||||
namespace PyroFetes.Endpoints.Material;
|
||||
|
||||
public class CreateMaterialEndpoint(PyroFetesDbContext pyrofetesdbcontext) : Endpoint<CreateMaterialDto, GetMaterialDto>
|
||||
public class CreateMaterialEndpoint(PyroFetesDbContext pyrofetesdbcontext) : Endpoint<CreateMaterialDto, GetMaterialDto> //Instanciation d'une connexion à la bdd dans un endpoint, utilise l'élément de requête CreateMaterialDto et l'élement de réponse GetMaterialDto
|
||||
{
|
||||
public override void Configure()
|
||||
public override void Configure() //Configuration de l'endpoint
|
||||
{
|
||||
Post("/materials");
|
||||
Post("Api/materials"); //Créer un matériel
|
||||
AllowAnonymous();//Autorise l'accès sans authentification
|
||||
}
|
||||
|
||||
public override async Task HandleAsync(CreateMaterialDto req, CancellationToken ct)
|
||||
{
|
||||
Models.Material quantity = new()
|
||||
Models.Material quantity = new() //Création d'un nom, quantité et liaison de l'id de l'entrepôt rentré par l'utilisateur
|
||||
{
|
||||
Name = req.Label,
|
||||
Quantity = req.Quantity,
|
||||
WarehouseId = req.WarehouseId,
|
||||
};
|
||||
|
||||
pyrofetesdbcontext.Materials.Add(quantity);
|
||||
await pyrofetesdbcontext.SaveChangesAsync(ct);
|
||||
Console.WriteLine("Material added");
|
||||
pyrofetesdbcontext.Materials.Add(quantity); //Ajoute quantity à la bdd
|
||||
await pyrofetesdbcontext.SaveChangesAsync(ct); //Sauvegarde les changements effectués dans la bdd
|
||||
Console.WriteLine("Material added"); //Affiche Material Added si réussi
|
||||
|
||||
GetMaterialDto responseDto = new()
|
||||
GetMaterialDto responseDto = new() //Constuire l'objet de réponse pour retourner name, quantity et warehouseId à l'utilisateur
|
||||
{
|
||||
Id = quantity.Id,
|
||||
WarehouseId = quantity.WarehouseId,
|
||||
Label = req.Label,
|
||||
Id = quantity.Id, //Affiche l'id lors de la réponse
|
||||
WarehouseId = quantity.WarehouseId, //Affiche le label lors de la réponse
|
||||
Label = req.Label, //Affiche le label lors de la réponse
|
||||
};
|
||||
|
||||
await Send.OkAsync(responseDto, ct);
|
||||
await Send.OkAsync(responseDto, ct); //Envoie de la réponse réussite 200 au client
|
||||
}
|
||||
}
|
||||
@@ -2,33 +2,34 @@ using FastEndpoints;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace PyroFetes.Endpoints.Material;
|
||||
public class DeleteMaterialRequest
|
||||
public class DeleteMaterialRequest //Création d'une classe DeleteMaterialRequest
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public int Id { get; set; } //Création d'un Id
|
||||
}
|
||||
public class DeleteMaterialEndpoint(PyroFetesDbContext pyrofetesdbcontext) : Endpoint<DeleteMaterialRequest>
|
||||
{
|
||||
public override void Configure()
|
||||
public override void Configure() //Configuration de l'endpoint
|
||||
{
|
||||
Delete("/materials/{@id}", x => new { x.Id });
|
||||
Delete("Api/materials/{@id}", x => new { x.Id }); //Création d'un endpoint qui supprime un matériel grâce à son id
|
||||
AllowAnonymous(); //Ignorer les requêtes non authentifiées
|
||||
}
|
||||
|
||||
public override async Task HandleAsync(DeleteMaterialRequest req, CancellationToken ct)
|
||||
public override async Task HandleAsync(DeleteMaterialRequest req, CancellationToken ct) //Méthode asynchrone qui traite la suppression du matériel
|
||||
{
|
||||
Models.Material? materialToDelete = await pyrofetesdbcontext
|
||||
.Materials
|
||||
.SingleOrDefaultAsync(a => a.Id == req.Id, cancellationToken: ct);
|
||||
Models.Material? materialToDelete = await pyrofetesdbcontext //Récupère un matériel dans la bdd et le stocke dans materialToDelete
|
||||
.Materials //Recherche la couleur dans la table Colors
|
||||
.SingleOrDefaultAsync(a => a.Id == req.Id, cancellationToken: ct); //Recherche un matériel dont l'id correspond à req.Id
|
||||
|
||||
if (materialToDelete == null)
|
||||
if (materialToDelete == null) //Si le matériel n'est pas trouvé
|
||||
{
|
||||
Console.WriteLine($"Aucun matériel avec l'ID {req.Id} trouvé.");
|
||||
await Send.NotFoundAsync(ct);
|
||||
return;
|
||||
}
|
||||
Console.WriteLine($"Aucun matériel avec l'ID {req.Id} trouvé."); //Afficher aucun matériel avec l'id ... trouvé
|
||||
await Send.NotFoundAsync(ct); //Renvoie une erreur 404
|
||||
return; //Arrêt de la méthode
|
||||
}
|
||||
|
||||
pyrofetesdbcontext.Materials.Remove(materialToDelete);
|
||||
await pyrofetesdbcontext.SaveChangesAsync(ct);
|
||||
pyrofetesdbcontext.Materials.Remove(materialToDelete); //Supprime le matériel dans la bdd
|
||||
await pyrofetesdbcontext.SaveChangesAsync(ct); //Sauvegarde les changements effectués dans la bdd
|
||||
|
||||
await Send.NoContentAsync(ct);
|
||||
await Send.NoContentAsync(ct); //Renvoie une réponse réussite 204
|
||||
}
|
||||
}
|
||||
@@ -6,22 +6,23 @@ namespace PyroFetes.Endpoints.Material;
|
||||
|
||||
public class GetAllMaterialsEndpoint(PyroFetesDbContext pyrofetesdbcontext) : EndpointWithoutRequest<List<GetMaterialDto>>
|
||||
{
|
||||
public override void Configure()
|
||||
public override void Configure() //Configuration de l'endpoint
|
||||
{
|
||||
Get("/materials");
|
||||
Get("Api/materials"); //Création d'un endpoint pour récupérer tous les matériaux grâce à la liste
|
||||
AllowAnonymous(); //Ignorer les requêtes non authentifiées
|
||||
}
|
||||
|
||||
public override async Task HandleAsync(CancellationToken ct)
|
||||
{
|
||||
List<GetMaterialDto> responseDto = await pyrofetesdbcontext.Materials
|
||||
.Select(a => new GetMaterialDto
|
||||
List<GetMaterialDto> responseDto = await pyrofetesdbcontext.Materials //Création d'une liste qui récupère tous les matériaux de la bdd
|
||||
.Select(a => new GetMaterialDto //Sélectionne dans la liste chaque matériel
|
||||
{
|
||||
Id = a.Id,
|
||||
Label = a.Name,
|
||||
Quantity = a.Quantity,
|
||||
WarehouseId = a.WarehouseId,
|
||||
Id = a.Id, //Récupère l'id
|
||||
Label = a.Name, //Récupère le label
|
||||
Quantity = a.Quantity, //Récupère la quantité
|
||||
WarehouseId = a.WarehouseId, //Récupère l'id de l'entrepot
|
||||
}
|
||||
).ToListAsync(ct);
|
||||
await Send.OkAsync(responseDto, ct);
|
||||
).ToListAsync(ct); //Retourne la liste du matériel
|
||||
await Send.OkAsync(responseDto, ct); //Envoie de la réponse réussite 200 au client
|
||||
}
|
||||
}
|
||||
@@ -11,31 +11,32 @@ public class GetMaterialRequest
|
||||
|
||||
public class GetMaterialEndpoint(PyroFetesDbContext pyrofetesdbcontext) : Endpoint<GetMaterialRequest, GetMaterialDto>
|
||||
{
|
||||
public override void Configure()
|
||||
public override void Configure() //Configuration de l'endpoint
|
||||
{
|
||||
Get("/materials/{@id}", x => new { x.Id });
|
||||
Get("Api/materials/{@id}", x => new { x.Id }); //Création d'un endpoint qui récupère un matériel grâce à son id
|
||||
AllowAnonymous(); //Ignorer les requêtes non authentifiées
|
||||
}
|
||||
|
||||
public override async Task HandleAsync(GetMaterialRequest req, CancellationToken ct)
|
||||
public override async Task HandleAsync(GetMaterialRequest req, CancellationToken ct) //Méthode asynchrone qui traite la récupération du matériel
|
||||
{
|
||||
Models.Material? material = await pyrofetesdbcontext
|
||||
.Materials
|
||||
.SingleOrDefaultAsync(x => x.Id == req.Id, cancellationToken: ct);
|
||||
Models.Material? material = await pyrofetesdbcontext //Récupère un matériel dans la bdd et le stocke dans material
|
||||
.Materials //Recherche le matériel dans la table Materials
|
||||
.SingleOrDefaultAsync(x => x.Id == req.Id, cancellationToken: ct); //Recherche un matériel dont l'id correspond à req.Id
|
||||
|
||||
if (material == null)
|
||||
if (material == null) //Si le matériel n'est pas trouvé
|
||||
{
|
||||
Console.WriteLine("Aucun matériel avec l'ID {req.Id} trouvé.");
|
||||
await Send.NotFoundAsync(ct);
|
||||
return;
|
||||
Console.WriteLine("Aucun matériel avec l'ID {req.Id} trouvé."); //Afficher aucun matériel avec l'id ... trouvé
|
||||
await Send.NotFoundAsync(ct); //Renvoie une erreur 404
|
||||
return; //Arrêt de la méthode
|
||||
}
|
||||
|
||||
GetMaterialDto responseDto = new()
|
||||
GetMaterialDto responseDto = new() //Constuire l'objet de réponse pour retourner id, label et warehouseId à l'utilisateur
|
||||
{
|
||||
Id = material.Id,
|
||||
Label = material.Name,
|
||||
WarehouseId = material.WarehouseId,
|
||||
Id = material.Id, //Affiche l'id lors de la réponse
|
||||
Label = material.Name, //Affiche le label lors de la réponse
|
||||
WarehouseId = material.WarehouseId, //Affiche warehouseId lors de la réponse
|
||||
};
|
||||
await Send.OkAsync(responseDto, ct);
|
||||
await Send.OkAsync(responseDto, ct); //Envoie de la réponse réussite 200 au client
|
||||
|
||||
}
|
||||
}
|
||||
@@ -7,35 +7,36 @@ namespace PyroFetes.Endpoints.Material;
|
||||
|
||||
public class UpdateMaterialEndpoint(PyroFetesDbContext pyrofetesdbcontext) : Endpoint<UpdateMaterialDto, GetMaterialDto>
|
||||
{
|
||||
public override void Configure()
|
||||
public override void Configure() //Configuration de l'endpoint
|
||||
{
|
||||
Put("/materials/{@id}", x => new { x.Id });
|
||||
Put("Api/materials/{@id}", x => new { x.Id }); //Création d'un endpoint qui modifie le matériel grâce à son id
|
||||
AllowAnonymous(); //Ignorer les requêtes non authentifiées
|
||||
}
|
||||
|
||||
public override async Task HandleAsync(UpdateMaterialDto req, CancellationToken ct)
|
||||
{
|
||||
Models.Material? materialToEdit = await pyrofetesdbcontext
|
||||
.Materials
|
||||
.SingleOrDefaultAsync(x => x.Id == req.Id, cancellationToken: ct);
|
||||
Models.Material? materialToEdit = await pyrofetesdbcontext //Récupère un matériel dans la bdd et le stocke dans materialToEdit
|
||||
.Materials //Recherche le matériel dans la table Materials
|
||||
.SingleOrDefaultAsync(x => x.Id == req.Id, cancellationToken: ct);//Recherche un matériel dont l'id correspond à req.Id
|
||||
|
||||
if (materialToEdit == null)
|
||||
if (materialToEdit == null) //Si le matériel n'est pas trouvé
|
||||
{
|
||||
Console.WriteLine("Aucun matériel avec l'id {req.Id} trouvé.");
|
||||
await Send.NotFoundAsync(ct);
|
||||
return;
|
||||
Console.WriteLine("Aucun matériel avec l'id {req.Id} trouvé."); //Afficher aucun matériel avec l'id ... trouvé
|
||||
await Send.NotFoundAsync(ct); //Renvoie une erreur 404
|
||||
return; //Arrêt de la méthode
|
||||
|
||||
}
|
||||
materialToEdit.Name = req.Label;
|
||||
materialToEdit.WarehouseId = req.WarehouseId;
|
||||
await pyrofetesdbcontext.SaveChangesAsync(ct);
|
||||
materialToEdit.Name = req.Label; //Modification du label
|
||||
materialToEdit.WarehouseId = req.WarehouseId; //Modification de warehouseId
|
||||
await pyrofetesdbcontext.SaveChangesAsync(ct); //Sauvegarde les changements effectués dans la bdd
|
||||
|
||||
GetMaterialDto responseDto = new()
|
||||
GetMaterialDto responseDto = new() //Constuire l'objet de réponse pour retourner l'id, le label et warehouseId du nouveau matériel
|
||||
{
|
||||
Id = req.Id,
|
||||
Label = req.Label,
|
||||
WarehouseId = req.WarehouseId,
|
||||
Id = req.Id, //Affiche l'id
|
||||
Label = req.Label, //Affiche le label
|
||||
WarehouseId = req.WarehouseId, //Affiche warehouseId
|
||||
};
|
||||
await Send.OkAsync(responseDto, ct);
|
||||
await Send.OkAsync(responseDto, ct); //Envoie de la réponse réussite 200 au client
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,43 +1,41 @@
|
||||
using API.DTO.Movement.Request;
|
||||
using API.DTO.Movement.Response;
|
||||
using FastEndpoints;
|
||||
using PyroFetes.DTO.Movement.Request;
|
||||
|
||||
namespace PyroFetes.Endpoints.Movement;
|
||||
|
||||
public class CreateMovementEndpoint(PyroFetesDbContext pyrofetesdbcontext) : Endpoint<CreateMovementDto, GetMovementDto>
|
||||
public class CreateMovementEndpoint(PyroFetesDbContext pyrofetesdbcontext) : Endpoint<CreateMovementDto, GetMovementDto> //Instanciation d'une connexion à la bdd dans un endpoint, utilise l'élément de requête CreateMovementDto et l'élement de réponse GetMovementDto
|
||||
{
|
||||
public override void Configure()
|
||||
public override void Configure() //Configuration de l'endpoint
|
||||
{
|
||||
Post("/movements");
|
||||
Post("/api/movements"); //Créer un mouvement
|
||||
AllowAnonymous(); //Autorise l'accès sans authentification
|
||||
}
|
||||
|
||||
public override async Task HandleAsync(CreateMovementDto req, CancellationToken ct)
|
||||
{
|
||||
|
||||
Models.Movement movement = new ()
|
||||
{
|
||||
Date = req.Date,
|
||||
ProductId = req.ProductId,
|
||||
Start = req.Start,
|
||||
Arrival = req.Arrival,
|
||||
Quantity = req.Quantity,
|
||||
Type = req.Type,
|
||||
};
|
||||
|
||||
pyrofetesdbcontext.Movements.Add(movement);
|
||||
await pyrofetesdbcontext.SaveChangesAsync(ct);
|
||||
|
||||
Console.WriteLine("Movement créée avec succès !");
|
||||
|
||||
GetMovementDto responseDto = new ()
|
||||
Models.Movement movement = new () //Création d'une date, d'une date de départ, d'arrivée et d'une quantité rentré par l'utilisateur
|
||||
{
|
||||
Date = req.Date,
|
||||
Start = req.Start,
|
||||
Arrival = req.Arrival,
|
||||
Quantity = req.Quantity
|
||||
};
|
||||
|
||||
pyrofetesdbcontext.Movements.Add(movement); //Ajoute movement à la bdd
|
||||
await pyrofetesdbcontext.SaveChangesAsync(ct); //Sauvegarde les changements effectués dans la bdd
|
||||
|
||||
Console.WriteLine("Movement créée avec succès !"); //Affiche Movement créée avec succès ! si réussi
|
||||
|
||||
await Send.OkAsync(responseDto, ct);
|
||||
GetMovementDto responseDto = new () //Constuire l'objet de réponse pour retourner les informations à l'utilisateur
|
||||
{
|
||||
Date = req.Date, //Affiche date lors de la réponse
|
||||
Start = req.Start, //Affiche start lors de la réponse
|
||||
Arrival = req.Arrival, //Affiche arrival lors de la réponse
|
||||
Quantity = req.Quantity //Affiche quantity lors de la réponse
|
||||
};
|
||||
|
||||
await Send.OkAsync(responseDto, ct); //Envoie de la réponse réussite 200 au client
|
||||
}
|
||||
}
|
||||
@@ -3,35 +3,36 @@ using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace PyroFetes.Endpoints.Movement;
|
||||
|
||||
public class DeleteMovementRequest
|
||||
public class DeleteMovementRequest //Création d'une classe DeleteMovementRequest
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public int Id { get; set; } //Création d'un Id
|
||||
}
|
||||
|
||||
public class DeleteMovementEndpoint(PyroFetesDbContext pyrofetesdbcontext) : Endpoint<DeleteMovementRequest>
|
||||
{
|
||||
public override void Configure()
|
||||
public override void Configure() //Configuration de l'endpoint
|
||||
{
|
||||
Delete("/Movements/{@id}", x => new { x.Id });
|
||||
Delete("/api/Movements/{@id}", x => new { x.Id }); //Création d'un endpoint qui supprime un mouvement grâce à son id
|
||||
AllowAnonymous(); //Ignorer les requêtes non authentifiées
|
||||
}
|
||||
|
||||
public override async Task HandleAsync(DeleteMovementRequest req, CancellationToken ct)
|
||||
public override async Task HandleAsync(DeleteMovementRequest req, CancellationToken ct) //Méthode asynchrone qui traite la suppression du mouvement
|
||||
{
|
||||
|
||||
Models.Movement? movementToDelete = await pyrofetesdbcontext
|
||||
.Movements
|
||||
.SingleOrDefaultAsync(a => a.Id == req.Id, cancellationToken: ct);
|
||||
Models.Movement? movementToDelete = await pyrofetesdbcontext //Récupère un mouvement dans la bdd et le stocke dans movementToDelete
|
||||
.Movements //Recherche le mouvement dans la table Movements
|
||||
.SingleOrDefaultAsync(a => a.Id == req.Id, cancellationToken: ct);//Recherche une mouvement dont l'id correspond à req.Id
|
||||
|
||||
if (movementToDelete == null)
|
||||
if (movementToDelete == null) //Si le mouvement n'est pas trouvé
|
||||
{
|
||||
Console.WriteLine($"Aucune mouvement avec l'ID {req.Id} trouvé.");
|
||||
await Send.NotFoundAsync(ct);
|
||||
return;
|
||||
Console.WriteLine($"Aucune mouvement avec l'ID {req.Id} trouvé."); //Affiche aucun mouvement avec l'id ... trouvé
|
||||
await Send.NotFoundAsync(ct); //Renvoie une erreur 404
|
||||
return; //Arrêt de la méthode
|
||||
}
|
||||
|
||||
pyrofetesdbcontext.Movements.Remove(movementToDelete);
|
||||
await pyrofetesdbcontext.SaveChangesAsync(ct);
|
||||
pyrofetesdbcontext.Movements.Remove(movementToDelete); //Supprime le mouvement dans la bdd
|
||||
await pyrofetesdbcontext.SaveChangesAsync(ct); //Sauvegarde les changements effectués dans la bdd
|
||||
|
||||
await Send.NoContentAsync(ct);
|
||||
await Send.NoContentAsync(ct); //Renvoie une réponse réussite 204
|
||||
}
|
||||
}
|
||||
@@ -6,25 +6,26 @@ namespace PyroFetes.Endpoints.Movement;
|
||||
|
||||
public class GetAllMovementsEndpoint(PyroFetesDbContext pyrofetesdbcontext) : EndpointWithoutRequest<List<GetMovementDto>>
|
||||
{
|
||||
public override void Configure()
|
||||
public override void Configure() //Configuration de l'endpoint
|
||||
{
|
||||
Get("/movements");
|
||||
Get("/api/movements"); //Création d'un endpoint pour récupérer tous les mouvements grâce à la liste
|
||||
AllowAnonymous(); //Ignorer les requêtes non authentifiées
|
||||
}
|
||||
|
||||
public override async Task HandleAsync(CancellationToken ct)
|
||||
{
|
||||
|
||||
List<GetMovementDto> responseDto = await pyrofetesdbcontext.Movements
|
||||
.Select(a => new GetMovementDto
|
||||
List<GetMovementDto> responseDto = await pyrofetesdbcontext.Movements //Création d'une liste qui récupère tous les mouvements de la bdd
|
||||
.Select(a => new GetMovementDto //Sélectionne dans la liste chaque mouvement
|
||||
{
|
||||
Id = a.Id,
|
||||
Date = a.Date,
|
||||
Start = a.Start,
|
||||
Arrival = a.Arrival,
|
||||
Quantity = a.Quantity
|
||||
Id = a.Id, //Récupère l'id
|
||||
Date = a.Date, //Récupère la date
|
||||
Start = a.Start, //Récupère start
|
||||
Arrival = a.Arrival, //Récupère arrival
|
||||
Quantity = a.Quantity //Récupère quantity
|
||||
}
|
||||
).ToListAsync(ct);
|
||||
).ToListAsync(ct); //Retourne la liste de mouvement
|
||||
|
||||
await Send.OkAsync(responseDto, ct);
|
||||
await Send.OkAsync(responseDto, ct); //Envoie de la réponse réussite 200 au client
|
||||
}
|
||||
}
|
||||
@@ -11,34 +11,35 @@ public class GetMovementRequest
|
||||
|
||||
public class GetMovementEndpoint(PyroFetesDbContext pyrofetesdbcontext) :Endpoint<GetMovementRequest, GetMovementDto>
|
||||
{
|
||||
public override void Configure()
|
||||
public override void Configure() //Configuration de l'endpoint
|
||||
{
|
||||
Get("/movements/{@id}", x => new { x.Id });
|
||||
Get("/api/movements/{@id}", x => new { x.Id }); //Création d'un endpoint qui récupère un mouvement grâce à son id
|
||||
AllowAnonymous(); //Ignorer les requêtes non authentifiées
|
||||
}
|
||||
|
||||
public override async Task HandleAsync(GetMovementRequest req, CancellationToken ct)
|
||||
public override async Task HandleAsync(GetMovementRequest req, CancellationToken ct) //Méthode asynchrone qui traite la récupération du mouvement
|
||||
{
|
||||
|
||||
Models.Movement? movement = await pyrofetesdbcontext
|
||||
.Movements
|
||||
.SingleOrDefaultAsync(a => a.Id == req.Id, cancellationToken: ct);
|
||||
Models.Movement? movement = await pyrofetesdbcontext //Récupère un mouvement dans la bdd et le stocke dans movement
|
||||
.Movements //Recherche la couleur dans la table Movements
|
||||
.SingleOrDefaultAsync(a => a.Id == req.Id, cancellationToken: ct);//Recherche un mouvement dont l'id correspond à req.Id
|
||||
|
||||
if (movement == null)
|
||||
if (movement == null) //Si le mouvement n'est pas trouvé
|
||||
{
|
||||
Console.WriteLine($"Aucun mouvement avec l'ID {req.Id} trouvé.");
|
||||
await Send.NotFoundAsync(ct);
|
||||
return;
|
||||
Console.WriteLine($"Aucun mouvement avec l'ID {req.Id} trouvé."); //Affiche aucun mouvement avec l'id ... trouvé
|
||||
await Send.NotFoundAsync(ct); //Renvoie une erreur 404
|
||||
return; //Arrêt de la méthode
|
||||
}
|
||||
|
||||
GetMovementDto responseDto = new()
|
||||
GetMovementDto responseDto = new() //Constuire l'objet de réponse pour retourner les informations à l'utilisateur
|
||||
{
|
||||
Id = req.Id,
|
||||
Date = movement.Date,
|
||||
Start = movement.Start,
|
||||
Arrival = movement.Arrival,
|
||||
Quantity = movement.Quantity
|
||||
Id = req.Id, //Affiche l'id lors de la réponse
|
||||
Date = movement.Date, //Affiche date lors de la réponse
|
||||
Start = movement.Start, //Affiche start lors de la réponse
|
||||
Arrival = movement.Arrival, //Affiche arrival lors de la réponse
|
||||
Quantity = movement.Quantity //Affiche quantity lors de la réponse
|
||||
};
|
||||
|
||||
await Send.OkAsync(responseDto, ct);
|
||||
await Send.OkAsync(responseDto, ct); //Envoie de la réponse réussite 200 au client
|
||||
}
|
||||
}
|
||||
@@ -6,25 +6,26 @@ namespace PyroFetes.Endpoints.Movement;
|
||||
|
||||
public class UpdateMovementEndpoint(PyroFetesDbContext pyrofetesdbcontext) : Endpoint<UpdateMovementDto, GetMovementDto>
|
||||
{
|
||||
public override void Configure()
|
||||
public override void Configure() //Configuration de l'endpoint
|
||||
{
|
||||
Put("/movements");
|
||||
Put("/api/movements"); //Création d'un endpoint qui modifie le mouvement grâce à son id
|
||||
AllowAnonymous(); //Ignorer les requêtes non authentifiées
|
||||
}
|
||||
|
||||
public override async Task HandleAsync(UpdateMovementDto req, CancellationToken ct)
|
||||
{
|
||||
|
||||
Models.Movement movement = new()
|
||||
Models.Movement movement = new()
|
||||
{
|
||||
Date = req.Date,
|
||||
Start = req.Start,
|
||||
Arrival = req.Arrival,
|
||||
Quantity = req.Quantity
|
||||
};
|
||||
pyrofetesdbcontext.Add(movement);
|
||||
await pyrofetesdbcontext.SaveChangesAsync(ct);
|
||||
pyrofetesdbcontext.Add(movement); //Modification du mouvement
|
||||
await pyrofetesdbcontext.SaveChangesAsync(ct); //Sauvegarde les changements effectués dans la bdd
|
||||
|
||||
GetMovementDto response = new()
|
||||
GetMovementDto response = new() //Constuire l'objet de réponse pour retourner les informations du mouvement
|
||||
{
|
||||
Id = req.Id,
|
||||
Date = req.Date,
|
||||
@@ -33,7 +34,7 @@ public class UpdateMovementEndpoint(PyroFetesDbContext pyrofetesdbcontext) : End
|
||||
Quantity = req.Quantity
|
||||
};
|
||||
|
||||
await Send.OkAsync(response, ct);
|
||||
await Send.OkAsync(response, ct); //Envoie de la réponse réussite 200 au client
|
||||
|
||||
}
|
||||
}
|
||||
@@ -7,18 +7,19 @@ using PyroFetes.Models;
|
||||
namespace PyroFetes.Endpoints.Product;
|
||||
|
||||
public class CreateProductEndpoint(PyroFetesDbContext db)
|
||||
: Endpoint<CreateProductDto, GetProductDto>
|
||||
: Endpoint<CreateProductDto, GetProductDto> //Instanciation d'une connexion à la bdd dans un endpoint, utilise l'élément de requête CreateProductDto et l'élement de réponse GetProductDto
|
||||
{
|
||||
public override void Configure()
|
||||
public override void Configure() //Configuration de l'endpoint
|
||||
{
|
||||
Post("/products");
|
||||
Post("/api/products"); //Créer un produit
|
||||
AllowAnonymous(); //Autorise l'accès sans authentification
|
||||
}
|
||||
|
||||
public override async Task HandleAsync(CreateProductDto req, CancellationToken ct)
|
||||
{
|
||||
var product = new Models.Product
|
||||
var product = new Models.Product //Création d'un nom, référence, durée, calibre, numéro d'aprovisionnement, poids, nec, image, lien, liaison de la catégorie du produit et de la classification rentré par l'utilisateur
|
||||
{
|
||||
Reference = req.Reference,
|
||||
Reference = req.References.ToString(),
|
||||
Name = req.Name!,
|
||||
Duration = req.Duration,
|
||||
Caliber = req.Caliber,
|
||||
@@ -28,11 +29,11 @@ public class CreateProductEndpoint(PyroFetesDbContext db)
|
||||
Image = req.Image!,
|
||||
Link = req.Link!,
|
||||
ProductCategoryId = req.ProductCategoryId,
|
||||
ClassificationId = req.ClassificationId,
|
||||
ClassificationId = req.ClassificationId
|
||||
};
|
||||
|
||||
db.Products.Add(product);
|
||||
await db.SaveChangesAsync(ct);
|
||||
db.Products.Add(product); //Ajout du produit à la bdd
|
||||
await db.SaveChangesAsync(ct); //Sauvegarde du produit dans la bdd
|
||||
|
||||
// Ajout des fournisseurs liés
|
||||
if (req.Suppliers is not null && req.Suppliers.Any())
|
||||
@@ -45,9 +46,9 @@ public class CreateProductEndpoint(PyroFetesDbContext db)
|
||||
SupplierId = s.SupplierId,
|
||||
SellingPrice = s.SellingPrice
|
||||
};
|
||||
db.Prices.Add(price);
|
||||
db.Prices.Add(price); //Ajout du prix à la bdd
|
||||
}
|
||||
await db.SaveChangesAsync(ct);
|
||||
await db.SaveChangesAsync(ct); //Sauvegarde du produit dans la bdd
|
||||
}
|
||||
|
||||
// Ajout des entrepôts liés
|
||||
@@ -65,16 +66,16 @@ public class CreateProductEndpoint(PyroFetesDbContext db)
|
||||
WarehouseId = w.WarehouseId,
|
||||
Quantity = w.Quantity
|
||||
};
|
||||
db.WarehouseProducts.Add(warehouseProduct);
|
||||
db.WarehouseProducts.Add(warehouseProduct); //Ajout du produit de l'entrepot à la bdd
|
||||
}
|
||||
await db.SaveChangesAsync(ct);
|
||||
await db.SaveChangesAsync(ct); //Sauvegarde du produit de l'entrepot dans la bdd
|
||||
}
|
||||
|
||||
// Construction de la réponse
|
||||
var response = new GetProductDto
|
||||
{
|
||||
Id = product.Id,
|
||||
Reference = req.Reference,
|
||||
Reference = req.References,
|
||||
Name = req.Name,
|
||||
Duration = req.Duration,
|
||||
Caliber = req.Caliber,
|
||||
@@ -99,6 +100,6 @@ public class CreateProductEndpoint(PyroFetesDbContext db)
|
||||
}).ToList() ?? new()
|
||||
};
|
||||
|
||||
await Send.OkAsync(response, ct);
|
||||
await Send.OkAsync(response, ct); //Réponse au client
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,27 +6,28 @@ namespace PyroFetes.Endpoints.Product;
|
||||
|
||||
public class DeleteProductRequest
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public int Id { get; set; } //Création d'un Id
|
||||
}
|
||||
|
||||
public class DeleteProductEndpoint(PyroFetesDbContext db) : Endpoint<DeleteProductRequest>
|
||||
{
|
||||
public override void Configure()
|
||||
{
|
||||
Delete("/products/{@id}", x => new { x.Id });
|
||||
Delete("/api/products/{@id}", x => new { x.Id }); //endpoint qui supprime un produit grâce à son id
|
||||
AllowAnonymous(); //Autorise l'accès sans authentification
|
||||
}
|
||||
|
||||
public override async Task HandleAsync(DeleteProductRequest req, CancellationToken ct)
|
||||
{
|
||||
// Récupérer le produit
|
||||
var productToDelete = await db.Products
|
||||
var productToDelete = await db.Products
|
||||
.SingleOrDefaultAsync(p => p.Id == req.Id, ct);
|
||||
|
||||
if (productToDelete is null)
|
||||
{
|
||||
Console.WriteLine($"Aucun produit avec l'ID {req.Id} trouvé.");
|
||||
await Send.NotFoundAsync(ct);
|
||||
return;
|
||||
await Send.NotFoundAsync(ct); //Renvoie une erreur 404
|
||||
return; //Arrêt de la méthode
|
||||
}
|
||||
|
||||
// Supprimer les liaisons Price
|
||||
@@ -53,6 +54,6 @@ public class DeleteProductEndpoint(PyroFetesDbContext db) : Endpoint<DeleteProdu
|
||||
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);
|
||||
await Send.NoContentAsync(ct); //Renvoie une réponse réussite 204
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,8 @@ public class GetAllProductsEndpoint(PyroFetesDbContext db)
|
||||
{
|
||||
public override void Configure()
|
||||
{
|
||||
Get("/products");
|
||||
Get("/api/products");
|
||||
AllowAnonymous();
|
||||
}
|
||||
|
||||
public override async Task HandleAsync(CancellationToken ct)
|
||||
@@ -19,7 +20,7 @@ public class GetAllProductsEndpoint(PyroFetesDbContext db)
|
||||
// Inclure toutes les relations nécessaires : Prices + WarehouseProducts + Warehouse
|
||||
var products = await db.Products
|
||||
.Include(p => p.Prices)
|
||||
.Include(p => p.WarehouseProducts)!
|
||||
.Include(p => p.WarehouseProducts)
|
||||
.ThenInclude(wp => wp.Warehouse)
|
||||
.ToListAsync(ct);
|
||||
|
||||
@@ -27,7 +28,7 @@ public class GetAllProductsEndpoint(PyroFetesDbContext db)
|
||||
{
|
||||
Id = p.Id,
|
||||
// Le modèle Product contient "Reference" (string) — pas "References" (int)
|
||||
Reference = p.Reference,
|
||||
Reference = int.TryParse(p.Reference, out var refInt) ? refInt : 0,
|
||||
Name = p.Name,
|
||||
Duration = p.Duration,
|
||||
Caliber = p.Caliber,
|
||||
|
||||
@@ -16,7 +16,8 @@ public class GetProductEndpoint(PyroFetesDbContext db)
|
||||
{
|
||||
public override void Configure()
|
||||
{
|
||||
Get("/products/{@id}", x => new { x.Id });
|
||||
Get("/api/products/{@id}", x => new { x.Id });
|
||||
AllowAnonymous();
|
||||
}
|
||||
|
||||
public override async Task HandleAsync(GetProductRequest req, CancellationToken ct)
|
||||
@@ -24,7 +25,7 @@ public class GetProductEndpoint(PyroFetesDbContext db)
|
||||
// Inclure toutes les relations : Prices + WarehouseProducts + Warehouse
|
||||
var product = await db.Products
|
||||
.Include(p => p.Prices)
|
||||
.Include(p => p.WarehouseProducts)!
|
||||
.Include(p => p.WarehouseProducts)
|
||||
.ThenInclude(wp => wp.Warehouse)
|
||||
.SingleOrDefaultAsync(p => p.Id == req.Id, ct);
|
||||
|
||||
@@ -40,7 +41,7 @@ public class GetProductEndpoint(PyroFetesDbContext db)
|
||||
Id = product.Id,
|
||||
|
||||
// Le modèle Product contient "Reference" (string), pas "References" (int)
|
||||
Reference = product.Reference,
|
||||
Reference = int.TryParse(product.Reference, out var refInt) ? refInt : 0,
|
||||
|
||||
Name = product.Name,
|
||||
Duration = product.Duration,
|
||||
|
||||
@@ -6,29 +6,36 @@ using PyroFetes.Models;
|
||||
|
||||
namespace PyroFetes.Endpoints.Product;
|
||||
|
||||
// Endpoint permettant de mettre à jour un produit existant
|
||||
public class UpdateProductEndpoint(PyroFetesDbContext db)
|
||||
: Endpoint<UpdateProductDto, GetProductDto>
|
||||
{
|
||||
public override void Configure()
|
||||
{
|
||||
Put("/products/{@id}", x => new { x.Id });
|
||||
// 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)
|
||||
{
|
||||
// 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);
|
||||
|
||||
// Si le produit n'existe pas, on retourne une réponse 404
|
||||
if (product is null)
|
||||
{
|
||||
await Send.NotFoundAsync(ct);
|
||||
return;
|
||||
}
|
||||
|
||||
product.Reference = req.Reference;
|
||||
// Mise à jour des propriétés principales du produit
|
||||
product.Reference = req.References.ToString(); // Converti int → string
|
||||
product.Name = req.Name;
|
||||
product.Duration = req.Duration;
|
||||
product.Caliber = req.Caliber;
|
||||
@@ -40,6 +47,7 @@ public class UpdateProductEndpoint(PyroFetesDbContext db)
|
||||
product.ClassificationId = req.ClassificationId;
|
||||
product.ProductCategoryId = req.ProductCategoryId;
|
||||
|
||||
// Mise à jour des prix fournisseurs associés
|
||||
db.Prices.RemoveRange(product.Prices);
|
||||
foreach (var s in req.Suppliers)
|
||||
{
|
||||
@@ -51,6 +59,7 @@ public class UpdateProductEndpoint(PyroFetesDbContext db)
|
||||
});
|
||||
}
|
||||
|
||||
// Mise à jour des entrepôts associés
|
||||
db.WarehouseProducts.RemoveRange(product.WarehouseProducts);
|
||||
foreach (var w in req.Warehouses)
|
||||
{
|
||||
@@ -64,16 +73,18 @@ public class UpdateProductEndpoint(PyroFetesDbContext db)
|
||||
|
||||
await db.SaveChangesAsync(ct);
|
||||
|
||||
// Construction de la réponse renvoyée au client
|
||||
var response = new GetProductDto
|
||||
{
|
||||
Id = product.Id,
|
||||
Reference = req.Reference,
|
||||
Reference = req.References, // DTO garde int pour cohérence
|
||||
Name = req.Name,
|
||||
Duration = req.Duration,
|
||||
Caliber = req.Caliber,
|
||||
ApprovalNumber = req.ApprovalNumber,
|
||||
Weight = req.Weight,
|
||||
Nec = req.Nec,
|
||||
// Le prix de vente est pris depuis Prices
|
||||
SellingPrice = req.Suppliers.FirstOrDefault()?.SellingPrice ?? 0,
|
||||
Image = req.Image,
|
||||
Link = req.Link,
|
||||
|
||||
@@ -4,33 +4,34 @@ using FastEndpoints;
|
||||
|
||||
namespace PyroFetes.Endpoints.ProductCategory;
|
||||
|
||||
public class CreateProductCategoryEndpoint(PyroFetesDbContext pyrofetesdbcontext) : Endpoint<CreateProductCategoryDto, GetProductCategoryDto>
|
||||
public class CreateProductCategoryEndpoint(PyroFetesDbContext pyrofetesdbcontext) : Endpoint<CreateProductCategoryDto, GetProductCategoryDto> //Instanciation d'une connexion à la bdd dans un endpoint, utilise l'élément de requête CreateProductCategoryDto et l'élement de réponse GetProductCategoryDto
|
||||
{
|
||||
public override void Configure()
|
||||
public override void Configure() //Configuration de l'endpoint
|
||||
{
|
||||
Post("/productcategories");
|
||||
Post("/api/productcategories"); //Créer une catégorie de produits
|
||||
AllowAnonymous(); //Autorise l'accès sans authentification
|
||||
}
|
||||
|
||||
public override async Task HandleAsync(CreateProductCategoryDto req, CancellationToken ct)
|
||||
{
|
||||
Models.ProductCategory productCategory = new ()
|
||||
Models.ProductCategory productCategory = new () //Création d'un label rentré par l'utilisateur
|
||||
{
|
||||
Label = req.Label,
|
||||
|
||||
};
|
||||
|
||||
pyrofetesdbcontext.ProductCategories.Add(productCategory);
|
||||
await pyrofetesdbcontext.SaveChangesAsync(ct);
|
||||
pyrofetesdbcontext.ProductCategories.Add(productCategory); //Ajout du catégorie de la produit à la bdd
|
||||
await pyrofetesdbcontext.SaveChangesAsync(ct); //Sauvegarde du catégorie de la produit dans la bdd
|
||||
|
||||
Console.WriteLine("Category créé avec succès !");
|
||||
|
||||
GetProductCategoryDto responseDto = new ()
|
||||
GetProductCategoryDto responseDto = new () //renvoie l'id et le label
|
||||
{
|
||||
Id = productCategory.Id,
|
||||
Label = productCategory.Label
|
||||
|
||||
};
|
||||
|
||||
await Send.OkAsync(responseDto, ct);
|
||||
await Send.OkAsync(responseDto, ct); //Réponse au client
|
||||
}
|
||||
}
|
||||
@@ -12,24 +12,25 @@ public class DeleteProductCategoryEndpoint(PyroFetesDbContext pyrofetesdbcontext
|
||||
{
|
||||
public override void Configure()
|
||||
{
|
||||
Delete("/productcategories/{@id}", x => new { x.Id });
|
||||
Delete("/api/productcategories/{@id}", x => new { x.Id }); //endpoint qui supprime une catégorie de produit grâce à son id
|
||||
AllowAnonymous(); //Ignorer les requêtes non authentifiées
|
||||
}
|
||||
|
||||
public override async Task HandleAsync(DeleteProductCategoryRequest req, CancellationToken ct)
|
||||
{
|
||||
Models.ProductCategory? productCategoryToDelete = await pyrofetesdbcontext
|
||||
.ProductCategories
|
||||
.SingleOrDefaultAsync(pc => pc.Id == req.Id, cancellationToken: ct);
|
||||
Models.ProductCategory? productCategoryToDelete = await pyrofetesdbcontext //Récupère une catégorie de produit dans la bdd et le stocke dans productCategoryToDelete
|
||||
.ProductCategories //Recherche la couleur dans la table ProductCategories
|
||||
.SingleOrDefaultAsync(pc => pc.Id == req.Id, cancellationToken: ct); //Recherche une catégorie de produit dont l'id correspond à req.Id
|
||||
|
||||
if (productCategoryToDelete == null)
|
||||
{
|
||||
await Send.NotFoundAsync(ct);
|
||||
return;
|
||||
await Send.NotFoundAsync(ct); //Renvoie une erreur 404
|
||||
return; //Arrêt de la méthode
|
||||
}
|
||||
|
||||
pyrofetesdbcontext.ProductCategories.Remove(productCategoryToDelete);
|
||||
await pyrofetesdbcontext.SaveChangesAsync(ct);
|
||||
pyrofetesdbcontext.ProductCategories.Remove(productCategoryToDelete); //Supprime la catégorie de produit dans la bdd
|
||||
await pyrofetesdbcontext.SaveChangesAsync(ct); //Sauvegarde les changements effectués dans la bdd
|
||||
|
||||
await Send.NoContentAsync(ct);
|
||||
await Send.NoContentAsync(ct); //Renvoie une réponse réussite 204
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
using API.DTO.ProductCategory.Response;
|
||||
using FastEndpoints;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace PyroFetes.Endpoints.ProductCategory;
|
||||
|
||||
public class GetAllProductCategoriesEndpoint(PyroFetesDbContext pyrofetesdbcontext) : EndpointWithoutRequest<List<GetProductCategoryDto>>
|
||||
{
|
||||
public override void Configure()
|
||||
{
|
||||
Get("/api/productcategories"); //Endpoint qui affiche toutes les catégories de produits
|
||||
AllowAnonymous(); //Ignorer les requêtes non authentifiées
|
||||
}
|
||||
|
||||
public override async Task HandleAsync(CancellationToken ct)
|
||||
{
|
||||
List<GetProductCategoryDto> responseDto = await pyrofetesdbcontext.ProductCategories //Création d'une liste qui récupère toutes les catégories de produits dans la bdd
|
||||
.Select(pc => new GetProductCategoryDto() //Sélectionne dans la liste chaque catégorie de produits
|
||||
{
|
||||
Id = pc.Id, //Récupère l'id
|
||||
Label = pc.Label //Récupère le label
|
||||
}
|
||||
).ToListAsync(ct); //Retourne la liste
|
||||
|
||||
await Send.OkAsync(responseDto, ct); //Envoie de la réponse réussite 200 au client
|
||||
}
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
using API.DTO.ProductCategory.Response;
|
||||
using FastEndpoints;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace PyroFetes.Endpoints.ProductCategory;
|
||||
|
||||
public class GetAllProductCategoryEndpoint(PyroFetesDbContext pyrofetesdbcontext) : EndpointWithoutRequest<List<GetProductCategoryDto>>
|
||||
{
|
||||
public override void Configure()
|
||||
{
|
||||
Get("/productcategories");
|
||||
}
|
||||
|
||||
public override async Task HandleAsync(CancellationToken ct)
|
||||
{
|
||||
List<GetProductCategoryDto> responseDto = await pyrofetesdbcontext.ProductCategories
|
||||
.Select(pc => new GetProductCategoryDto()
|
||||
{
|
||||
Id = pc.Id,
|
||||
Label = pc.Label
|
||||
}
|
||||
).ToListAsync(ct);
|
||||
|
||||
await Send.OkAsync(responseDto, ct);
|
||||
}
|
||||
}
|
||||
@@ -14,28 +14,29 @@ public class GetProductCategoryEndpoint(PyroFetesDbContext pyrofetesdbcontext) :
|
||||
{
|
||||
public override void Configure()
|
||||
{
|
||||
Get("/productcategory/{@id}", x => new { x.Id });
|
||||
Get("/api/productcategory/{@id}", x => new { x.Id }); //endpoint qui récupère une catégorie de produit grâce à son id
|
||||
AllowAnonymous(); //Autorise l'accès sans authentification
|
||||
}
|
||||
|
||||
public override async Task HandleAsync(GetProductCategoryRequest req, CancellationToken ct)
|
||||
{
|
||||
Models.ProductCategory? productCategory = await pyrofetesdbcontext
|
||||
.ProductCategories
|
||||
.SingleOrDefaultAsync(pc => pc.Id == req.Id, cancellationToken: ct);
|
||||
Models.ProductCategory? productCategory = await pyrofetesdbcontext //Récupère une catégorie de produits dans la bdd et le stocke dans productCategory
|
||||
.ProductCategories //Recherche dans la table ProductCategories
|
||||
.SingleOrDefaultAsync(pc => pc.Id == req.Id, cancellationToken: ct);//Recherche une catégorie de produits dont l'id correspond à req.Id
|
||||
|
||||
if (productCategory == null)
|
||||
if (productCategory == null) //Si la catégorie de produit n'est pas trouvé
|
||||
{
|
||||
await Send.NotFoundAsync(ct);
|
||||
return;
|
||||
await Send.NotFoundAsync(ct); //Renvoie une erreur 404
|
||||
return; //Arrêt de la méthode
|
||||
}
|
||||
|
||||
GetProductCategoryDto responseDto = new()
|
||||
{
|
||||
Id = productCategory.Id,
|
||||
Label = productCategory.Label
|
||||
Id = productCategory.Id, //Affiche l'id lors de la réponse
|
||||
Label = productCategory.Label //Affiche le label lors de la réponse
|
||||
|
||||
};
|
||||
|
||||
await Send.OkAsync(responseDto, ct);
|
||||
await Send.OkAsync(responseDto, ct); //Envoie de la réponse réussite 200 au client
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,30 +9,31 @@ public class UpdateProductCategoryEndpoint(PyroFetesDbContext pyrofetesdbcontext
|
||||
{
|
||||
public override void Configure()
|
||||
{
|
||||
Put("/productcategory/{@id}", x => new { x.Id });
|
||||
Put("/api/productcategory/{@id}", x => new { x.Id }); //endpoint qui modifie la catégorie de produit grâce à son id
|
||||
AllowAnonymous(); //Ignorer les requêtes non authentifiées
|
||||
}
|
||||
|
||||
public override async Task HandleAsync(UpdateProductCategoryDto req, CancellationToken ct)
|
||||
{
|
||||
Models.ProductCategory? productCategoryToEdit = await pyrofetesdbcontext
|
||||
.ProductCategories
|
||||
.SingleOrDefaultAsync(pc => pc.Id == req.Id, cancellationToken: ct);
|
||||
Models.ProductCategory? productCategoryToEdit = await pyrofetesdbcontext //Récupère une catégorie de produits dans la bdd et le stocke dans productCategoryToEdit
|
||||
.ProductCategories //Recherche dans la table ProductCategories
|
||||
.SingleOrDefaultAsync(pc => pc.Id == req.Id, cancellationToken: ct); //Recherche une catégorie de produits dont l'id correspond à req.Id
|
||||
|
||||
if (productCategoryToEdit == null)
|
||||
if (productCategoryToEdit == null) //Si la catégorie de produit n'est pas trouvé
|
||||
{
|
||||
await Send.NotFoundAsync(ct);
|
||||
return;
|
||||
await Send.NotFoundAsync(ct); //Renvoie une erreur 404
|
||||
return; //Arrêt de la méthode
|
||||
}
|
||||
|
||||
productCategoryToEdit.Label = req.Label;
|
||||
await pyrofetesdbcontext.SaveChangesAsync(ct);
|
||||
productCategoryToEdit.Label = req.Label; //Modification du label
|
||||
await pyrofetesdbcontext.SaveChangesAsync(ct); //Sauvegarde les changements effectués dans la bdd
|
||||
|
||||
GetProductCategoryDto responseDto = new()
|
||||
{
|
||||
Id = req.Id,
|
||||
Label = req.Label,
|
||||
Id = req.Id, //Affiche l'id
|
||||
Label = req.Label, //Affiche le label
|
||||
};
|
||||
|
||||
await Send.OkAsync(responseDto, ct);
|
||||
await Send.OkAsync(responseDto, ct); //Envoie de la réponse réussite 200 au client
|
||||
}
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
using System.IdentityModel.Tokens.Jwt;
|
||||
using System.Security.Claims;
|
||||
using FastEndpoints;
|
||||
using FastEndpoints.Security;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using PyroFetes.DTO.Refrresh.Response;
|
||||
|
||||
namespace PyroFetes.Endpoints.Refresh;
|
||||
|
||||
public class RefreshTokenEndpoint(PyroFetesDbContext database) : EndpointWithoutRequest<GetRefreshDto>
|
||||
{
|
||||
public override void Configure()
|
||||
{
|
||||
Post("/refresh");
|
||||
// [Authorize] est géré ici avec les rôles
|
||||
Roles("Admin", "User");
|
||||
}
|
||||
|
||||
public override async Task HandleAsync(CancellationToken ct)
|
||||
{
|
||||
try
|
||||
{
|
||||
// 1. 🚨 CORRECTION : Lire le claim 'Name' du jeton validé par le middleware
|
||||
// Le claim 'Name' contient le nom d'utilisateur
|
||||
string? userName = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Name)?.Value;
|
||||
|
||||
if (string.IsNullOrWhiteSpace(userName))
|
||||
{
|
||||
// Si le claim Name est manquant (ce qui ne devrait pas arriver)
|
||||
await Send.UnauthorizedAsync(ct);
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. 🚨 CORRECTION : Utiliser le Nom (Name) pour la recherche BDD
|
||||
// Assurez-vous que la propriété de l'entité est 'Name' et qu'elle est unique
|
||||
var login = await database.Users.FirstOrDefaultAsync(x => x.Name == userName, ct);
|
||||
if (login == null)
|
||||
{
|
||||
await Send.UnauthorizedAsync(ct);
|
||||
return;
|
||||
}
|
||||
|
||||
// 3. Création du NOUVEAU jeton
|
||||
string jwtToken = JwtBearer.CreateToken(
|
||||
o =>
|
||||
{
|
||||
o.SigningKey = "ThisIsASuperSecretJwtKeyThatIsAtLeast32CharsLong";
|
||||
o.ExpireAt = DateTime.UtcNow.AddMinutes(15);
|
||||
|
||||
// Assurez-vous que les claims sont corrects pour Angular
|
||||
if (login.Fonction != null) o.User.Roles.Add(login.Fonction);
|
||||
|
||||
// Ajouter le claim Name (Nom d'utilisateur)
|
||||
o.User.Claims.Add((ClaimTypes.Name, login.Name)!);
|
||||
|
||||
// Si votre API mettait d'autres claims, ajoutez-les ici (ex: "Username")
|
||||
// o.User.Claims.Add(("Username", login.Name)!);
|
||||
});
|
||||
|
||||
// 4. Envoi de la réponse
|
||||
GetRefreshDto responseDto = new()
|
||||
{
|
||||
Token = jwtToken
|
||||
};
|
||||
|
||||
await Send.OkAsync(responseDto, ct);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
await Send.UnauthorizedAsync(ct);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,16 +7,17 @@ using PyroFetes.Models;
|
||||
namespace PyroFetes.Endpoints.Supplier;
|
||||
|
||||
public class CreateSupplierEndpoint(PyroFetesDbContext pyrofetesdbcontext)
|
||||
: Endpoint<CreateSupplierDto, GetSupplierDto>
|
||||
: Endpoint<CreateSupplierDto, GetSupplierDto> //Instanciation d'une connexion à la bdd dans un endpoint, utilise l'élément de requête CreateSupplierDto et l'élement de réponse GetSupplierDto
|
||||
{
|
||||
public override void Configure()
|
||||
public override void Configure() //Configuration de l'endpoint
|
||||
{
|
||||
Post("/suppliers");
|
||||
Post("/api/suppliers"); //Créer un fournisseur
|
||||
AllowAnonymous(); //Autorise l'accès sans authentification
|
||||
}
|
||||
|
||||
public override async Task HandleAsync(CreateSupplierDto req, CancellationToken ct)
|
||||
{
|
||||
var supplier = new Models.Supplier
|
||||
var supplier = new Models.Supplier //Création d'un nom, email, numéro de téléphone, adresse, code postal et nom de la ville rentré par l'utilisateur
|
||||
{
|
||||
Name = req.Name,
|
||||
Email = req.Email,
|
||||
@@ -26,8 +27,8 @@ public class CreateSupplierEndpoint(PyroFetesDbContext pyrofetesdbcontext)
|
||||
City = req.City
|
||||
};
|
||||
|
||||
pyrofetesdbcontext.Suppliers.Add(supplier);
|
||||
await pyrofetesdbcontext.SaveChangesAsync(ct);
|
||||
pyrofetesdbcontext.Suppliers.Add(supplier); //Ajout du fournisseur à la bdd
|
||||
await pyrofetesdbcontext.SaveChangesAsync(ct); //Sauvegarde du fournisseur dans la bdd
|
||||
|
||||
// Ajout des liaisons Price si produits renseignés
|
||||
if (req.Products is not null && req.Products.Any())
|
||||
@@ -42,10 +43,10 @@ public class CreateSupplierEndpoint(PyroFetesDbContext pyrofetesdbcontext)
|
||||
};
|
||||
pyrofetesdbcontext.Prices.Add(price);
|
||||
}
|
||||
await pyrofetesdbcontext.SaveChangesAsync(ct);
|
||||
await pyrofetesdbcontext.SaveChangesAsync(ct); //Sauvegarde du fournisseur dans la bdd
|
||||
}
|
||||
|
||||
var response = new GetSupplierDto
|
||||
var response = new GetSupplierDto //renvoie l'id, d'un nom, d'un email, d'un numéro de téléphone, d'une adresse, d'un code postal et du nom de la ville
|
||||
{
|
||||
Id = supplier.Id,
|
||||
Name = supplier.Name,
|
||||
@@ -56,6 +57,6 @@ public class CreateSupplierEndpoint(PyroFetesDbContext pyrofetesdbcontext)
|
||||
City = supplier.City
|
||||
};
|
||||
|
||||
await Send.OkAsync(response, ct);
|
||||
await Send.OkAsync(response, ct); //Réponse au client
|
||||
}
|
||||
}
|
||||
@@ -13,20 +13,21 @@ public class DeleteSupplierEndpoint(PyroFetesDbContext pyrofetesdbcontext) : End
|
||||
{
|
||||
public override void Configure()
|
||||
{
|
||||
Delete("/suppliers/{@id}", x => new { x.Id });
|
||||
Delete("/api/suppliers/{@id}", x => new { x.Id }); //Endpoint qui supprime un fournisseur en fonction de l'id
|
||||
AllowAnonymous(); //Autorise l'accès sans authentification
|
||||
}
|
||||
|
||||
public override async Task HandleAsync(DeleteSupplierRequest req, CancellationToken ct)
|
||||
{
|
||||
var supplierToDelete = await pyrofetesdbcontext
|
||||
.Suppliers
|
||||
.SingleOrDefaultAsync(s => s.Id == req.Id, ct);
|
||||
var supplierToDelete = await pyrofetesdbcontext //Récupère un fournisseur dans la bdd et le stocke dans supplierToDelete
|
||||
.Suppliers //Recherche un fournisseur dans la table Suppliers
|
||||
.SingleOrDefaultAsync(s => s.Id == req.Id, ct); //Recherche un fournisseur dont l'id correspond à req.Id
|
||||
|
||||
if (supplierToDelete is null)
|
||||
{
|
||||
Console.WriteLine($"Aucun fournisseur avec l'ID {req.Id} trouvé.");
|
||||
await Send.NotFoundAsync(ct);
|
||||
return;
|
||||
await Send.NotFoundAsync(ct); //Renvoie une erreur 404
|
||||
return; //Arrêt de la méthode
|
||||
}
|
||||
|
||||
// Supprimer les liaisons Price avant le fournisseur
|
||||
@@ -45,6 +46,6 @@ public class DeleteSupplierEndpoint(PyroFetesDbContext pyrofetesdbcontext) : End
|
||||
await pyrofetesdbcontext.SaveChangesAsync(ct);
|
||||
Console.WriteLine($"Fournisseur {req.Id} et ses prix liés supprimés avec succès.");
|
||||
|
||||
await Send.NoContentAsync(ct);
|
||||
await Send.NoContentAsync(ct); //Renvoie une réponse réussite 204
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,8 @@ public class GetAllSuppliersEndpoint(PyroFetesDbContext pyrofetesdbcontext)
|
||||
{
|
||||
public override void Configure()
|
||||
{
|
||||
Get("/suppliers");
|
||||
Get("/api/suppliers"); //endpoint qui affiche le fournisseur en fonction de l'id
|
||||
AllowAnonymous(); //Autorise l'accès sans authentification
|
||||
}
|
||||
|
||||
public override async Task HandleAsync(CancellationToken ct)
|
||||
|
||||
@@ -15,7 +15,8 @@ public class GetSupplierEndpoint(PyroFetesDbContext pyrofetesdbcontext)
|
||||
{
|
||||
public override void Configure()
|
||||
{
|
||||
Get("/suppliers/{@id}", x => new { x.Id });
|
||||
Get("/api/suppliers/{@id}", x => new { x.Id }); //endpoint qui affiche le fournisseur en fonction de l'id
|
||||
AllowAnonymous(); //Autorise l'accès sans authentification
|
||||
}
|
||||
|
||||
public override async Task HandleAsync(GetSupplierRequest req, CancellationToken ct)
|
||||
@@ -27,8 +28,8 @@ public class GetSupplierEndpoint(PyroFetesDbContext pyrofetesdbcontext)
|
||||
if (supplier == null)
|
||||
{
|
||||
Console.WriteLine($"Aucun fournisseur avec l'ID {req.Id} trouvé.");
|
||||
await Send.NotFoundAsync(ct);
|
||||
return;
|
||||
await Send.NotFoundAsync(ct); //Renvoie une erreur 404
|
||||
return; //Arrêt de la méthode
|
||||
}
|
||||
|
||||
var responseDto = new GetSupplierDto
|
||||
|
||||
@@ -10,7 +10,8 @@ public class UpdateSupplierEndpoint(PyroFetesDbContext pyrofetesdbcontext) : End
|
||||
{
|
||||
public override void Configure()
|
||||
{
|
||||
Put("/suppliers/{@id}", x => new { x.Id });
|
||||
Put("/api/suppliers/{@id}", x => new { x.Id });
|
||||
AllowAnonymous();
|
||||
}
|
||||
|
||||
public override async Task HandleAsync(UpdateSupplierDto req, CancellationToken ct)
|
||||
@@ -51,7 +52,7 @@ public class UpdateSupplierEndpoint(PyroFetesDbContext pyrofetesdbcontext) : End
|
||||
}
|
||||
}
|
||||
|
||||
await pyrofetesdbcontext.SaveChangesAsync(ct);
|
||||
await pyrofetesdbcontext.SaveChangesAsync(ct); //Sauvegarde les changements
|
||||
|
||||
var response = new GetSupplierDto
|
||||
{
|
||||
@@ -64,6 +65,6 @@ public class UpdateSupplierEndpoint(PyroFetesDbContext pyrofetesdbcontext) : End
|
||||
City = supplierToEdit.City
|
||||
};
|
||||
|
||||
await Send.OkAsync(response, ct);
|
||||
await Send.OkAsync(response, ct); //Envoie de la réponse réussite 200 au client
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,16 +6,17 @@ using PyroFetes.Models;
|
||||
namespace PyroFetes.Endpoints.Warehouse;
|
||||
|
||||
public class CreateWarehouseEndpoint(PyroFetesDbContext db)
|
||||
: Endpoint<CreateWarehouseDto, GetWarehouseDto>
|
||||
: Endpoint<CreateWarehouseDto, GetWarehouseDto> //Instanciation d'une connexion à la bdd dans un endpoint, utilise l'élément de requête CreateWarehouseDto et l'élement de réponse GetWarehouseDto
|
||||
{
|
||||
public override void Configure()
|
||||
public override void Configure() //Configuration de l'endpoint
|
||||
{
|
||||
Post("/warehouse");
|
||||
Post("/api/warehouse"); //Créer un entrepot
|
||||
AllowAnonymous(); //Autorise l'accès sans authentification
|
||||
}
|
||||
|
||||
public override async Task HandleAsync(CreateWarehouseDto req, CancellationToken ct)
|
||||
{
|
||||
var warehouse = new Models.Warehouse
|
||||
var warehouse = new Models.Warehouse //Création d'un nom, d'un poids maximal et minimal, d'une adresse, d'un code postal et du nom de la ville rentré par l'utilisateur
|
||||
{
|
||||
Name = req.Name,
|
||||
MaxWeight = req.MaxWeight,
|
||||
@@ -26,8 +27,8 @@ public class CreateWarehouseEndpoint(PyroFetesDbContext db)
|
||||
City = req.City
|
||||
};
|
||||
|
||||
db.Warehouses.Add(warehouse);
|
||||
await db.SaveChangesAsync(ct);
|
||||
db.Warehouses.Add(warehouse); //Ajout de l'entrepot à la bdd
|
||||
await db.SaveChangesAsync(ct); //Sauvegarde de l'entrepot dans la bdd
|
||||
|
||||
// 🔹 Ajout des produits liés à cet entrepôt
|
||||
if (req.Products is not null && req.Products.Any())
|
||||
@@ -45,7 +46,7 @@ public class CreateWarehouseEndpoint(PyroFetesDbContext db)
|
||||
await db.SaveChangesAsync(ct);
|
||||
}
|
||||
|
||||
var response = new GetWarehouseDto
|
||||
var response = new GetWarehouseDto //renvoie l'id, d'un nom, d'un poids maximal et minimal, d'une adresse, d'un code postal et du nom de la ville
|
||||
{
|
||||
Id = warehouse.Id,
|
||||
Name = warehouse.Name,
|
||||
@@ -57,6 +58,6 @@ public class CreateWarehouseEndpoint(PyroFetesDbContext db)
|
||||
City = warehouse.City
|
||||
};
|
||||
|
||||
await Send.OkAsync(response, ct);
|
||||
await Send.OkAsync(response, ct); //Réponse au client
|
||||
}
|
||||
}
|
||||
@@ -13,7 +13,8 @@ public class DeleteWarehouseEndpoint(PyroFetesDbContext db) : Endpoint<DeleteWar
|
||||
{
|
||||
public override void Configure()
|
||||
{
|
||||
Delete("/warehouse/{id}");
|
||||
Delete("/api/warehouse/{id}");
|
||||
AllowAnonymous();
|
||||
}
|
||||
public override async Task HandleAsync(DeleteWarehouseRequest req, CancellationToken ct)
|
||||
{
|
||||
@@ -44,6 +45,6 @@ public class DeleteWarehouseEndpoint(PyroFetesDbContext db) : Endpoint<DeleteWar
|
||||
await db.SaveChangesAsync(ct);
|
||||
|
||||
Console.WriteLine($"Entrepôt {warehouseToDelete.Name} (ID {req.Id}) supprimé avec succès.");
|
||||
await Send.NoContentAsync(ct);
|
||||
await Send.NoContentAsync(ct); //Renvoie une réponse réussite 204
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using API.DTO.Warehouse.Response;
|
||||
using API.DTO.Warehouse.Request;
|
||||
using FastEndpoints;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using PyroFetes.Models;
|
||||
@@ -10,65 +11,36 @@ public class GetAllWarehouseEndpoint(PyroFetesDbContext db)
|
||||
{
|
||||
public override void Configure()
|
||||
{
|
||||
Get("/warehouses");
|
||||
Get("/api/warehouses");
|
||||
AllowAnonymous();
|
||||
}
|
||||
|
||||
public override async Task HandleAsync(CancellationToken ct)
|
||||
{
|
||||
try
|
||||
// 🔹 On inclut les relations avec WarehouseProducts et Product
|
||||
var warehouses = await db.Warehouses
|
||||
.Include(w => w.WarehouseProducts)
|
||||
.ThenInclude(wp => wp.Product)
|
||||
.ToListAsync(ct);
|
||||
|
||||
var response = warehouses.Select(w => new GetWarehouseDto
|
||||
{
|
||||
// 1. Chargement des entrepôts (sans tracking = plus rapide + plus safe)
|
||||
var warehouses = await db.Warehouses
|
||||
.AsNoTracking()
|
||||
.ToListAsync(ct);
|
||||
|
||||
// 2. Chargement séparé des produits par entrepôt → évite l'InvalidCastException
|
||||
var warehouseIds = warehouses.Select(w => w.Id).ToList();
|
||||
|
||||
var warehouseProducts = await db.WarehouseProducts
|
||||
.Where(wp => warehouseIds.Contains(wp.WarehouseId))
|
||||
.Include(wp => wp.Product)
|
||||
.AsNoTracking()
|
||||
.ToListAsync(ct);
|
||||
|
||||
// 3. Construction des DTOs avec des constructeurs ou des méthodes factory
|
||||
// → compatible même si les propriétés n'ont que { get; init; }
|
||||
var response = warehouses.Select(w =>
|
||||
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
|
||||
{
|
||||
var dto = new GetWarehouseDto();
|
||||
dto.GetType().GetProperty("Id")?.SetValue(dto, w.Id);
|
||||
dto.GetType().GetProperty("Name")?.SetValue(dto, w.Name ?? string.Empty);
|
||||
dto.GetType().GetProperty("MaxWeight")?.SetValue(dto, w.MaxWeight);
|
||||
dto.GetType().GetProperty("Current")?.SetValue(dto, w.Current);
|
||||
dto.GetType().GetProperty("MinWeight")?.SetValue(dto, w.MinWeight);
|
||||
dto.GetType().GetProperty("Adress")?.SetValue(dto, w.Address ?? string.Empty);
|
||||
dto.GetType().GetProperty("ZipCode")?.SetValue(dto, w.ZipCode);
|
||||
dto.GetType().GetProperty("City")?.SetValue(dto, w.City ?? string.Empty);
|
||||
ProductId = wp.ProductId,
|
||||
ProductName = wp.Product?.Name,
|
||||
Quantity = wp.Quantity
|
||||
}).ToList()
|
||||
}).ToList();
|
||||
|
||||
// Products
|
||||
var productsList = warehouseProducts
|
||||
.Where(wp => wp.WarehouseId == w.Id)
|
||||
.Select(wp =>
|
||||
{
|
||||
var prodDto = new WarehouseProductDto();
|
||||
prodDto.GetType().GetProperty("ProductId")?.SetValue(prodDto, wp.ProductId);
|
||||
prodDto.GetType().GetProperty("ProductName")?.SetValue(prodDto, wp.Product?.Name ?? "Produit inconnu");
|
||||
prodDto.GetType().GetProperty("Quantity")?.SetValue(prodDto, wp.Quantity);
|
||||
return prodDto;
|
||||
})
|
||||
.ToList();
|
||||
|
||||
dto.GetType().GetProperty("Products")?.SetValue(dto, productsList);
|
||||
|
||||
return dto;
|
||||
}).ToList();
|
||||
|
||||
await Send.OkAsync(response, ct);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// En dev tu vois l'erreur réelle, en prod tu peux la logger
|
||||
await Send.OkAsync(ct);
|
||||
}
|
||||
await Send.OkAsync(response, ct);
|
||||
}
|
||||
}
|
||||
@@ -16,14 +16,15 @@ public class GetWarehouseEndpoint(PyroFetesDbContext db)
|
||||
public override void Configure()
|
||||
{
|
||||
// Pas de "@id" ici, juste {id}
|
||||
Get("/warehouses/{Id}");
|
||||
Get("/api/warehouses/{Id}");
|
||||
AllowAnonymous();
|
||||
}
|
||||
|
||||
public override async Task HandleAsync(GetWarehouseRequest req, CancellationToken ct)
|
||||
{
|
||||
// 🔹 Inclut les produits associés à cet entrepôt
|
||||
var warehouse = await db.Warehouses
|
||||
.Include(w => w.WarehouseProducts)!
|
||||
.Include(w => w.WarehouseProducts)
|
||||
.ThenInclude(wp => wp.Product)
|
||||
.SingleOrDefaultAsync(w => w.Id == req.Id, cancellationToken: ct);
|
||||
|
||||
|
||||
@@ -12,7 +12,8 @@ public class UpdateWarehouseEndpoint(PyroFetesDbContext db)
|
||||
public override void Configure()
|
||||
{
|
||||
// Utilise {id} plutôt que {@id}
|
||||
Put("/warehouses/{Id}");
|
||||
Put("/api/warehouses/{Id}");
|
||||
AllowAnonymous();
|
||||
}
|
||||
|
||||
public override async Task HandleAsync(UpdateWarehouseDto req, CancellationToken ct)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Generated
+13
@@ -0,0 +1,13 @@
|
||||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Rider ignored files
|
||||
/.idea.Models.iml
|
||||
/modules.xml
|
||||
/contentModel.xml
|
||||
/projectSettingsUpdater.xml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
||||
Generated
+4
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Encoding" addBOMForNewFiles="with BOM under Windows, with no BOM otherwise" />
|
||||
</project>
|
||||
Generated
+8
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="UserContentModel">
|
||||
<attachedFolders />
|
||||
<explicitIncludes />
|
||||
<explicitExcludes />
|
||||
</component>
|
||||
</project>
|
||||
@@ -9,7 +9,7 @@ public class DeliveryNote
|
||||
public int DelivererId { get; set; }
|
||||
[Required] public DateOnly EstimateDeliveryDate { get; set; }
|
||||
[Required] public DateOnly ExpeditionDate { get; set; }
|
||||
public DateOnly? RealDeliveryDate { get; set; }
|
||||
[Required] public DateOnly RealDeliveryDate { get; set; }
|
||||
|
||||
public Deliverer? Deliverer { get; set; }
|
||||
public List<ProductDelivery>? ProductDeliveries { get; set; }
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace PyroFetes.Models;
|
||||
|
||||
public class Login
|
||||
{
|
||||
[Key] public int Id { get; set; }
|
||||
[Required, MaxLength(100)] public string? Username { get; set; }
|
||||
[Required, MaxLength(200)] public string? FullName { get; set; }
|
||||
[Required, Length(60, 60)] public string? Password { get; set; }
|
||||
[Required, Length(24, 24)] public string? Salt { get; set; }
|
||||
[Required, MaxLength(100)] public string? Role { get; set; }
|
||||
}
|
||||
@@ -2,42 +2,18 @@
|
||||
|
||||
namespace PyroFetes.Models;
|
||||
|
||||
// 1. Définition des types possibles pour la logique métier
|
||||
public enum MovementType
|
||||
{
|
||||
Entry, // Entrée (ex: Achat fournisseur)
|
||||
Exit, // Sortie (ex: Vente, Casse)
|
||||
Transfer, // Transfert entre deux entrepôts
|
||||
Inventory // Ajustement manuel
|
||||
}
|
||||
|
||||
public class Movement
|
||||
{
|
||||
[Key]
|
||||
public int Id { get; set; }
|
||||
|
||||
[Required]
|
||||
public DateTime Date { get; set; } = DateTime.Now;
|
||||
|
||||
public DateTime Start { get; set; }
|
||||
public DateTime Arrival { get; set; }
|
||||
|
||||
[Required]
|
||||
public int Quantity { get; set; }
|
||||
|
||||
[Required]
|
||||
public MovementType Type { get; set; }
|
||||
|
||||
[Required]
|
||||
public int ProductId { get; set; }
|
||||
public Product? Product { get; set; }
|
||||
|
||||
public int? SourceWarehouseId { get; set; }
|
||||
public Warehouse? SourceWarehouse { get; set; }
|
||||
|
||||
public int? DestinationWarehouseId { get; set; }
|
||||
public Warehouse? DestinationWarehouse { get; set; }
|
||||
|
||||
[MaxLength(500)]
|
||||
public string? Comment { get; set; }
|
||||
[Key] public int Id { get; set; }
|
||||
[Required] public DateTime Date { get; set; }
|
||||
[Required] public DateTime Start {get; set;}
|
||||
[Required] public DateTime Arrival {get; set;}
|
||||
[Required] public int Quantity {get; set;}
|
||||
|
||||
public List<Product>? Products { get; set; }
|
||||
|
||||
public int? SourceWarehouseId {get; set;}
|
||||
public Warehouse? SourceWarehouse {get; set;}
|
||||
public int? DestinationWarehouseId {get; set;}
|
||||
public Warehouse? DestinationWarehouse {get; set;}
|
||||
}
|
||||
@@ -8,13 +8,13 @@ namespace PyroFetes.Models
|
||||
[Required, MaxLength(20)] public string? Reference { get; set; }
|
||||
[Required, MaxLength(100)] public string? Name { get; set; }
|
||||
[Required] public decimal Duration {get; set;}
|
||||
[Required] public int Caliber { get; set; }
|
||||
[Required, MaxLength(100)] public string? ApprovalNumber { get; set; }
|
||||
[Required] public decimal Caliber { get; set; }
|
||||
[Required] public int ApprovalNumber { get; set; }
|
||||
[Required] public decimal Weight { get; set; }
|
||||
[Required] public decimal Nec { get; set; }
|
||||
public string? Image { get; set; }
|
||||
[MaxLength(200)] public string? Link { get; set; }
|
||||
public int MinimalQuantity { get; set; }
|
||||
[Required] public string? Image { get; set; }
|
||||
[Required, MaxLength(200)] public string? Link { get; set; }
|
||||
[Required] public int MinimalQuantity { get; set; }
|
||||
|
||||
// Relations
|
||||
[Required] public int ClassificationId { get; set; }
|
||||
@@ -23,7 +23,8 @@ namespace PyroFetes.Models
|
||||
[Required] public int ProductCategoryId { get; set; }
|
||||
public ProductCategory? ProductCategory { get; set; }
|
||||
|
||||
public List<Movement>? Movements { get; set; }
|
||||
[Required] public int MovementId {get; set;}
|
||||
public Movement? Movement {get; set;}
|
||||
|
||||
public List<ProductDelivery>? ProductDeliveries { get; set; }
|
||||
public List<Brand>? Brands { get; set; }
|
||||
@@ -35,5 +36,6 @@ namespace PyroFetes.Models
|
||||
public List<WarehouseProduct>? WarehouseProducts { get; set; }
|
||||
public List<ProductTimecode>? ProductTimecodes { get; set; }
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,7 @@ public class Supplier
|
||||
[Required, MaxLength(100)] public string? Email { get; set; }
|
||||
[Required, MaxLength(30)] public string? Phone { get; set; }
|
||||
[Required, MaxLength(100)] public string? Address { get; set; }
|
||||
[Required,Length(5,5)] public string? ZipCode { get; set; }
|
||||
[Required] public int ZipCode { get; set; }
|
||||
[Required, MaxLength(100)] public string? City { get; set; }
|
||||
[Required] public int DeliveryDelay { get; set; }
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ public class User
|
||||
{
|
||||
[Key] public int Id { get; set; }
|
||||
[Required, MaxLength(100)] public string? Name { get; set; }
|
||||
[Required, MaxLength(60)] public string? Password { get; set; }
|
||||
[Required, MinLength(12), MaxLength(50)] public string? Password { get; set; }
|
||||
[Required, MaxLength(100)] public string? Salt { get; set; }
|
||||
[Required, MaxLength(100)] public string? Email { get; set; }
|
||||
[Required, MaxLength(100)] public string? Fonction { get; set; }
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace PyroFetes.Models;
|
||||
|
||||
@@ -10,7 +10,7 @@ public class Warehouse
|
||||
[Required] public int Current {get; set;}
|
||||
[Required] public int MinWeight {get; set;}
|
||||
[Required, MaxLength(100)] public string? Address { get; set; }
|
||||
[Required, Length(5,5)] public string? ZipCode { get; set; }
|
||||
[Required] public int ZipCode { get; set; }
|
||||
[Required, MaxLength(100)] public string? City { get; set; }
|
||||
|
||||
public List<WarehouseProduct>? WarehouseProducts { get; set; }
|
||||
|
||||
+12
-33
@@ -1,50 +1,29 @@
|
||||
using API;
|
||||
using FastEndpoints;
|
||||
using FastEndpoints.Security;
|
||||
using FastEndpoints.Swagger;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using PyroFetes;
|
||||
|
||||
using FastEndpoints.Security;
|
||||
|
||||
|
||||
WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
// On ajoute ici FastEndpoints, un framework REPR et Swagger aux services disponibles dans le projet
|
||||
builder.Services
|
||||
.AddAuthenticationJwtBearer(s => s.SigningKey = "ThisIsASuperSecretJwtKeyThatIsAtLeast32CharsLong")
|
||||
.AddAuthentication();
|
||||
|
||||
builder.Services.AddAuthorization();
|
||||
|
||||
builder.Services.AddCors(options =>
|
||||
options.AddDefaultPolicy(policyBuilder =>
|
||||
policyBuilder.WithOrigins("http://localhost:4200")
|
||||
.WithMethods("GET", "POST", "PUT", "PATCH", "DELETE")
|
||||
.AllowAnyHeader()
|
||||
.AllowCredentials()
|
||||
)
|
||||
);
|
||||
|
||||
builder.Services.AddFastEndpoints().SwaggerDocument(options =>
|
||||
{
|
||||
options.ShortSchemaNames = true;
|
||||
});
|
||||
.AddAuthorization()
|
||||
.AddFastEndpoints()
|
||||
.SwaggerDocument();
|
||||
|
||||
// On ajoute ici la configuration de la base de données
|
||||
builder.Services.AddDbContext<PyroFetesDbContext>();
|
||||
|
||||
// On construit l'application en lui donnant vie
|
||||
WebApplication app = builder.Build();
|
||||
|
||||
app.UseAuthentication()
|
||||
.UseAuthorization()
|
||||
.UseFastEndpoints()
|
||||
.UseSwaggerGen();
|
||||
|
||||
app.UseHttpsRedirection();
|
||||
|
||||
app.UseCors();
|
||||
|
||||
app.UseAuthentication();
|
||||
|
||||
app.UseAuthorization();
|
||||
|
||||
app.UseFastEndpoints(options =>
|
||||
{
|
||||
options.Endpoints.RoutePrefix = "API";
|
||||
options.Endpoints.ShortNames = true;
|
||||
}).UseSwaggerGen();
|
||||
|
||||
app.Run();
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<RollForward>Major</RollForward>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
</PropertyGroup>
|
||||
@@ -15,8 +14,8 @@
|
||||
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.19" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.20" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.20">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.20" />
|
||||
<PackageReference Include="PasswordGenerator" Version="2.1.0" />
|
||||
|
||||
@@ -6,8 +6,6 @@ namespace PyroFetes;
|
||||
|
||||
public class PyroFetesDbContext : DbContext
|
||||
{
|
||||
|
||||
|
||||
// Entities
|
||||
public DbSet<Availability> Availabilities { get; set; }
|
||||
public DbSet<Brand> Brands { get; set; }
|
||||
@@ -51,15 +49,16 @@ public class PyroFetesDbContext : DbContext
|
||||
public DbSet<User> Users { get; set; }
|
||||
public DbSet<Warehouse> Warehouses { get; set; }
|
||||
public DbSet<WarehouseProduct> WarehouseProducts { get; set; }
|
||||
public DbSet<Login> Logins { get; set; }
|
||||
|
||||
// Database configuration
|
||||
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
|
||||
{
|
||||
string connectionString =
|
||||
"Server=romaric-thibault.fr;" +
|
||||
"Database=PyroMana;" +
|
||||
"User Id=matheo;" +
|
||||
"Password=Onto9-Cage-Afflicted;" +
|
||||
"Database=PyroFetes;" +
|
||||
"User Id=pyrofetes;" +
|
||||
"Password=Crablike8-Fringe-Swimmable;" +
|
||||
"TrustServerCertificate=true;";
|
||||
|
||||
optionsBuilder.UseSqlServer(connectionString);
|
||||
|
||||
@@ -1,281 +0,0 @@
|
||||
# 🎆 Pyrofêtes — Backend
|
||||
|
||||
> API REST de gestion des entrepôts et produits pyrotechniques, développée avec **C#**, **ASP.NET Core** et **FastEndpoints**.
|
||||
|
||||
---
|
||||
|
||||
## 🛠️ Stack technique
|
||||
|
||||
| Technologie | Rôle |
|
||||
|---|---|
|
||||
| [C# / .NET 8](https://dotnet.microsoft.com/) | Langage et runtime principal |
|
||||
| [ASP.NET Core](https://learn.microsoft.com/en-us/aspnet/core/) | Framework web |
|
||||
| [FastEndpoints](https://fast-endpoints.com/) | Bibliothèque d'endpoints REST performants |
|
||||
| Entity Framework Core | ORM pour l'accès à la base de données |
|
||||
| SQL Server | Base de données relationnelle |
|
||||
| JWT Bearer | Authentification par token |
|
||||
|
||||
---
|
||||
|
||||
## 📁 Structure du projet
|
||||
|
||||
```
|
||||
Pyrofetes.API/
|
||||
│
|
||||
├── Models/ # Entités de la base de données (EF Core)
|
||||
│
|
||||
├── DTO/ # Objets de transfert de données
|
||||
│ ├── Brand/
|
||||
│ │ ├── Request/
|
||||
│ │ │ ├── CreateBrandDto.cs
|
||||
│ │ │ └── UpdateBrandDto.cs
|
||||
│ │ └── Response/
|
||||
│ │ └── GetBrandDto.cs
|
||||
│ ├── Classification/
|
||||
│ ├── Color/
|
||||
│ ├── Effect/
|
||||
│ ├── Login/
|
||||
│ ├── Material/
|
||||
│ ├── Movement/
|
||||
│ ├── Product/
|
||||
│ ├── ProductCategory/
|
||||
│ ├── ProductColor/
|
||||
│ ├── ProductEffect/
|
||||
│ ├── ProductSupplierPrice/
|
||||
│ ├── ProductWarehouse/
|
||||
│ ├── Refrresh/ # Token refresh
|
||||
│ ├── Supplier/
|
||||
│ └── Warehouse/
|
||||
│
|
||||
├── Endpoints/ # Endpoints FastEndpoints (CRUD par domaine)
|
||||
│ ├── Brand/
|
||||
│ │ ├── CreateBrandEndpoint.cs
|
||||
│ │ ├── DeleteBrandEndpoint.cs
|
||||
│ │ ├── GetAllBrandsEndpoint.cs
|
||||
│ │ ├── GetBrandEndpoint.cs
|
||||
│ │ └── UpdateBrandEndpoint.cs
|
||||
│ ├── Classification/
|
||||
│ ├── Color/
|
||||
│ ├── Effect/
|
||||
│ ├── Login/
|
||||
│ ├── Material/
|
||||
│ ├── Movement/
|
||||
│ ├── Product/
|
||||
│ ├── ProductCategory/
|
||||
│ ├── Refresh/ # Refresh token JWT
|
||||
│ ├── Supplier/
|
||||
│ └── Warehouse/
|
||||
│
|
||||
├── Data/ # Contexte Entity Framework Core
|
||||
│ └── AppDbContext.cs
|
||||
│
|
||||
├── Migrations/ # Migrations EF Core
|
||||
├── appsettings.json # Configuration production
|
||||
├── appsettings.Development.json # Configuration développement
|
||||
└── Program.cs # Point d'entrée et configuration des services
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Installation et lancement
|
||||
|
||||
### Prérequis
|
||||
|
||||
- [.NET SDK](https://dotnet.microsoft.com/download) >= 8.0
|
||||
- SQL Server en cours d'exécution (local ou distant)
|
||||
- [Entity Framework CLI](https://learn.microsoft.com/en-us/ef/core/cli/dotnet)
|
||||
|
||||
```bash
|
||||
dotnet tool install --global dotnet-ef
|
||||
```
|
||||
|
||||
### Installation
|
||||
|
||||
```bash
|
||||
# Cloner le dépôt
|
||||
git clone https://gitea.btssio-poitiers.fr/reignem/PyroFetes-Sujet1.git
|
||||
cd pyrofetes-backend
|
||||
```
|
||||
|
||||
### Migrations et base de données
|
||||
|
||||
```bash
|
||||
# Créer la base de données et appliquer les migrations
|
||||
dotnet ef database update
|
||||
```
|
||||
|
||||
### Lancement
|
||||
|
||||
```bash
|
||||
dotnet run
|
||||
```
|
||||
|
||||
L'API sera disponible sur [http://localhost:5000](http://localhost:5000)
|
||||
La documentation Swagger sera accessible sur [http://localhost:5000/swagger](http://localhost:5000/swagger)
|
||||
|
||||
---
|
||||
|
||||
## ⚙️ Configuration FastEndpoints + CORS
|
||||
|
||||
Dans `Program.cs` :
|
||||
|
||||
```csharp
|
||||
builder.Services.AddCors(options =>
|
||||
{
|
||||
options.AddPolicy("AllowAngular", policy =>
|
||||
policy.WithOrigins("http://localhost:4200")
|
||||
.AllowAnyHeader()
|
||||
.AllowAnyMethod());
|
||||
});
|
||||
|
||||
builder.Services.AddFastEndpoints();
|
||||
builder.Services.AddJWTBearerAuth("votre-cle-secrete");
|
||||
|
||||
var app = builder.Build();
|
||||
|
||||
app.UseCors("AllowAngular");
|
||||
app.UseAuthentication();
|
||||
app.UseAuthorization();
|
||||
app.UseFastEndpoints();
|
||||
app.Run();
|
||||
```
|
||||
|
||||
### Anatomie d'un endpoint
|
||||
|
||||
Chaque endpoint suit le pattern **Request → Handler → Response** de FastEndpoints :
|
||||
|
||||
```csharp
|
||||
// Endpoints/Brand/GetAllBrandsEndpoint.cs
|
||||
public class GetAllBrandsEndpoint : EndpointWithoutRequest<List<GetBrandDto>>
|
||||
{
|
||||
private readonly AppDbContext _db;
|
||||
|
||||
public GetAllBrandsEndpoint(AppDbContext db) => _db = db;
|
||||
|
||||
public override void Configure()
|
||||
{
|
||||
Get("/api/brands");
|
||||
Roles("Admin", "User");
|
||||
}
|
||||
|
||||
public override async Task HandleAsync(CancellationToken ct)
|
||||
{
|
||||
var brands = await _db.Brands
|
||||
.Select(b => new GetBrandDto { Id = b.Id, Name = b.Name })
|
||||
.ToListAsync(ct);
|
||||
|
||||
await SendOkAsync(brands, ct);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Pattern DTO
|
||||
|
||||
```
|
||||
DTO/
|
||||
└── Brand/
|
||||
├── Request/
|
||||
│ ├── CreateBrandDto.cs ← payload entrant (POST)
|
||||
│ └── UpdateBrandDto.cs ← payload entrant (PUT)
|
||||
└── Response/
|
||||
└── GetBrandDto.cs ← payload sortant (GET)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📡 Endpoints API
|
||||
|
||||
> Tous les endpoints (sauf `/api/auth/*` et `/api/auth/refresh`) requièrent un header `Authorization: Bearer <token>`.
|
||||
|
||||
### Authentification
|
||||
|
||||
| Méthode | Route | Description | Auth |
|
||||
|---|---|---|---|
|
||||
| `POST` | `/api/auth/login` | Connexion, retourne JWT + refresh token | ❌ |
|
||||
| `POST` | `/api/auth/refresh` | Renouvellement du JWT via refresh token | ❌ |
|
||||
|
||||
### Marques (Brand)
|
||||
|
||||
| Méthode | Route | Description |
|
||||
|---|---|---|
|
||||
| `GET` | `/api/brands` | Liste toutes les marques |
|
||||
| `GET` | `/api/brands/{id}` | Détail d'une marque |
|
||||
| `POST` | `/api/brands` | Créer une marque |
|
||||
| `PUT` | `/api/brands/{id}` | Modifier une marque |
|
||||
| `DELETE` | `/api/brands/{id}` | Supprimer une marque |
|
||||
|
||||
### Produits (Product)
|
||||
|
||||
| Méthode | Route | Description |
|
||||
|---|---|---|
|
||||
| `GET` | `/api/products` | Liste tous les produits |
|
||||
| `GET` | `/api/products/{id}` | Détail d'un produit |
|
||||
| `POST` | `/api/products` | Créer un produit |
|
||||
| `PUT` | `/api/products/{id}` | Modifier un produit |
|
||||
| `DELETE` | `/api/products/{id}` | Supprimer un produit |
|
||||
|
||||
### Entrepôts (Warehouse)
|
||||
|
||||
| Méthode | Route | Description |
|
||||
|---|---|---|
|
||||
| `GET` | `/api/warehouses` | Liste tous les entrepôts |
|
||||
| `GET` | `/api/warehouses/{id}` | Détail d'un entrepôt |
|
||||
| `POST` | `/api/warehouses` | Créer un entrepôt |
|
||||
| `PUT` | `/api/warehouses/{id}` | Modifier un entrepôt |
|
||||
| `DELETE` | `/api/warehouses/{id}` | Supprimer un entrepôt |
|
||||
|
||||
### Fournisseurs (Supplier)
|
||||
|
||||
| Méthode | Route | Description |
|
||||
|---|---|---|
|
||||
| `GET` | `/api/suppliers` | Liste tous les fournisseurs |
|
||||
| `GET` | `/api/suppliers/{id}` | Détail d'un fournisseur |
|
||||
| `POST` | `/api/suppliers` | Créer un fournisseur |
|
||||
| `PUT` | `/api/suppliers/{id}` | Modifier un fournisseur |
|
||||
| `DELETE` | `/api/suppliers/{id}` | Supprimer un fournisseur |
|
||||
|
||||
### Autres domaines disponibles
|
||||
|
||||
| Domaine | Préfixe route |
|
||||
|---|---|
|
||||
| Classifications | `/api/classifications` |
|
||||
| Couleurs | `/api/colors` |
|
||||
| Effets | `/api/effects` |
|
||||
| Matériaux | `/api/materials` |
|
||||
| Mouvements de stock | `/api/movements` |
|
||||
| Catégories produit | `/api/product-categories` |
|
||||
| Couleurs produit | `/api/product-colors` |
|
||||
| Effets produit | `/api/product-effects` |
|
||||
| Prix fournisseur produit | `/api/product-supplier-prices` |
|
||||
|
||||
---
|
||||
|
||||
## 🔐 Authentification JWT
|
||||
|
||||
### Flux d'authentification
|
||||
|
||||
```
|
||||
Client (Angular) API (FastEndpoints)
|
||||
│ │
|
||||
│── POST /api/auth/login ──▶│
|
||||
│ │ Vérifie credentials
|
||||
│◀── { token, refreshToken }│
|
||||
│ │
|
||||
│── GET /api/... ──────────▶│
|
||||
│ Authorization: Bearer │ Valide le JWT
|
||||
│◀── 200 OK ────────────────│
|
||||
│ │
|
||||
│── POST /api/auth/refresh ▶│ (token expiré)
|
||||
│◀── { newToken } ──────────│
|
||||
```
|
||||
|
||||
### Header requis
|
||||
|
||||
```
|
||||
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
|
||||
```
|
||||
---
|
||||
|
||||
## 📄 Licence
|
||||
|
||||
Ce projet est à usage interne — © Pyrofêtes. Tous droits réservés.
|
||||
@@ -1,281 +1,50 @@
|
||||
# 🎆 Pyrofêtes — Backend
|
||||
# Gestionnaire de Stocks et Commandes
|
||||
|
||||
> API REST de gestion des entrepôts et produits pyrotechniques, développée avec **C#**, **ASP.NET Core** et **FastEndpoints**.
|
||||
Cette application web permet de **suivre les stocks**, **automatiser les commandes fournisseurs** et **gérer le cycle complet d’approvisionnement**.
|
||||
Elle est conçue pour simplifier le travail des entreprises en offrant une vue en temps réel sur les produits, leurs fournisseurs et l’état des livraisons.
|
||||
|
||||
---
|
||||
|
||||
## 🛠️ Stack technique
|
||||
## ✨ Fonctionnalités principales
|
||||
|
||||
| Technologie | Rôle |
|
||||
|---|---|
|
||||
| [C# / .NET 8](https://dotnet.microsoft.com/) | Langage et runtime principal |
|
||||
| [ASP.NET Core](https://learn.microsoft.com/en-us/aspnet/core/) | Framework web |
|
||||
| [FastEndpoints](https://fast-endpoints.com/) | Bibliothèque d'endpoints REST performants |
|
||||
| Entity Framework Core | ORM pour l'accès à la base de données |
|
||||
| SQL Server | Base de données relationnelle |
|
||||
| JWT Bearer | Authentification par token |
|
||||
### 1️⃣ Suivi et réapprovisionnement des stocks
|
||||
- Définissez un **niveau minimal de stock** pour chaque produit.
|
||||
- Surveillez les **niveaux en temps réel** grâce à une interface claire.
|
||||
- Lorsqu’un produit atteint ou descend sous son seuil minimal, le système **génère automatiquement un bon de commande** pour le réapprovisionner.
|
||||
|
||||
### 2️⃣ Gestion des fournisseurs
|
||||
- Enregistrez les informations complètes des fournisseurs : nom, adresse, coordonnées, produits fournis, délais de livraison.
|
||||
- **Associez un ou plusieurs fournisseurs** à chaque produit.
|
||||
- Lorsqu’un bon de commande est créé, le système **propose automatiquement les fournisseurs appropriés**.
|
||||
|
||||
### 3️⃣ Devis et bons de commande
|
||||
- Créez des **devis personnalisés** : sélection des produits, quantités, prix, ajout d’un logo, message ou conditions de vente.
|
||||
- **Imprimez ou exportez** vos devis au format PDF.
|
||||
- Générez des **bons de commande** en quelques clics, avec personnalisation (logo, conditions d’achat) et exportation en PDF.
|
||||
|
||||
### 4️⃣ Suivi des livraisons
|
||||
- **Transformez un bon de commande en bon de livraison** dès l’expédition des produits par le fournisseur.
|
||||
- Enregistrez toutes les informations importantes : date d’expédition, transporteur, numéro de suivi, date prévue et date effective de livraison.
|
||||
- Recevez des **alertes en cas de retard**.
|
||||
- Gérez la **réception des produits** et vérifiez leur conformité.
|
||||
|
||||
---
|
||||
|
||||
## 📁 Structure du projet
|
||||
|
||||
```
|
||||
Pyrofetes.API/
|
||||
│
|
||||
├── Models/ # Entités de la base de données (EF Core)
|
||||
│
|
||||
├── DTO/ # Objets de transfert de données
|
||||
│ ├── Brand/
|
||||
│ │ ├── Request/
|
||||
│ │ │ ├── CreateBrandDto.cs
|
||||
│ │ │ └── UpdateBrandDto.cs
|
||||
│ │ └── Response/
|
||||
│ │ └── GetBrandDto.cs
|
||||
│ ├── Classification/
|
||||
│ ├── Color/
|
||||
│ ├── Effect/
|
||||
│ ├── Login/
|
||||
│ ├── Material/
|
||||
│ ├── Movement/
|
||||
│ ├── Product/
|
||||
│ ├── ProductCategory/
|
||||
│ ├── ProductColor/
|
||||
│ ├── ProductEffect/
|
||||
│ ├── ProductSupplierPrice/
|
||||
│ ├── ProductWarehouse/
|
||||
│ ├── Refrresh/ # Token refresh
|
||||
│ ├── Supplier/
|
||||
│ └── Warehouse/
|
||||
│
|
||||
├── Endpoints/ # Endpoints FastEndpoints (CRUD par domaine)
|
||||
│ ├── Brand/
|
||||
│ │ ├── CreateBrandEndpoint.cs
|
||||
│ │ ├── DeleteBrandEndpoint.cs
|
||||
│ │ ├── GetAllBrandsEndpoint.cs
|
||||
│ │ ├── GetBrandEndpoint.cs
|
||||
│ │ └── UpdateBrandEndpoint.cs
|
||||
│ ├── Classification/
|
||||
│ ├── Color/
|
||||
│ ├── Effect/
|
||||
│ ├── Login/
|
||||
│ ├── Material/
|
||||
│ ├── Movement/
|
||||
│ ├── Product/
|
||||
│ ├── ProductCategory/
|
||||
│ ├── Refresh/ # Refresh token JWT
|
||||
│ ├── Supplier/
|
||||
│ └── Warehouse/
|
||||
│
|
||||
├── Data/ # Contexte Entity Framework Core
|
||||
│ └── AppDbContext.cs
|
||||
│
|
||||
├── Migrations/ # Migrations EF Core
|
||||
├── appsettings.json # Configuration production
|
||||
├── appsettings.Development.json # Configuration développement
|
||||
└── Program.cs # Point d'entrée et configuration des services
|
||||
```
|
||||
## 🗂️ Livrables prévus
|
||||
- **Modèle de données** : diagramme de classes commun à tous les groupes.
|
||||
- **Interface utilisateur** : maquettes ou prototypes interactifs.
|
||||
- **Code source commenté** pour une meilleure compréhension.
|
||||
- **Documentation technique** : description des fonctionnalités, architecture de l’application et API.
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Installation et lancement
|
||||
|
||||
### Prérequis
|
||||
|
||||
- [.NET SDK](https://dotnet.microsoft.com/download) >= 8.0
|
||||
- SQL Server en cours d'exécution (local ou distant)
|
||||
- [Entity Framework CLI](https://learn.microsoft.com/en-us/ef/core/cli/dotnet)
|
||||
|
||||
```bash
|
||||
dotnet tool install --global dotnet-ef
|
||||
```
|
||||
|
||||
### Installation
|
||||
|
||||
```bash
|
||||
# Cloner le dépôt
|
||||
git clone https://gitea.btssio-poitiers.fr/reignem/PyroFetes-Sujet1.git
|
||||
cd pyrofetes-backend
|
||||
```
|
||||
|
||||
### Migrations et base de données
|
||||
|
||||
```bash
|
||||
# Créer la base de données et appliquer les migrations
|
||||
dotnet ef database update
|
||||
```
|
||||
|
||||
### Lancement
|
||||
|
||||
```bash
|
||||
dotnet run
|
||||
```
|
||||
|
||||
L'API sera disponible sur [http://localhost:5000](http://localhost:5000)
|
||||
La documentation Swagger sera accessible sur [http://localhost:5000/swagger](http://localhost:5000/swagger)
|
||||
## 👥 Équipe
|
||||
- **Mathys**
|
||||
- **Enzo**
|
||||
- **Cristiano**
|
||||
- **Arsène**
|
||||
|
||||
---
|
||||
|
||||
## ⚙️ Configuration FastEndpoints + CORS
|
||||
|
||||
Dans `Program.cs` :
|
||||
|
||||
```csharp
|
||||
builder.Services.AddCors(options =>
|
||||
{
|
||||
options.AddPolicy("AllowAngular", policy =>
|
||||
policy.WithOrigins("http://localhost:4200")
|
||||
.AllowAnyHeader()
|
||||
.AllowAnyMethod());
|
||||
});
|
||||
|
||||
builder.Services.AddFastEndpoints();
|
||||
builder.Services.AddJWTBearerAuth("votre-cle-secrete");
|
||||
|
||||
var app = builder.Build();
|
||||
|
||||
app.UseCors("AllowAngular");
|
||||
app.UseAuthentication();
|
||||
app.UseAuthorization();
|
||||
app.UseFastEndpoints();
|
||||
app.Run();
|
||||
```
|
||||
|
||||
### Anatomie d'un endpoint
|
||||
|
||||
Chaque endpoint suit le pattern **Request → Handler → Response** de FastEndpoints :
|
||||
|
||||
```csharp
|
||||
// Endpoints/Brand/GetAllBrandsEndpoint.cs
|
||||
public class GetAllBrandsEndpoint : EndpointWithoutRequest<List<GetBrandDto>>
|
||||
{
|
||||
private readonly AppDbContext _db;
|
||||
|
||||
public GetAllBrandsEndpoint(AppDbContext db) => _db = db;
|
||||
|
||||
public override void Configure()
|
||||
{
|
||||
Get("/api/brands");
|
||||
Roles("Admin", "User");
|
||||
}
|
||||
|
||||
public override async Task HandleAsync(CancellationToken ct)
|
||||
{
|
||||
var brands = await _db.Brands
|
||||
.Select(b => new GetBrandDto { Id = b.Id, Name = b.Name })
|
||||
.ToListAsync(ct);
|
||||
|
||||
await SendOkAsync(brands, ct);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Pattern DTO
|
||||
|
||||
```
|
||||
DTO/
|
||||
└── Brand/
|
||||
├── Request/
|
||||
│ ├── CreateBrandDto.cs ← payload entrant (POST)
|
||||
│ └── UpdateBrandDto.cs ← payload entrant (PUT)
|
||||
└── Response/
|
||||
└── GetBrandDto.cs ← payload sortant (GET)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📡 Endpoints API
|
||||
|
||||
> Tous les endpoints (sauf `/api/auth/*` et `/api/auth/refresh`) requièrent un header `Authorization: Bearer <token>`.
|
||||
|
||||
### Authentification
|
||||
|
||||
| Méthode | Route | Description | Auth |
|
||||
|---|---|---|---|
|
||||
| `POST` | `/api/auth/login` | Connexion, retourne JWT + refresh token | ❌ |
|
||||
| `POST` | `/api/auth/refresh` | Renouvellement du JWT via refresh token | ❌ |
|
||||
|
||||
### Marques (Brand)
|
||||
|
||||
| Méthode | Route | Description |
|
||||
|---|---|---|
|
||||
| `GET` | `/api/brands` | Liste toutes les marques |
|
||||
| `GET` | `/api/brands/{id}` | Détail d'une marque |
|
||||
| `POST` | `/api/brands` | Créer une marque |
|
||||
| `PUT` | `/api/brands/{id}` | Modifier une marque |
|
||||
| `DELETE` | `/api/brands/{id}` | Supprimer une marque |
|
||||
|
||||
### Produits (Product)
|
||||
|
||||
| Méthode | Route | Description |
|
||||
|---|---|---|
|
||||
| `GET` | `/api/products` | Liste tous les produits |
|
||||
| `GET` | `/api/products/{id}` | Détail d'un produit |
|
||||
| `POST` | `/api/products` | Créer un produit |
|
||||
| `PUT` | `/api/products/{id}` | Modifier un produit |
|
||||
| `DELETE` | `/api/products/{id}` | Supprimer un produit |
|
||||
|
||||
### Entrepôts (Warehouse)
|
||||
|
||||
| Méthode | Route | Description |
|
||||
|---|---|---|
|
||||
| `GET` | `/api/warehouses` | Liste tous les entrepôts |
|
||||
| `GET` | `/api/warehouses/{id}` | Détail d'un entrepôt |
|
||||
| `POST` | `/api/warehouses` | Créer un entrepôt |
|
||||
| `PUT` | `/api/warehouses/{id}` | Modifier un entrepôt |
|
||||
| `DELETE` | `/api/warehouses/{id}` | Supprimer un entrepôt |
|
||||
|
||||
### Fournisseurs (Supplier)
|
||||
|
||||
| Méthode | Route | Description |
|
||||
|---|---|---|
|
||||
| `GET` | `/api/suppliers` | Liste tous les fournisseurs |
|
||||
| `GET` | `/api/suppliers/{id}` | Détail d'un fournisseur |
|
||||
| `POST` | `/api/suppliers` | Créer un fournisseur |
|
||||
| `PUT` | `/api/suppliers/{id}` | Modifier un fournisseur |
|
||||
| `DELETE` | `/api/suppliers/{id}` | Supprimer un fournisseur |
|
||||
|
||||
### Autres domaines disponibles
|
||||
|
||||
| Domaine | Préfixe route |
|
||||
|---|---|
|
||||
| Classifications | `/api/classifications` |
|
||||
| Couleurs | `/api/colors` |
|
||||
| Effets | `/api/effects` |
|
||||
| Matériaux | `/api/materials` |
|
||||
| Mouvements de stock | `/api/movements` |
|
||||
| Catégories produit | `/api/product-categories` |
|
||||
| Couleurs produit | `/api/product-colors` |
|
||||
| Effets produit | `/api/product-effects` |
|
||||
| Prix fournisseur produit | `/api/product-supplier-prices` |
|
||||
|
||||
---
|
||||
|
||||
## 🔐 Authentification JWT
|
||||
|
||||
### Flux d'authentification
|
||||
|
||||
```
|
||||
Client (Angular) API (FastEndpoints)
|
||||
│ │
|
||||
│── POST /api/auth/login ──▶│
|
||||
│ │ Vérifie credentials
|
||||
│◀── { token, refreshToken }│
|
||||
│ │
|
||||
│── GET /api/... ──────────▶│
|
||||
│ Authorization: Bearer │ Valide le JWT
|
||||
│◀── 200 OK ────────────────│
|
||||
│ │
|
||||
│── POST /api/auth/refresh ▶│ (token expiré)
|
||||
│◀── { newToken } ──────────│
|
||||
```
|
||||
|
||||
### Header requis
|
||||
|
||||
```
|
||||
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
|
||||
```
|
||||
---
|
||||
|
||||
## 📄 Licence
|
||||
|
||||
Ce projet est à usage interne — © Pyrofêtes. Tous droits réservés.
|
||||
## 🚀 Objectif
|
||||
Fournir un outil complet pour automatiser la gestion des stocks et des commandes, réduisant les erreurs humaines, améliorant le suivi des livraisons et facilitant la communication avec les fournisseurs.
|
||||
Generated
-18
@@ -1,18 +0,0 @@
|
||||
{
|
||||
"name": "PyroFete",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"dependencies": {
|
||||
"zone.js": "^0.16.0"
|
||||
}
|
||||
},
|
||||
"node_modules/zone.js": {
|
||||
"version": "0.16.0",
|
||||
"resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.16.0.tgz",
|
||||
"integrity": "sha512-LqLPpIQANebrlxY6jKcYKdgN5DTXyyHAKnnWWjE5pPfEQ4n7j5zn7mOEEpwNZVKGqx3kKKmvplEmoBrvpgROTA==",
|
||||
"license": "MIT"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"zone.js": "^0.16.0"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user