No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.

145 líneas
4.8KB

  1. using CartWise.Application.Interfaces;
  2. using CartWise.Domain.Enums;
  3. using CartWise.Infrastructure.Identity;
  4. using CartWise.Web.ViewModels.Price;
  5. using Microsoft.AspNetCore.Authorization;
  6. using Microsoft.AspNetCore.Identity;
  7. using Microsoft.AspNetCore.Mvc;
  8. namespace CartWise.Web.Controllers;
  9. [Authorize]
  10. [Route("prices")]
  11. public class PriceController : Controller
  12. {
  13. private readonly IPriceService _priceService;
  14. private readonly IProductService _productService;
  15. private readonly IHouseholdService _householdService;
  16. private readonly UserManager<ApplicationUser> _userManager;
  17. public PriceController(
  18. IPriceService priceService,
  19. IProductService productService,
  20. IHouseholdService householdService,
  21. UserManager<ApplicationUser> userManager)
  22. {
  23. _priceService = priceService;
  24. _productService = productService;
  25. _householdService = householdService;
  26. _userManager = userManager;
  27. }
  28. [HttpGet("")]
  29. public async Task<IActionResult> Index(string? sort)
  30. {
  31. var household = await CurrentHouseholdOrNullAsync();
  32. if (household is null)
  33. {
  34. return RedirectToAction("Create", "Household");
  35. }
  36. var products = await _priceService.GetHouseholdPricedProductsAsync(household.HouseholdId);
  37. IEnumerable<Application.DTOs.PricedProductDto> ordered = sort switch
  38. {
  39. "price-asc" => products.OrderBy(p => p.LatestPrice),
  40. "price-desc" => products.OrderByDescending(p => p.LatestPrice),
  41. "recent" => products.OrderByDescending(p => p.LatestObservedUtc),
  42. _ => products.OrderBy(p => p.ProductName)
  43. };
  44. var viewModel = new PriceIndexViewModel
  45. {
  46. Sort = sort ?? "name",
  47. Products = ordered.Select(p => new PricedProductRowViewModel
  48. {
  49. ProductId = p.ProductId,
  50. ProductName = p.ProductName,
  51. LatestPrice = p.LatestPrice,
  52. LatestObservedUtc = p.LatestObservedUtc,
  53. AveragePrice = p.AveragePrice,
  54. LowestPrice = p.LowestPrice,
  55. ObservationCount = p.ObservationCount
  56. }).ToList()
  57. };
  58. return View(viewModel);
  59. }
  60. [HttpGet("product/{productId:guid}")]
  61. public async Task<IActionResult> Product(Guid productId)
  62. {
  63. var household = await CurrentHouseholdOrNullAsync();
  64. if (household is null)
  65. {
  66. return RedirectToAction("Create", "Household");
  67. }
  68. var details = await _productService.GetDetailsAsync(productId);
  69. if (details is null)
  70. {
  71. return NotFound();
  72. }
  73. var insight = await _priceService.GetHouseholdPriceInsightAsync(household.HouseholdId, productId);
  74. var history = await _priceService.GetHouseholdPriceHistoryAsync(household.HouseholdId, productId);
  75. var viewModel = new PriceProductViewModel
  76. {
  77. ProductId = productId,
  78. ProductName = details.Name,
  79. LatestPrice = insight?.LatestPrice,
  80. LatestObservedUtc = insight?.LatestObservedUtc,
  81. AveragePrice = insight?.AveragePrice,
  82. MedianPrice = insight?.MedianPrice,
  83. LowestPrice = insight?.LowestPrice,
  84. UnitPrice = insight?.UnitPrice,
  85. ObservationCount = insight?.ObservationCount ?? 0,
  86. History = history.Select(h => new PriceObservationRowViewModel
  87. {
  88. Price = h.Price,
  89. UnitPrice = h.UnitPrice,
  90. ObservedUtc = h.ObservedUtc,
  91. SourceType = h.SourceType
  92. }).ToList()
  93. };
  94. return View(viewModel);
  95. }
  96. [HttpPost("product/{productId:guid}/observe")]
  97. [ValidateAntiForgeryToken]
  98. public async Task<IActionResult> Observe(Guid productId, decimal price, DateTime? observedOn)
  99. {
  100. var household = await CurrentHouseholdOrNullAsync();
  101. if (household is null)
  102. {
  103. return RedirectToAction("Create", "Household");
  104. }
  105. if (price <= 0)
  106. {
  107. ModelState.AddModelError(string.Empty, "Price must be greater than zero.");
  108. return RedirectToAction(nameof(Product), new { productId });
  109. }
  110. var observedUtc = observedOn ?? DateTime.UtcNow;
  111. await _priceService.RecordObservationAsync(
  112. productId,
  113. price,
  114. observedUtc,
  115. PriceObservationSourceType.UserEntered,
  116. confidenceScore: 1m,
  117. householdId: household.HouseholdId);
  118. return RedirectToAction(nameof(Product), new { productId });
  119. }
  120. private async Task<Domain.Entities.Household?> CurrentHouseholdOrNullAsync()
  121. {
  122. var userId = _userManager.GetUserId(User)!;
  123. return await _householdService.GetCurrentHouseholdAsync(userId);
  124. }
  125. }

Powered by TurnKey Linux.