136 lines
4.4 KiB
C#
136 lines
4.4 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Microsoft.AspNetCore.Mvc.RazorPages;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using MoneyMap.Data;
|
|
using MoneyMap.Models;
|
|
|
|
namespace MoneyMap.Pages
|
|
{
|
|
public class TransactionsModel : PageModel
|
|
{
|
|
private readonly MoneyMapContext _db;
|
|
|
|
public TransactionsModel(MoneyMapContext db)
|
|
{
|
|
_db = db;
|
|
}
|
|
|
|
[BindProperty(SupportsGet = true)]
|
|
public string? Category { get; set; }
|
|
|
|
[BindProperty(SupportsGet = true)]
|
|
public string? CardId { get; set; }
|
|
|
|
[BindProperty(SupportsGet = true)]
|
|
public DateTime? StartDate { get; set; }
|
|
|
|
[BindProperty(SupportsGet = true)]
|
|
public DateTime? EndDate { get; set; }
|
|
|
|
public List<TransactionRow> Transactions { get; set; } = new();
|
|
public List<string> AvailableCategories { get; set; } = new();
|
|
public List<Card> AvailableCards { get; set; } = new();
|
|
public TransactionStats Stats { get; set; } = new();
|
|
|
|
public async Task OnGetAsync()
|
|
{
|
|
var query = _db.Transactions.Include(t => t.Card).AsQueryable();
|
|
|
|
// Apply filters
|
|
if (!string.IsNullOrWhiteSpace(Category))
|
|
{
|
|
if (Category == "(blank)")
|
|
{
|
|
query = query.Where(t => string.IsNullOrWhiteSpace(t.Category));
|
|
}
|
|
else
|
|
{
|
|
query = query.Where(t => t.Category == Category);
|
|
}
|
|
}
|
|
|
|
if (!string.IsNullOrWhiteSpace(CardId) && int.TryParse(CardId, out int cardIdInt))
|
|
{
|
|
query = query.Where(t => t.CardId == cardIdInt);
|
|
}
|
|
|
|
if (StartDate.HasValue)
|
|
{
|
|
query = query.Where(t => t.Date >= StartDate.Value);
|
|
}
|
|
|
|
if (EndDate.HasValue)
|
|
{
|
|
query = query.Where(t => t.Date <= EndDate.Value);
|
|
}
|
|
|
|
// Get transactions
|
|
var transactions = await query
|
|
.OrderByDescending(t => t.Date)
|
|
.ThenByDescending(t => t.Id)
|
|
.ToListAsync();
|
|
|
|
Transactions = transactions.Select(t => new TransactionRow
|
|
{
|
|
Id = t.Id,
|
|
Date = t.Date,
|
|
Name = t.Name,
|
|
Memo = t.Memo,
|
|
Amount = t.Amount,
|
|
Category = t.Category ?? "",
|
|
Notes = t.Notes ?? "",
|
|
CardLabel = t.Card != null
|
|
? $"{t.Card.Issuer} {t.Card.Last4}"
|
|
: (string.IsNullOrEmpty(t.CardLast4) ? "" : $"•••• {t.CardLast4}"),
|
|
ReceiptCount = t.Receipts?.Count ?? 0
|
|
}).ToList();
|
|
|
|
// Calculate stats for filtered results
|
|
Stats = new TransactionStats
|
|
{
|
|
Count = transactions.Count,
|
|
TotalDebits = transactions.Where(t => t.Amount < 0).Sum(t => t.Amount),
|
|
TotalCredits = transactions.Where(t => t.Amount > 0).Sum(t => t.Amount),
|
|
NetAmount = transactions.Sum(t => t.Amount)
|
|
};
|
|
|
|
// Get available categories for filter dropdown
|
|
AvailableCategories = await _db.Transactions
|
|
.Select(t => t.Category ?? "")
|
|
.Distinct()
|
|
.OrderBy(c => c)
|
|
.ToListAsync();
|
|
|
|
// Get available cards for filter dropdown
|
|
AvailableCards = await _db.Cards
|
|
.OrderBy(c => c.Owner)
|
|
.ThenBy(c => c.Last4)
|
|
.ToListAsync();
|
|
}
|
|
|
|
public class TransactionRow
|
|
{
|
|
public long Id { get; set; }
|
|
public DateTime Date { get; set; }
|
|
public string Name { get; set; } = "";
|
|
public string Memo { get; set; } = "";
|
|
public decimal Amount { get; set; }
|
|
public string Category { get; set; } = "";
|
|
public string Notes { get; set; } = "";
|
|
public string CardLabel { get; set; } = "";
|
|
public int ReceiptCount { get; set; }
|
|
}
|
|
|
|
public class TransactionStats
|
|
{
|
|
public int Count { get; set; }
|
|
public decimal TotalDebits { get; set; }
|
|
public decimal TotalCredits { get; set; }
|
|
public decimal NetAmount { get; set; }
|
|
}
|
|
}
|
|
} |