import 'package:seshat/data/services/api_client.dart'; import 'package:seshat/domain/models/accounting.dart'; import 'package:seshat/domain/models/bal.dart'; import 'package:seshat/domain/models/bal_stats.dart'; import 'package:seshat/domain/models/enums.dart'; import 'package:seshat/utils/result.dart'; class BalRepository { BalRepository({required ApiClient apiClient}) : _apiClient = apiClient; final ApiClient _apiClient; List? _bals; Accounting? accounting; Future>> getBals() async { if (_bals != null) { return Result.ok(_bals!); } final result = await _apiClient.getBals(); switch (result) { case Ok(): _bals = result.value; return Result.ok(result.value); case Error(): return result; } } Future>> _getBalsNoCache() async { final result = await _apiClient.getBals(); switch (result) { case Ok(): _bals = result.value; return Result.ok(result.value); case Error(): return result; } } Future> balById(int id) async { if (_bals == null) { await getBals(); } Bal? bal = _bals!.where((bal) => bal.id == id).firstOrNull; if (bal != null) { return Result.ok(bal); } final result = await _apiClient.getBalById(id); switch (result) { case Ok(): return Result.ok(result.value); case Error(): return result; } } bool isABalOngoing() { return _bals?.where((bal) => bal.state == BalState.ongoing).isNotEmpty ?? false; } Future ongoingBal() async { if (_bals == null) { await _getBalsNoCache(); } return _bals!.where((bal) => bal.state == BalState.ongoing).firstOrNull; } Future> stopBal(int id) async { final result = await _apiClient.stopBal(id); _getBalsNoCache(); return result; } Future> startBal(int id) async { if (isABalOngoing()) { return Result.error( Exception("Cannot have multiple BAL ongoing at the same time !"), ); } final result = await _apiClient.startBal(id); _getBalsNoCache(); return result; } Future> editBal( int id, String name, DateTime start, DateTime end, ) async { final result = await _apiClient.editBal(id, name, start, end); await _getBalsNoCache(); return result; } Future> addBal(String name, DateTime start, DateTime end) async { final result = await _apiClient.addBal(name, start, end); await _getBalsNoCache(); return result; } Future> getBalStats(int id) async { return _apiClient.getBalStats(id); } Future> getAccountingNoCache(int balId) async { final result = await _apiClient.getAccounting(balId); switch (result) { case Ok(): accounting = result.value; break; default: } return result; } Future> getAccounting(int balId) async { if (accounting != null) { return Result.ok(accounting!); } final result = await _apiClient.getAccounting(balId); switch (result) { case Ok(): accounting = result.value; break; default: } return result; } Future> returnToId( int balId, int ownerId, ReturnType type, ) async { final result = await _apiClient.returnToId(balId, ownerId, type.name); switch (result) { case Ok(): switch (type) { case ReturnType.books: final owner = accounting?.owners .where((el) => el.ownerId == ownerId) .firstOrNull; if (owner?.owedMoney == 0) { accounting?.owners.removeWhere((el) => el.ownerId == ownerId); } owner?.owed = []; owner?.owedInstances = []; break; case ReturnType.money: final owner = accounting?.owners .where((el) => el.ownerId == ownerId) .firstOrNull; if (owner?.owed == null || owner!.owed.isEmpty) { accounting?.owners.removeWhere((el) => el.ownerId == ownerId); } owner?.owedMoney = 0; break; case ReturnType.all: accounting?.owners.removeWhere((el) => el.ownerId == ownerId); break; } break; default: } return result; } }