fixed ledger account listing + quotation listing

This commit is contained in:
Stephan D
2026-01-23 02:48:10 +01:00
parent 218c4e20b3
commit 41f653775f
60 changed files with 469 additions and 283 deletions

View File

@@ -0,0 +1,46 @@
import 'package:flutter/foundation.dart';
import 'package:pshared/provider/ledger.dart';
class LedgerBalanceMaskController with ChangeNotifier {
String? _orgRef;
final Set<String> _maskedBalanceRefs = <String>{};
Set<String> _knownAccountRefs = <String>{};
void update(LedgerAccountsProvider accountsProvider) {
final nextOrgRef = accountsProvider.organizationRef;
final orgChanged = nextOrgRef != _orgRef;
if (orgChanged) {
_orgRef = nextOrgRef;
_maskedBalanceRefs.clear();
_knownAccountRefs = <String>{};
}
final refs = accountsProvider.accounts.map((a) => a.ledgerAccountRef).toSet();
_maskedBalanceRefs.removeWhere((id) => !refs.contains(id));
final newRefs = refs.difference(_knownAccountRefs);
if (newRefs.isNotEmpty) {
_maskedBalanceRefs.addAll(newRefs);
}
_knownAccountRefs = refs;
notifyListeners();
}
bool isBalanceMasked(String ledgerAccountRef) => _maskedBalanceRefs.contains(ledgerAccountRef);
bool isBalanceVisible(String ledgerAccountRef) => !isBalanceMasked(ledgerAccountRef);
void toggleBalanceMask(String ledgerAccountRef) {
final existed = _maskedBalanceRefs.remove(ledgerAccountRef);
if (!existed) _maskedBalanceRefs.add(ledgerAccountRef);
notifyListeners();
}
void unmaskAllBalances() {
_maskedBalanceRefs.clear();
notifyListeners();
}
}

View File

@@ -0,0 +1,106 @@
import 'package:flutter/foundation.dart';
import 'package:collection/collection.dart';
import 'package:pshared/models/payment/wallet.dart';
import 'package:pshared/provider/payment/wallets.dart';
class WalletsController with ChangeNotifier {
late WalletsProvider _wallets;
String? _orgRef;
/// UI-only: wallet refs with masked balances
final Set<String> _maskedBalanceWalletRefs = <String>{};
Set<String> _knownWalletRefs = <String>{};
String? _selectedWalletRef;
bool get isLoading => _wallets.isLoading;
Exception? get error => _wallets.error;
void update(WalletsProvider wallets) {
_wallets = wallets;
final nextOrgRef = wallets.organizationRef;
final orgChanged = nextOrgRef != _orgRef;
if (orgChanged) {
_orgRef = nextOrgRef;
_maskedBalanceWalletRefs.clear();
_knownWalletRefs = <String>{};
_selectedWalletRef = null;
}
// Remove ids that no longer exist
final ids = wallets.wallets.map((w) => w.id).toSet();
_maskedBalanceWalletRefs.removeWhere((id) => !ids.contains(id));
final newIds = ids.difference(_knownWalletRefs);
if (newIds.isNotEmpty) {
_maskedBalanceWalletRefs.addAll(newIds);
}
_knownWalletRefs = ids;
_selectedWalletRef = _resolveSelectedId(
currentRef: _selectedWalletRef,
wallets: wallets.wallets,
);
notifyListeners();
}
List<Wallet> get wallets => _wallets.wallets;
bool isBalanceMasked(String walletRef) => _maskedBalanceWalletRefs.contains(walletRef);
bool isBalanceVisible(String walletRef) => !isBalanceMasked(walletRef);
List<Wallet> get unmaskedWallets =>
wallets.where((w) => !_maskedBalanceWalletRefs.contains(w.id)).toList(growable: false);
Wallet? get selectedWallet {
final id = _selectedWalletRef;
if (id == null) return null;
return wallets.firstWhereOrNull((w) => w.id == id);
}
String? get selectedWalletRef => _selectedWalletRef;
void selectWallet(Wallet wallet) => selectWalletByRef(wallet.id);
void selectWalletByRef(String walletRef) {
if (_selectedWalletRef == walletRef) return;
_selectedWalletRef = walletRef;
notifyListeners();
}
/// Toggle wallet balance masking
void toggleBalanceMask(String walletRef) {
final existed = _maskedBalanceWalletRefs.remove(walletRef);
if (!existed) _maskedBalanceWalletRefs.add(walletRef);
notifyListeners();
}
/// Unmask balances for all wallets (bulk action)
void unmaskAllBalances() {
_maskedBalanceWalletRefs.clear();
notifyListeners();
}
String? _resolveSelectedId({
required String? currentRef,
required List<Wallet> wallets,
}) {
if (wallets.isEmpty) return null;
// Keep current selection if it still exists
if (currentRef != null && wallets.any((w) => w.id == currentRef)) {
return currentRef;
}
// Fallback to the first wallet
return wallets.first.id;
}
}

