CONTROLLERS.
This commit is contained in:
		| @@ -1,22 +1,181 @@ | ||||
| namespace GrossesMitainesAPI.Controllers; | ||||
|  | ||||
| #region Dependencies | ||||
| using GrossesMitainesAPI.Data; | ||||
| using GrossesMitainesAPI.Models; | ||||
| using GrossesMitainesAPI.Services; | ||||
| using Microsoft.AspNetCore.Identity; | ||||
| using Microsoft.AspNetCore.Authorization; | ||||
| using Microsoft.AspNetCore.Cors; | ||||
| using Microsoft.AspNetCore.Mvc; | ||||
| using Microsoft.EntityFrameworkCore; | ||||
| using Microsoft.AspNet.Identity; | ||||
| using System.Data; | ||||
| using System.Linq; | ||||
|  | ||||
| #endregion | ||||
|  | ||||
| [EnableCors("_myAllowSpecificOrigins"), ApiController, Route("api/[controller]"), | ||||
|  Authorize(AuthenticationSchemes = "Identity.Application", Roles = "Administrateur")] | ||||
| public class InvoiceController : Controller { | ||||
|     #region DI Fields | ||||
|     private readonly ILogger<InvoiceController> _logger; | ||||
|     private readonly InventoryContext _context; | ||||
|     private readonly DatabaseCacheService _cache; | ||||
|     private readonly SignInManager<InventoryUser> _signInMan; | ||||
|     private readonly Microsoft.AspNetCore.Identity.UserManager<InventoryUser> _userMan; | ||||
|  | ||||
|     public InvoiceController(ILogger<InvoiceController> logger, InventoryContext context) {  | ||||
|         this._logger = logger; | ||||
|         this._context = context; | ||||
|     #endregion | ||||
|  | ||||
|     #region Ctor | ||||
|     public InvoiceController(ILogger<InvoiceController> logger,  | ||||
|                              InventoryContext context,  | ||||
|                              DatabaseCacheService cache, | ||||
|                              Microsoft.AspNetCore.Identity.UserManager<InventoryUser> userMan) {  | ||||
|         _logger = logger; | ||||
|         _context = context; | ||||
|         _cache = cache; | ||||
|         _userMan = userMan; | ||||
|     } | ||||
|  | ||||
|     #endregion | ||||
|  | ||||
|     #region API Methods | ||||
|     [HttpGet, Route("GetList"), Authorize(Roles = "Client, Administrateur")] | ||||
|     public async Task<ActionResult<List<InvoiceModel>>> Get(bool? all = false) { | ||||
|         IList<string> roles; | ||||
|         string id; | ||||
|         try { // Trouver les rôles de l'utilisateur, assumer non-admin si impossible à trouver. | ||||
|             roles = await _userMan.GetRolesAsync(await _userMan.GetUserAsync(_signInMan.Context.User)); | ||||
|         } catch (Exception e) { | ||||
|             _logger.LogError(10, e.Message); | ||||
|             roles = new List<string>(); | ||||
|         } | ||||
|  | ||||
| } | ||||
|         try { | ||||
|             id = _signInMan.Context.User.Identity.GetUserId(); | ||||
|             if (all is not null && all == true && roles.Contains("Administrateur")) | ||||
|                 return _context.Invoices.Include("LinkedAccount, ShippingAddress").ToList(); | ||||
|             else return _context.Invoices.Include("ShippingAddress").Where(x => x.LinkedAccount != null && | ||||
|                                                 x.LinkedAccount.Id == id).ToList(); | ||||
|         } catch (Exception e) { | ||||
|             _logger.LogError(10, e.Message); | ||||
|             return BadRequest(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     [HttpGet, Route("Get"), Authorize(Roles = "Client, Administrateur")] | ||||
|     public async Task<ActionResult<InvoiceModel>> Get(int id) { | ||||
|         IList<string> roles; | ||||
|         InvoiceModel inv; | ||||
|  | ||||
|         try { // Trouver les rôles de l'utilisateur, assumer non-admin si impossible à trouver. | ||||
|             roles = await _userMan.GetRolesAsync(await _userMan.GetUserAsync(_signInMan.Context.User)); | ||||
|         } catch (Exception e) { | ||||
|             _logger.LogError(10, e.Message); | ||||
|             roles = new List<string>(); | ||||
|         } | ||||
|  | ||||
|         try { | ||||
|             inv = _context.Invoices.Where(x => x.Id == id).Include("ShippingAddress").First(); | ||||
|         } catch (Exception e) { | ||||
|             _logger.LogError(10, e.Message); | ||||
|             return BadRequest(); | ||||
|         } | ||||
|  | ||||
|         if (roles.Contains("Administrateur") || | ||||
|             (inv.LinkedAccount is not null && | ||||
|             inv.LinkedAccount.Id == _signInMan.Context.User.Identity.GetUserId())) | ||||
|             return inv; | ||||
|         else return Unauthorized(); | ||||
|     } | ||||
|  | ||||
|     [HttpPost, AllowAnonymous] | ||||
|     public async Task<ActionResult<InvoiceModel>> Post(InvoiceModel inv) { | ||||
|         var user = await _userMan.GetUserAsync(_signInMan.Context.User); | ||||
|         List<ProductModel> prods; | ||||
|  | ||||
|         if (user is not null) | ||||
|             inv.LinkedAccount = user; | ||||
|         inv.PurchaseDate = DateTime.Now; // Pour forcer la date. | ||||
|  | ||||
|         var prodcom = inv.Products.ToList(); | ||||
|  | ||||
|         try { | ||||
|             prods = _context.Products.Where(x => inv.Products.Select(x => x.Product).Contains(x)).ToList(); | ||||
|         } catch (Exception e) { | ||||
|             _logger.LogError(8, e.Message); | ||||
|             return BadRequest(); | ||||
|         } | ||||
|  | ||||
|         foreach (var prod in prodcom) { // Update de quantités dans l'inventaire. | ||||
|             ProductModel inventProd = prods.Where(x => x.Id == prod.Product.Id).First(); | ||||
|             if (inventProd.Quantity > prod.Quantity) | ||||
|                 return BadRequest(); // TODO: retourner le produit qui ne peut pas être vendu. | ||||
|             if (inventProd.Quantity == prod.Quantity) { | ||||
|                 inventProd.Quantity = 0; | ||||
|                 inventProd.Status = inventProd.Status == ProductModel.States.Clearance ? | ||||
|                                                          ProductModel.States.Discontinued : | ||||
|                                                          ProductModel.States.BackOrder; | ||||
|             } else inventProd.Quantity -= prod.Quantity; | ||||
|         } | ||||
|  | ||||
|         try { // Faire les updates dans la BD. | ||||
|             _context.Invoices.Add(inv); | ||||
|             _context.Products.UpdateRange(prods); | ||||
|             _context.SaveChanges(); | ||||
|         } catch (Exception e) { | ||||
|             _logger.LogError(8, e.Message); | ||||
|             return BadRequest(); | ||||
|         } | ||||
|  | ||||
|         _cache.askForRefresh(); | ||||
|         return Ok(inv); | ||||
|     } | ||||
|  | ||||
|     [HttpPost, Authorize(Roles = "Client, Administrateur")] | ||||
|     public async  Task<ActionResult<InvoiceModel>> Cancel(int id) { | ||||
|         InvoiceModel inv; | ||||
|         IList<string> roles; | ||||
|  | ||||
|         try { // Trouver la commande. | ||||
|             inv = _context.Invoices.Where(x => x.Id == id) | ||||
|                                    .Include("Product").First(); | ||||
|         } catch (Exception e) { | ||||
|             _logger.LogError(8, e.Message); | ||||
|             return BadRequest(); | ||||
|         } | ||||
|  | ||||
|         try { // Trouver les rôles de l'utilisateur, assumer non-admin si impossible à trouver. | ||||
|             roles = await _userMan.GetRolesAsync(await _userMan.GetUserAsync(_signInMan.Context.User)); | ||||
|         } catch (Exception e) { | ||||
|             _logger.LogError(10, e.Message); | ||||
|             roles = new List<string>(); | ||||
|         } | ||||
|  | ||||
|         // Pour ne pas pouvoir arbitrairement annuler la commande d'un autre client en tant que client. | ||||
|         if (!((inv.LinkedAccount is not null &&  | ||||
|              inv.LinkedAccount.Id == _signInMan.Context.User.Identity.GetUserId()) || | ||||
|              roles.Contains("Administrateur"))) | ||||
|             return Unauthorized(); | ||||
|  | ||||
|         inv.Status = InvoiceModel.InStates.Cancelled; | ||||
|  | ||||
|         foreach (var prod in inv.Products) // Revert l'inventaire. | ||||
|             prod.Product.Quantity = prod.Product.Quantity + prod.Quantity; | ||||
|  | ||||
|         try { | ||||
|             _context.Update(inv); | ||||
|             _context.SaveChanges(); | ||||
|         } catch (Exception e) { | ||||
|             _logger.LogError(8, e.Message); | ||||
|             return BadRequest(); | ||||
|         } | ||||
|  | ||||
|         _cache.askForRefresh(); | ||||
|  | ||||
|         return Ok(inv); | ||||
|     } | ||||
|  | ||||
|     #endregion | ||||
| } | ||||
| @@ -30,14 +30,6 @@ public class LoginController : Controller { | ||||
|  | ||||
|     #endregion | ||||
|  | ||||
|     #region Utility Classes | ||||
|     public class LoginUser { | ||||
|         public string email { get; set; } = ""; | ||||
|         public string password { get; set; } = ""; | ||||
|     } | ||||
|  | ||||
|     #endregion | ||||
|  | ||||
|     #region API Methods | ||||
|     [HttpGet, Route("WhoAmI")] | ||||
|     public async Task<ReturnUserViewModel> WhoAmI() { | ||||
| @@ -51,7 +43,7 @@ public class LoginController : Controller { | ||||
|     } | ||||
|  | ||||
|     [HttpPost, Route("Login"), AllowAnonymous] | ||||
|     public async Task<SignInResult> Login(LoginUser user, bool rememberMe = false) { | ||||
|     public async Task<SignInResult> Login(LoginModel user, bool rememberMe = false) { | ||||
|         var User = await _userMan.FindByEmailAsync(user.email); | ||||
|         return await _signInMan.PasswordSignInAsync(User, user.password, rememberMe, false); | ||||
|     } | ||||
|   | ||||
| @@ -1,4 +1,5 @@ | ||||
| using GrossesMitainesAPI.Data; | ||||
| using GrossesMitainesAPI.Models; | ||||
| using Microsoft.AspNetCore.Authorization; | ||||
| using Microsoft.AspNetCore.Cors; | ||||
| using Microsoft.AspNetCore.Identity; | ||||
| @@ -10,16 +11,34 @@ namespace GrossesMitainesAPI.Controllers; | ||||
| public class UserController : Controller { | ||||
|     private readonly UserManager<InventoryUser> _userMan; | ||||
|     private readonly SignInManager<InventoryUser> _signInMan; | ||||
|     private readonly ILogger<UserController> _logger; | ||||
|  | ||||
|     public UserController(SignInManager<InventoryUser> signin, UserManager<InventoryUser> userman) { | ||||
|         this._signInMan = signin; | ||||
|         this._userMan = userman; | ||||
|     public UserController(ILogger<UserController> logger, SignInManager<InventoryUser> signin, UserManager<InventoryUser> userman) { | ||||
|         _logger = logger; | ||||
|         _signInMan = signin; | ||||
|         _userMan = userman; | ||||
|     } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|     [HttpPost, AllowAnonymous] | ||||
|     public async Task<ActionResult<ReturnUserViewModel>> Post(SignUpUserModel sign) { | ||||
|         InventoryUser usr; | ||||
|         try { | ||||
|             usr = new(sign); | ||||
|         } catch {  | ||||
|             return BadRequest("Erreur utilisateur"); | ||||
|         } | ||||
|         try { | ||||
|             usr.PasswordHash = new PasswordHasher<InventoryUser>().HashPassword(usr, sign.Password); | ||||
|         } catch { | ||||
|             return BadRequest("Erreur de mot de passe."); | ||||
|         } | ||||
|         try { | ||||
|             await _userMan.CreateAsync(usr); | ||||
|             await _userMan.AddToRoleAsync(usr, "Client"); | ||||
|         } catch (Exception e) { | ||||
|             return BadRequest(e.Message); | ||||
|         } | ||||
|         return new ReturnUserViewModel(usr, "Client"); | ||||
|     } | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -9,5 +9,16 @@ public class InventoryUser : IdentityUser { | ||||
|     [Required, MinLength(1), MaxLength(30)] | ||||
|     public string LastName { get; set; } | ||||
|     public List<AddressModel> Adresses { get; set; } | ||||
|  | ||||
|     public InventoryUser(SignUpUserModel sign) { | ||||
|         FirstName = sign.FirstName; | ||||
|         LastName = sign.LastName; | ||||
|         UserName = sign.FirstName + " " + sign.LastName; | ||||
|         NormalizedUserName = UserName.ToUpper(); | ||||
|         NormalizedEmail = Email.ToUpper(); | ||||
|         Email = sign.Email; | ||||
|         PhoneNumber = sign.Phone; | ||||
|         Adresses = sign.Adresses; | ||||
|     } | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -5,11 +5,19 @@ using System.ComponentModel.DataAnnotations.Schema; | ||||
|  | ||||
| namespace GrossesMitainesAPI.Models; | ||||
| public class InvoiceModel { | ||||
|     public enum InStates {  | ||||
|         Confirmed, | ||||
|         Cancelled, | ||||
|         Preparing, | ||||
|         Shipping, | ||||
|         Shipped, | ||||
|         Returned | ||||
|     } | ||||
|     public class ProductInvoice { | ||||
|         [Key] | ||||
|         public int Id { get; set; } | ||||
|         public ProductModel Product { get; set; } | ||||
|         public int Quantity { get; set; } | ||||
|         public uint Quantity { get; set; } | ||||
|     } | ||||
|  | ||||
|     [Key] | ||||
| @@ -23,14 +31,11 @@ public class InvoiceModel { | ||||
|     [Required, EmailAddress] | ||||
|     public string EmailAddress { get; set; } | ||||
|     public InventoryUser? LinkedAccount { get; set; } | ||||
|     public DateTime PurchaseDate { get; } = DateTime.Now; | ||||
|     public DateTime PurchaseDate { get; set; } = DateTime.Now; | ||||
|     [Required] | ||||
|     public List<ProductInvoice> Products { get; set; } | ||||
|  | ||||
|     //[Required, Column("BillingAddress")] | ||||
|     //public AddressModel BillingAddress { get; set; } | ||||
|     [Required] | ||||
|     public AddressModel ShippingAddress { get; set; } | ||||
|     public bool Canceled { get; set; } = false; | ||||
|     public InStates Status { get; set; } = InStates.Confirmed; | ||||
| } | ||||
|  | ||||
|   | ||||
							
								
								
									
										5
									
								
								GrossesMitaines/GrossesMitainesAPI/Models/LoginModel.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								GrossesMitaines/GrossesMitainesAPI/Models/LoginModel.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | ||||
| namespace GrossesMitainesAPI.Models; | ||||
| public class LoginModel { | ||||
|     public string email { get; set; } = ""; | ||||
|     public string password { get; set; } = ""; | ||||
| } | ||||
							
								
								
									
										17
									
								
								GrossesMitaines/GrossesMitainesAPI/Models/SignUpUserModel.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								GrossesMitaines/GrossesMitainesAPI/Models/SignUpUserModel.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | ||||
| using System.ComponentModel.DataAnnotations; | ||||
|  | ||||
| namespace GrossesMitainesAPI.Models; | ||||
| public class SignUpUserModel { | ||||
|     [Required, MinLength(2), MaxLength(30)] | ||||
|     public string FirstName { get; set; } | ||||
|     [Required, MinLength(1), MaxLength(30)] | ||||
|     public string LastName { get; set; } | ||||
|     [Required, EmailAddress] | ||||
|     public string Email { get; set; } | ||||
|     [Required, Phone] | ||||
|     public string Phone { get; set; } | ||||
|     [Required] | ||||
|     public string Password { get; set; } | ||||
|     public List<AddressModel> Adresses { get; set; } | ||||
| } | ||||
|  | ||||
		Reference in New Issue
	
	Block a user