Gossage dans API

This commit is contained in:
MarcEricMartel 2022-10-27 09:37:13 -07:00
parent 04c7d68a44
commit 83331a4a08
10 changed files with 213 additions and 39 deletions

View File

@ -5,6 +5,7 @@ using GrossesMitainesAPI.Data;
using Microsoft.Extensions.Logging;
using Microsoft.AspNetCore.Cors;
using GrossesMitainesAPI.Services;
using Microsoft.AspNetCore.Authorization;
namespace GrossesMitainesAPI.Controllers;
@ -22,7 +23,7 @@ public class InventoryController : Controller {
_cache = cache;
}
[EnableCors("_myAllowSpecificOrigins"), HttpGet(Name = "Inventory")] // Pour faire des calls async par paquet de AMOUNT (5) (pour du loading en scrollant)
[EnableCors("_myAllowSpecificOrigins"), HttpGet(Name = "Inventory"), AllowAnonymous] // Pour faire des calls async par paquet de AMOUNT (5) (pour du loading en scrollant)
public IEnumerable<Product> Get(int? lastId, string? order, string? filterPrice, string? filterState, bool? all) {
bool islock = false;
IQueryable<Product> ret;
@ -127,7 +128,7 @@ public class InventoryController : Controller {
}
}
// Inventory/Delete => Décrémenter un produit. Va aller chercher directement dans la BD.
[EnableCors("_myAllowSpecificOrigins"), HttpDelete(Name = "Inventory")]
[EnableCors("_myAllowSpecificOrigins"), HttpDelete(Name = "Inventory"), AllowAnonymous]
public ActionResult<int> Delete(int? id) {
int rid = 0;
if (!id.HasValue) {
@ -139,6 +140,8 @@ public class InventoryController : Controller {
rid = prod.Id;
if (prod.Quantity > 0) {
prod.Quantity = prod.Quantity - 1;
prod.Sales = prod.Sales + 1;
prod.LastSale = DateTime.Now;
if (prod.Quantity == 0)
prod.Status = prod.Status == Product.States.Clearance?
Product.States.Discontinued:

View File

@ -29,7 +29,7 @@ public class ProductController : ControllerBase {
}
[EnableCors("_myAllowSpecificOrigins"), HttpGet(Name = "Product"), AllowAnonymous]
public ActionResult<Product> Get(int id) {
public ActionResult<ProductViewModel> Get(int id) {
Product prod;
try {
prod = _context.Products.Where(x => x.Id == id).First();
@ -38,7 +38,8 @@ public class ProductController : ControllerBase {
_logger.LogError(8, e.Message);
return NotFound();
}
return prod;
_cache.addHit((uint)id);
return new ProductViewModel(prod);
}
[EnableCors("_myAllowSpecificOrigins"), HttpPost(Name = "Product")]

View File

@ -26,14 +26,14 @@ public class SearchController : Controller {
_searchCache = _cache.GetCacheCopy();
}
[EnableCors("_myAllowSpecificOrigins"), HttpGet(Name = "Search")]
[EnableCors("_myAllowSpecificOrigins"), HttpGet(Name = "Search"), AllowAnonymous]
public IEnumerable<Product> Get(string query, bool? preview, bool? deep) {
if (_searchCache is not null)
return SearchCached(query, preview, deep);
else return Search(query, preview, deep);
else return SearchDirect(query, preview, deep);
}
private List<Product> Search(string query, bool? preview, bool? deep) {
private List<Product> SearchDirect(string query, bool? preview, bool? deep) {
List<Product> products = new();
query = query.Trim();
try { // Pour faire une liste priorisée.
@ -80,7 +80,7 @@ public class SearchController : Controller {
query = query.Trim();
if (_searchCache is null) {
_logger.LogError(8, "Erreur de cache.");
return Search(query, preview, deep); // Fallback vers version non-cached en cas d'erreur.
return SearchDirect(query, preview, deep); // Fallback vers version non-cached en cas d'erreur.
}
try { // Pour faire une liste priorisée.
if (preview.HasValue && preview == true)
@ -117,7 +117,7 @@ public class SearchController : Controller {
}
} catch (Exception e) {
_logger.LogError(8, e.Message);
return Search(query, preview, deep); // Fallback vers version non-cached en cas d'erreur.
return SearchDirect(query, preview, deep); // Fallback vers version non-cached en cas d'erreur.
}
return products;
}

View File

@ -1,4 +1,5 @@
// <auto-generated />
using System;
using GrossesMitainesAPI.Data;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
@ -11,7 +12,7 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
namespace GrossesMitainesAPI.Migrations
{
[DbContext(typeof(InventoryContext))]
[Migration("20221025170101_Initial-Db")]
[Migration("20221027160052_Initial-Db")]
partial class InitialDb
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
@ -39,9 +40,18 @@ namespace GrossesMitainesAPI.Migrations
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<long>("Hits")
.HasColumnType("bigint");
b.Property<string>("ImageName")
.HasColumnType("nvarchar(max)");
b.Property<DateTime?>("LastHit")
.HasColumnType("datetime2");
b.Property<DateTime?>("LastSale")
.HasColumnType("datetime2");
b.Property<decimal>("Price")
.HasColumnType("decimal(18,2)");
@ -51,6 +61,9 @@ namespace GrossesMitainesAPI.Migrations
b.Property<long>("Quantity")
.HasColumnType("bigint");
b.Property<long>("Sales")
.HasColumnType("bigint");
b.Property<int>("Status")
.HasColumnType("int");
@ -69,10 +82,12 @@ namespace GrossesMitainesAPI.Migrations
Id = 1,
Category = "Linge",
Description = "Pour faire votre propre bonhomme de 1837, comme dans le bon vieux temps.",
Hits = 0L,
ImageName = "ceintureflechee",
Price = 85.86m,
PromoPrice = 29.99m,
Quantity = 1L,
Sales = 0L,
Status = 4,
Title = "Ceinture flèchée"
},
@ -81,10 +96,12 @@ namespace GrossesMitainesAPI.Migrations
Id = 2,
Category = "Linge",
Description = "Parce que ça sent la coupe!",
Hits = 0L,
ImageName = "pantouflesCH",
Price = 15.64m,
PromoPrice = 9.99m,
Quantity = 54L,
Sales = 0L,
Status = 0,
Title = "Pantoufles du Canadien en Phentex"
},
@ -93,10 +110,12 @@ namespace GrossesMitainesAPI.Migrations
Id = 3,
Category = "Homme",
Description = "On ne lui ferait pas mal, en tout cas!!",
Hits = 0L,
ImageName = "jeanlucmongrain",
Price = 1453.12m,
PromoPrice = 999.99m,
Quantity = 1L,
Sales = 0L,
Status = 3,
Title = "Jean-Luc Mongrain"
},
@ -105,10 +124,12 @@ namespace GrossesMitainesAPI.Migrations
Id = 4,
Category = "Linge",
Description = "Tellement simple et comfortable.",
Hits = 0L,
ImageName = "tshirt",
Price = 12.12m,
PromoPrice = 9.99m,
Quantity = 143L,
Sales = 0L,
Status = 0,
Title = "T-Shirt"
},
@ -117,10 +138,12 @@ namespace GrossesMitainesAPI.Migrations
Id = 5,
Category = "Vêtement d'extérieur",
Description = "Deux pour un!",
Hits = 0L,
ImageName = "mitaines",
Price = 8.18m,
PromoPrice = 6.99m,
Quantity = 1423L,
Sales = 0L,
Status = 0,
Title = "Mitaines"
},
@ -129,10 +152,12 @@ namespace GrossesMitainesAPI.Migrations
Id = 6,
Category = "Vêtement d'extérieur",
Description = "Deux pour un!",
Hits = 0L,
ImageName = "foulard",
Price = 10.56m,
PromoPrice = 8.99m,
Quantity = 14L,
Sales = 0L,
Status = 4,
Title = "Foulard"
},
@ -141,10 +166,12 @@ namespace GrossesMitainesAPI.Migrations
Id = 7,
Category = "Sous-Vêtement",
Description = "Pour garder le p'tit bout au chaud.",
Hits = 0L,
ImageName = "kokin",
Price = 15.45m,
PromoPrice = 12.99m,
Quantity = 144L,
Sales = 0L,
Status = 4,
Title = "Jock-Strap en phentex"
},
@ -153,10 +180,12 @@ namespace GrossesMitainesAPI.Migrations
Id = 8,
Category = "Sous-Vêtement",
Description = "Pour garder l'absence de p'tit bout au chaud.",
Hits = 0L,
ImageName = "kokin",
Price = 15.45m,
PromoPrice = 12.99m,
Quantity = 224L,
Sales = 0L,
Status = 4,
Title = "Jock-Strap féminin en phentex"
},
@ -165,10 +194,12 @@ namespace GrossesMitainesAPI.Migrations
Id = 9,
Category = "Alien",
Description = "En chiffon.",
Hits = 0L,
ImageName = "bibi",
Price = 1045.45m,
PromoPrice = 1023.99m,
Quantity = 1L,
Sales = 0L,
Status = 3,
Title = "Bibi"
},
@ -177,10 +208,12 @@ namespace GrossesMitainesAPI.Migrations
Id = 10,
Category = "Vêtement d'extérieur",
Description = "En chiffon.",
Hits = 0L,
ImageName = "tuque",
Price = 15.45m,
PromoPrice = 12.99m,
Quantity = 1L,
Sales = 0L,
Status = 0,
Title = "Tuque en laine"
},
@ -189,10 +222,12 @@ namespace GrossesMitainesAPI.Migrations
Id = 11,
Category = "Vêtement d'extérieur",
Description = "Pour se faire taper dessus avec une poêle à frire tout en restant au chaud.",
Hits = 0L,
ImageName = "bonhomme",
Price = 145.45m,
PromoPrice = 123.99m,
Quantity = 1L,
Sales = 0L,
Status = 4,
Title = "Habit de Bonhomme Carnaval"
},
@ -201,10 +236,12 @@ namespace GrossesMitainesAPI.Migrations
Id = 12,
Category = "Autre",
Description = "Pour se pêter la fiole avec style.",
Hits = 0L,
ImageName = "gauze",
Price = 145.45m,
PromoPrice = 123.99m,
Quantity = 0L,
Sales = 0L,
Status = 1,
Title = "Gauze en phentex"
},
@ -213,10 +250,12 @@ namespace GrossesMitainesAPI.Migrations
Id = 13,
Category = "Homme",
Description = "En chiffon.",
Hits = 0L,
ImageName = "jesus",
Price = 145.45m,
PromoPrice = 123.99m,
Quantity = 1L,
Sales = 0L,
Status = 3,
Title = "Petit Jésus de plâtre"
},
@ -225,10 +264,12 @@ namespace GrossesMitainesAPI.Migrations
Id = 14,
Category = "Autre",
Description = "À écouter dans l'habit de Bonhomme Carnaval tant que possible.",
Hits = 0L,
ImageName = "vhs",
Price = 3.45m,
PromoPrice = 1.99m,
Quantity = 164363L,
Sales = 0L,
Status = 3,
Title = "VHS de la Guerre des Tuques"
},
@ -237,10 +278,12 @@ namespace GrossesMitainesAPI.Migrations
Id = 15,
Category = "Linge",
Description = "(N'est pas réellement pare-balle).",
Hits = 0L,
ImageName = "chandailquetaine",
Price = 1435.45m,
PromoPrice = 1223.99m,
Quantity = 18L,
Sales = 0L,
Status = 3,
Title = "Gilet pare-balle en laine"
},
@ -249,10 +292,12 @@ namespace GrossesMitainesAPI.Migrations
Id = 16,
Category = "Autre",
Description = "Pour s'éffoirer le nez dedans.",
Hits = 0L,
ImageName = "doudou",
Price = 14.45m,
PromoPrice = 13.99m,
Quantity = 14L,
Sales = 0L,
Status = 0,
Title = "Doudou"
},
@ -261,10 +306,12 @@ namespace GrossesMitainesAPI.Migrations
Id = 17,
Category = "Vêtements d'extérieur",
Description = "Pour avoir l'air thug en hiver.",
Hits = 0L,
ImageName = "mitaines2",
Price = 9.45m,
PromoPrice = 8.99m,
Quantity = 16L,
Sales = 0L,
Status = 0,
Title = "Mitaines pas de doigts"
});

