149 lines
4.1 KiB
Dart
149 lines
4.1 KiB
Dart
import 'package:dio/dio.dart';
|
|
import 'package:flutter/foundation.dart';
|
|
import 'package:qpay/http/http.dart';
|
|
import 'package:qpay/models/api_response.dart';
|
|
import 'package:qpay/screens/accounts/models/account_model.dart';
|
|
import 'package:qpay/screens/accounts/models/statement_model.dart';
|
|
|
|
class AccountProvider extends ChangeNotifier {
|
|
final Http http = Http();
|
|
|
|
AccountProvider();
|
|
|
|
AccountModel? _account;
|
|
StatementModel? _statement;
|
|
bool _isLoadingAccount = false;
|
|
bool _isLoadingStatement = false;
|
|
String? _accountError;
|
|
String? _statementError;
|
|
|
|
/// Cached balances keyed by currency code (e.g. 'USD', 'ZWG').
|
|
final Map<String, AccountModel?> _balances = {};
|
|
|
|
AccountModel? get account => _account;
|
|
StatementModel? get statement => _statement;
|
|
bool get isLoadingAccount => _isLoadingAccount;
|
|
bool get isLoadingStatement => _isLoadingStatement;
|
|
String? get accountError => _accountError;
|
|
String? get statementError => _statementError;
|
|
bool _isDisposed = false;
|
|
|
|
/// Returns a cached account balance for [currency], or null if not yet
|
|
/// fetched.
|
|
AccountModel? balanceForCurrency(String currency) {
|
|
return _balances[currency.toUpperCase()];
|
|
}
|
|
|
|
/// Returns the account with name 'City Wallet' for [currency], or null.
|
|
AccountModel? cityWalletBalance() {
|
|
return _balances.values.firstWhere(
|
|
(a) => a?.name == 'City Wallet',
|
|
orElse: () => null,
|
|
);
|
|
}
|
|
|
|
@override
|
|
void notifyListeners() {
|
|
if (!_isDisposed) {
|
|
super.notifyListeners();
|
|
}
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
_isDisposed = true;
|
|
super.dispose();
|
|
}
|
|
|
|
Future<ApiResponse<AccountModel>> fetchAccount(
|
|
String? workspaceId,
|
|
String currency,
|
|
) async {
|
|
_isLoadingAccount = true;
|
|
_accountError = null;
|
|
notifyListeners();
|
|
|
|
try {
|
|
Map<String, dynamic> response = await http.get(
|
|
'/accounts/$workspaceId/balance/$currency',
|
|
);
|
|
|
|
_account = AccountModel.fromJson(response);
|
|
_balances[currency.toUpperCase()] = _account;
|
|
_isLoadingAccount = false;
|
|
notifyListeners();
|
|
return ApiResponse.success(_account!);
|
|
} on DioException catch (e, s) {
|
|
logger.e(s);
|
|
_isLoadingAccount = false;
|
|
_accountError = 'Failed to fetch account. Please try again.';
|
|
notifyListeners();
|
|
return ApiResponse.failure(_accountError!);
|
|
} catch (e, s) {
|
|
logger.e(e);
|
|
logger.e(s);
|
|
_isLoadingAccount = false;
|
|
_accountError = 'An unexpected error occurred. Please try again.';
|
|
notifyListeners();
|
|
return ApiResponse.failure(_accountError!);
|
|
}
|
|
}
|
|
|
|
/// Pre-load multiple currency balances at once. Results are stored in the
|
|
/// [_balances] map so any widget can access them later.
|
|
Future<void> preloadBalances(
|
|
String? workspaceId,
|
|
List<String> currencies,
|
|
) async {
|
|
for (final currency in currencies) {
|
|
await fetchAccount(workspaceId, currency);
|
|
}
|
|
}
|
|
|
|
Future<ApiResponse<StatementModel>> fetchStatement({
|
|
required String workspaceId,
|
|
required String currency,
|
|
required String startDate,
|
|
required String endDate,
|
|
}) async {
|
|
_isLoadingStatement = true;
|
|
_statementError = null;
|
|
notifyListeners();
|
|
|
|
try {
|
|
Map<String, dynamic> response = await http.get(
|
|
'/accounts/$workspaceId/statement/$currency'
|
|
'?startDate=$startDate&endDate=$endDate',
|
|
);
|
|
|
|
_statement = StatementModel.fromJson(response);
|
|
_isLoadingStatement = false;
|
|
notifyListeners();
|
|
return ApiResponse.success(_statement!);
|
|
} on DioException catch (e, s) {
|
|
logger.e(s);
|
|
_isLoadingStatement = false;
|
|
_statementError = 'Failed to fetch statement. Please try again.';
|
|
notifyListeners();
|
|
return ApiResponse.failure(_statementError!);
|
|
} catch (e, s) {
|
|
logger.e(s);
|
|
_isLoadingStatement = false;
|
|
_statementError = 'An unexpected error occurred. Please try again.';
|
|
notifyListeners();
|
|
return ApiResponse.failure(_statementError!);
|
|
}
|
|
}
|
|
|
|
void clearAccount() {
|
|
_account = null;
|
|
_accountError = null;
|
|
notifyListeners();
|
|
}
|
|
|
|
void clearStatement() {
|
|
_statement = null;
|
|
_statementError = null;
|
|
notifyListeners();
|
|
}
|
|
} |