60 lines
No EOL
2.1 KiB
Dart
60 lines
No EOL
2.1 KiB
Dart
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()); |