77 lines
2.3 KiB
Dart
77 lines
2.3 KiB
Dart
import 'package:flutter/material.dart';
|
|
|
|
import 'package:pshared/models/money.dart';
|
|
import 'package:pshared/models/payment/payment.dart';
|
|
import 'package:pshared/models/payment/fx/quote.dart';
|
|
import 'package:pshared/utils/currency.dart';
|
|
import 'package:pshared/utils/money.dart';
|
|
|
|
import 'package:pweb/pages/report/details/section.dart';
|
|
import 'package:pweb/pages/report/details/sections/rows.dart';
|
|
|
|
import 'package:pweb/generated/i18n/app_localizations.dart';
|
|
|
|
|
|
class PaymentFxSection extends StatelessWidget {
|
|
final Payment payment;
|
|
|
|
const PaymentFxSection({super.key, required this.payment});
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final loc = AppLocalizations.of(context)!;
|
|
final fx = payment.lastQuote?.fxQuote;
|
|
final rows = buildDetailRows([
|
|
DetailValue(label: loc.fxRateLabel, value: _formatRate(fx)),
|
|
]);
|
|
|
|
return DetailsSection(title: loc.paymentDetailsFx, children: rows);
|
|
}
|
|
|
|
String? _formatRate(FxQuote? fx) {
|
|
if (fx == null) return null;
|
|
final price = fx.price?.trim();
|
|
if (price == null || price.isEmpty) return null;
|
|
|
|
final baseCurrency = _firstNonEmpty([
|
|
fx.baseCurrency,
|
|
fx.baseAmount?.currency,
|
|
currencySymbolFromCode(fx.baseCurrency),
|
|
currencySymbolFromCode(fx.baseAmount?.currency),
|
|
]);
|
|
final quoteCurrency = _firstNonEmpty([
|
|
fx.quoteCurrency,
|
|
fx.quoteAmount?.currency,
|
|
currencySymbolFromCode(fx.quoteCurrency),
|
|
currencySymbolFromCode(fx.quoteAmount?.currency),
|
|
]);
|
|
|
|
if (baseCurrency == null || quoteCurrency == null) return price;
|
|
|
|
final baseDisplay = formatMoneyDisplay(
|
|
Money(amount: '1', currency: baseCurrency),
|
|
fallback: '1 $baseCurrency',
|
|
invalidAmountFallback: '1',
|
|
);
|
|
final quoteDisplay = formatMoneyDisplay(
|
|
Money(amount: _normalizeAmount(price), currency: quoteCurrency),
|
|
fallback: '$price $quoteCurrency',
|
|
invalidAmountFallback: price,
|
|
);
|
|
|
|
return '$baseDisplay = $quoteDisplay';
|
|
}
|
|
|
|
String? _firstNonEmpty(List<String?> values) {
|
|
for (final value in values) {
|
|
final trimmed = value?.trim();
|
|
if (trimmed != null && trimmed.isNotEmpty) return trimmed;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
String _normalizeAmount(String raw) {
|
|
return raw.replaceAll(RegExp(r'\s+'), '').replaceAll(',', '.');
|
|
}
|
|
}
|