filter conditions
This commit is contained in:
@ -16,7 +16,22 @@ namespace Billing.Views
|
||||
{
|
||||
public partial class RankPage : BillingPage
|
||||
{
|
||||
private static readonly DateTime today = DateTime.Today;
|
||||
|
||||
private static readonly BindableProperty SegmentTypeProperty = Helper.Create<int, RankPage>(nameof(SegmentType), defaultValue: 0, propertyChanged: OnSegmentTypeChanged);
|
||||
private static readonly BindableProperty SegmentDateProperty = Helper.Create<int, RankPage>(nameof(SegmentDate), defaultValue: 0, propertyChanged: OnSegmentDateChanged);
|
||||
private static readonly BindableProperty StartDateProperty = Helper.Create<DateTime, RankPage>(nameof(StartDate),
|
||||
defaultValue: today.AddDays(1 - today.Day),
|
||||
propertyChanged: OnDateChanged);
|
||||
private static readonly BindableProperty EndDateProperty = Helper.Create<DateTime, RankPage>(nameof(EndDate),
|
||||
defaultValue: today.AddDays(DateTime.DaysInMonth(today.Year, today.Month) - today.Day).LastMoment(),
|
||||
propertyChanged: OnDateChanged);
|
||||
private static readonly BindableProperty StartPickerDateProperty = Helper.Create<DateTime, RankPage>(nameof(StartPickerDate),
|
||||
defaultValue: today.AddDays(1 - today.Day),
|
||||
propertyChanged: OnPickerStartDateChanged);
|
||||
private static readonly BindableProperty EndPickerDateProperty = Helper.Create<DateTime, RankPage>(nameof(EndPickerDate),
|
||||
defaultValue: today.AddDays(DateTime.DaysInMonth(today.Year, today.Month) - today.Day),
|
||||
propertyChanged: OnPickerEndDateChanged);
|
||||
private static readonly BindableProperty ChartProperty = Helper.Create<Chart, RankPage>(nameof(Chart));
|
||||
private static readonly BindableProperty CategoryChartProperty = Helper.Create<Chart, RankPage>(nameof(CategoryChart));
|
||||
private static readonly BindableProperty TopBillsProperty = Helper.Create<IList<UIBill>, RankPage>(nameof(TopBills));
|
||||
@ -34,8 +49,40 @@ namespace Billing.Views
|
||||
1 => CategoryType.Income,
|
||||
_ => CategoryType.Spending
|
||||
};
|
||||
page.OnFilterCommand(false);
|
||||
page.SetMonth(page.current);
|
||||
page.LoadData();
|
||||
}
|
||||
private static void OnSegmentDateChanged(RankPage page, int old, int @new)
|
||||
{
|
||||
page.OnDateTypeCommand(@new);
|
||||
}
|
||||
private static void OnDateChanged(RankPage page, DateTime old = default, DateTime @new = default)
|
||||
{
|
||||
page.isLocked = true;
|
||||
page.StartPickerDate = page.StartDate;
|
||||
page.EndPickerDate = page.EndDate;
|
||||
page.isLocked = false;
|
||||
if (!page.isFreezed)
|
||||
{
|
||||
var format = Resource.TitleDateFormat;
|
||||
page.Title = page.StartDate.ToString(format) + " ~ " + page.EndDate.ToString(format);
|
||||
page.LoadData();
|
||||
}
|
||||
}
|
||||
private static void OnPickerStartDateChanged(RankPage page, DateTime _, DateTime @new)
|
||||
{
|
||||
if (!page.isLocked)
|
||||
{
|
||||
page.SegmentDate = -1;
|
||||
page.StartDate = @new;
|
||||
}
|
||||
}
|
||||
private static void OnPickerEndDateChanged(RankPage page, DateTime _, DateTime @new)
|
||||
{
|
||||
if (!page.isLocked)
|
||||
{
|
||||
page.SegmentDate = -1;
|
||||
page.EndDate = @new;
|
||||
}
|
||||
}
|
||||
|
||||
public int SegmentType
|
||||
@ -43,6 +90,31 @@ namespace Billing.Views
|
||||
get => (int)GetValue(SegmentTypeProperty);
|
||||
set => SetValue(SegmentTypeProperty, value);
|
||||
}
|
||||
public int SegmentDate
|
||||
{
|
||||
get => (int)GetValue(SegmentDateProperty);
|
||||
set => SetValue(SegmentDateProperty, value);
|
||||
}
|
||||
public DateTime StartDate
|
||||
{
|
||||
get => (DateTime)GetValue(StartDateProperty);
|
||||
set => SetValue(StartDateProperty, value);
|
||||
}
|
||||
public DateTime EndDate
|
||||
{
|
||||
get => (DateTime)GetValue(EndDateProperty);
|
||||
set => SetValue(EndDateProperty, value);
|
||||
}
|
||||
public DateTime StartPickerDate
|
||||
{
|
||||
get => (DateTime)GetValue(StartPickerDateProperty);
|
||||
set => SetValue(StartPickerDateProperty, value);
|
||||
}
|
||||
public DateTime EndPickerDate
|
||||
{
|
||||
get => (DateTime)GetValue(EndPickerDateProperty);
|
||||
set => SetValue(EndPickerDateProperty, value);
|
||||
}
|
||||
public Chart Chart
|
||||
{
|
||||
get => (Chart)GetValue(ChartProperty);
|
||||
@ -82,11 +154,11 @@ namespace Billing.Views
|
||||
public Command FilterCommand { get; }
|
||||
public Command EditBilling { get; }
|
||||
|
||||
private DateTime current;
|
||||
private DateTime end;
|
||||
private IEnumerable<Bill> bills;
|
||||
private CategoryType type = CategoryType.Spending;
|
||||
private bool isFilterToggled;
|
||||
private bool isFreezed;
|
||||
private bool isLocked;
|
||||
|
||||
private readonly SKTypeface font;
|
||||
|
||||
@ -111,7 +183,76 @@ namespace Billing.Views
|
||||
|
||||
public override void OnLoaded()
|
||||
{
|
||||
SetMonth(DateTime.Today);
|
||||
OnDateChanged(this);
|
||||
}
|
||||
|
||||
private void OnDateTypeCommand(int index)
|
||||
{
|
||||
if (index < 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (scroller.ScrollY > 0)
|
||||
{
|
||||
scroller.ScrollToAsync(0, 0, true);
|
||||
}
|
||||
isFreezed = true;
|
||||
var today = DateTime.Today;
|
||||
switch (index)
|
||||
{
|
||||
case 0: // monthly
|
||||
StartDate = today.AddDays(1 - today.Day);
|
||||
EndDate = today.AddDays(DateTime.DaysInMonth(today.Year, today.Month) - today.Day).LastMoment();
|
||||
break;
|
||||
case 1: // today
|
||||
StartDate = today;
|
||||
EndDate = today.LastMoment();
|
||||
break;
|
||||
case 2: // past month
|
||||
StartDate = today.AddMonths(-1).AddDays(1);
|
||||
EndDate = today.LastMoment();
|
||||
break;
|
||||
case 3: // past quarter
|
||||
StartDate = today.AddMonths(-3).AddDays(1);
|
||||
EndDate = today.LastMoment();
|
||||
break;
|
||||
case 4: // past six months
|
||||
StartDate = today.AddMonths(-6).AddDays(1);
|
||||
EndDate = today.LastMoment();
|
||||
break;
|
||||
case 5: // past year
|
||||
StartDate = today.AddYears(-1).AddDays(1);
|
||||
EndDate = today.LastMoment();
|
||||
break;
|
||||
case 6: // total
|
||||
//StartDate = App.Bills.Min(b => b.CreateTime).Date;
|
||||
//EndDate = App.Bills.Max(b => b.CreateTime).Date.LastMoment();
|
||||
DateTime min = DateTime.MaxValue;
|
||||
DateTime max = DateTime.MinValue;
|
||||
App.Bills.ForEach(b =>
|
||||
{
|
||||
if (b.CreateTime < min)
|
||||
{
|
||||
min = b.CreateTime;
|
||||
}
|
||||
if (b.CreateTime > max)
|
||||
{
|
||||
max = b.CreateTime;
|
||||
}
|
||||
});
|
||||
StartDate = min.Date;
|
||||
EndDate = max.Date.LastMoment();
|
||||
break;
|
||||
}
|
||||
isFreezed = false;
|
||||
OnDateChanged(this);
|
||||
}
|
||||
|
||||
private bool IsPreset(DateTime start, DateTime end)
|
||||
{
|
||||
return start.Month == end.Month &&
|
||||
start.Day == 1 &&
|
||||
end.Day == DateTime.DaysInMonth(end.Year, end.Month);
|
||||
}
|
||||
|
||||
private void OnLeftCommand()
|
||||
@ -120,7 +261,29 @@ namespace Billing.Views
|
||||
{
|
||||
scroller.ScrollToAsync(0, 0, true);
|
||||
}
|
||||
SetMonth(current.AddMonths(-1));
|
||||
isFreezed = true;
|
||||
var start = StartDate;
|
||||
var end = EndDate;
|
||||
if (IsPreset(start, end))
|
||||
{
|
||||
start = start.AddMonths(-1);
|
||||
end = start.AddDays(DateTime.DaysInMonth(start.Year, start.Month) - 1).LastMoment();
|
||||
}
|
||||
else
|
||||
{
|
||||
var days = (end.Date - start.Date).TotalDays + 1;
|
||||
start = start.AddDays(-days);
|
||||
end = end.AddDays(-days);
|
||||
}
|
||||
if (start.Year < 1900)
|
||||
{
|
||||
isFreezed = false;
|
||||
return;
|
||||
}
|
||||
StartDate = start;
|
||||
EndDate = end;
|
||||
isFreezed = false;
|
||||
OnDateChanged(this);
|
||||
}
|
||||
|
||||
private void OnRightCommand()
|
||||
@ -129,7 +292,29 @@ namespace Billing.Views
|
||||
{
|
||||
scroller.ScrollToAsync(0, 0, true);
|
||||
}
|
||||
SetMonth(current.AddMonths(1));
|
||||
isFreezed = true;
|
||||
var start = StartDate;
|
||||
var end = EndDate;
|
||||
if (IsPreset(start, end))
|
||||
{
|
||||
start = start.AddMonths(1);
|
||||
end = start.AddDays(DateTime.DaysInMonth(start.Year, start.Month) - 1).LastMoment();
|
||||
}
|
||||
else
|
||||
{
|
||||
var days = (end.Date - start.Date).TotalDays + 1;
|
||||
start = start.AddDays(days);
|
||||
end = end.AddDays(days);
|
||||
}
|
||||
if (end.Year > DateTime.Today.Year + 100)
|
||||
{
|
||||
isFreezed = false;
|
||||
return;
|
||||
}
|
||||
StartDate = start;
|
||||
EndDate = end;
|
||||
isFreezed = false;
|
||||
OnDateChanged(this);
|
||||
}
|
||||
|
||||
private async void OnFilterCommand(object o)
|
||||
@ -146,6 +331,7 @@ namespace Billing.Views
|
||||
ViewExtensions.CancelAnimations(panelFilter);
|
||||
if (isFilterToggled)
|
||||
{
|
||||
await scroller.ScrollToAsync(scroller.ScrollX, scroller.ScrollY, false);
|
||||
await Task.WhenAll(
|
||||
gridFilter.TranslateTo(0, 0, easing: Easing.CubicOut),
|
||||
gridFilter.FadeTo(1, easing: Easing.CubicOut),
|
||||
@ -179,18 +365,9 @@ namespace Billing.Views
|
||||
}
|
||||
}
|
||||
|
||||
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 async void RefreshBalance()
|
||||
private async void RefreshBalance(DateTime start, DateTime end)
|
||||
{
|
||||
var bills = await Task.Run(() => App.Bills.Where(b => b.CreateTime >= current && b.CreateTime <= end));
|
||||
var bills = await Task.Run(() => App.Bills.Where(b => b.CreateTime >= start && b.CreateTime <= end));
|
||||
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);
|
||||
@ -198,43 +375,33 @@ namespace Billing.Views
|
||||
SetValue(BalanceProperty, income - spending);
|
||||
}
|
||||
|
||||
private void OnBillChecked(object sender, Bill e)
|
||||
private async void OnBillChecked(object sender, Bill e)
|
||||
{
|
||||
var bill = TopBills.FirstOrDefault(b => b.Bill == e);
|
||||
if (bill != null)
|
||||
{
|
||||
UpdateBill(bill);
|
||||
}
|
||||
RefreshBalance();
|
||||
|
||||
Task.Run(App.WriteBills);
|
||||
await Task.Run(App.WriteBills);
|
||||
LoadData();
|
||||
}
|
||||
|
||||
private async void SetMonth(DateTime date)
|
||||
private async void LoadData()
|
||||
{
|
||||
current = date.AddDays(1 - date.Day);
|
||||
end = current.AddDays(DateTime.DaysInMonth(current.Year, current.Month));
|
||||
|
||||
var format = Resource.DateRangeFormat;
|
||||
Title = current.ToString(format) + " ~ " + end.AddDays(-1).ToString(format);
|
||||
|
||||
var start = StartDate;
|
||||
var end = EndDate;
|
||||
var spending = type == CategoryType.Spending;
|
||||
bills = await Task.Run(() => App.Bills.Where(b => (b.Amount > 0 ^ spending) && b.CreateTime >= current && b.CreateTime <= end));
|
||||
bills = await Task.Run(() => App.Bills.Where(b => (b.Amount > 0 ^ spending) && b.CreateTime >= start && b.CreateTime <= end));
|
||||
|
||||
var primaryColor = BaseTheme.CurrentPrimaryColor.ToSKColor();
|
||||
var textColor = BaseTheme.CurrentSecondaryTextColor.ToSKColor();
|
||||
|
||||
_ = Task.Run(() => LoadReportChart(primaryColor, textColor));
|
||||
_ = Task.Run(() => LoadReportChart(primaryColor, textColor, start, end));
|
||||
_ = Task.Run(() => LoadCategoryChart(primaryColor, textColor));
|
||||
_ = Task.Run(LoadTopBills);
|
||||
|
||||
RefreshBalance();
|
||||
RefreshBalance(start, end);
|
||||
}
|
||||
|
||||
private void LoadReportChart(SKColor primaryColor, SKColor textColor)
|
||||
private void LoadReportChart(SKColor primaryColor, SKColor textColor, DateTime start, DateTime end)
|
||||
{
|
||||
var entries = new List<ChartEntry>();
|
||||
for (var day = current; day <= end; day = day.AddDays(1))
|
||||
for (var day = start; day <= end; day = day.AddDays(1))
|
||||
{
|
||||
var daybills = bills.Where(b => Helper.IsSameDay(b.CreateTime, day));
|
||||
decimal amount = Math.Abs(daybills.Sum(b => b.Amount));
|
||||
@ -350,5 +517,13 @@ namespace Billing.Views
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void Scroller_Scrolled(object sender, ScrolledEventArgs e)
|
||||
{
|
||||
if (isFilterToggled)
|
||||
{
|
||||
OnFilterCommand(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user