import 'package:flutter/widgets.dart'; import 'package:seshat/data/repositories/bal_repository.dart'; import 'package:seshat/data/repositories/owner_repository.dart'; import 'package:seshat/domain/models/bal.dart'; import 'package:seshat/domain/models/bal_stats.dart'; import 'package:seshat/domain/models/book.dart'; import 'package:seshat/domain/models/book_instance.dart'; import 'package:seshat/domain/models/enums.dart'; import 'package:seshat/domain/models/return_owner.dart'; import 'package:seshat/domain/models/search_result.dart'; import 'package:seshat/utils/command.dart'; import 'package:seshat/utils/result.dart'; class BalViewModel extends ChangeNotifier { BalViewModel({ required BalRepository balRepository, required this.id, required OwnerRepository ownerRepository, }) : _balRepository = balRepository, _ownerRepository = ownerRepository { load = Command0(_load)..execute(); } final BalRepository _balRepository; final OwnerRepository _ownerRepository; /* * ===================== * =====< General >===== * ===================== */ Bal? _bal; int id; Bal? get bal => _bal; bool isABalOngoing = false; Future> stopBal(int id) async { isLoaded = false; notifyListeners(); final result = await _balRepository.stopBal(id); switch (result) { case Ok(): _bal = result.value; break; default: } final result2 = await _loadEnded(); switch (result2) { case Ok(): isLoaded = true; break; case Error(): break; } notifyListeners(); return result; } Future> startBal(int id) async { if (isABalOngoing) { return Result.error(Exception("Cannot have multiple BALs ongoing !")); } final result = await _balRepository.startBal(id); switch (result) { case Ok(): _bal = result.value; notifyListeners(); break; default: } return result; } Future> editBal( int id, String name, DateTime start, DateTime end, ) async { final result = await _balRepository.editBal(id, name, start, end); switch (result) { case Ok(): debugPrint("\n\n\n\nDID EDIT\n\n\n\n"); _bal = result.value; notifyListeners(); break; case Error(): debugPrint("\n\n\n\nERROR: ${result.error}"); break; } return result; } /* * ============================ * =====< State Specific >===== * ============================ */ // Specific to ended state List? owedToOwners; double? totalOwed; BalStats? stats; Future applyAccountingOwners( List owners, Map books, ) async { owedToOwners = owners; for (ReturnOwner owedToOwner in owedToOwners!) { var res = await _ownerRepository.getOwnerById(owedToOwner.ownerId); switch (res) { case Ok(): owedToOwner.owner = res.value; break; default: } owedToOwner.owed = []; for (BookInstance instance in owedToOwner.owedInstances) { final bookId = instance.bookId; owedToOwner.owed.add(SearchResult(instance, books[bookId.toString()]!)); } } } Future> returnById(ReturnType type, int ownerId) async { final result = await _balRepository.returnToId(id, ownerId, type); final result2 = await _balRepository.getAccounting(id); switch (result2) { case Ok(): applyAccountingOwners(result2.value.owners, result2.value.books); break; case Error(): debugPrint(result2.error.toString()); } notifyListeners(); return result; } /* * ================================= * =====< COMMAND AND LOADING >===== * ================================= */ late final Command0 load; bool isLoaded = false; Future> _load() async { isABalOngoing = _balRepository.isABalOngoing(); final result1 = await _loadBal(); switch (result1) { case Ok(): isLoaded = (_bal == null || _bal?.state != BalState.ended) ? true : false; break; default: break; } if (_bal?.state == BalState.ended) { final result2 = await _loadEnded(); switch (result2) { case Ok(): isLoaded = true; break; case Error(): break; } } notifyListeners(); return result1; } Future> _loadBal() async { final result = await _balRepository.balById(id); switch (result) { case Ok(): _bal = result.value; break; case Error(): break; } return result; } Future> _loadEnded() async { final result = await _balRepository.getAccountingNoCache(id); switch (result) { case Ok(): applyAccountingOwners(result.value.owners, result.value.books); break; default: } final result2 = await _balRepository.getBalStats(id); switch (result2) { case Ok(): stats = result2.value; break; default: } return result; } }