Refactored json storage
This commit is contained in:
@@ -1,14 +1,14 @@
|
||||
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: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';
|
||||
@@ -34,20 +34,25 @@ final colors = [
|
||||
];
|
||||
|
||||
class AccountBloc extends Bloc<AccountEvent, AccountState> {
|
||||
final AccountRepository _accountRepository;
|
||||
final TransactionsRepository _transactionsRepository;
|
||||
final MetadataRepository _metadataRepository;
|
||||
|
||||
AccountBloc({required AccountRepository accountRepository})
|
||||
: _accountRepository = accountRepository,
|
||||
super(const AccountState()) {
|
||||
on<AccountImportJSON>(_onAccountImportJSON);
|
||||
AccountBloc({
|
||||
required MetadataRepository metadataRepository,
|
||||
required TransactionsRepository transactionsRepository,
|
||||
})
|
||||
: _metadataRepository = metadataRepository,
|
||||
_transactionsRepository = transactionsRepository,
|
||||
super(const AccountState()
|
||||
) {
|
||||
on<AccountImportCSV>(_onAccountImportCSV);
|
||||
on<SubAccountLoad>(_onSubAccountLoad);
|
||||
on<AccountLoad>(_onAccountLoad);
|
||||
// on<AccountExportJSON>(_onAccountImportJSON);
|
||||
// on<AccountExportCSV>(_onAccountImportJSON);
|
||||
|
||||
_accountRepository
|
||||
.getSubAccountsStream()
|
||||
.listen((subAccounts) => add(SubAccountLoad(subAccounts)));
|
||||
_metadataRepository
|
||||
.getAccountsStream()
|
||||
.listen((subAccounts) => add(AccountLoad(subAccounts)));
|
||||
}
|
||||
|
||||
double _universalConvertToDouble(dynamic value) {
|
||||
@@ -62,8 +67,7 @@ class AccountBloc extends Bloc<AccountEvent, AccountState> {
|
||||
}
|
||||
}
|
||||
|
||||
_onAccountImportCSV(
|
||||
AccountImportCSV event, Emitter<AccountState> emit) async {
|
||||
_onAccountImportCSV(AccountImportCSV event, Emitter<AccountState> emit) async {
|
||||
int colorIndex = 0;
|
||||
FilePickerResult? result = await FilePicker.platform.pickFiles();
|
||||
|
||||
@@ -74,27 +78,33 @@ class AccountBloc extends Bloc<AccountEvent, AccountState> {
|
||||
final List<List<dynamic>> csvList = const CsvToListConverter(fieldDelimiter: '|', eol: '\n').convert(csvFileContent);
|
||||
|
||||
final Map<String, Category> categoriesMap = {};
|
||||
final Set<String> subAccounts = {};
|
||||
final Map<String, Account> 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 );
|
||||
}
|
||||
// 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' );
|
||||
}
|
||||
|
||||
subAccounts.add(line[3]);
|
||||
String accountLabel = line[3];
|
||||
if (accounts[accountLabel] == null) {
|
||||
accounts[accountLabel] = Account(label: accountLabel);
|
||||
}
|
||||
|
||||
return Transaction(
|
||||
uuid: const Uuid().v8(),
|
||||
@@ -102,34 +112,23 @@ class AccountBloc extends Bloc<AccountEvent, AccountState> {
|
||||
category: categoryLabel,
|
||||
description: line[2],
|
||||
account: line[3],
|
||||
value: _universalConvertToDouble(line[4]));
|
||||
})
|
||||
value: value
|
||||
);
|
||||
})
|
||||
.toList();
|
||||
|
||||
await _accountRepository.deleteAccount();
|
||||
final account = Account(transactions: transactions, categories: categoriesMap.values.toList(), subAccounts: subAccounts);
|
||||
await _accountRepository.saveAccount(account);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
_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);
|
||||
}
|
||||
}
|
||||
|
||||
_onSubAccountLoad(
|
||||
SubAccountLoad event, Emitter<AccountState> emit
|
||||
_onAccountLoad(
|
||||
AccountLoad event, Emitter<AccountState> emit
|
||||
) {
|
||||
emit(
|
||||
state.copyWith(event.subAccounts)
|
||||
|
||||
@@ -23,9 +23,9 @@ final class AccountExportCSV extends AccountEvent {
|
||||
const AccountExportCSV();
|
||||
}
|
||||
|
||||
final class SubAccountLoad extends AccountEvent {
|
||||
final Set<String> subAccounts;
|
||||
const SubAccountLoad(this.subAccounts);
|
||||
final class AccountLoad extends AccountEvent {
|
||||
final List<Account> subAccounts;
|
||||
const AccountLoad(this.subAccounts);
|
||||
|
||||
@override
|
||||
List<Object> get props => [subAccounts];
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
part of 'account_bloc.dart';
|
||||
|
||||
final class AccountState extends Equatable {
|
||||
final Set<String> subAccounts;
|
||||
final List<Account> accounts;
|
||||
|
||||
const AccountState({
|
||||
this.subAccounts = const {},
|
||||
this.accounts = const [],
|
||||
});
|
||||
|
||||
AccountState copyWith(Set<String>? subAccounts) {
|
||||
AccountState copyWith(List<Account>? accounts) {
|
||||
return AccountState(
|
||||
subAccounts: subAccounts ?? this.subAccounts,
|
||||
accounts: accounts ?? this.accounts,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
List<Object?> get props => [subAccounts];
|
||||
List<Object?> get props => [accounts];
|
||||
}
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:tunas/repositories/account/account_repository.dart';
|
||||
import 'package:tunas/repositories/account/models/budget.dart';
|
||||
import 'package:tunas/repositories/metadata/models/budget.dart';
|
||||
import 'package:tunas/repositories/metadata/metadata_repository.dart';
|
||||
|
||||
part 'budget_event.dart';
|
||||
part 'budget_state.dart';
|
||||
|
||||
class BudgetBloc extends Bloc<BudgetEvent, BudgetState> {
|
||||
final AccountRepository _accountRepository;
|
||||
final MetadataRepository _metadataRepository;
|
||||
|
||||
BudgetBloc({required AccountRepository accountRepository}) : _accountRepository = accountRepository, super(const BudgetState()) {
|
||||
BudgetBloc({required MetadataRepository metadataRepository}) : _metadataRepository = metadataRepository, super(const BudgetState()) {
|
||||
on<BudgetsLoad>(_onBudgetsLoad);
|
||||
|
||||
_accountRepository
|
||||
_metadataRepository
|
||||
.getBudgetsStream()
|
||||
.listen((budgets) => add(BudgetsLoad(budgets)));
|
||||
}
|
||||
|
||||
@@ -2,19 +2,19 @@ import 'dart:ui';
|
||||
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:tunas/repositories/account/account_repository.dart';
|
||||
import 'package:tunas/repositories/account/models/category.dart';
|
||||
import 'package:tunas/repositories/metadata/metadata_repository.dart';
|
||||
import 'package:tunas/repositories/metadata/models/category.dart';
|
||||
|
||||
part 'category_event.dart';
|
||||
part 'category_state.dart';
|
||||
|
||||
class CategoryBloc extends Bloc<CategoryEvent, CategoryState> {
|
||||
final AccountRepository _accountRepository;
|
||||
final MetadataRepository _metadataRepository;
|
||||
|
||||
CategoryBloc({required AccountRepository accountRepository}) : _accountRepository = accountRepository, super(const CategoryState()) {
|
||||
CategoryBloc({required MetadataRepository metadataRepository}) : _metadataRepository = metadataRepository, super(const CategoryState()) {
|
||||
on<CategoriesLoad>(_onCategoriesLoad);
|
||||
|
||||
_accountRepository
|
||||
_metadataRepository
|
||||
.getCategoriesStream()
|
||||
.listen((categories) => add(CategoriesLoad(categories)));
|
||||
}
|
||||
|
||||
@@ -4,29 +4,32 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:tunas/domains/charts/models/month_totals.dart';
|
||||
import 'package:tunas/domains/transaction/models/transaction_line.dart';
|
||||
import 'package:tunas/domains/charts/models/chart_item.dart';
|
||||
import 'package:tunas/repositories/account/account_repository.dart';
|
||||
import 'package:tunas/repositories/account/models/category.dart';
|
||||
import 'package:tunas/repositories/account/models/transaction.dart';
|
||||
import 'package:tunas/repositories/metadata/metadata_repository.dart';
|
||||
import 'package:tunas/repositories/metadata/models/category.dart';
|
||||
import 'package:tunas/repositories/transactions/models/transaction.dart';
|
||||
import 'package:tunas/repositories/transactions/models/transactions.dart';
|
||||
import 'package:tunas/repositories/transactions/transactions_repository.dart';
|
||||
|
||||
part 'chart_event.dart';
|
||||
part 'chart_state.dart';
|
||||
|
||||
class ChartBloc extends Bloc<ChartEvent, ChartState> {
|
||||
final AccountRepository _accountRepository;
|
||||
final MetadataRepository _metadataRepository;
|
||||
final TransactionsRepository _transactionsRepository;
|
||||
|
||||
ChartBloc({required AccountRepository accountRepository}) :
|
||||
_accountRepository = accountRepository, super(const ChartState()) {
|
||||
ChartBloc({required MetadataRepository metadataRepository, required TransactionsRepository transactionsRepository}) :
|
||||
_metadataRepository = metadataRepository, _transactionsRepository = transactionsRepository, super(const ChartState()) {
|
||||
|
||||
on<ChartTransactionsLoad>(_onChartTransactionsLoad);
|
||||
on<ChartCategoriesLoad>(_onChartCategoriesLoad);
|
||||
on<ChartNextYear>(_onNextYear);
|
||||
on<ChartPreviousYear>(_onPreviousYear);
|
||||
|
||||
_accountRepository
|
||||
_transactionsRepository
|
||||
.getTransactionsStream()
|
||||
.listen((transactions) => add(ChartTransactionsLoad(transactions)));
|
||||
|
||||
_accountRepository
|
||||
_metadataRepository
|
||||
.getCategoriesStream()
|
||||
.listen((categories) => add(ChartCategoriesLoad(categories)));
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import 'package:tunas/repositories/account/models/transaction.dart';
|
||||
import 'package:tunas/repositories/transactions/models/transaction.dart';
|
||||
|
||||
class TransactionLine {
|
||||
Transaction transaction;
|
||||
|
||||
@@ -8,18 +8,18 @@ import 'package:tunas/domains/transaction/models/transaction_date.dart';
|
||||
import 'package:tunas/domains/transaction/models/transaction_description.dart';
|
||||
import 'package:tunas/domains/transaction/models/transaction_line.dart';
|
||||
import 'package:tunas/domains/transaction/models/transaction_value.dart';
|
||||
import 'package:tunas/repositories/account/account_repository.dart';
|
||||
import 'package:tunas/repositories/account/models/transaction.dart';
|
||||
import 'package:tunas/repositories/transactions/models/transaction.dart';
|
||||
import 'package:tunas/repositories/transactions/transactions_repository.dart';
|
||||
import 'package:uuid/uuid.dart';
|
||||
|
||||
part 'transaction_event.dart';
|
||||
part 'transaction_state.dart';
|
||||
|
||||
class TransactionBloc extends Bloc<TransactionEvent, TransactionState> {
|
||||
final AccountRepository _accountRepository;
|
||||
final TransactionsRepository _transactionsRepository;
|
||||
|
||||
TransactionBloc({required AccountRepository accountRepository})
|
||||
: _accountRepository = accountRepository,
|
||||
TransactionBloc({required TransactionsRepository transactionsRepository})
|
||||
: _transactionsRepository = transactionsRepository,
|
||||
super(const TransactionState()) {
|
||||
on<TransactionsLoad>(_onAccountLoad);
|
||||
on<TransactionDateChange>(_onTransactionDateChange);
|
||||
@@ -33,7 +33,7 @@ class TransactionBloc extends Bloc<TransactionEvent, TransactionState> {
|
||||
on<TransactionSetCurrent>(_onTransactionSetCurrent);
|
||||
on<TransactionDeleteCurrent>(_onTransactionDeleteCurrent);
|
||||
|
||||
_accountRepository
|
||||
_transactionsRepository
|
||||
.getTransactionsStream()
|
||||
.listen((transactions) => add(TransactionsLoad(transactions)));
|
||||
}
|
||||
@@ -161,7 +161,7 @@ class TransactionBloc extends Bloc<TransactionEvent, TransactionState> {
|
||||
));
|
||||
final computeResult = _computeTransactionLine(transactions);
|
||||
|
||||
await _accountRepository.saveTransactions(transactions);
|
||||
await _transactionsRepository.saveTransactions(transactions);
|
||||
|
||||
emit(state.copyWith(
|
||||
currentTransaction: null,
|
||||
@@ -211,7 +211,7 @@ class TransactionBloc extends Bloc<TransactionEvent, TransactionState> {
|
||||
List<Transaction> transactions = state.transactions;
|
||||
transactions.removeWhere((transaction) => transaction.uuid == currentTransaction.uuid);
|
||||
final computeResult = _computeTransactionLine(transactions);
|
||||
await _accountRepository.saveTransactions(transactions);
|
||||
await _transactionsRepository.saveTransactions(transactions);
|
||||
emit(state.copyWith(
|
||||
currentTransaction: null,
|
||||
transactionDate: const TransactionDate.pure(),
|
||||
|
||||
Reference in New Issue
Block a user