View File

@ -1,4 +1,5 @@
using Microsoft.EntityFrameworkCore.Migrations;
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
@ -21,6 +22,10 @@ namespace GrossesMitainesAPI.Migrations
PromoPrice = table.Column<decimal>(type: "decimal(18,2)", nullable: false),
Quantity = table.Column<long>(type: "bigint", nullable: false),
Status = table.Column<int>(type: "int", nullable: false),
Hits = table.Column<long>(type: "bigint", nullable: false),
Sales = table.Column<long>(type: "bigint", nullable: false),
LastSale = table.Column<DateTime>(type: "datetime2", nullable: true),
LastHit = table.Column<DateTime>(type: "datetime2", nullable: true),
ImageName = table.Column<string>(type: "nvarchar(max)", nullable: true)
},
constraints: table =>
@ -30,26 +35,26 @@ namespace GrossesMitainesAPI.Migrations
migrationBuilder.InsertData(
table: "Products",
columns: new[] { "Id", "Category", "Description", "ImageName", "Price", "PromoPrice", "Quantity", "Status", "Title" },
columns: new[] { "Id", "Category", "Description", "Hits", "ImageName", "LastHit", "LastSale", "Price", "PromoPrice", "Quantity", "Sales", "Status", "Title" },
values: new object[,]
{
{ 1, "Linge", "Pour faire votre propre bonhomme de 1837, comme dans le bon vieux temps.", "ceintureflechee", 85.86m, 29.99m, 1L, 4, "Ceinture flèchée" },
{ 2, "Linge", "Parce que ça sent la coupe!", "pantouflesCH", 15.64m, 9.99m, 54L, 0, "Pantoufles du Canadien en Phentex" },
{ 3, "Homme", "On ne lui ferait pas mal, en tout cas!!", "jeanlucmongrain", 1453.12m, 999.99m, 1L, 3, "Jean-Luc Mongrain" },
{ 4, "Linge", "Tellement simple et comfortable.", "tshirt", 12.12m, 9.99m, 143L, 0, "T-Shirt" },
{ 5, "Vêtement d'extérieur", "Deux pour un!", "mitaines", 8.18m, 6.99m, 1423L, 0, "Mitaines" },
{ 6, "Vêtement d'extérieur", "Deux pour un!", "foulard", 10.56m, 8.99m, 14L, 4, "Foulard" },
{ 7, "Sous-Vêtement", "Pour garder le p'tit bout au chaud.", "kokin", 15.45m, 12.99m, 144L, 4, "Jock-Strap en phentex" },
{ 8, "Sous-Vêtement", "Pour garder l'absence de p'tit bout au chaud.", "kokin", 15.45m, 12.99m, 224L, 4, "Jock-Strap féminin en phentex" },
{ 9, "Alien", "En chiffon.", "bibi", 1045.45m, 1023.99m, 1L, 3, "Bibi" },
{ 10, "Vêtement d'extérieur", "En chiffon.", "tuque", 15.45m, 12.99m, 1L, 0, "Tuque en laine" },
{ 11, "Vêtement d'extérieur", "Pour se faire taper dessus avec une poêle à frire tout en restant au chaud.", "bonhomme", 145.45m, 123.99m, 1L, 4, "Habit de Bonhomme Carnaval" },
{ 12, "Autre", "Pour se pêter la fiole avec style.", "gauze", 145.45m, 123.99m, 0L, 1, "Gauze en phentex" },
{ 13, "Homme", "En chiffon.", "jesus", 145.45m, 123.99m, 1L, 3, "Petit Jésus de plâtre" },
{ 14, "Autre", "À écouter dans l'habit de Bonhomme Carnaval tant que possible.", "vhs", 3.45m, 1.99m, 164363L, 3, "VHS de la Guerre des Tuques" },
{ 15, "Linge", "(N'est pas réellement pare-balle).", "chandailquetaine", 1435.45m, 1223.99m, 18L, 3, "Gilet pare-balle en laine" },
{ 16, "Autre", "Pour s'éffoirer le nez dedans.", "doudou", 14.45m, 13.99m, 14L, 0, "Doudou" },
{ 17, "Vêtements d'extérieur", "Pour avoir l'air thug en hiver.", "mitaines2", 9.45m, 8.99m, 16L, 0, "Mitaines pas de doigts" }
{ 1, "Linge", "Pour faire votre propre bonhomme de 1837, comme dans le bon vieux temps.", 0L, "ceintureflechee", null, null, 85.86m, 29.99m, 1L, 0L, 4, "Ceinture flèchée" },
{ 2, "Linge", "Parce que ça sent la coupe!", 0L, "pantouflesCH", null, null, 15.64m, 9.99m, 54L, 0L, 0, "Pantoufles du Canadien en Phentex" },
{ 3, "Homme", "On ne lui ferait pas mal, en tout cas!!", 0L, "jeanlucmongrain", null, null, 1453.12m, 999.99m, 1L, 0L, 3, "Jean-Luc Mongrain" },
{ 4, "Linge", "Tellement simple et comfortable.", 0L, "tshirt", null, null, 12.12m, 9.99m, 143L, 0L, 0, "T-Shirt" },
{ 5, "Vêtement d'extérieur", "Deux pour un!", 0L, "mitaines", null, null, 8.18m, 6.99m, 1423L, 0L, 0, "Mitaines" },
{ 6, "Vêtement d'extérieur", "Deux pour un!", 0L, "foulard", null, null, 10.56m, 8.99m, 14L, 0L, 4, "Foulard" },
{ 7, "Sous-Vêtement", "Pour garder le p'tit bout au chaud.", 0L, "kokin", null, null, 15.45m, 12.99m, 144L, 0L, 4, "Jock-Strap en phentex" },
{ 8, "Sous-Vêtement", "Pour garder l'absence de p'tit bout au chaud.", 0L, "kokin", null, null, 15.45m, 12.99m, 224L, 0L, 4, "Jock-Strap féminin en phentex" },
{ 9, "Alien", "En chiffon.", 0L, "bibi", null, null, 1045.45m, 1023.99m, 1L, 0L, 3, "Bibi" },
{ 10, "Vêtement d'extérieur", "En chiffon.", 0L, "tuque", null, null, 15.45m, 12.99m, 1L, 0L, 0, "Tuque en laine" },
{ 11, "Vêtement d'extérieur", "Pour se faire taper dessus avec une poêle à frire tout en restant au chaud.", 0L, "bonhomme", null, null, 145.45m, 123.99m, 1L, 0L, 4, "Habit de Bonhomme Carnaval" },
{ 12, "Autre", "Pour se pêter la fiole avec style.", 0L, "gauze", null, null, 145.45m, 123.99m, 0L, 0L, 1, "Gauze en phentex" },
{ 13, "Homme", "En chiffon.", 0L, "jesus", null, null, 145.45m, 123.99m, 1L, 0L, 3, "Petit Jésus de plâtre" },
{ 14, "Autre", "À écouter dans l'habit de Bonhomme Carnaval tant que possible.", 0L, "vhs", null, null, 3.45m, 1.99m, 164363L, 0L, 3, "VHS de la Guerre des Tuques" },
{ 15, "Linge", "(N'est pas réellement pare-balle).", 0L, "chandailquetaine", null, null, 1435.45m, 1223.99m, 18L, 0L, 3, "Gilet pare-balle en laine" },
{ 16, "Autre", "Pour s'éffoirer le nez dedans.", 0L, "doudou", null, null, 14.45m, 13.99m, 14L, 0L, 0, "Doudou" },
{ 17, "Vêtements d'extérieur", "Pour avoir l'air thug en hiver.", 0L, "mitaines2", null, null, 9.45m, 8.99m, 16L, 0L, 0, "Mitaines pas de doigts" }
});
}

