Implemented ledger provider

This commit is contained in:
Stephan D
2026-01-22 18:56:12 +01:00
parent 1b59823105
commit 7ae32cac55
8 changed files with 300 additions and 35 deletions

View File

@@ -29,10 +29,10 @@ class WalletsProvider with ChangeNotifier {
bool get isRefreshingBalances => _isRefreshingBalances;
final Set<String> _refreshingWallets = <String>{};
bool isWalletRefreshing(String walletId) => _refreshingWallets.contains(walletId);
bool isWalletRefreshing(String walletRef) => _refreshingWallets.contains(walletRef);
// Expose current org id so UI controller can reset per-org state if needed.
String? get organizationId =>
String? get organizationRef =>
(_organizations?.isOrganizationSet ?? false) ? _organizations!.current.id : null;
// Used to ignore stale async results (org changes / overlapping requests).
@@ -96,7 +96,7 @@ class WalletsProvider with ChangeNotifier {
if (org == null || !org.isOrganizationSet) return;
if (wallets.isEmpty) return;
final orgId = org.current.id;
final orgRef = org.current.id;
final seq = ++_opSeq;
_isRefreshingBalances = true;
@@ -104,7 +104,7 @@ class WalletsProvider with ChangeNotifier {
notifyListeners();
try {
final result = await _withBalances(orgId, wallets);
final result = await _withBalances(orgRef, wallets);
if (seq != _opSeq) return;
_applyResource(
@@ -123,37 +123,37 @@ class WalletsProvider with ChangeNotifier {
}
}
Future<void> refreshBalance(String walletId) async {
Future<void> refreshBalance(String walletRef) async {
final org = _organizations;
if (org == null || !org.isOrganizationSet) return;
if (_refreshingWallets.contains(walletId)) return;
if (_refreshingWallets.contains(walletRef)) return;
final existing = wallets.firstWhereOrNull((w) => w.id == walletId);
final existing = wallets.firstWhereOrNull((w) => w.id == walletRef);
if (existing == null) return;
final orgId = org.current.id;
final seq = (_walletSeq[walletId] ?? 0) + 1;
_walletSeq[walletId] = seq;
final seq = (_walletSeq[walletRef] ?? 0) + 1;
_walletSeq[walletRef] = seq;
_refreshingWallets.add(walletId);
_refreshingWallets.add(walletRef);
notifyListeners();
try {
final balance = await _service.getBalance(orgId, walletId);
if ((_walletSeq[walletId] ?? 0) != seq) return;
final balance = await _service.getBalance(orgId, walletRef);
if ((_walletSeq[walletRef] ?? 0) != seq) return;
final next = _replaceWallet(walletId, (w) => w.copyWith(balance: balance));
final next = _replaceWallet(walletRef, (w) => w.copyWith(balance: balance));
if (next == null) return;
_applyResource(_resource.copyWith(data: next), notify: false);
} catch (e) {
if ((_walletSeq[walletId] ?? 0) != seq) return;
if ((_walletSeq[walletRef] ?? 0) != seq) return;
_applyResource(_resource.copyWith(error: toException(e)), notify: false);
} finally {
if ((_walletSeq[walletId] ?? 0) == seq) {
_refreshingWallets.remove(walletId);
if ((_walletSeq[walletRef] ?? 0) == seq) {
_refreshingWallets.remove(walletRef);
notifyListeners();
}
}
@@ -166,8 +166,8 @@ class WalletsProvider with ChangeNotifier {
if (notify) notifyListeners();
}
List<Wallet>? _replaceWallet(String walletId, Wallet Function(Wallet) updater) {
final idx = wallets.indexWhere((w) => w.id == walletId);
List<Wallet>? _replaceWallet(String walletRef, Wallet Function(Wallet) updater) {
final idx = wallets.indexWhere((w) => w.id == walletRef);
if (idx < 0) return null;
final next = List<Wallet>.from(wallets);
@@ -175,7 +175,7 @@ class WalletsProvider with ChangeNotifier {
return next;
}
Future<_WalletLoadResult> _withBalances(String orgId, List<Wallet> base) async {
Future<_WalletLoadResult> _withBalances(String orgRef, List<Wallet> base) async {
Exception? firstError;
final withBalances = await _mapConcurrent<Wallet, Wallet>(
@@ -183,7 +183,7 @@ class WalletsProvider with ChangeNotifier {
_balanceConcurrency,
(wallet) async {
try {
final balance = await _service.getBalance(orgId, wallet.id);
final balance = await _service.getBalance(orgRef, wallet.id);
return wallet.copyWith(balance: balance);
} catch (e) {
firstError ??= toException(e);