79 lines
3.0 KiB
C#
79 lines
3.0 KiB
C#
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.Identity;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using PowderCoating.Application.Interfaces;
|
|
using PowderCoating.Core.Entities;
|
|
|
|
namespace PowderCoating.Web.Controllers;
|
|
|
|
[Authorize]
|
|
public class PowderInsightsController : Controller
|
|
{
|
|
private readonly IPowderInsightsService _powderInsights;
|
|
private readonly UserManager<ApplicationUser> _userManager;
|
|
private readonly ILogger<PowderInsightsController> _logger;
|
|
|
|
public PowderInsightsController(
|
|
IPowderInsightsService powderInsights,
|
|
UserManager<ApplicationUser> userManager,
|
|
ILogger<PowderInsightsController> logger)
|
|
{
|
|
_powderInsights = powderInsights;
|
|
_userManager = userManager;
|
|
_logger = logger;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Renders the Powder Insights dashboard showing AI coverage predictions, efficiency metrics, and color suggestions for the current company. Redirects to login when the user session cannot be resolved rather than returning 401, consistent with the MVC cookie-auth flow.
|
|
/// </summary>
|
|
public async Task<IActionResult> Index()
|
|
{
|
|
var user = await _userManager.GetUserAsync(User);
|
|
if (user == null) return RedirectToAction("Login", "Account", new { area = "Identity" });
|
|
|
|
var dashboard = await _powderInsights.GetDashboardAsync(user.CompanyId);
|
|
return View(dashboard);
|
|
}
|
|
|
|
/// <summary>
|
|
/// AJAX endpoint to record the actual powder weight used for a single coat against a JobItemCoat. The user ID and company ID are taken from the authenticated session rather than the request body to prevent cross-tenant data writes.
|
|
/// </summary>
|
|
[HttpPost]
|
|
[ValidateAntiForgeryToken]
|
|
public async Task<IActionResult> RecordUsage([FromBody] RecordUsageRequest request)
|
|
{
|
|
var user = await _userManager.GetUserAsync(User);
|
|
if (user == null) return Unauthorized();
|
|
|
|
var result = await _powderInsights.RecordActualUsageAsync(
|
|
request.JobItemCoatId,
|
|
request.ActualLbs,
|
|
user.Id,
|
|
user.CompanyId,
|
|
request.Notes);
|
|
|
|
return Json(result);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns the _JobPowderSummary partial view for embedding in the Job Details sidebar. CompanyId is passed from the session to enforce tenant isolation — a user cannot request powder data for a job in another company by guessing a jobId.
|
|
/// </summary>
|
|
public async Task<IActionResult> JobSummary(int jobId)
|
|
{
|
|
var user = await _userManager.GetUserAsync(User);
|
|
if (user == null) return Unauthorized();
|
|
|
|
var summary = await _powderInsights.GetJobPowderSummaryAsync(jobId, user.CompanyId);
|
|
if (summary == null) return NotFound();
|
|
|
|
return PartialView("_JobPowderSummary", summary);
|
|
}
|
|
}
|
|
|
|
public class RecordUsageRequest
|
|
{
|
|
public int JobItemCoatId { get; set; }
|
|
public decimal ActualLbs { get; set; }
|
|
public string? Notes { get; set; }
|
|
}
|