This commit is contained in:
Arseni
2026-03-04 17:43:18 +03:00
parent 80b25a8608
commit aff804ec58
46 changed files with 1090 additions and 345 deletions

View File

@@ -0,0 +1,23 @@
import 'package:pshared/models/payment/operation.dart';
List<OperationItem> sortOperations(List<OperationItem> operations) {
final sorted = List<OperationItem>.from(operations);
sorted.sort((a, b) {
final aTime = a.date.millisecondsSinceEpoch;
final bTime = b.date.millisecondsSinceEpoch;
final aUnknown = isUnknownDate(a.date);
final bUnknown = isUnknownDate(b.date);
if (aUnknown != bUnknown) {
return aUnknown ? 1 : -1;
}
if (aTime != bTime) {
return bTime.compareTo(aTime);
}
return a.payId.compareTo(b.payId);
});
return sorted;
}
bool isUnknownDate(DateTime date) => date.millisecondsSinceEpoch == 0;

View File

@@ -0,0 +1,12 @@
import 'package:flutter/material.dart';
import 'package:pweb/utils/payment/status_view.dart';
import 'package:pweb/generated/i18n/app_localizations.dart';
StatusView resolveStepStateView(BuildContext context, String? rawState) {
final loc = AppLocalizations.of(context)!;
final scheme = Theme.of(context).colorScheme;
return operationStatusViewFromToken(loc, scheme, rawState);
}

View File

@@ -0,0 +1,15 @@
import 'package:flutter/widgets.dart';
import 'package:pweb/utils/report/format.dart';
String formatCompletedAt(BuildContext context, DateTime? completedAt) {
final value = meaningfulDate(completedAt);
return formatDateLabel(context, value);
}
DateTime? meaningfulDate(DateTime? value) {
if (value == null) return null;
if (value.year <= 1) return null;
return value;
}

View File

@@ -0,0 +1,59 @@
import 'package:pweb/utils/payment/operation_code.dart';
import 'package:pweb/generated/i18n/app_localizations.dart';
String resolveOperationTitle(AppLocalizations loc, String? code) {
final pair = parseOperationCodePair(code);
if (pair == null) return '-';
final operation = _localizedOperation(loc, pair.operation);
final action = _localizedAction(loc, pair.action);
return loc.paymentOperationPair(operation, action);
}
String _localizedOperation(AppLocalizations loc, String operation) {
switch (operation) {
case 'card_payout':
return loc.paymentOperationCardPayout;
case 'crypto':
return loc.paymentOperationCrypto;
case 'settlement':
return loc.paymentOperationSettlement;
case 'ledger':
return loc.paymentOperationLedger;
default:
return _humanizeToken(operation);
}
}
String _localizedAction(AppLocalizations loc, String action) {
switch (action) {
case 'send':
return loc.paymentOperationActionSend;
case 'observe':
return loc.paymentOperationActionObserve;
case 'fx_convert':
return loc.paymentOperationActionFxConvert;
case 'credit':
return loc.paymentOperationActionCredit;
case 'block':
return loc.paymentOperationActionBlock;
case 'debit':
return loc.paymentOperationActionDebit;
case 'release':
return loc.paymentOperationActionRelease;
case 'move':
return loc.paymentOperationActionMove;
default:
return _humanizeToken(action);
}
}
String _humanizeToken(String token) {
final parts = token.split('_').where((part) => part.isNotEmpty).toList();
if (parts.isEmpty) return token;
return parts
.map((part) => '${part[0].toUpperCase()}${part.substring(1)}')
.join(' ');
}