multiple payout page and small fixes
This commit is contained in:
@@ -12,14 +12,13 @@ class MultiPaymentProvider extends ChangeNotifier {
|
||||
late OrganizationsProvider _organization;
|
||||
late MultiQuotationProvider _quotation;
|
||||
|
||||
Resource<List<Payment>> _payments = Resource(data: []);
|
||||
bool _isLoaded = false;
|
||||
Resource<List<Payment>> _payments = Resource(data: null);
|
||||
|
||||
List<Payment> get payments => _payments.data ?? [];
|
||||
bool get isLoading => _payments.isLoading;
|
||||
Exception? get error => _payments.error;
|
||||
bool get isReady =>
|
||||
_isLoaded && !_payments.isLoading && _payments.error == null;
|
||||
_payments.data != null && !_payments.isLoading && _payments.error == null;
|
||||
|
||||
void update(
|
||||
OrganizationsProvider organization,
|
||||
@@ -56,7 +55,6 @@ class MultiPaymentProvider extends ChangeNotifier {
|
||||
metadata: metadata,
|
||||
);
|
||||
|
||||
_isLoaded = true;
|
||||
_setResource(
|
||||
_payments.copyWith(data: response, isLoading: false, error: null),
|
||||
);
|
||||
@@ -70,8 +68,7 @@ class MultiPaymentProvider extends ChangeNotifier {
|
||||
}
|
||||
|
||||
void reset() {
|
||||
_isLoaded = false;
|
||||
_setResource(Resource(data: []));
|
||||
_setResource(Resource(data: null));
|
||||
}
|
||||
|
||||
void _setResource(Resource<List<Payment>> payments) {
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
||||
import 'package:uuid/uuid.dart';
|
||||
@@ -17,11 +19,13 @@ class MultiQuotationProvider extends ChangeNotifier {
|
||||
String? _loadedOrganizationRef;
|
||||
|
||||
Resource<PaymentQuotes> _quotation = Resource(data: null);
|
||||
bool _isLoaded = false;
|
||||
|
||||
List<PaymentIntent>? _lastIntents;
|
||||
bool _lastPreviewOnly = false;
|
||||
Map<String, String>? _lastMetadata;
|
||||
Timer? _autoRefreshTimer;
|
||||
|
||||
static const Duration _autoRefreshLead = Duration(seconds: 5);
|
||||
|
||||
Resource<PaymentQuotes> get resource => _quotation;
|
||||
PaymentQuotes? get quotation => _quotation.data;
|
||||
@@ -29,7 +33,7 @@ class MultiQuotationProvider extends ChangeNotifier {
|
||||
Exception? get error => _quotation.error;
|
||||
bool get canRefresh => _lastIntents != null && _lastIntents!.isNotEmpty;
|
||||
bool get isReady =>
|
||||
_isLoaded && !_quotation.isLoading && _quotation.error == null;
|
||||
quotation != null && !_quotation.isLoading && _quotation.error == null;
|
||||
|
||||
DateTime? get quoteExpiresAt {
|
||||
final quotes = quotation?.quotes;
|
||||
@@ -82,6 +86,7 @@ class MultiQuotationProvider extends ChangeNotifier {
|
||||
? null
|
||||
: Map<String, String>.from(metadata);
|
||||
|
||||
_cancelAutoRefresh();
|
||||
_setResource(_quotation.copyWith(isLoading: true, error: null));
|
||||
try {
|
||||
final response = await MultiplePaymentsService.getQuotation(
|
||||
@@ -94,10 +99,10 @@ class MultiQuotationProvider extends ChangeNotifier {
|
||||
),
|
||||
);
|
||||
|
||||
_isLoaded = true;
|
||||
_setResource(
|
||||
_quotation.copyWith(data: response, isLoading: false, error: null),
|
||||
);
|
||||
_scheduleAutoRefresh();
|
||||
} catch (e) {
|
||||
_setResource(
|
||||
_quotation.copyWith(
|
||||
@@ -123,10 +128,10 @@ class MultiQuotationProvider extends ChangeNotifier {
|
||||
}
|
||||
|
||||
void reset() {
|
||||
_isLoaded = false;
|
||||
_lastIntents = null;
|
||||
_lastPreviewOnly = false;
|
||||
_lastMetadata = null;
|
||||
_cancelAutoRefresh();
|
||||
_quotation = Resource(data: null);
|
||||
notifyListeners();
|
||||
}
|
||||
@@ -135,4 +140,37 @@ class MultiQuotationProvider extends ChangeNotifier {
|
||||
_quotation = quotation;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void _scheduleAutoRefresh() {
|
||||
_autoRefreshTimer?.cancel();
|
||||
final expiresAt = quoteExpiresAt;
|
||||
if (expiresAt == null) return;
|
||||
|
||||
final now = DateTime.now().toUtc();
|
||||
var delay = expiresAt.difference(now) - _autoRefreshLead;
|
||||
if (delay.isNegative) delay = Duration.zero;
|
||||
_autoRefreshTimer = Timer(delay, _triggerAutoRefresh);
|
||||
}
|
||||
|
||||
Future<void> _triggerAutoRefresh() async {
|
||||
if (_quotation.isLoading) return;
|
||||
final intents = _lastIntents;
|
||||
if (intents == null || intents.isEmpty) return;
|
||||
await quotePayments(
|
||||
intents,
|
||||
previewOnly: _lastPreviewOnly,
|
||||
metadata: _lastMetadata,
|
||||
);
|
||||
}
|
||||
|
||||
void _cancelAutoRefresh() {
|
||||
_autoRefreshTimer?.cancel();
|
||||
_autoRefreshTimer = null;
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_cancelAutoRefresh();
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
import 'package:pshared/controllers/balance_mask/wallets.dart';
|
||||
import 'package:pshared/models/payment/asset.dart';
|
||||
import 'package:pshared/models/payment/chain_network.dart';
|
||||
import 'package:pshared/models/payment/currency_pair.dart';
|
||||
import 'package:pshared/models/payment/customer.dart';
|
||||
import 'package:pshared/models/payment/fx/intent.dart';
|
||||
import 'package:pshared/models/payment/fx/side.dart';
|
||||
import 'package:pshared/models/payment/kind.dart';
|
||||
import 'package:pshared/models/payment/methods/card.dart';
|
||||
import 'package:pshared/models/payment/methods/crypto_address.dart';
|
||||
@@ -21,6 +18,7 @@ import 'package:pshared/provider/payment/amount.dart';
|
||||
import 'package:pshared/provider/payment/flow.dart';
|
||||
import 'package:pshared/provider/recipient/provider.dart';
|
||||
import 'package:pshared/utils/currency.dart';
|
||||
import 'package:pshared/utils/payment/fx_helpers.dart';
|
||||
|
||||
|
||||
class QuotationIntentBuilder {
|
||||
@@ -40,22 +38,19 @@ class QuotationIntentBuilder {
|
||||
method: selectedMethod,
|
||||
data: paymentData,
|
||||
);
|
||||
final sourceCurrency = currencyCodeToString(selectedWallet.currency);
|
||||
final amount = Money(
|
||||
amount: payment.amount.toString(),
|
||||
// TODO: adapt to possible other sources
|
||||
currency: currencyCodeToString(selectedWallet.currency),
|
||||
currency: sourceCurrency,
|
||||
);
|
||||
final isCryptoToCrypto = paymentData is CryptoAddressPaymentMethod &&
|
||||
(paymentData.asset?.tokenSymbol ?? '').trim().toUpperCase() == amount.currency;
|
||||
final fxIntent = isCryptoToCrypto
|
||||
? null
|
||||
: FxIntent(
|
||||
pair: CurrencyPair(
|
||||
base: currencyCodeToString(selectedWallet.currency),
|
||||
quote: 'RUB', // TODO: exentd target currencies
|
||||
),
|
||||
side: FxSide.sellBaseBuyQuote,
|
||||
);
|
||||
final fxIntent = FxIntentHelper.buildSellBaseBuyQuote(
|
||||
baseCurrency: sourceCurrency,
|
||||
quoteCurrency: 'RUB', // TODO: exentd target currencies
|
||||
enabled: !isCryptoToCrypto,
|
||||
);
|
||||
return PaymentIntent(
|
||||
kind: PaymentKind.payout,
|
||||
amount: amount,
|
||||
@@ -69,35 +64,14 @@ class QuotationIntentBuilder {
|
||||
),
|
||||
fx: fxIntent,
|
||||
settlementMode: payment.payerCoversFee ? SettlementMode.fixReceived : SettlementMode.fixSource,
|
||||
settlementCurrency: _resolveSettlementCurrency(amount: amount, fx: fxIntent),
|
||||
settlementCurrency: FxIntentHelper.resolveSettlementCurrency(
|
||||
amount: amount,
|
||||
fx: fxIntent,
|
||||
),
|
||||
customer: customer,
|
||||
);
|
||||
}
|
||||
|
||||
String _resolveSettlementCurrency({
|
||||
required Money amount,
|
||||
required FxIntent? fx,
|
||||
}) {
|
||||
final pair = fx?.pair;
|
||||
if (pair != null) {
|
||||
switch (fx?.side ?? FxSide.unspecified) {
|
||||
case FxSide.buyBaseSellQuote:
|
||||
if (pair.base.isNotEmpty) return pair.base;
|
||||
break;
|
||||
case FxSide.sellBaseBuyQuote:
|
||||
if (pair.quote.isNotEmpty) return pair.quote;
|
||||
break;
|
||||
case FxSide.unspecified:
|
||||
break;
|
||||
}
|
||||
if (amount.currency == pair.base && pair.quote.isNotEmpty) return pair.quote;
|
||||
if (amount.currency == pair.quote && pair.base.isNotEmpty) return pair.base;
|
||||
if (pair.quote.isNotEmpty) return pair.quote;
|
||||
if (pair.base.isNotEmpty) return pair.base;
|
||||
}
|
||||
return amount.currency;
|
||||
}
|
||||
|
||||
Customer? _buildCustomer({
|
||||
required Recipient? recipient,
|
||||
required PaymentMethod? method,
|
||||
|
||||
Reference in New Issue
Block a user