react-version #1

Merged
memartel_loc merged 290 commits from react-version into main 2023-11-04 09:48:15 -04:00
7 changed files with 119 additions and 42 deletions
Showing only changes of commit 0b7b9689b1 - Show all commits

View File

@ -58,7 +58,7 @@ public class InvoiceController : Controller {
try { // TODO: Débugger ça.
id = _signInMan.Context.User.Identity.GetUserId();
if (all is not null && all == true && roles.Contains("Administrateur"))
return Ok(_context.Invoices.Include("LinkedAccount, ShippingAddress").ToList());
return Ok(_context.Invoices/*.Include("LinkedAccount").Include("ShippingAddress"/*"LinkedAccount, ShippingAddress")*/.ToList());
else return Ok(_context.Invoices.Include("ShippingAddress").Where(x => x.LinkedAccount != null &&
x.LinkedAccount.Id == id).ToList());
} catch (Exception e) {
@ -94,18 +94,39 @@ public class InvoiceController : Controller {
}
[HttpPost, AllowAnonymous]
public async Task<ActionResult<InvoiceModel>> Post(InvoiceModel inv) {
public async Task<ActionResult<InvoiceModel>> Post(SendInvoiceModel sinv) {
var user = await _userMan.GetUserAsync(_signInMan.Context.User);
var prodcom = inv.Products.ToList();
var prodcom = sinv.ProdQuant;
Dictionary<int, uint> badprods = new();
List<ProductModel> prods;
InvoiceModel inv = new() {
FirstName = sinv.FirstName,
LastName = sinv.LastName,
EmailAddress = sinv.EmailAddress,
PhoneNumber = sinv.PhoneNumber,
PurchaseDate = DateTime.Now
};
AddressModel ad = _context.Addresses.FirstOrDefault(x => x.CivicNumber == sinv.CivicNumber &&
x.Appartment == sinv.Appartment &&
x.Street == sinv.Street &&
x.City == sinv.City &&
x.Province == sinv.Province &&
x.Country == sinv.Country) ??
new() {
CivicNumber = sinv.CivicNumber,
Appartment = sinv.Appartment,
Street = sinv.Street,
City = sinv.City,
Province = sinv.Province,
Country = sinv.Country,
PostalCode = sinv.PostalCode
};
inv.ShippingAddress = ad;
if (user is not null)
inv.LinkedAccount = user;
inv.PurchaseDate = DateTime.Now; // Pour forcer la date.
try {
prods = _context.Products.Where(x => inv.Products.Select(x => x.Product).Contains(x)).ToList();
prods = _context.Products.Where(x => sinv.ProdQuant.Select(x => x.Key).Contains(x.Id)).ToList();
} catch (Exception e) {
_logger.LogError(8, e.Message);
return BadRequest();
@ -114,30 +135,31 @@ public class InvoiceController : Controller {
if (prods.Count == 0)
return BadRequest("Vous devez inclure au moins un produit à votre commande.");
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)
badprods.Add(prod.Id, prod.Quantity);
if (inventProd.Quantity == prod.Quantity) {
foreach (var prod in sinv.ProdQuant) { // Update de quantités dans l'inventaire.
ProductModel inventProd = prods.Where(x => x.Id == prod.Key).First();
if (inventProd.Quantity > prod.Value)
badprods.Add(prod.Key, prod.Value);
if (inventProd.Quantity == prod.Value) {
inventProd.Quantity = 0;
inventProd.Status = inventProd.Status == ProductModel.States.Clearance ?
ProductModel.States.Discontinued :
ProductModel.States.BackOrder;
} else inventProd.Quantity -= prod.Quantity;
} else inventProd.Quantity -= prod.Value;
inventProd.LastSale = DateTime.Now;
inventProd.Sales += prod.Quantity;
inventProd.Sales += prod.Value;
}
if (badprods.Count > 0) // Retour des produits non-achetable avec l'inventaire restant.
return BadRequest(badprods.ToArray());
try { // Faire les updates dans la BD.
_context.Addresses.Add(ad);
_context.Invoices.Add(inv);
_context.Products.UpdateRange(prods);
_context.SaveChanges();
} catch (Exception e) {
_logger.LogError(8, e.Message);
return BadRequest();
return BadRequest(e.InnerException.Message);
}
_cache.askForRefresh();

View File

@ -12,7 +12,7 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
namespace GrossesMitainesAPI.Migrations
{
[DbContext(typeof(InventoryContext))]
[Migration("20221101172005_Initial.Db")]
[Migration("20221104221311_Initial-Db")]
partial class InitialDb
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
@ -103,7 +103,7 @@ namespace GrossesMitainesAPI.Migrations
{
Id = "ecf7503a-591c-454e-a824-048e10bd0474",
AccessFailedCount = 0,
ConcurrencyStamp = "6259a59c-35df-4662-84e5-a783e653a643",
ConcurrencyStamp = "6ecf4a66-157e-4a5c-a6ba-84c0d8df9d8f",
Email = "admin@admin.com",
EmailConfirmed = false,
FirstName = "Roger",
@ -111,9 +111,9 @@ namespace GrossesMitainesAPI.Migrations
LockoutEnabled = false,
NormalizedEmail = "ADMIN@ADMIN.COM",
NormalizedUserName = "ADMIN",
PasswordHash = "AQAAAAEAACcQAAAAELHpALZdYcW7KzDcU2ovqwdWsfSx68md+LnjvL5ZgJ2OWuTFwJM3gPzQ1yP3RHCn9g==",
PasswordHash = "AQAAAAEAACcQAAAAELk80UgvLbSDu3xg805PHJkdcTaFrtU/wZOBkOdJFw9ji5gpPe6G3lTu2FF1ysj7eg==",
PhoneNumberConfirmed = false,
SecurityStamp = "c43f4d48-f1bb-4a24-8cd3-78422556cf85",
SecurityStamp = "eb2a7531-4487-4a67-9601-adfc03a601cf",
TwoFactorEnabled = false,
UserName = "Admin"
});
@ -175,9 +175,6 @@ namespace GrossesMitainesAPI.Migrations
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"), 1L, 1);
b.Property<bool>("Canceled")
.HasColumnType("bit");
b.Property<string>("EmailAddress")
.IsRequired()
.HasColumnType("nvarchar(max)");
@ -199,9 +196,15 @@ namespace GrossesMitainesAPI.Migrations
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<DateTime>("PurchaseDate")
.HasColumnType("datetime2");
b.Property<int>("ShippingAddressId")
.HasColumnType("int");
b.Property<int>("Status")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("LinkedAccountId");
@ -225,8 +228,8 @@ namespace GrossesMitainesAPI.Migrations
b.Property<int>("ProductId")
.HasColumnType("int");
b.Property<int>("Quantity")
.HasColumnType("int");
b.Property<long>("Quantity")
.HasColumnType("bigint");
b.HasKey("Id");
@ -560,14 +563,14 @@ namespace GrossesMitainesAPI.Migrations
new
{
Id = "c9e08b20-d8a5-473f-9f52-572eb23c12af",
ConcurrencyStamp = "56321382-1bb3-4dfe-87bf-6919c0791765",
ConcurrencyStamp = "9708e256-7f72-43a3-9981-3d46a496efef",
Name = "Administrateur",
NormalizedName = "ADMINISTRATEUR"
},
new
{
Id = "1b7b9c55-c746-493a-a24f-3d5ca937298e",
ConcurrencyStamp = "0e3b1bc2-f632-4f63-9bea-ac995e2e95a7",
ConcurrencyStamp = "ea9b728b-01ce-41db-a0b8-267b641c38c8",
Name = "Client",
NormalizedName = "CLIENT"
});

View File

@ -216,8 +216,9 @@ namespace GrossesMitainesAPI.Migrations
PhoneNumber = table.Column<string>(type: "nvarchar(max)", nullable: false),
EmailAddress = table.Column<string>(type: "nvarchar(max)", nullable: false),
LinkedAccountId = table.Column<string>(type: "nvarchar(450)", nullable: true),
PurchaseDate = table.Column<DateTime>(type: "datetime2", nullable: false),
ShippingAddressId = table.Column<int>(type: "int", nullable: false),
Canceled = table.Column<bool>(type: "bit", nullable: false)
Status = table.Column<int>(type: "int", nullable: false)
},
constraints: table =>
{
@ -242,7 +243,7 @@ namespace GrossesMitainesAPI.Migrations
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
ProductId = table.Column<int>(type: "int", nullable: false),
Quantity = table.Column<int>(type: "int", nullable: false),
Quantity = table.Column<long>(type: "bigint", nullable: false),
InvoiceModelId = table.Column<int>(type: "int", nullable: true)
},
constraints: table =>
@ -266,14 +267,14 @@ namespace GrossesMitainesAPI.Migrations
columns: new[] { "Id", "ConcurrencyStamp", "Name", "NormalizedName" },
values: new object[,]
{
{ "1b7b9c55-c746-493a-a24f-3d5ca937298e", "0e3b1bc2-f632-4f63-9bea-ac995e2e95a7", "Client", "CLIENT" },
{ "c9e08b20-d8a5-473f-9f52-572eb23c12af", "56321382-1bb3-4dfe-87bf-6919c0791765", "Administrateur", "ADMINISTRATEUR" }
{ "1b7b9c55-c746-493a-a24f-3d5ca937298e", "ea9b728b-01ce-41db-a0b8-267b641c38c8", "Client", "CLIENT" },
{ "c9e08b20-d8a5-473f-9f52-572eb23c12af", "9708e256-7f72-43a3-9981-3d46a496efef", "Administrateur", "ADMINISTRATEUR" }
});
migrationBuilder.InsertData(
table: "AspNetUsers",
columns: new[] { "Id", "AccessFailedCount", "ConcurrencyStamp", "Email", "EmailConfirmed", "FirstName", "LastName", "LockoutEnabled", "LockoutEnd", "NormalizedEmail", "NormalizedUserName", "PasswordHash", "PhoneNumber", "PhoneNumberConfirmed", "SecurityStamp", "TwoFactorEnabled", "UserName" },
values: new object[] { "ecf7503a-591c-454e-a824-048e10bd0474", 0, "6259a59c-35df-4662-84e5-a783e653a643", "admin@admin.com", false, "Roger", "Admin", false, null, "ADMIN@ADMIN.COM", "ADMIN", "AQAAAAEAACcQAAAAELHpALZdYcW7KzDcU2ovqwdWsfSx68md+LnjvL5ZgJ2OWuTFwJM3gPzQ1yP3RHCn9g==", null, false, "c43f4d48-f1bb-4a24-8cd3-78422556cf85", false, "Admin" });
values: new object[] { "ecf7503a-591c-454e-a824-048e10bd0474", 0, "6ecf4a66-157e-4a5c-a6ba-84c0d8df9d8f", "admin@admin.com", false, "Roger", "Admin", false, null, "ADMIN@ADMIN.COM", "ADMIN", "AQAAAAEAACcQAAAAELk80UgvLbSDu3xg805PHJkdcTaFrtU/wZOBkOdJFw9ji5gpPe6G3lTu2FF1ysj7eg==", null, false, "eb2a7531-4487-4a67-9601-adfc03a601cf", false, "Admin" });
migrationBuilder.InsertData(
table: "Products",

View File

@ -101,7 +101,7 @@ namespace GrossesMitainesAPI.Migrations
{
Id = "ecf7503a-591c-454e-a824-048e10bd0474",
AccessFailedCount = 0,
ConcurrencyStamp = "6259a59c-35df-4662-84e5-a783e653a643",
ConcurrencyStamp = "6ecf4a66-157e-4a5c-a6ba-84c0d8df9d8f",
Email = "admin@admin.com",
EmailConfirmed = false,
FirstName = "Roger",
@ -109,9 +109,9 @@ namespace GrossesMitainesAPI.Migrations
LockoutEnabled = false,
NormalizedEmail = "ADMIN@ADMIN.COM",
NormalizedUserName = "ADMIN",
PasswordHash = "AQAAAAEAACcQAAAAELHpALZdYcW7KzDcU2ovqwdWsfSx68md+LnjvL5ZgJ2OWuTFwJM3gPzQ1yP3RHCn9g==",
PasswordHash = "AQAAAAEAACcQAAAAELk80UgvLbSDu3xg805PHJkdcTaFrtU/wZOBkOdJFw9ji5gpPe6G3lTu2FF1ysj7eg==",
PhoneNumberConfirmed = false,
SecurityStamp = "c43f4d48-f1bb-4a24-8cd3-78422556cf85",
SecurityStamp = "eb2a7531-4487-4a67-9601-adfc03a601cf",
TwoFactorEnabled = false,
UserName = "Admin"
});
@ -173,9 +173,6 @@ namespace GrossesMitainesAPI.Migrations
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"), 1L, 1);
b.Property<bool>("Canceled")
.HasColumnType("bit");
b.Property<string>("EmailAddress")
.IsRequired()
.HasColumnType("nvarchar(max)");
@ -197,9 +194,15 @@ namespace GrossesMitainesAPI.Migrations
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<DateTime>("PurchaseDate")
.HasColumnType("datetime2");
b.Property<int>("ShippingAddressId")
.HasColumnType("int");
b.Property<int>("Status")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("LinkedAccountId");
@ -223,8 +226,8 @@ namespace GrossesMitainesAPI.Migrations
b.Property<int>("ProductId")
.HasColumnType("int");
b.Property<int>("Quantity")
.HasColumnType("int");
b.Property<long>("Quantity")
.HasColumnType("bigint");
b.HasKey("Id");
@ -558,14 +561,14 @@ namespace GrossesMitainesAPI.Migrations
new
{
Id = "c9e08b20-d8a5-473f-9f52-572eb23c12af",
ConcurrencyStamp = "56321382-1bb3-4dfe-87bf-6919c0791765",
ConcurrencyStamp = "9708e256-7f72-43a3-9981-3d46a496efef",
Name = "Administrateur",
NormalizedName = "ADMINISTRATEUR"
},
new
{
Id = "1b7b9c55-c746-493a-a24f-3d5ca937298e",
ConcurrencyStamp = "0e3b1bc2-f632-4f63-9bea-ac995e2e95a7",
ConcurrencyStamp = "ea9b728b-01ce-41db-a0b8-267b641c38c8",
Name = "Client",
NormalizedName = "CLIENT"
});

