redesigned payment page + a lot of fixes
This commit is contained in:
160
frontend/pweb/lib/controllers/payouts/multiple_payouts.dart
Normal file
160
frontend/pweb/lib/controllers/payouts/multiple_payouts.dart
Normal file
@@ -0,0 +1,160 @@
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
||||
import 'package:pshared/controllers/balance_mask/wallets.dart';
|
||||
import 'package:pshared/models/money.dart';
|
||||
import 'package:pshared/models/payment/payment.dart';
|
||||
import 'package:pshared/models/payment/quote/status_type.dart';
|
||||
import 'package:pshared/models/payment/wallet.dart';
|
||||
|
||||
import 'package:pweb/models/payment/multiple_payouts/csv_row.dart';
|
||||
import 'package:pweb/models/payment/multiple_payouts/state.dart';
|
||||
import 'package:pweb/providers/multiple_payouts.dart';
|
||||
import 'package:pweb/services/payments/csv_input.dart';
|
||||
|
||||
|
||||
class MultiplePayoutsController extends ChangeNotifier {
|
||||
final CsvInputService _csvInput;
|
||||
MultiplePayoutsProvider? _provider;
|
||||
WalletsController? _wallets;
|
||||
_PickState _pickState = _PickState.idle;
|
||||
Exception? _uiError;
|
||||
|
||||
MultiplePayoutsController({
|
||||
required CsvInputService csvInput,
|
||||
}) : _csvInput = csvInput;
|
||||
|
||||
void update(MultiplePayoutsProvider provider, WalletsController wallets) {
|
||||
var shouldNotify = false;
|
||||
if (!identical(_provider, provider)) {
|
||||
_provider?.removeListener(_onProviderChanged);
|
||||
_provider = provider;
|
||||
_provider?.addListener(_onProviderChanged);
|
||||
shouldNotify = true;
|
||||
}
|
||||
if (!identical(_wallets, wallets)) {
|
||||
_wallets?.removeListener(_onWalletsChanged);
|
||||
_wallets = wallets;
|
||||
_wallets?.addListener(_onWalletsChanged);
|
||||
shouldNotify = true;
|
||||
}
|
||||
if (shouldNotify) {
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
||||
MultiplePayoutsState get state =>
|
||||
_provider?.state ?? MultiplePayoutsState.idle;
|
||||
String? get selectedFileName => _provider?.selectedFileName;
|
||||
List<CsvPayoutRow> get rows => _provider?.rows ?? const <CsvPayoutRow>[];
|
||||
int get sentCount => _provider?.sentCount ?? 0;
|
||||
Exception? get error => _uiError ?? _provider?.error;
|
||||
|
||||
bool get isQuoting => _provider?.isQuoting ?? false;
|
||||
bool get isSending => _provider?.isSending ?? false;
|
||||
bool get isBusy => _provider?.isBusy ?? false;
|
||||
|
||||
bool get quoteIsLoading => _provider?.quoteIsLoading ?? false;
|
||||
QuoteStatusType get quoteStatusType =>
|
||||
_provider?.quoteStatusType ?? QuoteStatusType.missing;
|
||||
Duration? get quoteTimeLeft => _provider?.quoteTimeLeft;
|
||||
|
||||
bool get canSend => _provider?.canSend ?? false;
|
||||
Money? get aggregateDebitAmount =>
|
||||
_provider?.aggregateDebitAmountFor(_selectedWallet);
|
||||
Money? get requestedSentAmount => _provider?.requestedSentAmount;
|
||||
Money? get aggregateSettlementAmount =>
|
||||
_provider?.aggregateSettlementAmountFor(_selectedWallet);
|
||||
Money? get aggregateFeeAmount =>
|
||||
_provider?.aggregateFeeAmountFor(_selectedWallet);
|
||||
double? get aggregateFeePercent =>
|
||||
_provider?.aggregateFeePercentFor(_selectedWallet);
|
||||
|
||||
Future<void> pickAndQuote() async {
|
||||
if (_pickState == _PickState.picking) return;
|
||||
final provider = _provider;
|
||||
if (provider == null) {
|
||||
_setUiError(StateError('Multiple payouts provider is not ready'));
|
||||
return;
|
||||
}
|
||||
|
||||
_clearUiError();
|
||||
_pickState = _PickState.picking;
|
||||
try {
|
||||
final picked = await _csvInput.pickCsv();
|
||||
if (picked == null) return;
|
||||
final wallet = _selectedWallet;
|
||||
if (wallet == null) {
|
||||
_setUiError(StateError('Select source wallet first'));
|
||||
return;
|
||||
}
|
||||
await provider.quoteFromCsv(
|
||||
fileName: picked.name,
|
||||
content: picked.content,
|
||||
sourceWallet: wallet,
|
||||
);
|
||||
} catch (e) {
|
||||
_setUiError(e);
|
||||
} finally {
|
||||
_pickState = _PickState.idle;
|
||||
}
|
||||
}
|
||||
|
||||
Future<List<Payment>> send() async {
|
||||
return _provider?.send() ?? const <Payment>[];
|
||||
}
|
||||
|
||||
Future<MultiplePayoutSendOutcome> sendAndGetOutcome() async {
|
||||
_clearUiError();
|
||||
final provider = _provider;
|
||||
if (provider == null) {
|
||||
_setUiError(StateError('Multiple payouts provider is not ready'));
|
||||
return MultiplePayoutSendOutcome.failure;
|
||||
}
|
||||
|
||||
final payments = await provider.send();
|
||||
final hasError = provider.error != null;
|
||||
if (hasError || payments.isEmpty) {
|
||||
return MultiplePayoutSendOutcome.failure;
|
||||
}
|
||||
return MultiplePayoutSendOutcome.success;
|
||||
}
|
||||
|
||||
void removeUploadedFile() {
|
||||
_provider?.removeUploadedFile();
|
||||
_clearUiError(notify: false);
|
||||
}
|
||||
|
||||
void _onProviderChanged() {
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void _onWalletsChanged() {
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
Wallet? get _selectedWallet => _wallets?.selectedWallet;
|
||||
|
||||
void _setUiError(Object error) {
|
||||
_uiError = error is Exception ? error : Exception(error.toString());
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void _clearUiError({bool notify = true}) {
|
||||
if (_uiError == null) return;
|
||||
_uiError = null;
|
||||
if (notify) {
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_provider?.removeListener(_onProviderChanged);
|
||||
_wallets?.removeListener(_onWalletsChanged);
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
enum _PickState { idle, picking }
|
||||
|
||||
enum MultiplePayoutSendOutcome { success, failure }
|
||||
Reference in New Issue
Block a user