using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Billing.Models; using Billing.UI; using Xamarin.Forms; namespace Billing.Views { public partial class AccountPage : BillingPage { private static readonly BindableProperty BalanceProperty = BindableProperty.Create(nameof(Balance), typeof(decimal), typeof(AccountPage)); private static readonly BindableProperty AssetProperty = BindableProperty.Create(nameof(Asset), typeof(decimal), typeof(AccountPage)); private static readonly BindableProperty LiabilityProperty = BindableProperty.Create(nameof(Liability), typeof(decimal), typeof(AccountPage)); private static readonly BindableProperty AccountsProperty = BindableProperty.Create(nameof(Accounts), typeof(List), typeof(AccountPage)); public decimal Balance => (decimal)GetValue(BalanceProperty); public decimal Asset => (decimal)GetValue(AssetProperty); public decimal Liability => (decimal)GetValue(LiabilityProperty); public List Accounts => (List)GetValue(AccountsProperty); public Command AddAccount { get; } private readonly List accounts = new(); private bool initialized; public AccountPage() { AddAccount = new Command(OnAddAccount); SetValue(AccountsProperty, accounts); InitializeComponent(); } protected override void OnAppearing() { if (!initialized) { initialized = true; accounts.Clear(); foreach (var account in App.Accounts) { AddToAccountGroup(account); } } groupLayout.Refresh(accounts); } private void AddToAccountGroup(Account account) { int maxId; if (accounts.Count > 0) { maxId = accounts.Max(g => g.Max(a => a.Id)); } else { maxId = -1; } account.Id = maxId + 1; var group = accounts.FirstOrDefault(g => g.Key == account.Category); if (group == null) { group = new AccountGrouping(account.Category, account.Balance) { account }; accounts.Add(group); } else { group.Add(account); group.Balance += account.Balance; } } private async void OnAddAccount() { if (Tap.IsBusy) { return; } using (Tap.Start()) { var page = new AddAccountPage(); page.AccountChecked += AccountChecked; await Navigation.PushAsync(page); } } private void AccountChecked(object sender, AccountEventArgs e) { App.Accounts.Add(e.Account); AddToAccountGroup(e.Account); groupLayout.Refresh(accounts); Task.Run(App.WriteAccounts); } } public class AccountGrouping : List, IGrouping { public AccountCategory Key { get; } public decimal Balance { get; set; } public AccountGrouping(AccountCategory key, decimal balance) : base() { Key = key; Balance = balance; } } }