new widget types

This commit is contained in:
davmar
2026-09-10 17:31:18 +02:00
parent 2727f1baf2
commit 86b5f1e09b
8 changed files with 817 additions and 89 deletions
+73 -1
View File
@@ -2,6 +2,7 @@
library;
import '../models/bank.dart';
import '../models/home_filter_widget.dart';
import '../models/transaction_meta.dart';
import '../providers/tx_meta_provider.dart';
import '../utils/tx_calendar.dart';
@@ -23,15 +24,40 @@ class TxFilterMetrics {
double get net => amountIn - amountOut;
}
class HomeBudgetMetrics {
const HomeBudgetMetrics({
required this.monthNet,
required this.target,
required this.averageMonths,
});
/// Net (in − out) for the current calendar month.
final double monthNet;
/// Positive budget ceiling (fixed amount or avg |net| of last N months).
final double target;
final int averageMonths;
/// How much of the ceiling is used, based on |monthNet|.
double get used => monthNet.abs();
double get progress => target <= 0 ? 0 : used / target;
bool get overBudget => target > 0 && used > target;
}
/// Filter [all] the same way Transactions does (pool → search → flow/amount).
List<BankTransaction> applyTransactionFilter({
required List<BankTransaction> all,
required TxMetaController meta,
required TransactionFilterSelection filter,
DateTime? month,
bool forceMonthOnly = false,
}) {
final nowMonth = monthStart(month ?? DateTime.now());
final pool = filter.monthOnly
final limitToMonth = forceMonthOnly || filter.monthOnly;
final pool = limitToMonth
? [
for (final tx in all)
if (_txInMonth(tx, nowMonth)) tx,
@@ -55,12 +81,14 @@ TxFilterMetrics computeTxFilterMetrics({
required TxMetaController meta,
required TransactionFilterSelection filter,
DateTime? month,
bool forceMonthOnly = false,
}) {
final filtered = applyTransactionFilter(
all: all,
meta: meta,
filter: filter,
month: month,
forceMonthOnly: forceMonthOnly,
);
var amountIn = 0.0;
var amountOut = 0.0;
@@ -80,6 +108,50 @@ TxFilterMetrics computeTxFilterMetrics({
);
}
/// Budget progress: this month’s |net| vs fixed or average-of-last-N-months cap.
HomeBudgetMetrics computeHomeBudgetMetrics({
required List<BankTransaction> all,
required TxMetaController meta,
required HomeFilterWidget widget,
DateTime? now,
}) {
final today = now ?? DateTime.now();
final currentMonth = monthStart(today);
final monthFilter = widget.filter;
final monthNet = computeTxFilterMetrics(
all: all,
meta: meta,
filter: monthFilter,
month: currentMonth,
forceMonthOnly: true,
).net;
final months = widget.budgetAverageMonths.clamp(1, 36);
final double target;
if (widget.budgetCapMode == HomeBudgetCapMode.fixed) {
target = widget.budgetFixedAmount.abs();
} else {
var sum = 0.0;
for (var i = 1; i <= months; i++) {
final month = addMonths(currentMonth, -i);
sum += computeTxFilterMetrics(
all: all,
meta: meta,
filter: monthFilter,
month: month,
forceMonthOnly: true,
).net.abs();
}
target = sum / months;
}
return HomeBudgetMetrics(
monthNet: monthNet,
target: target,
averageMonths: months,
);
}
bool _txInMonth(BankTransaction tx, DateTime month) {
final date = DateTime.tryParse(tx.date);
if (date == null) return false;