Files
sendico/frontend/pweb/lib/utils/report/payment_mapper.dart
2026-02-27 13:08:23 +01:00

109 lines
3.1 KiB
Dart

import 'package:pshared/models/payment/operation.dart';
import 'package:pshared/models/payment/payment.dart';
import 'package:pshared/models/payment/state.dart';
import 'package:pshared/models/payment/status.dart';
import 'package:pshared/utils/money.dart';
OperationItem mapPaymentToOperation(Payment payment) {
final debit = payment.lastQuote?.amounts?.sourceDebitTotal;
final settlement = payment.lastQuote?.amounts?.destinationSettlement;
final amountMoney = debit ?? settlement;
final amount = parseMoneyAmount(amountMoney?.amount);
final currency = amountMoney?.currency ?? '';
final toAmount = settlement == null
? amount
: parseMoneyAmount(settlement.amount);
final toCurrency = settlement?.currency ?? currency;
final payId =
_firstNonEmpty([payment.paymentRef, payment.idempotencyKey]) ?? '-';
final name =
_firstNonEmpty([
payment.lastQuote?.quoteRef,
payment.paymentRef,
payment.idempotencyKey,
]) ??
'-';
final comment =
_firstNonEmpty([
payment.failureReason,
payment.failureCode,
payment.state,
]) ??
'';
return OperationItem(
status: statusFromPayment(payment),
fileName: _extractFileName(payment.metadata),
amount: amount,
currency: currency,
toAmount: toAmount,
toCurrency: toCurrency,
payId: payId,
paymentRef: payment.paymentRef,
cardNumber: null,
name: name,
date: resolvePaymentDate(payment),
comment: comment,
);
}
OperationStatus statusFromPayment(Payment payment) {
switch (payment.orchestrationState) {
case PaymentOrchestrationState.failed:
return OperationStatus.error;
case PaymentOrchestrationState.settled:
return OperationStatus.success;
case PaymentOrchestrationState.created:
case PaymentOrchestrationState.executing:
case PaymentOrchestrationState.needsAttention:
case PaymentOrchestrationState.unspecified:
return OperationStatus.processing;
}
}
DateTime resolvePaymentDate(Payment payment) {
final createdAt = payment.createdAt;
if (createdAt != null) return createdAt.toLocal();
final expiresAt = payment.lastQuote?.fxQuote?.expiresAtUnixMs;
if (expiresAt != null && expiresAt > 0) {
return DateTime.fromMillisecondsSinceEpoch(
expiresAt,
isUtc: true,
).toLocal();
}
return DateTime.fromMillisecondsSinceEpoch(0);
}
String? paymentIdFromOperation(OperationItem operation) {
final candidates = [operation.paymentRef, operation.payId];
for (final candidate in candidates) {
final trimmed = candidate?.trim();
if (trimmed != null && trimmed.isNotEmpty && trimmed != '-') {
return trimmed;
}
}
return null;
}
String? _extractFileName(Map<String, String>? metadata) {
if (metadata == null || metadata.isEmpty) return null;
return _firstNonEmpty([
metadata['upload_filename'],
metadata['upload_file_name'],
metadata['filename'],
]);
}
String? _firstNonEmpty(List<String?> values) {
for (final value in values) {
final trimmed = value?.trim();
if (trimmed != null && trimmed.isNotEmpty) return trimmed;
}
return null;
}