import 'package:dio/dio.dart'; import 'package:fintracker_api/fintracker_api.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../../core/api/api_client.dart'; import '../../core/auth/auth_controller.dart'; import '../portfolio/providers.dart' show scopesProvider; import '../portfolios/providers.dart' show portfolioListProvider; import '../rebalance/providers.dart' show portfoliosProvider; import 'providers.dart'; /// Changes to accounts: one place for a single switch and for a bulk edit. abstract class AccountActions { /// Applies [patch] to every account in [ids]. Returns null on success, or a message naming /// how many failed and why. One failure does not stop the rest: a bulk «отключить» that /// stalls on the 20th of 30 accounts would leave the list half changed and silent. Future patch(Iterable ids, AccountPatch patch); } final accountActionsProvider = Provider( (ref) => _ApiAccountActions(ref), ); class _ApiAccountActions implements AccountActions { _ApiAccountActions(this._ref); final Ref _ref; @override Future patch(Iterable ids, AccountPatch patch) async { final list = ids.toList(); final api = _ref.read(apiProvider).getAccountsApi(); var failed = 0; String? reason; for (final id in list) { try { await api.accountsPatch(accountId: id, accountPatch: patch); } on DioException catch (e) { failed++; reason ??= problemMessage(e); } } _ref.invalidate(accountsProvider); if (patch.disabled != null || patch.includeInNetWorth != null || patch.role != null) { // net worth, scopes and portfolios all follow these switches: refetch what is derived // from them and rebuild the metrics once, however many accounts changed _ref ..invalidate(scopesProvider) ..invalidate(portfolioListProvider) ..invalidate(portfoliosProvider); try { await _ref.read(apiProvider).getMetricsApi().metricsRefresh(); } on DioException { // the next scheduled or manual refresh picks the change up } } return failed == 0 ? null : 'Не удалось изменить $failed из ${list.length}: $reason'; } }