123 lines
3.8 KiB
Dart
123 lines
3.8 KiB
Dart
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<AccountEvent, AccountState> {
|
|
final AccountRepository _accountRepository;
|
|
|
|
AccountBloc({required AccountRepository accountRepository})
|
|
: _accountRepository = accountRepository,
|
|
super(const AccountState()) {
|
|
on<AccountImportJSON>(_onAccountImportJSON);
|
|
on<AccountImportCSV>(_onAccountImportCSV);
|
|
// on<AccountExportJSON>(_onAccountImportJSON);
|
|
// on<AccountExportCSV>(_onAccountImportJSON);
|
|
}
|
|
|
|
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<AccountState> 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<List<dynamic>> csvList = const CsvToListConverter(fieldDelimiter: '|', eol: '\n').convert(csvFileContent);
|
|
|
|
final Map<String, Category> categoriesMap = {};
|
|
|
|
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 );
|
|
}
|
|
}
|
|
|
|
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());
|
|
await _accountRepository.saveAccount(account);
|
|
}
|
|
}
|
|
|
|
_onAccountImportJSON(
|
|
AccountImportJSON event, Emitter<AccountState> 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<dynamic> jsonList = jsonDecode(jsonString);
|
|
final List<Transaction> transactions = jsonList.map((transaction) => Transaction.fromJson(transaction)).toList();
|
|
|
|
await _accountRepository.deleteAccount();
|
|
await _accountRepository.saveTransactions(transactions);
|
|
}
|
|
}
|
|
}
|