import 'dart:convert'; 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/account/account_repository.dart'; import 'package:tunas/repositories/account/models/account.dart'; import 'package:tunas/repositories/account/models/category.dart'; import 'package:tunas/repositories/account/models/transaction.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 AccountRepository _accountRepository; AccountBloc({required AccountRepository accountRepository}) : _accountRepository = accountRepository, super(const AccountState()) { on(_onAccountImportJSON); on(_onAccountImportCSV); on(_onSubAccountLoad); // on(_onAccountImportJSON); // on(_onAccountImportJSON); _accountRepository .getSubAccountsStream() .listen((subAccounts) => add(SubAccountLoad(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 Set subAccounts = {}; final transactions = csvList .map((line) { 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 ); } } subAccounts.add(line[3]); return Transaction( uuid: const Uuid().v8(), date: DateTime.parse(line[0]), category: categoryLabel, description: line[2], account: line[3], value: _universalConvertToDouble(line[4])); }) .toList(); await _accountRepository.deleteAccount(); final account = Account(transactions: transactions, categories: categoriesMap.values.toList(), subAccounts: subAccounts); await _accountRepository.saveAccount(account); } } _onAccountImportJSON( AccountImportJSON event, Emitter emit) async { FilePickerResult? result = await FilePicker.platform.pickFiles(); final jsonPath = result?.files.first.path; if (jsonPath != null) { final File json = File(jsonPath); final String jsonString = await json.readAsString(); final List jsonList = jsonDecode(jsonString); final List transactions = jsonList.map((transaction) => Transaction.fromJson(transaction)).toList(); await _accountRepository.deleteAccount(); await _accountRepository.saveTransactions(transactions); } } _onSubAccountLoad( SubAccountLoad event, Emitter emit ) { emit( state.copyWith(event.subAccounts) ); } }