calcolatrice/lib/features/splitter/splitter_provider.dart

60 lines
2.1 KiB
Dart
Raw Normal View History

2026-03-04 14:33:15 +01:00
import 'package:flutter_riverpod/flutter_riverpod.dart';
class FriendExpense {
final String name;
final double spent;
final String note;
FriendExpense({required this.name, required this.spent, this.note = ""});
}
class SplitterState {
final List<FriendExpense> friends;
SplitterState({this.friends = const []});
}
class SplitterNotifier extends StateNotifier<SplitterState> {
SplitterNotifier() : super(SplitterState());
void addFriend(String name, double spent, String note) {
state = SplitterState(friends: [...state.friends, FriendExpense(name: name, spent: spent, note: note)]);
}
void removeFriend(int index) {
var newList = List<FriendExpense>.from(state.friends);
newList.removeAt(index);
state = SplitterState(friends: newList);
}
List<String> calculateSettlements(double userSpent) {
List<FriendExpense> all = [
FriendExpense(name: "Io (Tu)", spent: userSpent, note: "Mio anticipo"),
...state.friends
];
if (all.length < 2) return ["Aggiungi almeno un amico per il calcolo"];
double totalSpent = all.fold(0, (sum, f) => sum + f.spent);
double share = totalSpent / all.length;
List<String> results = [
"TOTALE: ${totalSpent.toStringAsFixed(2)}",
"QUOTA: ${share.toStringAsFixed(2)}",
"--------------------------------"
];
Map<String, double> balances = { for (var f in all) f.name: f.spent - share };
var creditors = balances.entries.where((e) => e.value > 0.01).toList();
var debtors = balances.entries.where((e) => e.value < -0.01).toList();
int cIdx = 0, dIdx = 0;
while (cIdx < creditors.length && dIdx < debtors.length) {
double amount = (creditors[cIdx].value < -debtors[dIdx].value) ? creditors[cIdx].value : -debtors[dIdx].value;
results.add("${debtors[dIdx].key}${creditors[cIdx].key}: ${amount.toStringAsFixed(2)}");
if ((creditors[cIdx].value - amount).abs() < 0.01) cIdx++;
if ((debtors[dIdx].value + amount).abs() < 0.01) dIdx++;
}
return results;
}
}
final splitterProvider = StateNotifierProvider<SplitterNotifier, SplitterState>((ref) => SplitterNotifier());