View File

@ -3,7 +3,7 @@
namespace GrossesMitainesAPI.Models;
public class AddressModel {
[Key]
public int Id { get; set; }
public int Id { get; set; } = 0;
[Required, Range(1, int.MaxValue)]
public int CivicNumber { get; set; }
public string? Appartment { get; set; }
@ -18,5 +18,16 @@ public class AddressModel {
// Source pour regex: https://stackoverflow.com/questions/15774555/efficient-regex-for-canadian-postal-code-function
//[Required, RegularExpression(@"/^[ABCEGHJ-NPRSTVXY]\d[ABCEGHJ-NPRSTV-Z][ -]?\d[ABCEGHJ-NPRSTV-Z]\d$/i")]
public string PostalCode { get; set; }
public AddressModel() { }
public AddressModel(SendInvoiceModel sinv) {
CivicNumber = sinv.CivicNumber;
Appartment = sinv.Appartment;
Street = sinv.Street;
City = sinv.City;
Province = sinv.Province;
Country = sinv.Country;
PostalCode = sinv.PostalCode;
}
}

View File

@ -37,5 +37,13 @@ public class InvoiceModel {
[Required]
public AddressModel ShippingAddress { get; set; }
public InStates Status { get; set; } = InStates.Confirmed;
public InvoiceModel() { }
public InvoiceModel(SendInvoiceModel sinv) {
FirstName = sinv.FirstName;
LastName = sinv.LastName;
PhoneNumber = sinv.PhoneNumber;
EmailAddress = sinv.EmailAddress;
}
}

View File

@ -0,0 +1,29 @@
using System.ComponentModel.DataAnnotations;
namespace GrossesMitainesAPI.Models;
public class SendInvoiceModel {
[Required, MinLength(2), MaxLength(30)]
public string FirstName { get; set; }
[Required, MinLength(1), MaxLength(30)]
public string LastName { get; set; }
[Required, Phone]
public string PhoneNumber { get; set; }
[Required, EmailAddress]
public string EmailAddress { get; set; }
[Required, Range(1, int.MaxValue)]
public int CivicNumber { get; set; }
public string? Appartment { get; set; }
[Required, MinLength(3), MaxLength(50)]
public string Street { get; set; }
[Required, MinLength(4), MaxLength(50)]
public string City { get; set; }
[Required, MaxLength(3)]
public string Province { get; set; }
[Required, MinLength(4), MaxLength(30)]
public string Country { get; set; }
// Source pour regex: https://stackoverflow.com/questions/15774555/efficient-regex-for-canadian-postal-code-function
//[Required, RegularExpression(@"/^[ABCEGHJ-NPRSTVXY]\d[ABCEGHJ-NPRSTV-Z][ -]?\d[ABCEGHJ-NPRSTV-Z]\d$/i")]
public string PostalCode { get; set; }
public Dictionary<int, uint> ProdQuant { get; set; }
}