Begin making the Expense page more arbitrary for future re-use by creating superclasses which will fit all 3 object use cases.

This commit is contained in:
2025-02-11 14:33:38 -07:00
parent 7a3eaf70b5
commit ab9b3e0bf9
4 changed files with 91 additions and 55 deletions

View File

@ -6,7 +6,7 @@ import 'package:flutter_expense_tracker/db.dart';
import '/models/expense.dart';
import '/models/frequency.dart';
// TODO: Make this a generic class based on a suerclass of Expense, Income, and Assets?
// TODO: Make this a generic class based on a superclass of Expense, Income, and Assets?
class ExpensePage extends StatefulWidget {
const ExpensePage({
@ -30,10 +30,12 @@ class _ExpensePageState extends State<ExpensePage> {
future: DatabaseHelper.instance.getExpenses(),
builder: (BuildContext context, AsyncSnapshot<List<Expense>> snapshot) {
if (!snapshot.hasData) {
return Center(child: Text('Loading...'));
return Text('Loading...');
}
snapshot.data!.sort(
(a, b) => (b.calcComparableCost() - a.calcComparableCost()).toInt(),
(a, b) => (b.calcComparableAmountYearly() -
a.calcComparableAmountYearly())
.toInt(),
);
return snapshot.data!.isEmpty
? Text(
@ -50,7 +52,7 @@ class _ExpensePageState extends State<ExpensePage> {
.toStringAsFixed(2)
.endsWith(".00") &&
curr
.calcComparableCost()
.calcComparableAmountYearly()
.toStringAsFixed(3)
.endsWith("0")
? ""
@ -59,7 +61,7 @@ class _ExpensePageState extends State<ExpensePage> {
.toStringAsFixed(2)
.endsWith(".00") &&
curr
.calcComparableCostDaily()
.calcComparableAmountDaily()
.toStringAsFixed(3)
.endsWith("0")
? ""
@ -133,7 +135,7 @@ class _ExpensePageState extends State<ExpensePage> {
style: TextStyle(fontSize: 20.0),
),
Text(
"${curr.cost.toStringAsFixed(2)} ${curr.frequency.title}",
"${curr.amount.toStringAsFixed(2)} ${curr.frequency.title}",
style: TextStyle(fontSize: 12.0),
),
],
@ -155,12 +157,12 @@ class _ExpensePageState extends State<ExpensePage> {
children: [
//if (curr.frequency != Frequency.daily)
Text(
"$estimateSymbolDaily${curr.calcComparableCostDaily().toStringAsFixed(2)} ${Frequency.daily.title}",
"$estimateSymbolDaily${curr.calcComparableAmountDaily().toStringAsFixed(2)} ${Frequency.daily.title}",
style: TextStyle(fontSize: 12.0),
),
//if (curr.frequency != Frequency.yearly)
Text(
"$estimateSymbolYearly${curr.calcComparableCost().toStringAsFixed(2)} ${Frequency.yearly.title}",
"$estimateSymbolYearly${curr.calcComparableAmountYearly().toStringAsFixed(2)} ${Frequency.yearly.title}",
style: TextStyle(fontSize: 12.0),
),
],
@ -196,7 +198,7 @@ class _ExpenseInputDialogState extends State<ExpenseInputDialog> {
int? _id;
String _name = "";
double _cost = 0;
double _amount = 0;
Frequency _freq = Frequency.monthly;
String _desc = "";
@ -205,7 +207,7 @@ class _ExpenseInputDialogState extends State<ExpenseInputDialog> {
if (widget.expense != null) {
_id = widget.expense!.id;
_name = widget.expense!.name;
_cost = widget.expense!.cost;
_amount = widget.expense!.amount;
_freq = widget.expense!.frequency;
_desc = widget.expense!.description;
}
@ -277,29 +279,29 @@ class _ExpenseInputDialogState extends State<ExpenseInputDialog> {
keyboardType:
TextInputType.numberWithOptions(decimal: true),
decoration: InputDecoration(
labelText: "Cost",
labelText: "${Expense.amountText}",
hintText: "Example: 10.00",
hintStyle: TextStyle(fontSize: 10.0),
errorStyle: TextStyle(fontSize: 10.0),
),
initialValue: _cost != 0 ? _cost.toString() : "",
initialValue: _amount != 0 ? _amount.toString() : "",
validator: (value) {
if (value == null || value.isEmpty) {
return "Cost must be provided.";
return "${Expense.amountText} must be provided.";
}
if (double.parse(value) < 0) {
return "Please use the Income page rather than having negative expenses.";
}
if (double.parse(value) < 0.01) {
return "Cost must be one hundreth (0.01) or higher.";
return "${Expense.amountText} must be one hundreth (0.01) or higher.";
}
if (double.tryParse(value) == null) {
return "Cost must be a valid number.";
return "${Expense.amountText} must be a valid number.";
}
return null;
},
onSaved: (value) {
_cost = double.parse(value!);
_amount = double.parse(value!);
},
),
DropdownButtonFormField(
@ -374,7 +376,7 @@ class _ExpenseInputDialogState extends State<ExpenseInputDialog> {
Expense expense = Expense(
id: _id,
name: _name,
cost: _cost,
amount: _amount,
frequency: _freq,
description: _desc,
);