added ledger as souec of funds for payouts

This commit is contained in:
Arseni
2026-03-03 21:03:30 +03:00
parent 3f578353da
commit 51c72a87ae
29 changed files with 796 additions and 385 deletions

View File

@@ -0,0 +1,159 @@
import 'package:flutter/foundation.dart';
import 'package:pshared/controllers/balance_mask/wallets.dart';
import 'package:pshared/models/ledger/account.dart';
import 'package:pshared/models/payment/source_type.dart';
import 'package:pshared/models/payment/wallet.dart';
import 'package:pshared/provider/ledger.dart';
import 'package:pshared/utils/currency.dart';
class PaymentSourceController with ChangeNotifier {
WalletsController? _walletsController;
List<Wallet> _wallets = const <Wallet>[];
Map<String, Wallet> _walletsById = const <String, Wallet>{};
List<LedgerAccount> _ledgerAccounts = const <LedgerAccount>[];
Map<String, LedgerAccount> _ledgerByRef = const <String, LedgerAccount>{};
PaymentSourceType? _selectedType;
String? _selectedRef;
List<Wallet> get wallets => _wallets;
List<LedgerAccount> get ledgerAccounts => _ledgerAccounts;
bool get hasSources => _wallets.isNotEmpty || _ledgerAccounts.isNotEmpty;
PaymentSourceType? get selectedType => _selectedType;
String? get selectedRef => _selectedRef;
Wallet? get selectedWallet {
if (_selectedType != PaymentSourceType.wallet) return null;
final ref = _selectedRef;
if (ref == null) return null;
return _walletsById[ref];
}
LedgerAccount? get selectedLedgerAccount {
if (_selectedType != PaymentSourceType.ledger) return null;
final ref = _selectedRef;
if (ref == null) return null;
return _ledgerByRef[ref];
}
String? get selectedCurrencyCode {
final wallet = selectedWallet;
if (wallet != null) {
return currencyCodeToString(wallet.currency);
}
final ledger = selectedLedgerAccount;
if (ledger != null) {
final code = ledger.currency.trim().toUpperCase();
return code.isEmpty ? null : code;
}
return null;
}
void update(WalletsController wallets, LedgerAccountsProvider ledger) {
_walletsController = wallets;
_walletsById = _uniqueWalletsById(wallets.wallets);
_wallets = _walletsById.values.toList(growable: false);
_ledgerByRef = _uniqueLedgerByRef(ledger.accounts);
_ledgerAccounts = _ledgerByRef.values.toList(growable: false);
_syncSelection();
notifyListeners();
}
void selectWallet(Wallet wallet) {
selectWalletByRef(wallet.id);
}
void selectWalletByRef(String walletRef) {
if (!_walletsById.containsKey(walletRef)) return;
_walletsController?.selectWalletByRef(walletRef);
_setSelection(PaymentSourceType.wallet, walletRef);
}
void selectLedgerByRef(String ledgerAccountRef) {
if (!_ledgerByRef.containsKey(ledgerAccountRef)) return;
_setSelection(PaymentSourceType.ledger, ledgerAccountRef);
}
bool isWalletSelected(String walletRef) {
return _selectedType == PaymentSourceType.wallet &&
_selectedRef == walletRef;
}
bool isLedgerSelected(String ledgerAccountRef) {
return _selectedType == PaymentSourceType.ledger &&
_selectedRef == ledgerAccountRef;
}
void _syncSelection() {
final currentType = _selectedType;
final currentRef = _selectedRef;
if (currentType == PaymentSourceType.wallet &&
currentRef != null &&
_walletsById.containsKey(currentRef)) {
return;
}
if (currentType == PaymentSourceType.ledger &&
currentRef != null &&
_ledgerByRef.containsKey(currentRef)) {
return;
}
final selectedWalletRef = _walletsController?.selectedWalletRef;
if (selectedWalletRef != null &&
_walletsById.containsKey(selectedWalletRef)) {
_selectedType = PaymentSourceType.wallet;
_selectedRef = selectedWalletRef;
return;
}
if (_wallets.isNotEmpty) {
_selectedType = PaymentSourceType.wallet;
_selectedRef = _wallets.first.id;
return;
}
if (_ledgerAccounts.isNotEmpty) {
_selectedType = PaymentSourceType.ledger;
_selectedRef = _ledgerAccounts.first.ledgerAccountRef;
return;
}
_selectedType = null;
_selectedRef = null;
}
void _setSelection(PaymentSourceType type, String ref) {
if (_selectedType == type && _selectedRef == ref) return;
_selectedType = type;
_selectedRef = ref;
notifyListeners();
}
Map<String, Wallet> _uniqueWalletsById(List<Wallet> wallets) {
final result = <String, Wallet>{};
for (final wallet in wallets) {
result.putIfAbsent(wallet.id, () => wallet);
}
return result;
}
Map<String, LedgerAccount> _uniqueLedgerByRef(List<LedgerAccount> accounts) {
final result = <String, LedgerAccount>{};
for (final account in accounts) {
result.putIfAbsent(account.ledgerAccountRef, () => account);
}
return result;
}
}