|
- using CartWise.Application.Interfaces;
- using CartWise.Domain.Enums;
- using CartWise.Infrastructure.Identity;
- using CartWise.Web.ViewModels.Price;
- using Microsoft.AspNetCore.Authorization;
- using Microsoft.AspNetCore.Identity;
- using Microsoft.AspNetCore.Mvc;
-
- namespace CartWise.Web.Controllers;
-
- [Authorize]
- [Route("prices")]
- public class PriceController : Controller
- {
- private readonly IPriceService _priceService;
- private readonly IProductService _productService;
- private readonly IHouseholdService _householdService;
- private readonly UserManager<ApplicationUser> _userManager;
-
- public PriceController(
- IPriceService priceService,
- IProductService productService,
- IHouseholdService householdService,
- UserManager<ApplicationUser> userManager)
- {
- _priceService = priceService;
- _productService = productService;
- _householdService = householdService;
- _userManager = userManager;
- }
-
- [HttpGet("")]
- public async Task<IActionResult> Index(string? sort)
- {
- var household = await CurrentHouseholdOrNullAsync();
- if (household is null)
- {
- return RedirectToAction("Create", "Household");
- }
-
- var products = await _priceService.GetHouseholdPricedProductsAsync(household.HouseholdId);
-
- IEnumerable<Application.DTOs.PricedProductDto> ordered = sort switch
- {
- "price-asc" => products.OrderBy(p => p.LatestPrice),
- "price-desc" => products.OrderByDescending(p => p.LatestPrice),
- "recent" => products.OrderByDescending(p => p.LatestObservedUtc),
- _ => products.OrderBy(p => p.ProductName)
- };
-
- var viewModel = new PriceIndexViewModel
- {
- Sort = sort ?? "name",
- Products = ordered.Select(p => new PricedProductRowViewModel
- {
- ProductId = p.ProductId,
- ProductName = p.ProductName,
- LatestPrice = p.LatestPrice,
- LatestObservedUtc = p.LatestObservedUtc,
- AveragePrice = p.AveragePrice,
- LowestPrice = p.LowestPrice,
- ObservationCount = p.ObservationCount
- }).ToList()
- };
-
- return View(viewModel);
- }
-
- [HttpGet("product/{productId:guid}")]
- public async Task<IActionResult> Product(Guid productId)
- {
- var household = await CurrentHouseholdOrNullAsync();
- if (household is null)
- {
- return RedirectToAction("Create", "Household");
- }
-
- var details = await _productService.GetDetailsAsync(productId);
- if (details is null)
- {
- return NotFound();
- }
-
- var insight = await _priceService.GetHouseholdPriceInsightAsync(household.HouseholdId, productId);
- var history = await _priceService.GetHouseholdPriceHistoryAsync(household.HouseholdId, productId);
-
- var viewModel = new PriceProductViewModel
- {
- ProductId = productId,
- ProductName = details.Name,
- LatestPrice = insight?.LatestPrice,
- LatestObservedUtc = insight?.LatestObservedUtc,
- AveragePrice = insight?.AveragePrice,
- MedianPrice = insight?.MedianPrice,
- LowestPrice = insight?.LowestPrice,
- UnitPrice = insight?.UnitPrice,
- ObservationCount = insight?.ObservationCount ?? 0,
- History = history.Select(h => new PriceObservationRowViewModel
- {
- Price = h.Price,
- UnitPrice = h.UnitPrice,
- ObservedUtc = h.ObservedUtc,
- SourceType = h.SourceType
- }).ToList()
- };
-
- return View(viewModel);
- }
-
- [HttpPost("product/{productId:guid}/observe")]
- [ValidateAntiForgeryToken]
- public async Task<IActionResult> Observe(Guid productId, decimal price, DateTime? observedOn)
- {
- var household = await CurrentHouseholdOrNullAsync();
- if (household is null)
- {
- return RedirectToAction("Create", "Household");
- }
-
- if (price <= 0)
- {
- ModelState.AddModelError(string.Empty, "Price must be greater than zero.");
- return RedirectToAction(nameof(Product), new { productId });
- }
-
- var observedUtc = observedOn ?? DateTime.UtcNow;
-
- await _priceService.RecordObservationAsync(
- productId,
- price,
- observedUtc,
- PriceObservationSourceType.UserEntered,
- confidenceScore: 1m,
- householdId: household.HouseholdId);
-
- return RedirectToAction(nameof(Product), new { productId });
- }
-
- private async Task<Domain.Entities.Household?> CurrentHouseholdOrNullAsync()
- {
- var userId = _userManager.GetUserId(User)!;
- return await _householdService.GetCurrentHouseholdAsync(userId);
- }
- }
|