using Billing.Languages; using Billing.Models; using Billing.UI; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Xamarin.Forms; namespace Billing.Views { public partial class BillPage : BillingPage { private static readonly BindableProperty SelectedDateProperty = BindableProperty.Create(nameof(SelectedDate), typeof(DateTime), typeof(BillPage)); private static readonly BindableProperty BillsProperty = BindableProperty.Create(nameof(Bills), typeof(List), typeof(BillPage)); private static readonly BindableProperty NoBillsProperty = BindableProperty.Create(nameof(NoBills), typeof(bool), typeof(BillPage)); private static readonly BindableProperty IncomeProperty = BindableProperty.Create(nameof(Income), typeof(decimal), typeof(BillPage)); private static readonly BindableProperty SpendingProperty = BindableProperty.Create(nameof(Spending), typeof(decimal), typeof(BillPage)); private static readonly BindableProperty BalanceProperty = BindableProperty.Create(nameof(Balance), typeof(decimal), typeof(BillPage)); public DateTime SelectedDate { get => (DateTime)GetValue(SelectedDateProperty); set => SetValue(SelectedDateProperty, value); } public List Bills { get => (List)GetValue(BillsProperty); set => SetValue(BillsProperty, value); } public bool NoBills => (bool)GetValue(NoBillsProperty); public decimal Income => (decimal)GetValue(IncomeProperty); public decimal Spending => (decimal)GetValue(SpendingProperty); public decimal Balance => (decimal)GetValue(BalanceProperty); public Command TitleLongPressed { get; } public Command EditBilling { get; } public Command DeleteBilling { get; } public BillPage() { TitleLongPressed = new Command(OnTitleDateLongPressed); EditBilling = new Command(OnEditBilling); DeleteBilling = new Command(OnDeleteBilling); InitializeComponent(); billingDate.SetDateTime(DateTime.Now); } private void OnDateSelected(object sender, DateEventArgs e) { SelectedDate = e.Date; Task.Run(() => { var bills = App.Bills.Where(b => b.CreateTime.Year == e.Date.Year && b.CreateTime.Month == e.Date.Month && b.CreateTime.Day == e.Date.Day); Bills = new List(bills.Select(b => WrapBill(b))); RefreshBalance(Bills); }); } private void RefreshBalance(List bills) { SetValue(NoBillsProperty, bills.Count == 0); var income = bills.Where(b => b.Amount > 0).Sum(b => b.Amount); var spending = -bills.Where(b => b.Amount < 0).Sum(b => b.Amount); SetValue(IncomeProperty, income); SetValue(SpendingProperty, spending); SetValue(BalanceProperty, income - spending); } private UIBill WrapBill(Bill b) { return new UIBill(b) { Icon = App.Categories.FirstOrDefault(c => c.Id == b.CategoryId)?.Icon ?? BaseModel.ICON_DEFAULT, Name = b.Name, DateCreation = b.CreateTime, Amount = b.Amount, Wallet = App.Accounts.FirstOrDefault(a => a.Id == b.WalletId)?.Name }; } private void UpdateBill(UIBill bill) { bill.Icon = App.Categories.FirstOrDefault(c => c.Id == bill.Bill.CategoryId)?.Icon ?? BaseModel.ICON_DEFAULT; bill.Name = bill.Bill.Name; bill.DateCreation = bill.Bill.CreateTime; bill.Amount = bill.Bill.Amount; bill.Wallet = App.Accounts.FirstOrDefault(a => a.Id == bill.Bill.WalletId)?.Name; } private void OnTitleDateLongPressed() { billingDate.SetDateTime(DateTime.Now); } private async void OnEditBilling(object o) { if (Tap.IsBusy) { return; } using (Tap.Start()) { AddBillPage page; if (o is UIBill bill) { page = new AddBillPage(bill.Bill); } else { if (App.Accounts.Count == 0) { await this.ShowMessage(Resource.NeedAccount); await Shell.Current.GoToAsync("//Accounts"); return; } page = new AddBillPage(SelectedDate); } page.BillChecked += OnBillChecked; await Navigation.PushAsync(page); } } private async void OnDeleteBilling(object o) { if (Tap.IsBusy) { return; } using (Tap.Start()) { if (o is UIBill bill) { var result = await this.ShowConfirm(Resource.ConfirmDeleteBill); if (result) { var bills = Bills; bills.Remove(bill); App.Bills.Remove(bill.Bill); billsLayout.Refresh(bills); RefreshBalance(bills); _ = Task.Run(App.WriteBills); } } } } private void OnBillChecked(object sender, Bill e) { if (e.Id < 0) { int maxId; if (App.Bills.Count > 0) { maxId = App.Bills.Max(b => b.Id); } else { maxId = -1; } e.Id = maxId + 1; App.Bills.Add(e); Bills.Add(WrapBill(e)); billsLayout.Refresh(Bills); } else { var bill = Bills.FirstOrDefault(b => b.Bill == e); if (bill != null) { UpdateBill(bill); } } RefreshBalance(Bills); Task.Run(App.WriteBills); } } public class UIBill : BindableObject { public static readonly BindableProperty IconProperty = BindableProperty.Create(nameof(Icon), typeof(string), typeof(UIBill)); public static readonly BindableProperty NameProperty = BindableProperty.Create(nameof(Name), typeof(string), typeof(UIBill)); public static readonly BindableProperty DateCreationProperty = BindableProperty.Create(nameof(DateCreation), typeof(DateTime), typeof(UIBill)); public static readonly BindableProperty AmountProperty = BindableProperty.Create(nameof(Amount), typeof(decimal), typeof(UIBill)); public static readonly BindableProperty WalletProperty = BindableProperty.Create(nameof(Wallet), typeof(string), typeof(UIBill)); public string Icon { get => (string)GetValue(IconProperty); set => SetValue(IconProperty, value); } public string Name { get => (string)GetValue(NameProperty); set => SetValue(NameProperty, value); } public DateTime DateCreation { get => (DateTime)GetValue(DateCreationProperty); set => SetValue(DateCreationProperty, value); } public decimal Amount { get => (decimal)GetValue(AmountProperty); set => SetValue(AmountProperty, value); } public string Wallet { get => (string)GetValue(WalletProperty); set => SetValue(WalletProperty, value); } public Bill Bill { get; } public UIBill(Bill bill) { Bill = bill; } } }