View File

@@ -1,124 +0,0 @@
import 'package:flutter/foundation.dart';
import 'package:collection/collection.dart';
import 'package:pshared/models/payment/wallet.dart';
import 'package:pshared/provider/payment/wallets.dart';
class WalletsController with ChangeNotifier {
late WalletsProvider _wallets;
String? _orgRef;
/// UI-only: which wallets are allowed to be visible
final Set<String> _visibleWalletRefs = <String>{};
String? _selectedWalletRef;
bool get isLoading => _wallets.isLoading;
Exception? get error => _wallets.error;
void update(WalletsProvider wallets) {
_wallets = wallets;
final nextOrgRef = wallets.organizationRef;
final orgChanged = nextOrgRef != _orgRef;
if (orgChanged) {
_orgRef = nextOrgRef;
_visibleWalletRefs.clear(); // All wallets hidden on org change
_selectedWalletRef = null;
}
// Remove ids that no longer exist
final ids = wallets.wallets.map((w) => w.id).toSet();
_visibleWalletRefs.removeWhere((id) => !ids.contains(id));
_selectedWalletRef = _resolveSelectedId(
currentRef: _selectedWalletRef,
wallets: wallets.wallets,
visibleRefs: _visibleWalletRefs,
);
notifyListeners();
}
List<Wallet> get wallets => _wallets.wallets;
bool isVisible(String walletRef) => _visibleWalletRefs.contains(walletRef);
bool isHidden(String walletRef) => !isVisible(walletRef);
List<Wallet> get visibleWallets =>
wallets.where((w) => _visibleWalletRefs.contains(w.id)).toList(growable: false);
Wallet? get selectedWallet {
final id = _selectedWalletRef;
if (id == null) return null;
return wallets.firstWhereOrNull((w) => w.id == id);
}
String? get selectedWalletRef => _selectedWalletRef;
void selectWallet(Wallet wallet, {bool allowHidden = false}) =>
selectWalletByRef(wallet.id, allowHidden: allowHidden);
void selectWalletByRef(String walletRef, {bool allowHidden = false}) {
if (_selectedWalletRef == walletRef) return;
// Prevent selecting a hidden wallet
if (!allowHidden && !_visibleWalletRefs.contains(walletRef)) return;
_selectedWalletRef = walletRef;
notifyListeners();
}
/// Toggle wallet visibility
void toggleVisibility(String accountRef) {
final existed = _visibleWalletRefs.remove(accountRef);
if (!existed) _visibleWalletRefs.add(accountRef);
_selectedWalletRef = _resolveSelectedId(
currentRef: _selectedWalletRef,
wallets: wallets,
visibleRefs: _visibleWalletRefs,
);
notifyListeners();
}
/// Show all wallets (bulk action)
void showAll() {
final allRefs = wallets.map((w) => w.id);
_visibleWalletRefs
..clear()
..addAll(allRefs);
_selectedWalletRef = _resolveSelectedId(
currentRef: _selectedWalletRef,
wallets: wallets,
visibleRefs: _visibleWalletRefs,
);
notifyListeners();
}
String? _resolveSelectedId({
required String? currentRef,
required List<Wallet> wallets,
required Set<String> visibleRefs,
}) {
if (wallets.isEmpty) return null;
// Keep current selection if it still exists and is visible
if (currentRef != null &&
visibleRefs.contains(currentRef) &&
wallets.any((w) => w.id == currentRef)) {
return currentRef;
}
// Select the first visible wallet
final firstVisible = wallets.firstWhereOrNull((w) => visibleRefs.contains(w.id));
return firstVisible?.id;
}
}