reports page
This commit is contained in:
44
frontend/pweb/lib/controllers/payout_volumes.dart
Normal file
44
frontend/pweb/lib/controllers/payout_volumes.dart
Normal file
@@ -0,0 +1,44 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
|
||||
class PayoutVolumesController extends ChangeNotifier {
|
||||
DateTimeRange _range;
|
||||
|
||||
PayoutVolumesController({DateTime? now})
|
||||
: _range = _defaultRange(now ?? DateTime.now());
|
||||
|
||||
DateTimeRange get range => _range;
|
||||
|
||||
void setRange(DateTimeRange range) {
|
||||
final normalized = _normalizeRange(range);
|
||||
if (_isSameRange(_range, normalized)) return;
|
||||
_range = normalized;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
static DateTimeRange _defaultRange(DateTime now) {
|
||||
final local = now.toLocal();
|
||||
final start = DateTime(local.year, local.month, 1);
|
||||
final end = DateTime(
|
||||
local.year,
|
||||
local.month,
|
||||
local.day,
|
||||
);
|
||||
return DateTimeRange(start: start, end: end);
|
||||
}
|
||||
|
||||
static DateTimeRange _normalizeRange(DateTimeRange range) {
|
||||
final start = DateTime(range.start.year, range.start.month, range.start.day);
|
||||
final end = DateTime(
|
||||
range.end.year,
|
||||
range.end.month,
|
||||
range.end.day,
|
||||
);
|
||||
return DateTimeRange(start: start, end: end);
|
||||
}
|
||||
|
||||
static bool _isSameRange(DateTimeRange a, DateTimeRange b) {
|
||||
return a.start.isAtSameMomentAs(b.start) &&
|
||||
a.end.isAtSameMomentAs(b.end);
|
||||
}
|
||||
}
|
||||
44
frontend/pweb/lib/controllers/recent_payments.dart
Normal file
44
frontend/pweb/lib/controllers/recent_payments.dart
Normal file
@@ -0,0 +1,44 @@
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
||||
import 'package:pshared/models/payment/operation.dart';
|
||||
import 'package:pshared/provider/payment/payments.dart';
|
||||
|
||||
import 'package:pweb/utils/report/operations.dart';
|
||||
import 'package:pweb/utils/report/payment_mapper.dart';
|
||||
|
||||
|
||||
class RecentPaymentsController extends ChangeNotifier {
|
||||
PaymentsProvider? _payments;
|
||||
List<OperationItem> _recent = const [];
|
||||
|
||||
List<OperationItem> get recentOperations => _recent;
|
||||
bool get isLoading => _payments?.isLoading ?? false;
|
||||
Exception? get error => _payments?.error;
|
||||
|
||||
void update(PaymentsProvider provider) {
|
||||
if (!identical(_payments, provider)) {
|
||||
_payments?.removeListener(_onPaymentsChanged);
|
||||
_payments = provider;
|
||||
_payments?.addListener(_onPaymentsChanged);
|
||||
}
|
||||
_rebuild();
|
||||
}
|
||||
|
||||
void _onPaymentsChanged() {
|
||||
_rebuild();
|
||||
}
|
||||
|
||||
void _rebuild() {
|
||||
final operations = (_payments?.payments ?? const [])
|
||||
.map(mapPaymentToOperation)
|
||||
.toList();
|
||||
_recent = sortOperations(operations).take(5).toList();
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_payments?.removeListener(_onPaymentsChanged);
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
115
frontend/pweb/lib/controllers/report_operations.dart
Normal file
115
frontend/pweb/lib/controllers/report_operations.dart
Normal file
@@ -0,0 +1,115 @@
|
||||
import 'dart:collection';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:pshared/models/payment/operation.dart';
|
||||
import 'package:pshared/models/payment/status.dart';
|
||||
import 'package:pshared/provider/payment/payments.dart';
|
||||
|
||||
import 'package:pweb/utils/report/operations.dart';
|
||||
import 'package:pweb/utils/report/payment_mapper.dart';
|
||||
|
||||
|
||||
class ReportOperationsController extends ChangeNotifier {
|
||||
PaymentsProvider? _payments;
|
||||
DateTimeRange? _selectedRange;
|
||||
final Set<OperationStatus> _selectedStatuses = {};
|
||||
List<OperationItem> _operations = const [];
|
||||
List<OperationItem> _filtered = const [];
|
||||
|
||||
List<OperationItem> get operations => _operations;
|
||||
List<OperationItem> get filteredOperations => _filtered;
|
||||
DateTimeRange? get selectedRange => _selectedRange;
|
||||
Set<OperationStatus> get selectedStatuses =>
|
||||
UnmodifiableSetView(_selectedStatuses);
|
||||
|
||||
bool get isLoading => _payments?.isLoading ?? false;
|
||||
Exception? get error => _payments?.error;
|
||||
|
||||
void update(PaymentsProvider provider) {
|
||||
if (!identical(_payments, provider)) {
|
||||
_payments?.removeListener(_onPaymentsChanged);
|
||||
_payments = provider;
|
||||
_payments?.addListener(_onPaymentsChanged);
|
||||
}
|
||||
_rebuildOperations();
|
||||
}
|
||||
|
||||
void setRange(DateTimeRange? range) {
|
||||
if (_isSameRange(_selectedRange, range)) return;
|
||||
_selectedRange = range;
|
||||
_rebuildFiltered();
|
||||
}
|
||||
|
||||
void toggleStatus(OperationStatus status) {
|
||||
if (_selectedStatuses.contains(status)) {
|
||||
_selectedStatuses.remove(status);
|
||||
} else {
|
||||
_selectedStatuses.add(status);
|
||||
}
|
||||
_rebuildFiltered();
|
||||
}
|
||||
|
||||
void clearFilters() {
|
||||
if (_selectedRange == null && _selectedStatuses.isEmpty) return;
|
||||
_selectedRange = null;
|
||||
_selectedStatuses.clear();
|
||||
_rebuildFiltered();
|
||||
}
|
||||
|
||||
Future<void> refresh() async {
|
||||
await _payments?.refresh();
|
||||
}
|
||||
|
||||
void _onPaymentsChanged() {
|
||||
_rebuildOperations();
|
||||
}
|
||||
|
||||
void _rebuildOperations() {
|
||||
final items = _payments?.payments ?? const [];
|
||||
_operations = items.map(mapPaymentToOperation).toList();
|
||||
_rebuildFiltered(notify: true);
|
||||
}
|
||||
|
||||
void _rebuildFiltered({bool notify = true}) {
|
||||
_filtered = _applyFilters(_operations);
|
||||
if (notify) {
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
||||
List<OperationItem> _applyFilters(List<OperationItem> operations) {
|
||||
if (_selectedRange == null && _selectedStatuses.isEmpty) {
|
||||
return sortOperations(operations);
|
||||
}
|
||||
|
||||
final filtered = operations.where((op) {
|
||||
final statusMatch =
|
||||
_selectedStatuses.isEmpty || _selectedStatuses.contains(op.status);
|
||||
final dateMatch = _selectedRange == null ||
|
||||
isUnknownDate(op.date) ||
|
||||
(op.date.isAfter(
|
||||
_selectedRange!.start.subtract(const Duration(seconds: 1)),
|
||||
) &&
|
||||
op.date.isBefore(
|
||||
_selectedRange!.end.add(const Duration(seconds: 1)),
|
||||
));
|
||||
return statusMatch && dateMatch;
|
||||
}).toList();
|
||||
|
||||
return sortOperations(filtered);
|
||||
}
|
||||
|
||||
bool _isSameRange(DateTimeRange? left, DateTimeRange? right) {
|
||||
if (left == null && right == null) return true;
|
||||
if (left == null || right == null) return false;
|
||||
return left.start.isAtSameMomentAs(right.start) &&
|
||||
left.end.isAtSameMomentAs(right.end);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_payments?.removeListener(_onPaymentsChanged);
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
import 'package:pshared/models/payment/payment.dart';
|
||||
|
||||
|
||||
class UploadHistoryTableController {
|
||||
const UploadHistoryTableController();
|
||||
|
||||
String amountText(Payment payment) {
|
||||
final receivedAmount = payment.lastQuote?.expectedSettlementAmount;
|
||||
if (receivedAmount != null) {
|
||||
return '${receivedAmount.amount} ${receivedAmount.currency}';
|
||||
}
|
||||
|
||||
final fallbackAmount = payment.lastQuote?.debitAmount;
|
||||
if (fallbackAmount != null) {
|
||||
return '${fallbackAmount.amount} ${fallbackAmount.currency}';
|
||||
}
|
||||
|
||||
return '-';
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user