6 Commits

3 changed files with 106 additions and 68 deletions

View File

@ -1,4 +1,6 @@
// Flutter
import 'dart:async';
import 'package:flutter/material.dart';
import '/models/item_type.dart';
@ -13,11 +15,11 @@ import '/models/tracked_item.dart';
/// - Fix bug where editing an item does not reflect immediately when returning to Reports page.
/// - Currently reflects after going back to Reports the 2nd time.
double _assetTotal = 0,
_expenseMonthly = 0,
_expenseYearly = 0,
_incomeMonthly = 0,
_incomeYearly = 0;
double _assetTotal = -1,
_expenseMonthly = -1,
_expenseYearly = -1,
_incomeMonthly = -1,
_incomeYearly = -1;
class ProjectionPage extends StatefulWidget {
const ProjectionPage({
@ -29,67 +31,111 @@ class ProjectionPage extends StatefulWidget {
}
class _ProjectionPageState extends State<ProjectionPage> {
bool _showProjections = true;
@override
void dispose() {
_assetTotal = -2;
_expenseMonthly = -2;
_expenseYearly = -2;
_incomeMonthly = -2;
_incomeYearly = -2;
super.dispose();
}
@override
Widget build(BuildContext context) {
// Summaries for display as well as calculation of totals for projections.
Widget expenseSummary = SummaryCardForTotals(
list: DatabaseHelper.instance.getExpenses(),
summaryTypeLabel: ItemType.expense.title,
itemType: ItemType.expense,
);
Widget incomeSummary = SummaryCardForTotals(
list: DatabaseHelper.instance.getIncomes(),
summaryTypeLabel: ItemType.income.title,
itemType: ItemType.income,
);
Widget assetSummary = SummaryCardForTotals(
list: DatabaseHelper.instance.getAssets(),
summaryTypeLabel: ItemType.asset.title,
itemType: ItemType.asset,
);
// Calculations for the projections.
double oneMonth = _assetTotal + _incomeMonthly - _expenseMonthly,
threeMonths = _assetTotal + (3 * (_incomeMonthly - _expenseMonthly)),
sixMonths = _assetTotal + (6 * (_incomeMonthly - _expenseMonthly)),
oneYear = _assetTotal + (_incomeYearly - _expenseYearly),
twoYears = _assetTotal + (2 * (_incomeYearly - _expenseYearly)),
fiveYears = _assetTotal + (5 * (_incomeYearly - _expenseYearly));
Widget projections;
if (_assetTotal < 0 ||
_incomeMonthly < 0 ||
_incomeYearly < 0 ||
_expenseMonthly < 0 ||
_expenseYearly < 0) {
_showProjections = false;
// Widgets to show the projections.
Widget proj1 = SummaryCard(
name: "One month from now...",
leftText: "",
middleText: oneMonth.toStringAsFixed(2),
rightText: "",
);
Widget proj2 = SummaryCard(
name: "Three months from now...",
leftText: "",
middleText: threeMonths.toStringAsFixed(2),
rightText: "",
);
Widget proj3 = SummaryCard(
name: "Half a year from now...",
leftText: "",
middleText: sixMonths.toStringAsFixed(2),
rightText: "",
);
Widget proj4 = SummaryCard(
name: "One year from now...",
leftText: "",
middleText: oneYear.toStringAsFixed(2),
rightText: "",
);
Widget proj5 = SummaryCard(
name: "Two years from now...",
leftText: "",
middleText: twoYears.toStringAsFixed(2),
rightText: "",
);
Widget proj6 = SummaryCard(
name: "Five years from now...",
leftText: "",
middleText: fiveYears.toStringAsFixed(2),
rightText: "",
);
projections = Center(
child: SizedBox(
child: CircularProgressIndicator(),
),
);
Future.delayed(Duration(seconds: 1), () {
setState(() {
_showProjections = true;
});
});
} else {
double oneMonth = _assetTotal + _incomeMonthly - _expenseMonthly,
threeMonths = _assetTotal + (3 * (_incomeMonthly - _expenseMonthly)),
sixMonths = _assetTotal + (6 * (_incomeMonthly - _expenseMonthly)),
oneYear = _assetTotal + (_incomeYearly - _expenseYearly),
twoYears = _assetTotal + (2 * (_incomeYearly - _expenseYearly)),
fiveYears = _assetTotal + (5 * (_incomeYearly - _expenseYearly));
// Widgets to show the projections.
Widget proj1 = SummaryCard(
name: "One month from now...",
leftText: "",
middleText: oneMonth.toStringAsFixed(2),
rightText: "",
);
Widget proj2 = SummaryCard(
name: "Three months from now...",
leftText: "",
middleText: threeMonths.toStringAsFixed(2),
rightText: "",
);
Widget proj3 = SummaryCard(
name: "Half a year from now...",
leftText: "",
middleText: sixMonths.toStringAsFixed(2),
rightText: "",
);
Widget proj4 = SummaryCard(
name: "One year from now...",
leftText: "",
middleText: oneYear.toStringAsFixed(2),
rightText: "",
);
Widget proj5 = SummaryCard(
name: "Two years from now...",
leftText: "",
middleText: twoYears.toStringAsFixed(2),
rightText: "",
);
Widget proj6 = SummaryCard(
name: "Five years from now...",
leftText: "",
middleText: fiveYears.toStringAsFixed(2),
rightText: "",
);
projections = Column(
children: [
proj1,
proj2,
proj3,
proj4,
proj5,
proj6,
],
);
}
// Return all of the UI elements.
return ListView(
@ -99,12 +145,7 @@ class _ProjectionPageState extends State<ProjectionPage> {
incomeSummary,
assetSummary,
TitleCard(title: "Projections"),
proj1,
proj2,
proj3,
proj4,
proj5,
proj6,
projections,
],
);
}
@ -114,14 +155,16 @@ class SummaryCardForTotals extends StatelessWidget {
const SummaryCardForTotals({
super.key,
required this.list,
required this.summaryTypeLabel,
required this.itemType,
});
final Future<List<TrackedItem>> list;
final String summaryTypeLabel;
final ItemType itemType;
@override
Widget build(BuildContext context) {
String summaryTypeLabel = itemType.title.toString();
return FutureBuilder<List<TrackedItem>>(
future: list,
builder: (
@ -134,12 +177,9 @@ class SummaryCardForTotals extends StatelessWidget {
// Calculate the total fields based on item type.
double dailyTotal = 0, monthlyTotal = 0, yearlyTotal = 0;
ItemType? itemType;
for (TrackedItem e in snapshot.data!) {
if (itemType == null) {
itemType = e.type!;
} else if (itemType != e.type) {
throw "List in SummaryCardForTotals has multiple item types, abort!";
if (e.type != itemType) {
throw "List in SummaryCardForTotals has incorrect item types, abort!";
}
if (e.type == ItemType.asset) {
@ -153,9 +193,6 @@ class SummaryCardForTotals extends StatelessWidget {
/* Load page variables based on calculated totals. */
switch (itemType) {
case null:
break;
case ItemType.asset:
_assetTotal = monthlyTotal;
break;

View File

@ -337,6 +337,7 @@ class _TrackedItemInputDialogState extends State<TrackedItemInputDialog> {
: Text("Edit ${_type!.title}"),
),
content: FutureBuilder<List<Expense>>(
// TODO / TBD -- This should no longer only be Expenses.
future: DatabaseHelper.instance.getExpenses(),
builder: (BuildContext context,
AsyncSnapshot<List<Expense>> snapshot) {

View File

@ -1,7 +1,7 @@
name: expense_tracker
description: Track recurring expenses against income and liquid assets.
publish_to: 'none'
version: 0.1.1
version: 0.1.3
environment:
sdk: ^3.6.1