using System.Collections.Generic; using System.Linq; using Billing.Languages; using Billing.Models; using Billing.Store; using Billing.UI; using Xamarin.Forms; namespace Billing.Views { public partial class AccountPage : BillingPage { private static readonly BindableProperty BalanceProperty = Helper.Create(nameof(Balance)); private static readonly BindableProperty AssetProperty = Helper.Create(nameof(Asset)); private static readonly BindableProperty LiabilityProperty = Helper.Create(nameof(Liability)); private static readonly BindableProperty AccountsProperty = Helper.Create, AccountPage>(nameof(Accounts)); 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 EditAccount { get; } public Command DeleteAccount { get; } private readonly List accounts = new(); private bool initialized; public AccountPage() { EditAccount = new Command(OnEditAccount); DeleteAccount = new Command(OnDeleteAccount); SetValue(AccountsProperty, accounts); InitializeComponent(); } protected override void OnAppearing() { if (!initialized || accounts.Count == 0) { initialized = true; accounts.Clear(); foreach (var account in App.Accounts) { AddToAccountGroup(account); } } RefreshBalance(true); groupLayout.Refresh(accounts); } protected override void OnRefresh() { accounts.Clear(); foreach (var account in App.Accounts) { AddToAccountGroup(account); } RefreshBalance(true); groupLayout.Refresh(accounts); } private void RefreshBalance(bool calc = false) { if (calc) { foreach (var account in App.Accounts) { account.Balance = account.Initial + App.Bills.Where(b => b.WalletId == account.Id).Sum(b => b.Amount); } } SetValue(BalanceProperty, App.Accounts.Sum(a => a.Balance)); } private void AddToAccountGroup(Account account) { 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 OnEditAccount(object o) { if (Tap.IsBusy) { return; } using (Tap.Start()) { var page = new AddAccountPage(o as Account); page.AccountChecked += AccountChecked; await Navigation.PushAsync(page); } } private async void OnDeleteAccount(object o) { if (Tap.IsBusy) { return; } using (Tap.Start()) { if (o is Account account) { var result = await this.ShowConfirm(Resource.ConfirmDeleteAccount); if (result) { App.Accounts.Remove(account); var group = accounts.FirstOrDefault(a => a.Key == account.Category); if (group == null) { Helper.Error("account.delete", "unexpected deleting account, cannot find the current category"); } else { group.Remove(account); if (group.Count == 0) { accounts.Remove(group); } } RefreshBalance(); groupLayout.Refresh(accounts); RankPage.Instance?.SetNeedRefresh(); await StoreHelper.DeleteAccountItemAsync(account); } } } } private async void AccountChecked(object sender, AccountEventArgs e) { var add = e.Account.Id <= 0; if (add) { App.Accounts.Add(e.Account); AddToAccountGroup(e.Account); } RefreshBalance(!add); groupLayout.Refresh(accounts); RankPage.Instance?.SetNeedRefresh(); await StoreHelper.SaveAccountItemAsync(e.Account); } } 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; } } }