import 'dart:async'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:mobile_scanner/mobile_scanner.dart'; import 'package:seshat/data/repositories/bal_repository.dart'; import 'package:seshat/data/repositories/book_instance_repository.dart'; import 'package:seshat/data/repositories/book_repository.dart'; import 'package:seshat/data/repositories/owner_repository.dart'; import 'package:seshat/domain/models/bal.dart'; import 'package:seshat/domain/models/book.dart'; import 'package:seshat/domain/models/book_instance.dart'; import 'package:seshat/domain/models/owner.dart'; import 'package:seshat/utils/command.dart'; import 'package:seshat/utils/result.dart'; class AddViewModel extends ChangeNotifier { AddViewModel({ required OwnerRepository ownerRepository, required BookRepository bookRepository, required BookInstanceRepository bookInstanceRepository, required BalRepository balRepository, }) : _ownerRepository = ownerRepository, _bookRepository = bookRepository, _bookInstanceRepository = bookInstanceRepository, _balRepository = balRepository { load = Command0(_load)..execute(); } final OwnerRepository _ownerRepository; final BookRepository _bookRepository; final BookInstanceRepository _bookInstanceRepository; final BalRepository _balRepository; /* * ==================== * =====[ OWNERS ]===== * ==================== */ Owner? _currentOwner; Owner? get currentOwner => _currentOwner; set currentOwner(Owner? owner) { _currentOwner = owner; notifyListeners(); } Owner? _sectionOwner; Owner? get sectionOwner => _sectionOwner; List _owners = []; List? get owners => _owners; Future> addOwner( String firstName, String lastName, String contact, ) async { final result = await _ownerRepository.addOwner( firstName, lastName, contact, ); switch (result) { case Ok(): final secondResult = await _ownerRepository.getOwners(); switch (secondResult) { case Ok(): _owners = secondResult.value; _currentOwner = result.value; notifyListeners(); return Result.ok(result.value); case Error(): return Result.error(secondResult.error); } case Error(): return Result.error(result.error); } } /* * ================= * =====[ BAL ]===== * ================= */ Bal? _currentBal; Bal? get currentBal => _currentBal; /* * =================== * =====[ PRICE ]===== * =================== */ bool _askPrice = true; bool get askPrice => _askPrice; set askPrice(bool newValue) { _askPrice = newValue; notifyListeners(); } /* * ================================= * =====[ BOOKS AND INSTANCES ]===== * ================================= */ /// Sends an api request with a [bacorde], then gets the [Book] that was /// either created or retrieved. Sens the [Book] back wrapped in a [Result]. Future> scanBook(BarcodeCapture barcode) async { var ean = barcode.barcodes.first.rawValue!; var result = await _bookRepository.getBookByEAN(ean); return result; } Future> sendBook( Book book, Owner owner, Bal bal, double price, ) async { return await _bookInstanceRepository.sendBook(book, owner, bal, price); } /* * ================================= * =====[ COMMAND AND LOADING ]===== * ================================= */ late final Command0 load; bool isLoaded = false; Future> _load() async { final result1 = await _loadOwners(); switch (result1) { case Error(): return result1; default: break; } final result2 = await _loadBal(); switch (result2) { case Ok(): isLoaded = true; break; default: break; } notifyListeners(); return result2; } Future> _loadBal() async { final result = await _balRepository.getBals(); switch (result) { case Ok(): _currentBal = result.value .where((bal) => bal.state == BalState.ongoing) .firstOrNull; break; case Error(): break; } return result; } Future> _loadOwners() async { final result = await _ownerRepository.getOwners(); switch (result) { case Ok(): _owners = result.value ..sort( (a, b) => "${a.firstName} ${a.lastName}".compareTo( "${b.firstName} ${b.lastName}", ), ); case Error(): return result; } final result2 = await _ownerRepository.sectionOwner; switch (result2) { case Ok(): _sectionOwner = result2.value; break; default: } return result2; } }