import 'dart:io'; import 'package:csv/csv.dart'; import 'package:equatable/equatable.dart'; import 'package:file_picker/file_picker.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:tunas/repositories/metadata/models/category.dart'; import 'package:tunas/repositories/metadata/metadata_repository.dart'; import 'package:tunas/repositories/metadata/models/account.dart'; import 'package:tunas/repositories/transactions/models/transaction.dart'; import 'package:tunas/repositories/transactions/transactions_repository.dart'; import 'package:uuid/uuid.dart'; part 'account_event.dart'; part 'account_state.dart'; final colors = [ 'FF74feff', 'FF64c0ff', 'FF5873fe', 'FF4b4cff', 'FFc0fcfd', 'FFa7caff', 'FF8d7efd', 'FF7f65fe', 'FFe7ffff', 'FFd7dafd', 'FFd8a6ff', 'FFc065fe', 'FFffffff', 'FFffe6fe', 'FFffbdff', 'FFff80fe', ]; class AccountBloc extends Bloc { final TransactionsRepository _transactionsRepository; final MetadataRepository _metadataRepository; AccountBloc({ required MetadataRepository metadataRepository, required TransactionsRepository transactionsRepository, }) : _metadataRepository = metadataRepository, _transactionsRepository = transactionsRepository, super(const AccountState() ) { on(_onAccountImportCSV); on(_onAccountLoad); // on(_onAccountImportJSON); // on(_onAccountImportJSON); _metadataRepository .getAccountsStream() .listen((subAccounts) => add(AccountLoad(subAccounts))); } double _universalConvertToDouble(dynamic value) { if (value is String) { return double.parse(value); } else if (value is int) { return value.toDouble(); } else if (value is double) { return value; } else { throw Error(); } } _onAccountImportCSV(AccountImportCSV event, Emitter emit) async { int colorIndex = 0; FilePickerResult? result = await FilePicker.platform.pickFiles(); final csvPath = result?.files.first.path; if (csvPath != null) { final File csv = File(csvPath); final String csvFileContent = await csv.readAsString(); final List> csvList = const CsvToListConverter(fieldDelimiter: '|', eol: '\n').convert(csvFileContent); final Map categoriesMap = {}; final Map accounts = {}; final transactions = csvList .map((line) { double value = _universalConvertToDouble(line[4]); String? categoryLabel = line[1]; if (categoryLabel == null || categoryLabel == '') { categoryLabel = 'N/A'; } if (categoriesMap[categoryLabel] == null) { // if (categoryLabel == 'N/A') { // categoriesMap[categoryLabel] = Category(label: 'N/A', color: 'FFFF0000' ); // } else { // String color = colorIndex >= colors.length ? 'FF0000FF' : colors[colorIndex]; // colorIndex++; // categoriesMap[categoryLabel] = Category(label: categoryLabel, color: color ); // } categoriesMap[categoryLabel] = Category(label: categoryLabel, color: value > 0 ? 'FF21E297' : 'FFFFB4AB' ); } String accountLabel = line[3]; if (accounts[accountLabel] == null) { accounts[accountLabel] = Account(label: accountLabel); } return Transaction( uuid: const Uuid().v8(), date: DateTime.parse(line[0]), category: categoryLabel, description: line[2], account: line[3], value: value ); }) .toList(); await _metadataRepository.deleteMetadata(); await _transactionsRepository.deleteTransactions(); await _metadataRepository.saveAccounts(accounts.values.toList()); await _metadataRepository.saveBudgets([]); await _metadataRepository.saveCategories(categoriesMap.values.toList()); await _transactionsRepository.saveTransactions(transactions); } } _onAccountLoad( AccountLoad event, Emitter emit ) { emit( state.copyWith(event.subAccounts) ); } }