View File

@ -1,4 +1,5 @@
// <auto-generated />
using System;
using GrossesMitainesAPI.Data;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
@ -37,9 +38,18 @@ namespace GrossesMitainesAPI.Migrations
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<long>("Hits")
.HasColumnType("bigint");
b.Property<string>("ImageName")
.HasColumnType("nvarchar(max)");
b.Property<DateTime?>("LastHit")
.HasColumnType("datetime2");
b.Property<DateTime?>("LastSale")
.HasColumnType("datetime2");
b.Property<decimal>("Price")
.HasColumnType("decimal(18,2)");
@ -49,6 +59,9 @@ namespace GrossesMitainesAPI.Migrations
b.Property<long>("Quantity")
.HasColumnType("bigint");
b.Property<long>("Sales")
.HasColumnType("bigint");
b.Property<int>("Status")
.HasColumnType("int");
@ -67,10 +80,12 @@ namespace GrossesMitainesAPI.Migrations
Id = 1,
Category = "Linge",
Description = "Pour faire votre propre bonhomme de 1837, comme dans le bon vieux temps.",
Hits = 0L,
ImageName = "ceintureflechee",
Price = 85.86m,
PromoPrice = 29.99m,
Quantity = 1L,
Sales = 0L,
Status = 4,
Title = "Ceinture flèchée"
},
@ -79,10 +94,12 @@ namespace GrossesMitainesAPI.Migrations
Id = 2,
Category = "Linge",
Description = "Parce que ça sent la coupe!",
Hits = 0L,
ImageName = "pantouflesCH",
Price = 15.64m,
PromoPrice = 9.99m,
Quantity = 54L,
Sales = 0L,
Status = 0,
Title = "Pantoufles du Canadien en Phentex"
},
@ -91,10 +108,12 @@ namespace GrossesMitainesAPI.Migrations
Id = 3,
Category = "Homme",
Description = "On ne lui ferait pas mal, en tout cas!!",
Hits = 0L,
ImageName = "jeanlucmongrain",
Price = 1453.12m,
PromoPrice = 999.99m,
Quantity = 1L,
Sales = 0L,
Status = 3,
Title = "Jean-Luc Mongrain"
},
@ -103,10 +122,12 @@ namespace GrossesMitainesAPI.Migrations
Id = 4,
Category = "Linge",
Description = "Tellement simple et comfortable.",
Hits = 0L,
ImageName = "tshirt",
Price = 12.12m,
PromoPrice = 9.99m,
Quantity = 143L,
Sales = 0L,
Status = 0,
Title = "T-Shirt"
},
@ -115,10 +136,12 @@ namespace GrossesMitainesAPI.Migrations
Id = 5,
Category = "Vêtement d'extérieur",
Description = "Deux pour un!",
Hits = 0L,
ImageName = "mitaines",
Price = 8.18m,
PromoPrice = 6.99m,
Quantity = 1423L,
Sales = 0L,
Status = 0,
Title = "Mitaines"
},
@ -127,10 +150,12 @@ namespace GrossesMitainesAPI.Migrations
Id = 6,
Category = "Vêtement d'extérieur",
Description = "Deux pour un!",
Hits = 0L,
ImageName = "foulard",
Price = 10.56m,
PromoPrice = 8.99m,
Quantity = 14L,
Sales = 0L,
Status = 4,
Title = "Foulard"
},
@ -139,10 +164,12 @@ namespace GrossesMitainesAPI.Migrations
Id = 7,
Category = "Sous-Vêtement",
Description = "Pour garder le p'tit bout au chaud.",
Hits = 0L,
ImageName = "kokin",
Price = 15.45m,
PromoPrice = 12.99m,
Quantity = 144L,
Sales = 0L,
Status = 4,
Title = "Jock-Strap en phentex"
},
@ -151,10 +178,12 @@ namespace GrossesMitainesAPI.Migrations
Id = 8,
Category = "Sous-Vêtement",
Description = "Pour garder l'absence de p'tit bout au chaud.",
Hits = 0L,
ImageName = "kokin",
Price = 15.45m,
PromoPrice = 12.99m,
Quantity = 224L,
Sales = 0L,
Status = 4,
Title = "Jock-Strap féminin en phentex"
},
@ -163,10 +192,12 @@ namespace GrossesMitainesAPI.Migrations
Id = 9,
Category = "Alien",
Description = "En chiffon.",
Hits = 0L,
ImageName = "bibi",
Price = 1045.45m,
PromoPrice = 1023.99m,
Quantity = 1L,
Sales = 0L,
Status = 3,
Title = "Bibi"
},
@ -175,10 +206,12 @@ namespace GrossesMitainesAPI.Migrations
Id = 10,
Category = "Vêtement d'extérieur",
Description = "En chiffon.",
Hits = 0L,
ImageName = "tuque",
Price = 15.45m,
PromoPrice = 12.99m,
Quantity = 1L,
Sales = 0L,
Status = 0,
Title = "Tuque en laine"
},
@ -187,10 +220,12 @@ namespace GrossesMitainesAPI.Migrations
Id = 11,
Category = "Vêtement d'extérieur",
Description = "Pour se faire taper dessus avec une poêle à frire tout en restant au chaud.",
Hits = 0L,
ImageName = "bonhomme",
Price = 145.45m,
PromoPrice = 123.99m,
Quantity = 1L,
Sales = 0L,
Status = 4,
Title = "Habit de Bonhomme Carnaval"
},
@ -199,10 +234,12 @@ namespace GrossesMitainesAPI.Migrations
Id = 12,
Category = "Autre",
Description = "Pour se pêter la fiole avec style.",
Hits = 0L,
ImageName = "gauze",
Price = 145.45m,
PromoPrice = 123.99m,
Quantity = 0L,
Sales = 0L,
Status = 1,
Title = "Gauze en phentex"
},
@ -211,10 +248,12 @@ namespace GrossesMitainesAPI.Migrations
Id = 13,
Category = "Homme",
Description = "En chiffon.",
Hits = 0L,
ImageName = "jesus",
Price = 145.45m,
PromoPrice = 123.99m,
Quantity = 1L,
Sales = 0L,
Status = 3,
Title = "Petit Jésus de plâtre"
},
@ -223,10 +262,12 @@ namespace GrossesMitainesAPI.Migrations
Id = 14,
Category = "Autre",
Description = "À écouter dans l'habit de Bonhomme Carnaval tant que possible.",
Hits = 0L,
ImageName = "vhs",
Price = 3.45m,
PromoPrice = 1.99m,
Quantity = 164363L,
Sales = 0L,
Status = 3,
Title = "VHS de la Guerre des Tuques"
},
@ -235,10 +276,12 @@ namespace GrossesMitainesAPI.Migrations
Id = 15,
Category = "Linge",
Description = "(N'est pas réellement pare-balle).",
Hits = 0L,
ImageName = "chandailquetaine",
Price = 1435.45m,
PromoPrice = 1223.99m,
Quantity = 18L,
Sales = 0L,
Status = 3,
Title = "Gilet pare-balle en laine"
},
@ -247,10 +290,12 @@ namespace GrossesMitainesAPI.Migrations
Id = 16,
Category = "Autre",
Description = "Pour s'éffoirer le nez dedans.",
Hits = 0L,
ImageName = "doudou",
Price = 14.45m,
PromoPrice = 13.99m,
Quantity = 14L,
Sales = 0L,
Status = 0,
Title = "Doudou"
},
@ -259,10 +304,12 @@ namespace GrossesMitainesAPI.Migrations
Id = 17,
Category = "Vêtements d'extérieur",
Description = "Pour avoir l'air thug en hiver.",
Hits = 0L,
ImageName = "mitaines2",
Price = 9.45m,
PromoPrice = 8.99m,
Quantity = 16L,
Sales = 0L,
Status = 0,
Title = "Mitaines pas de doigts"
});

