Enforce quarterly run limit on AI price check
- GET: sets ViewBag.NextRunAvailable if last run was within 90 days; view disables the button and shows the next eligible date - POST: returns early with a warning if called before the 90-day window Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -941,6 +941,13 @@ namespace PowderCoating.Web.Controllers
|
|||||||
var pricedItems = await _unitOfWork.CatalogItems.FindAsync(ci => ci.IsActive && ci.DefaultPrice > 0);
|
var pricedItems = await _unitOfWork.CatalogItems.FindAsync(ci => ci.IsActive && ci.DefaultPrice > 0);
|
||||||
ViewBag.ActiveItemCount = pricedItems.Count();
|
ViewBag.ActiveItemCount = pricedItems.Count();
|
||||||
|
|
||||||
|
if (report != null)
|
||||||
|
{
|
||||||
|
var nextRun = report.RunAt.AddDays(90);
|
||||||
|
if (nextRun > DateTime.UtcNow)
|
||||||
|
ViewBag.NextRunAvailable = nextRun.ToLocalTime().ToString("MMMM d, yyyy");
|
||||||
|
}
|
||||||
|
|
||||||
CatalogPriceCheckReportDto? dto = null;
|
CatalogPriceCheckReportDto? dto = null;
|
||||||
if (report != null)
|
if (report != null)
|
||||||
{
|
{
|
||||||
@@ -988,6 +995,20 @@ namespace PowderCoating.Web.Controllers
|
|||||||
var currentUser = await _userManager.GetUserAsync(User);
|
var currentUser = await _userManager.GetUserAsync(User);
|
||||||
if (currentUser == null) return Forbid();
|
if (currentUser == null) return Forbid();
|
||||||
|
|
||||||
|
// Enforce quarterly run limit — check the most recent report for this company.
|
||||||
|
var lastReport = (await _unitOfWork.CatalogPriceCheckReports.FindAsync(
|
||||||
|
r => r.CompanyId == currentUser.CompanyId))
|
||||||
|
.OrderByDescending(r => r.RunAt).FirstOrDefault();
|
||||||
|
if (lastReport != null)
|
||||||
|
{
|
||||||
|
var nextRun = lastReport.RunAt.AddDays(90);
|
||||||
|
if (nextRun > DateTime.UtcNow)
|
||||||
|
{
|
||||||
|
TempData["Warning"] = $"Price check can only be run once per quarter. Next run available: {nextRun.ToLocalTime():MMMM d, yyyy}.";
|
||||||
|
return RedirectToAction(nameof(AiPriceCheck));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Load active catalog items with a real price — skip $0 items (placeholders,
|
// Load active catalog items with a real price — skip $0 items (placeholders,
|
||||||
|
|||||||
@@ -94,6 +94,17 @@
|
|||||||
<a asp-action="Index" class="btn btn-outline-secondary btn-sm">
|
<a asp-action="Index" class="btn btn-outline-secondary btn-sm">
|
||||||
<i class="bi bi-arrow-left me-1"></i> Back to Catalog
|
<i class="bi bi-arrow-left me-1"></i> Back to Catalog
|
||||||
</a>
|
</a>
|
||||||
|
@if (ViewBag.NextRunAvailable != null)
|
||||||
|
{
|
||||||
|
<div class="text-end">
|
||||||
|
<button class="btn btn-primary" disabled>
|
||||||
|
<i class="bi bi-robot me-2"></i>Re-run Price Check
|
||||||
|
</button>
|
||||||
|
<div class="small text-muted mt-1">Next run available: @ViewBag.NextRunAvailable</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
<form asp-action="RunAiPriceCheck" method="post" id="runForm" class="run-btn-wrap">
|
<form asp-action="RunAiPriceCheck" method="post" id="runForm" class="run-btn-wrap">
|
||||||
@Html.AntiForgeryToken()
|
@Html.AntiForgeryToken()
|
||||||
<button type="submit" class="btn btn-primary" id="runBtn"
|
<button type="submit" class="btn btn-primary" id="runBtn"
|
||||||
@@ -102,6 +113,7 @@
|
|||||||
@(Model == null ? "Run Price Check" : "Re-run Price Check")
|
@(Model == null ? "Run Price Check" : "Re-run Price Check")
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@if (TempData["Success"] != null)
|
@if (TempData["Success"] != null)
|
||||||
|
|||||||
Reference in New Issue
Block a user