Files
fin-tracker/app/lib/features/accounts/actions.dart
T
Dmitry 62d36aa3e8 feat(app): новый визуальный язык, верхняя навигация, портфели, создание счетов и ручные события
Тема и общие виджеты (AssetIcon, ServiceMark, HelpTip, глоссарий), верхняя панель TopNav и вкладки Аналитики вместо NavSidebar, иконки PWA. Экраны: портфели, создание брокерского счёта, ручное событие, правка инструмента, Обзор карточками по скоупам и таблица активов, пересчёт метрик с опросом /metrics/status. design-system.md обновлён.
2026-09-19 22:14:21 +03:00

64 lines
2.2 KiB
Dart

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<String?> patch(Iterable<int> ids, AccountPatch patch);
}
final accountActionsProvider = Provider<AccountActions>(
(ref) => _ApiAccountActions(ref),
);
class _ApiAccountActions implements AccountActions {
_ApiAccountActions(this._ref);
final Ref _ref;
@override
Future<String?> patch(Iterable<int> 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';
}
}