View File

@ -2,9 +2,7 @@
using System.ComponentModel.DataAnnotations;
namespace GrossesMitainesAPI.Models;
// nom du produit,
// catégories, description, quantité disponible, images, prix normal et
// autres informations pertinentes
public class Product {
public enum States {
Available,
@ -28,5 +26,9 @@ public class Product {
public decimal PromoPrice { get; set; } = 0;
public uint Quantity { get; set; } = 0;
public States Status { get; set; } = States.Available;
public uint Hits { get; set; } = 0;
public uint Sales { get; set; } = 0;
public DateTime? LastSale { get; set; }
public DateTime? LastHit { get; set; }
public string? ImageName { get; set; } // Base pour sortir les images ({ImageName}.jpg , {ImageName}_thumbnail.jpg, etc...)
}

View File

@ -0,0 +1,27 @@
using static GrossesMitainesAPI.Models.Product;
using System.ComponentModel.DataAnnotations;
namespace GrossesMitainesAPI.Models;
public class ProductViewModel {
public int Id { get; set; }
public string Title { get; set; } = "Erreur Aucun Objet";
public string Category { get; set; } = "Inconnue";
public string Description { get; set; } = "Lorem Ipsum.";
public decimal Price { get; set; } = 0;
public decimal PromoPrice { get; set; } = 0;
public uint Quantity { get; set; } = 0;
public States Status { get; set; } = States.Available;
public string? ImageName { get; set; }
public ProductViewModel(Product prod) {
this.Id = prod.Id;
this.Title = prod.Title;
this.Category = prod.Category;
this.Description = prod.Description;
this.Price = prod.Price;
this.PromoPrice = prod.PromoPrice;
this.Quantity = prod.Quantity;
this.Status = prod.Status;
this.ImageName = prod.ImageName;
}
}

View File

@ -8,6 +8,7 @@ namespace GrossesMitainesAPI.Services {
private readonly ILogger<DatabaseCacheService> _logger;
private Product[] _cache = new Product[1];
private Dictionary<uint, uint> _hits = new();
private bool _ok = false, _needUpd = true;
private PeriodicTimer _timer = new PeriodicTimer(TimeSpan.FromSeconds(10));
@ -20,11 +21,14 @@ namespace GrossesMitainesAPI.Services {
}
private async void UpdateJob() {
while (await _timer.WaitForNextTickAsync())
if (_needUpd) {
while (await _timer.WaitForNextTickAsync()) {
if (_needUpd) {
_ok = UpdateCache();
_needUpd = !_ok;
}
}
if (_hits.Count > 0 && _ok)
UpdateMetrics();
}
}
private bool UpdateCache() {
try {
@ -42,10 +46,47 @@ namespace GrossesMitainesAPI.Services {
}
return true;
}
private bool UpdateMetrics() {
try {
Dictionary<uint, uint> hits;
lock (_hits) {
hits = new(_hits);
_hits.Clear();
}
List<uint> ids = hits.Keys.ToList();
using (var scope = _contextFactory.CreateScope()) {
var db = scope.ServiceProvider.GetRequiredService<InventoryContext>();
List<Product> lst = db.Products.Where(x => ids.Contains((uint)x.Id)).ToList();
foreach (var x in hits) {
//Product prod = lst.First(x => x.Id == x.Id);
lst.First(x => x.Id == x.Id).Hits += x.Value;
// prod.Hits = prod.Hits + x.Value;
// db.Products.Update(prod);
}
db.UpdateRange(lst);
db.SaveChanges();
}
} catch (Exception e) {
_logger.LogError(e, "Erreur de mise à jour de cache.");
return false;
}
return true;
}
public bool isOk() { return _ok; }
public void askForRefresh() { _needUpd = true; }
public void addHit(uint id) {
lock (_hits) {
if (_hits.ContainsKey(id))
_hits[id] = _hits[id] + 1;
else _hits[id] = 1;
}
}
public Product[]? GetCacheCopy() {
if (!_ok) return null;
if (!_ok)
return null;
Product[] copy;
try {
@ -59,9 +100,10 @@ namespace GrossesMitainesAPI.Services {
}
return copy;
}
public IQueryable<Product> queryCache() {
if (!_ok) return null;
public IQueryable<Product> queryCache() {
if (!_ok)
return null;
try {
return _cache.AsQueryable();
} catch (Exception e) {

View File

@ -7,6 +7,6 @@
},
"AllowedHosts": "*",
"ConnectionStrings": {
"DefaultConnection": "Server=(localdb)\\mssqllocaldb; Database=GrossesMitainesDB3; Trusted_Connection=True; MultipleActiveResultSets=true"
"DefaultConnection": "Server=(localdb)\\mssqllocaldb; Database=GrossesMitainesDB; Trusted_Connection=True; MultipleActiveResultSets=true"
}
}