groceries/Groceries/Items/ItemsController.cs
2023-07-23 20:00:53 +01:00

95 lines
2.8 KiB
C#

namespace Groceries.Items;
using Groceries.Common;
using Groceries.Data;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
[Route("/items")]
public class ItemsController : Controller
{
private readonly AppDbContext dbContext;
public ItemsController(AppDbContext dbContext)
{
this.dbContext = dbContext;
}
[HttpGet]
public async Task<IActionResult> Index(int page, string? search)
{
var itemsQuery = dbContext.Items.AsQueryable();
if (!string.IsNullOrEmpty(search))
{
var searchPattern = $"%{search}%";
itemsQuery = itemsQuery.Where(item => EF.Functions.ILike(item.Brand + ' ' + item.Name, searchPattern));
}
var lastPurchasesQuery = dbContext.ItemPurchases
.GroupBy(purchase => purchase.ItemId)
.Select(purchases => new
{
ItemId = purchases.Key,
CreatedAt = purchases.Max(purchase => purchase.CreatedAt),
});
var items = await itemsQuery
.OrderBy(item => item.Brand)
.ThenBy(item => item.Name)
.GroupJoin(
lastPurchasesQuery,
item => item.Id,
lastPurchase => lastPurchase.ItemId,
(item, lastPurchase) => new { item, lastPurchase })
.SelectMany(
group => group.lastPurchase.DefaultIfEmpty(),
(group, lastPurchase) => new ItemListModel.Item(group.item.Id, group.item.Brand, group.item.Name)
{
HasBarcode = group.item.Barcodes.Any(),
LastPurchasedAt = lastPurchase != null ? lastPurchase.CreatedAt : null,
})
.ToListPageModelAsync(page, cancellationToken: HttpContext.RequestAborted);
if (items.Page != page)
{
return RedirectToAction(nameof(Index), new { page = items.Page, search });
}
var model = new ItemListModel(search, items);
return View(model);
}
[HttpGet("{id}")]
public async Task<IActionResult> EditItem(Guid id)
{
var item = await dbContext.Items
.SingleOrDefaultAsync(item => item.Id == id, HttpContext.RequestAborted);
if (item == null)
{
return NotFound();
}
return View(item);
}
[HttpPost("{id}")]
public async Task<IActionResult> EditItem(Guid id, string brand, string name)
{
var item = await dbContext.Items
.SingleOrDefaultAsync(item => item.Id == id, HttpContext.RequestAborted);
if (item == null)
{
return NotFound();
}
if (Request.AcceptsTurboStream())
{
return this.TurboStream(TurboStreamAction.Replace, "modal-body", item);
}
return RedirectToAction(nameof(EditItem));
}
}