removed legacy from bff
This commit is contained in:
@@ -1,20 +0,0 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
import 'package:pshared/data/dto/money.dart';
|
||||
|
||||
part 'network_fee.g.dart';
|
||||
|
||||
|
||||
@JsonSerializable()
|
||||
class NetworkFeeDTO {
|
||||
final MoneyDTO? networkFee;
|
||||
final String? estimationContext;
|
||||
|
||||
const NetworkFeeDTO({
|
||||
this.networkFee,
|
||||
this.estimationContext,
|
||||
});
|
||||
|
||||
factory NetworkFeeDTO.fromJson(Map<String, dynamic> json) => _$NetworkFeeDTOFromJson(json);
|
||||
Map<String, dynamic> toJson() => _$NetworkFeeDTOToJson(this);
|
||||
}
|
||||
@@ -1,35 +1,21 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
import 'package:pshared/data/dto/payment/fee_line.dart';
|
||||
import 'package:pshared/data/dto/payment/fx_quote.dart';
|
||||
import 'package:pshared/data/dto/money.dart';
|
||||
import 'package:pshared/data/dto/payment/network_fee.dart';
|
||||
import 'package:pshared/data/dto/payment/quote_amounts.dart';
|
||||
import 'package:pshared/data/dto/payment/quote_fees.dart';
|
||||
|
||||
part 'payment_quote.g.dart';
|
||||
|
||||
|
||||
@JsonSerializable()
|
||||
class PaymentQuoteDTO {
|
||||
final String? quoteRef;
|
||||
final MoneyDTO? debitAmount;
|
||||
final MoneyDTO? debitSettlementAmount;
|
||||
final MoneyDTO? expectedSettlementAmount;
|
||||
final MoneyDTO? expectedFeeTotal;
|
||||
final List<FeeLineDTO>? feeLines;
|
||||
final NetworkFeeDTO? networkFee;
|
||||
final QuoteAmountsDTO? amounts;
|
||||
final QuoteFeesDTO? fees;
|
||||
final FxQuoteDTO? fxQuote;
|
||||
|
||||
const PaymentQuoteDTO({
|
||||
this.quoteRef,
|
||||
this.debitAmount,
|
||||
this.debitSettlementAmount,
|
||||
this.expectedSettlementAmount,
|
||||
this.expectedFeeTotal,
|
||||
this.feeLines,
|
||||
this.networkFee,
|
||||
this.fxQuote,
|
||||
});
|
||||
const PaymentQuoteDTO({this.quoteRef, this.amounts, this.fees, this.fxQuote});
|
||||
|
||||
factory PaymentQuoteDTO.fromJson(Map<String, dynamic> json) => _$PaymentQuoteDTOFromJson(json);
|
||||
factory PaymentQuoteDTO.fromJson(Map<String, dynamic> json) =>
|
||||
_$PaymentQuoteDTOFromJson(json);
|
||||
Map<String, dynamic> toJson() => _$PaymentQuoteDTOToJson(this);
|
||||
}
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
import 'package:pshared/data/dto/money.dart';
|
||||
|
||||
part 'quote_aggregate.g.dart';
|
||||
|
||||
|
||||
@JsonSerializable()
|
||||
class PaymentQuoteAggregateDTO {
|
||||
final List<MoneyDTO>? debitAmounts;
|
||||
final List<MoneyDTO>? expectedSettlementAmounts;
|
||||
final List<MoneyDTO>? expectedFeeTotals;
|
||||
final List<MoneyDTO>? networkFeeTotals;
|
||||
|
||||
const PaymentQuoteAggregateDTO({
|
||||
this.debitAmounts,
|
||||
this.expectedSettlementAmounts,
|
||||
this.expectedFeeTotals,
|
||||
this.networkFeeTotals,
|
||||
});
|
||||
|
||||
factory PaymentQuoteAggregateDTO.fromJson(Map<String, dynamic> json) => _$PaymentQuoteAggregateDTOFromJson(json);
|
||||
Map<String, dynamic> toJson() => _$PaymentQuoteAggregateDTOToJson(this);
|
||||
}
|
||||
22
frontend/pshared/lib/data/dto/payment/quote_amounts.dart
Normal file
22
frontend/pshared/lib/data/dto/payment/quote_amounts.dart
Normal file
@@ -0,0 +1,22 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
import 'package:pshared/data/dto/money.dart';
|
||||
|
||||
part 'quote_amounts.g.dart';
|
||||
|
||||
@JsonSerializable()
|
||||
class QuoteAmountsDTO {
|
||||
final MoneyDTO? sourcePrincipal;
|
||||
final MoneyDTO? sourceDebitTotal;
|
||||
final MoneyDTO? destinationSettlement;
|
||||
|
||||
const QuoteAmountsDTO({
|
||||
this.sourcePrincipal,
|
||||
this.sourceDebitTotal,
|
||||
this.destinationSettlement,
|
||||
});
|
||||
|
||||
factory QuoteAmountsDTO.fromJson(Map<String, dynamic> json) =>
|
||||
_$QuoteAmountsDTOFromJson(json);
|
||||
Map<String, dynamic> toJson() => _$QuoteAmountsDTOToJson(this);
|
||||
}
|
||||
16
frontend/pshared/lib/data/dto/payment/quote_fees.dart
Normal file
16
frontend/pshared/lib/data/dto/payment/quote_fees.dart
Normal file
@@ -0,0 +1,16 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
import 'package:pshared/data/dto/payment/fee_line.dart';
|
||||
|
||||
part 'quote_fees.g.dart';
|
||||
|
||||
@JsonSerializable()
|
||||
class QuoteFeesDTO {
|
||||
final List<FeeLineDTO>? lines;
|
||||
|
||||
const QuoteFeesDTO({this.lines});
|
||||
|
||||
factory QuoteFeesDTO.fromJson(Map<String, dynamic> json) =>
|
||||
_$QuoteFeesDTOFromJson(json);
|
||||
Map<String, dynamic> toJson() => _$QuoteFeesDTOToJson(this);
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
import 'package:pshared/data/dto/payment/quote_aggregate.dart';
|
||||
import 'package:pshared/data/dto/payment/payment_quote.dart';
|
||||
|
||||
part 'quotes.g.dart';
|
||||
@@ -9,14 +8,12 @@ part 'quotes.g.dart';
|
||||
class PaymentQuotesDTO {
|
||||
final String quoteRef;
|
||||
final String? idempotencyKey;
|
||||
final PaymentQuoteAggregateDTO? aggregate;
|
||||
final List<PaymentQuoteDTO>? quotes;
|
||||
final List<PaymentQuoteDTO>? items;
|
||||
|
||||
const PaymentQuotesDTO({
|
||||
required this.quoteRef,
|
||||
this.idempotencyKey,
|
||||
this.aggregate,
|
||||
this.quotes,
|
||||
this.items,
|
||||
});
|
||||
|
||||
factory PaymentQuotesDTO.fromJson(Map<String, dynamic> json) =>
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
import 'package:pshared/data/dto/payment/network_fee.dart';
|
||||
import 'package:pshared/data/mapper/money.dart';
|
||||
import 'package:pshared/models/payment/fees/network.dart';
|
||||
|
||||
|
||||
extension NetworkFeeDTOMapper on NetworkFeeDTO {
|
||||
NetworkFee toDomain() => NetworkFee(
|
||||
networkFee: networkFee?.toDomain(),
|
||||
estimationContext: estimationContext,
|
||||
);
|
||||
}
|
||||
|
||||
extension NetworkFeeMapper on NetworkFee {
|
||||
NetworkFeeDTO toDTO() => NetworkFeeDTO(
|
||||
networkFee: networkFee?.toDTO(),
|
||||
estimationContext: estimationContext,
|
||||
);
|
||||
}
|
||||
@@ -1,21 +1,15 @@
|
||||
import 'package:pshared/data/dto/payment/payment_quote.dart';
|
||||
import 'package:pshared/data/mapper/payment/fees/line.dart';
|
||||
import 'package:pshared/data/mapper/payment/fx_quote.dart';
|
||||
import 'package:pshared/data/mapper/money.dart';
|
||||
import 'package:pshared/data/mapper/payment/network_fee.dart';
|
||||
import 'package:pshared/data/mapper/payment/quote/amounts.dart';
|
||||
import 'package:pshared/data/mapper/payment/quote/fees.dart';
|
||||
import 'package:pshared/models/payment/quote/quote.dart';
|
||||
|
||||
|
||||
extension PaymentQuoteDTOMapper on PaymentQuoteDTO {
|
||||
PaymentQuote toDomain({String? idempotencyKey}) => PaymentQuote(
|
||||
quoteRef: quoteRef,
|
||||
idempotencyKey: idempotencyKey,
|
||||
debitAmount: debitAmount?.toDomain(),
|
||||
debitSettlementAmount: debitSettlementAmount?.toDomain(),
|
||||
expectedSettlementAmount: expectedSettlementAmount?.toDomain(),
|
||||
expectedFeeTotal: expectedFeeTotal?.toDomain(),
|
||||
feeLines: feeLines?.map((line) => line.toDomain()).toList(),
|
||||
networkFee: networkFee?.toDomain(),
|
||||
amounts: amounts?.toDomain(),
|
||||
fees: fees?.toDomain(),
|
||||
fxQuote: fxQuote?.toDomain(),
|
||||
);
|
||||
}
|
||||
@@ -23,12 +17,8 @@ extension PaymentQuoteDTOMapper on PaymentQuoteDTO {
|
||||
extension PaymentQuoteMapper on PaymentQuote {
|
||||
PaymentQuoteDTO toDTO() => PaymentQuoteDTO(
|
||||
quoteRef: quoteRef,
|
||||
debitAmount: debitAmount?.toDTO(),
|
||||
debitSettlementAmount: debitSettlementAmount?.toDTO(),
|
||||
expectedSettlementAmount: expectedSettlementAmount?.toDTO(),
|
||||
expectedFeeTotal: expectedFeeTotal?.toDTO(),
|
||||
feeLines: feeLines?.map((line) => line.toDTO()).toList(),
|
||||
networkFee: networkFee?.toDTO(),
|
||||
amounts: amounts?.toDTO(),
|
||||
fees: fees?.toDTO(),
|
||||
fxQuote: fxQuote?.toDTO(),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
import 'package:pshared/data/dto/payment/quote_aggregate.dart';
|
||||
import 'package:pshared/data/mapper/money.dart';
|
||||
import 'package:pshared/models/payment/quote/aggregate.dart';
|
||||
|
||||
|
||||
extension PaymentQuoteAggregateDTOMapper on PaymentQuoteAggregateDTO {
|
||||
PaymentQuoteAggregate toDomain() => PaymentQuoteAggregate(
|
||||
debitAmounts: debitAmounts?.map((amount) => amount.toDomain()).toList(),
|
||||
expectedSettlementAmounts: expectedSettlementAmounts?.map((amount) => amount.toDomain()).toList(),
|
||||
expectedFeeTotals: expectedFeeTotals?.map((amount) => amount.toDomain()).toList(),
|
||||
networkFeeTotals: networkFeeTotals?.map((amount) => amount.toDomain()).toList(),
|
||||
);
|
||||
}
|
||||
|
||||
extension PaymentQuoteAggregateMapper on PaymentQuoteAggregate {
|
||||
PaymentQuoteAggregateDTO toDTO() => PaymentQuoteAggregateDTO(
|
||||
debitAmounts: debitAmounts?.map((amount) => amount.toDTO()).toList(),
|
||||
expectedSettlementAmounts: expectedSettlementAmounts?.map((amount) => amount.toDTO()).toList(),
|
||||
expectedFeeTotals: expectedFeeTotals?.map((amount) => amount.toDTO()).toList(),
|
||||
networkFeeTotals: networkFeeTotals?.map((amount) => amount.toDTO()).toList(),
|
||||
);
|
||||
}
|
||||
19
frontend/pshared/lib/data/mapper/payment/quote/amounts.dart
Normal file
19
frontend/pshared/lib/data/mapper/payment/quote/amounts.dart
Normal file
@@ -0,0 +1,19 @@
|
||||
import 'package:pshared/data/dto/payment/quote_amounts.dart';
|
||||
import 'package:pshared/data/mapper/money.dart';
|
||||
import 'package:pshared/models/payment/quote/amounts.dart';
|
||||
|
||||
extension QuoteAmountsDTOMapper on QuoteAmountsDTO {
|
||||
QuoteAmounts toDomain() => QuoteAmounts(
|
||||
sourcePrincipal: sourcePrincipal?.toDomain(),
|
||||
sourceDebitTotal: sourceDebitTotal?.toDomain(),
|
||||
destinationSettlement: destinationSettlement?.toDomain(),
|
||||
);
|
||||
}
|
||||
|
||||
extension QuoteAmountsMapper on QuoteAmounts {
|
||||
QuoteAmountsDTO toDTO() => QuoteAmountsDTO(
|
||||
sourcePrincipal: sourcePrincipal?.toDTO(),
|
||||
sourceDebitTotal: sourceDebitTotal?.toDTO(),
|
||||
destinationSettlement: destinationSettlement?.toDTO(),
|
||||
);
|
||||
}
|
||||
13
frontend/pshared/lib/data/mapper/payment/quote/fees.dart
Normal file
13
frontend/pshared/lib/data/mapper/payment/quote/fees.dart
Normal file
@@ -0,0 +1,13 @@
|
||||
import 'package:pshared/data/dto/payment/quote_fees.dart';
|
||||
import 'package:pshared/data/mapper/payment/fees/line.dart';
|
||||
import 'package:pshared/models/payment/quote/fees.dart';
|
||||
|
||||
extension QuoteFeesDTOMapper on QuoteFeesDTO {
|
||||
QuoteFees toDomain() =>
|
||||
QuoteFees(lines: lines?.map((line) => line.toDomain()).toList());
|
||||
}
|
||||
|
||||
extension QuoteFeesMapper on QuoteFees {
|
||||
QuoteFeesDTO toDTO() =>
|
||||
QuoteFeesDTO(lines: lines?.map((line) => line.toDTO()).toList());
|
||||
}
|
||||
@@ -1,14 +1,12 @@
|
||||
import 'package:pshared/data/dto/payment/quotes.dart';
|
||||
import 'package:pshared/data/mapper/payment/quote.dart';
|
||||
import 'package:pshared/data/mapper/payment/quote/aggregate.dart';
|
||||
import 'package:pshared/models/payment/quote/quotes.dart';
|
||||
|
||||
extension PaymentQuotesDTOMapper on PaymentQuotesDTO {
|
||||
PaymentQuotes toDomain({String? idempotencyKey}) => PaymentQuotes(
|
||||
quoteRef: quoteRef,
|
||||
idempotencyKey: idempotencyKey ?? this.idempotencyKey,
|
||||
aggregate: aggregate?.toDomain(),
|
||||
quotes: quotes?.map((quote) => quote.toDomain()).toList(),
|
||||
items: items?.map((quote) => quote.toDomain()).toList(),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -16,7 +14,6 @@ extension PaymentQuotesMapper on PaymentQuotes {
|
||||
PaymentQuotesDTO toDTO() => PaymentQuotesDTO(
|
||||
quoteRef: quoteRef,
|
||||
idempotencyKey: idempotencyKey,
|
||||
aggregate: aggregate?.toDTO(),
|
||||
quotes: quotes?.map((quote) => quote.toDTO()).toList(),
|
||||
items: items?.map((quote) => quote.toDTO()).toList(),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
import 'package:pshared/models/money.dart';
|
||||
|
||||
|
||||
class NetworkFee {
|
||||
final Money? networkFee;
|
||||
final String? estimationContext;
|
||||
|
||||
const NetworkFee({
|
||||
required this.networkFee,
|
||||
required this.estimationContext,
|
||||
});
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
import 'package:pshared/models/money.dart';
|
||||
|
||||
|
||||
class PaymentQuoteAggregate {
|
||||
final List<Money>? debitAmounts;
|
||||
final List<Money>? expectedSettlementAmounts;
|
||||
final List<Money>? expectedFeeTotals;
|
||||
final List<Money>? networkFeeTotals;
|
||||
|
||||
const PaymentQuoteAggregate({
|
||||
required this.debitAmounts,
|
||||
required this.expectedSettlementAmounts,
|
||||
required this.expectedFeeTotals,
|
||||
required this.networkFeeTotals,
|
||||
});
|
||||
}
|
||||
13
frontend/pshared/lib/models/payment/quote/amounts.dart
Normal file
13
frontend/pshared/lib/models/payment/quote/amounts.dart
Normal file
@@ -0,0 +1,13 @@
|
||||
import 'package:pshared/models/money.dart';
|
||||
|
||||
class QuoteAmounts {
|
||||
final Money? sourcePrincipal;
|
||||
final Money? sourceDebitTotal;
|
||||
final Money? destinationSettlement;
|
||||
|
||||
const QuoteAmounts({
|
||||
required this.sourcePrincipal,
|
||||
required this.sourceDebitTotal,
|
||||
required this.destinationSettlement,
|
||||
});
|
||||
}
|
||||
7
frontend/pshared/lib/models/payment/quote/fees.dart
Normal file
7
frontend/pshared/lib/models/payment/quote/fees.dart
Normal file
@@ -0,0 +1,7 @@
|
||||
import 'package:pshared/models/payment/fees/line.dart';
|
||||
|
||||
class QuoteFees {
|
||||
final List<FeeLine>? lines;
|
||||
|
||||
const QuoteFees({required this.lines});
|
||||
}
|
||||
@@ -1,29 +1,19 @@
|
||||
import 'package:pshared/models/payment/fees/line.dart';
|
||||
import 'package:pshared/models/payment/fx/quote.dart';
|
||||
import 'package:pshared/models/money.dart';
|
||||
import 'package:pshared/models/payment/fees/network.dart';
|
||||
|
||||
import 'package:pshared/models/payment/quote/amounts.dart';
|
||||
import 'package:pshared/models/payment/quote/fees.dart';
|
||||
|
||||
class PaymentQuote {
|
||||
final String? quoteRef;
|
||||
final String? idempotencyKey;
|
||||
final Money? debitAmount;
|
||||
final Money? debitSettlementAmount;
|
||||
final Money? expectedSettlementAmount;
|
||||
final Money? expectedFeeTotal;
|
||||
final List<FeeLine>? feeLines;
|
||||
final NetworkFee? networkFee;
|
||||
final QuoteAmounts? amounts;
|
||||
final QuoteFees? fees;
|
||||
final FxQuote? fxQuote;
|
||||
|
||||
const PaymentQuote({
|
||||
required this.quoteRef,
|
||||
required this.idempotencyKey,
|
||||
required this.debitAmount,
|
||||
required this.debitSettlementAmount,
|
||||
required this.expectedSettlementAmount,
|
||||
required this.expectedFeeTotal,
|
||||
required this.feeLines,
|
||||
required this.networkFee,
|
||||
required this.amounts,
|
||||
required this.fees,
|
||||
required this.fxQuote,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,17 +1,13 @@
|
||||
import 'package:pshared/models/payment/quote/quote.dart';
|
||||
import 'package:pshared/models/payment/quote/aggregate.dart';
|
||||
|
||||
|
||||
class PaymentQuotes {
|
||||
final String quoteRef;
|
||||
final String? idempotencyKey;
|
||||
final PaymentQuoteAggregate? aggregate;
|
||||
final List<PaymentQuote>? quotes;
|
||||
final List<PaymentQuote>? items;
|
||||
|
||||
const PaymentQuotes({
|
||||
required this.quoteRef,
|
||||
required this.idempotencyKey,
|
||||
required this.aggregate,
|
||||
required this.quotes,
|
||||
required this.items,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -34,11 +34,11 @@ class MultiQuotationProvider extends ChangeNotifier {
|
||||
quotation != null && !_quotation.isLoading && _quotation.error == null;
|
||||
|
||||
DateTime? get quoteExpiresAt {
|
||||
final quotes = quotation?.quotes;
|
||||
if (quotes == null || quotes.isEmpty) return null;
|
||||
final items = quotation?.items;
|
||||
if (items == null || items.isEmpty) return null;
|
||||
|
||||
int? minExpiresAt;
|
||||
for (final quote in quotes) {
|
||||
for (final quote in items) {
|
||||
final expiresAtUnixMs = quote.fxQuote?.expiresAtUnixMs;
|
||||
if (expiresAtUnixMs == null) continue;
|
||||
minExpiresAt = minExpiresAt == null
|
||||
|
||||
@@ -23,12 +23,16 @@ import 'package:pshared/provider/recipient/pmethods.dart';
|
||||
import 'package:pshared/provider/resource.dart';
|
||||
import 'package:pshared/provider/payment/quotation/intent_builder.dart';
|
||||
import 'package:pshared/service/payment/quotation.dart';
|
||||
import 'package:pshared/utils/payment/quote_helpers.dart';
|
||||
import 'package:pshared/utils/exception.dart';
|
||||
|
||||
|
||||
class QuotationProvider extends ChangeNotifier {
|
||||
static final _logger = Logger('provider.payment.quotation');
|
||||
Resource<PaymentQuote> _quotation = Resource(data: null, isLoading: false, error: null);
|
||||
Resource<PaymentQuote> _quotation = Resource(
|
||||
data: null,
|
||||
isLoading: false,
|
||||
error: null,
|
||||
);
|
||||
late OrganizationsProvider _organizations;
|
||||
bool _isLoaded = false;
|
||||
PaymentIntent? _lastIntent;
|
||||
@@ -37,7 +41,7 @@ class QuotationProvider extends ChangeNotifier {
|
||||
AutoRefreshMode _autoRefreshMode = AutoRefreshMode.on;
|
||||
|
||||
void update(
|
||||
OrganizationsProvider venue,
|
||||
OrganizationsProvider venue,
|
||||
PaymentAmountProvider payment,
|
||||
WalletsController wallets,
|
||||
PaymentFlowProvider flow,
|
||||
@@ -62,7 +66,8 @@ class QuotationProvider extends ChangeNotifier {
|
||||
bool get isLoading => _quotation.isLoading;
|
||||
Exception? get error => _quotation.error;
|
||||
bool get canRefresh => _lastIntent != null;
|
||||
bool get isReady => _isLoaded && !_quotation.isLoading && _quotation.error == null;
|
||||
bool get isReady =>
|
||||
_isLoaded && !_quotation.isLoading && _quotation.error == null;
|
||||
AutoRefreshMode get autoRefreshMode => _autoRefreshMode;
|
||||
|
||||
DateTime? get quoteExpiresAt {
|
||||
@@ -71,10 +76,10 @@ class QuotationProvider extends ChangeNotifier {
|
||||
return DateTime.fromMillisecondsSinceEpoch(expiresAtUnixMs, isUtc: true);
|
||||
}
|
||||
|
||||
|
||||
Asset? get fee => _assetFromMoney(quotation?.expectedFeeTotal);
|
||||
Asset? get total => _assetFromMoney(quotation?.debitAmount);
|
||||
Asset? get recipientGets => _assetFromMoney(quotation?.expectedSettlementAmount);
|
||||
Asset? get fee => _assetFromMoney(quoteFeeTotal(quotation));
|
||||
Asset? get total => _assetFromMoney(quotation?.amounts?.sourceDebitTotal);
|
||||
Asset? get recipientGets =>
|
||||
_assetFromMoney(quotation?.amounts?.destinationSettlement);
|
||||
|
||||
Asset? _assetFromMoney(Money? money) {
|
||||
if (money == null) return null;
|
||||
@@ -101,26 +106,32 @@ class QuotationProvider extends ChangeNotifier {
|
||||
}
|
||||
|
||||
Future<PaymentQuote?> getQuotation(PaymentIntent intent) async {
|
||||
if (!_organizations.isOrganizationSet) throw StateError('Organization is not set');
|
||||
if (!_organizations.isOrganizationSet) {
|
||||
throw StateError('Organization is not set');
|
||||
}
|
||||
_lastIntent = intent;
|
||||
try {
|
||||
_setResource(_quotation.copyWith(isLoading: true, error: null));
|
||||
final response = await QuotationService.getQuotation(
|
||||
_organizations.current.id,
|
||||
_organizations.current.id,
|
||||
QuotePaymentRequest(
|
||||
idempotencyKey: Uuid().v4(),
|
||||
intent: intent.toDTO(),
|
||||
),
|
||||
);
|
||||
_isLoaded = true;
|
||||
_setResource(_quotation.copyWith(data: response, isLoading: false, error: null));
|
||||
_setResource(
|
||||
_quotation.copyWith(data: response, isLoading: false, error: null),
|
||||
);
|
||||
} catch (e, st) {
|
||||
_logger.warning('Failed to get quotation', e, st);
|
||||
_setResource(_quotation.copyWith(
|
||||
data: null,
|
||||
error: toException(e),
|
||||
isLoading: false,
|
||||
));
|
||||
_setResource(
|
||||
_quotation.copyWith(
|
||||
data: null,
|
||||
error: toException(e),
|
||||
isLoading: false,
|
||||
),
|
||||
);
|
||||
}
|
||||
return _quotation.data;
|
||||
}
|
||||
|
||||
92
frontend/pshared/lib/utils/payment/quote_helpers.dart
Normal file
92
frontend/pshared/lib/utils/payment/quote_helpers.dart
Normal file
@@ -0,0 +1,92 @@
|
||||
import 'package:pshared/models/money.dart';
|
||||
import 'package:pshared/models/payment/fees/line.dart';
|
||||
import 'package:pshared/models/payment/quote/quote.dart';
|
||||
import 'package:pshared/utils/currency.dart';
|
||||
import 'package:pshared/utils/money.dart';
|
||||
|
||||
Money? quoteFeeTotal(PaymentQuote? quote) {
|
||||
final preferredCurrency =
|
||||
quote?.amounts?.sourcePrincipal?.currency ??
|
||||
quote?.amounts?.sourceDebitTotal?.currency;
|
||||
return quoteFeeTotalFromLines(
|
||||
quote?.fees?.lines,
|
||||
preferredCurrency: preferredCurrency,
|
||||
);
|
||||
}
|
||||
|
||||
Money? quoteFeeTotalFromLines(
|
||||
List<FeeLine>? lines, {
|
||||
String? preferredCurrency,
|
||||
}) {
|
||||
if (lines == null || lines.isEmpty) return null;
|
||||
|
||||
final normalizedPreferred = _normalizeCurrency(preferredCurrency);
|
||||
final totalsByCurrency = <String, double>{};
|
||||
|
||||
for (final line in lines) {
|
||||
final money = line.amount;
|
||||
if (money == null) continue;
|
||||
|
||||
final currency = _normalizeCurrency(money.currency);
|
||||
if (currency == null) continue;
|
||||
|
||||
final amount = parseMoneyAmount(money.amount, fallback: double.nan);
|
||||
if (amount.isNaN) continue;
|
||||
|
||||
final sign = _lineSign(line.side);
|
||||
final signedAmount = sign * amount.abs();
|
||||
totalsByCurrency[currency] =
|
||||
(totalsByCurrency[currency] ?? 0) + signedAmount;
|
||||
}
|
||||
|
||||
if (totalsByCurrency.isEmpty) return null;
|
||||
|
||||
final selectedCurrency =
|
||||
normalizedPreferred != null &&
|
||||
totalsByCurrency.containsKey(normalizedPreferred)
|
||||
? normalizedPreferred
|
||||
: totalsByCurrency.keys.first;
|
||||
final total = totalsByCurrency[selectedCurrency];
|
||||
if (total == null) return null;
|
||||
|
||||
return Money(amount: amountToString(total), currency: selectedCurrency);
|
||||
}
|
||||
|
||||
List<Money> aggregateMoneyByCurrency(Iterable<Money?> values) {
|
||||
final totals = <String, double>{};
|
||||
for (final value in values) {
|
||||
if (value == null) continue;
|
||||
|
||||
final currency = _normalizeCurrency(value.currency);
|
||||
if (currency == null) continue;
|
||||
|
||||
final amount = parseMoneyAmount(value.amount, fallback: double.nan);
|
||||
if (amount.isNaN) continue;
|
||||
|
||||
totals[currency] = (totals[currency] ?? 0) + amount;
|
||||
}
|
||||
|
||||
return totals.entries
|
||||
.map(
|
||||
(entry) =>
|
||||
Money(amount: amountToString(entry.value), currency: entry.key),
|
||||
)
|
||||
.toList();
|
||||
}
|
||||
|
||||
double _lineSign(String? side) {
|
||||
final normalized = side?.trim().toLowerCase() ?? '';
|
||||
switch (normalized) {
|
||||
case 'entry_side_credit':
|
||||
case 'credit':
|
||||
return -1;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
String? _normalizeCurrency(String? currency) {
|
||||
final normalized = currency?.trim().toUpperCase();
|
||||
if (normalized == null || normalized.isEmpty) return null;
|
||||
return normalized;
|
||||
}
|
||||
Reference in New Issue
Block a user