WheresMyMoney/WheresMyMoney.Maui/BalanceHistoryPage.xaml.cs
2025-01-25 00:27:02 +01:00

156 lines
6.6 KiB
C#

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WheresMyMoney.Maui.Core;
namespace WheresMyMoney.Maui;
public partial class BalanceHistoryPage : ContentPage
{
private DateTime _nearestPayday = DateTime.MinValue;
private decimal _balanceAmount = 0;
public ObservableCollection<GroupedBalanceChangeViewModel> GroupedBalanceChangeViewModels { get; } = [];
private static readonly GroupedBalanceChangeViewModel Empty = new("Pusto", []);
public BalanceHistoryPage()
{
InitializeComponent();
BindingContext = this;
UpdateUi();
Repository.Instance.DataChanged += OnDataChanged;
}
private void OnDataChanged(object? sender, EventArgs e)
{
UpdateUi();
}
private void UpdateUi()
{
GroupedBalanceChangeViewModels.Clear();
var balances = Repository.Instance.GetAllBalances().GroupBy(x => x.Date.Date).OrderBy(x => x.Key);
var now = DateTime.Now;
_nearestPayday = Repository.Instance.GetNearestPayday(now);
var allPlannedPayments = Repository.Instance.GetAllPlannedPayments().OrderBy(x => x.DateStart).ToList();
var plannedPayments = allPlannedPayments.Where(x =>
(!x.IsSubscription && x.DateStart <= _nearestPayday) ||
(x.IsSubscription && (x.DateEnd == null || x.DateEnd >= now)))
.SelectMany(x =>
x.ExpandSubscription(balances.FirstOrDefault()?.Key.Date ?? DateTime.MinValue, _nearestPayday))
.OrderBy(x => x.DateStart).ToList();
_balanceAmount = 0;
foreach (var balanceGroup in balances)
{
var balanceDate = balanceGroup.Key.Date;
var payments = plannedPayments.Where(x => x.DateStart.Date < balanceDate).ToList();
foreach (var paymentGroup in payments.GroupBy(x => x.DateStart.Date).OrderBy(x => x.Key))
{
var paymentDate = paymentGroup.Key.Date;
var paymentVm = new GroupedBalanceChangeViewModel(paymentDate.ToString("yyyy MMMM dd"), []);
foreach (var payment in paymentGroup)
{
_balanceAmount -= payment.Amount;
paymentVm.BalanceChanges.Add(new BalanceChangeViewModel(payment.Name,
$"{(payment.Amount < 0 ? "+" : "")}{payment.Amount * -1m:C}",
_balanceAmount.ToString("C"), payment.Amount >= 0, _balanceAmount < 0));
}
GroupedBalanceChangeViewModels.Add(paymentVm);
}
plannedPayments = plannedPayments.Except(payments).ToList();
var vm = new GroupedBalanceChangeViewModel(balanceDate.ToString("yyyy MMMM dd"), []);
foreach (var thisBalanceAmount in balanceGroup.Select(x => x.Amount))
{
var change = thisBalanceAmount - _balanceAmount;
_balanceAmount = thisBalanceAmount;
vm.BalanceChanges.Add(new BalanceChangeViewModel("Zmiana salda",
$"{(change < 0 ? "" : "+")}{change:C}",
thisBalanceAmount.ToString("C"), change < 0, _balanceAmount < 0));
}
payments = plannedPayments.Where(x => x.DateStart.Date == balanceDate).ToList();
foreach (var payment in payments)
{
_balanceAmount -= payment.Amount;
vm.BalanceChanges.Add(new BalanceChangeViewModel(payment.Name,
$"{(payment.Amount < 0 ? "+" : "")}{payment.Amount * -1m:C}",
_balanceAmount.ToString("C"), payment.Amount >= 0, _balanceAmount < 0));
}
GroupedBalanceChangeViewModels.Add(vm);
plannedPayments = plannedPayments.Except(payments).ToList();
}
foreach (var paymentGroup in plannedPayments.GroupBy(x => x.DateStart.Date).OrderBy(x => x.Key))
{
var paymentDate = paymentGroup.Key.Date;
var paymentVm = new GroupedBalanceChangeViewModel(paymentDate.ToString("yyyy MMMM dd"), []);
foreach (var payment in paymentGroup)
{
_balanceAmount -= payment.Amount;
paymentVm.BalanceChanges.Add(new BalanceChangeViewModel(payment.Name,
$"{(payment.Amount < 0 ? "+" : "")}{payment.Amount * -1m:C}",
_balanceAmount.ToString("C"), payment.Amount >= 0, _balanceAmount < 0));
}
GroupedBalanceChangeViewModels.Add(paymentVm);
}
if (!GroupedBalanceChangeViewModels.Any())
{
GroupedBalanceChangeViewModels.Add(Empty);
}
}
private void ItemsView_OnRemainingItemsThresholdReached(object? sender, EventArgs e)
{
Debug.WriteLine($"ItemsView_OnRemainingItemsThresholdReached");
var start = _nearestPayday.AddDays(1);
_nearestPayday = _nearestPayday.AddMonths(1);
Debug.WriteLine($"Start: {start}");
Debug.WriteLine($"End: {_nearestPayday}");
var plannedPayments = Repository.Instance.GetAllPlannedPayments().Where(x =>
(!x.IsSubscription && x.DateStart >= start && x.DateStart <= _nearestPayday) ||
(x.IsSubscription && (x.DateEnd == null || x.DateEnd >= start)))
.SelectMany(x => x.ExpandSubscription(start, _nearestPayday))
.OrderBy(x => x.DateStart).ToList();
if (GroupedBalanceChangeViewModels.FirstOrDefault() == Empty)
{
GroupedBalanceChangeViewModels.Clear();
}
foreach (var paymentGroup in plannedPayments.GroupBy(x => x.DateStart.Date).OrderBy(x => x.Key))
{
var paymentDate = paymentGroup.Key.Date;
var paymentVm = new GroupedBalanceChangeViewModel(paymentDate.ToString("yyyy MMMM dd"), []);
foreach (var payment in paymentGroup)
{
_balanceAmount -= payment.Amount;
paymentVm.BalanceChanges.Add(new BalanceChangeViewModel(payment.Name,
$"{(payment.Amount < 0 ? "+" : "")}{payment.Amount * -1m:C}",
_balanceAmount.ToString("C"), payment.Amount >= 0, _balanceAmount < 0));
}
GroupedBalanceChangeViewModels.Add(paymentVm);
}
if (!GroupedBalanceChangeViewModels.Any())
{
GroupedBalanceChangeViewModels.Add(Empty);
}
}
}
public record GroupedBalanceChangeViewModel(string DateText, List<BalanceChangeViewModel> BalanceChanges);
public record BalanceChangeViewModel(
string Name,
string AmountText,
string BalanceText,
bool IsPayment,
bool IsBalanceNegative);