Skip to content
This repository has been archived by the owner on Oct 4, 2024. It is now read-only.

Sirsimon04/feat/190 implement remote storage #292

Merged
merged 17 commits into from
Jun 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@ class ActiveAccountFactory extends Factory<ActiveAccount,
ActiveAccountFactory deserialise(
{required Map<String, dynamic> data, bool isRemote = false, String? id}) {
obj = ActiveAccount(data["name"], data["account_number"]);
soll = parseDynamicListToStringList(data["soll"]);
haben = parseDynamicListToStringList(data["haben"]);
deserialiseDbObj(id ?? data["id"], !isRemote);
soll = parseDynamicListToStringList(data["soll"] ?? []);
haben = parseDynamicListToStringList(data["haben"] ?? []);
deserialiseDbObj(id ?? data["ID"], !isRemote);
return this;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@ mixin BaseBookableSerializer {

mixin BaseDatabaseObjSerialiser {
void serialiseDbObj(Map<String, dynamic> map, DatabaseObject obj) {
map.addAll({"id": obj.id, "isUploaded": obj.isUploaded});
map.addAll({"ID": obj.id, "isUploaded": obj.isUploaded});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@ class CategoryFactory extends Factory<Category, CategorySerializer,
{required Map<String, dynamic> data, bool isRemote = false, String? id}) {
obj = Category(
data["name"], data["account_number"], data["color"], data["icon"]);
soll = parseDynamicListToStringList(data["soll"]);
haben = parseDynamicListToStringList(data["haben"]);
deserialiseDbObj(id ?? data["id"], !isRemote);
soll = parseDynamicListToStringList(data["soll"] ?? []);
haben = parseDynamicListToStringList(data["haben"] ?? []);
deserialiseDbObj(id ?? data["ID"], !isRemote);
return this;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@ class PassiveAccountFactory extends Factory<PassiveAccount,
PassiveAccountFactory deserialise(
{required Map<String, dynamic> data, bool isRemote = false, String? id}) {
obj = PassiveAccount(data["name"], data["account_number"]);
soll = parseDynamicListToStringList(data["soll"]);
haben = parseDynamicListToStringList(data["haben"]);
deserialiseDbObj(id ?? data["id"], !isRemote);
soll = parseDynamicListToStringList(data["soll"] ?? []);
haben = parseDynamicListToStringList(data["haben"] ?? []);
deserialiseDbObj(id ?? data["ID"], !isRemote);
return this;
}
}
13 changes: 10 additions & 3 deletions client/cashcompass_hook/lib/src/connector/api_exception.dart
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
class ApiException implements Exception {
final String msg;
final int? statusCode;
ApiException(this.msg, this.statusCode);
final String? body;
ApiException(this.msg, this.statusCode, {this.body});

factory ApiException.badRequest() {
return ApiException("Bad Request", 400);
factory ApiException.badRequest(String body) {
return ApiException("Bad Request", 400, body: body);
}

factory ApiException.unauthorized() {
Expand All @@ -22,4 +23,10 @@ class ApiException implements Exception {
factory ApiException.internalServerError() {
return ApiException("Internal Server Error", 500);
}

@override
String toString() {
// TODO: implement toString
return "$statusCode: $msg ${body ?? ""}";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class ErrorHandler {
case (401):
throw ApiException.unauthorized();
case (400):
throw ApiException.badRequest();
throw ApiException.badRequest(response.body);
case (500):
throw ApiException.internalServerError();
case (403):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,31 +13,31 @@ class MockDataAdapter extends DataAdapter {
Map<String, Map<String, dynamic>> db = {
EntityPaths.activeaccount.path: {
"11": {
"id": 11,
"ID": 11,
"isUploaded": true,
"name": "ING",
"account_number": 11,
"soll": [],
"haben": []
},
"12": {
"id": 12,
"ID": 12,
"isUploaded": true,
"name": "Sparkasse",
"account_number": 12,
"soll": [],
"haben": []
},
"13": {
"id": 13,
"ID": 13,
"isUploaded": true,
"name": "BAR",
"account_number": 13,
"soll": [],
"haben": []
},
"45": {
"id": 45,
"ID": 45,
"isUploaded": true,
"name": "active1",
"account_number": 45,
Expand All @@ -47,7 +47,7 @@ class MockDataAdapter extends DataAdapter {
},
EntityPaths.category.path: {
"21": {
"id": 21,
"ID": 21,
"isUploaded": true,
"name": "GiftsDonations",
"account_number": 21,
Expand All @@ -56,7 +56,7 @@ class MockDataAdapter extends DataAdapter {
"haben": []
},
"22": {
"id": 22,
"ID": 22,
"isUploaded": true,
"name": "Groceries",
"account_number": 22,
Expand All @@ -65,7 +65,7 @@ class MockDataAdapter extends DataAdapter {
"haben": []
},
"23": {
"id": 23,
"ID": 23,
"isUploaded": true,
"name": "Transport",
"account_number": 23,
Expand All @@ -74,7 +74,7 @@ class MockDataAdapter extends DataAdapter {
"haben": []
},
"24": {
"id": 24,
"ID": 24,
"isUploaded": true,
"name": "Loans",
"account_number": 24,
Expand All @@ -85,7 +85,7 @@ class MockDataAdapter extends DataAdapter {
},
EntityPaths.passiveaccount.path: {
"31": {
"id": 31,
"ID": 31,
"isUploaded": true,
"name": "pass1",
"account_number": 31,
Expand Down
62 changes: 59 additions & 3 deletions client/cashcompass_hook/lib/src/connector/remote_storage.dart
Original file line number Diff line number Diff line change
@@ -1,18 +1,74 @@
import 'package:cashcompass_hook/src/accounts/active_account/active_account_factory.dart';
import 'package:cashcompass_hook/src/accounts/category/category_factory.dart';
import 'package:cashcompass_hook/src/accounts/initial_pull.dart';
import 'package:cashcompass_hook/src/accounts/passive_account/passive_account_factory.dart';
import 'package:cashcompass_hook/src/connector/sync_controller.dart';
import 'package:cashcompass_hook/src/connector/entity_paths.dart';
import 'package:cashcompass_hook/src/connector/rest_client.dart';
import 'package:cashcompass_hook/src/data_storage/accout_manager.dart';
import 'package:cashcompass_hook/src/data_storage/database_object.dart';
import 'package:cashcompass_hook/src/transactions/transactions/transactions_factory.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';

class RemoteStorage implements DataAdapter {
// ignore: unused_field
final RestClient _client;
RemoteStorage(this._client);
@override
Future<InitialPullData> getInitialPull(Accountmanager accountmanager) {
// TODO: implement getInitialPull
throw UnimplementedError();
Future<InitialPullData> getInitialPull(Accountmanager accountManager) async {
http.Response response = await _client.post(
"/data/getInitalPullData",
"",
);
if (response.statusCode != 200) {
throw Error();
}

final Map<String, dynamic> responseBody = json.decode(response.body);

final Map<String, dynamic> data = responseBody["value"];

List<Map<String, dynamic>> activeAccounts =
data[EntityPaths.activeaccount.path]
.map<Map<String, dynamic>>((entry) => entry as Map<String, dynamic>)
.toList();

List<Map<String, dynamic>> passiveAccounts =
data[EntityPaths.passiveaccount.path]
.map<Map<String, dynamic>>((entry) => entry as Map<String, dynamic>)
.toList();

List<Map<String, dynamic>> transactions = data[EntityPaths.transaction.path]
.map<Map<String, dynamic>>((entry) => entry as Map<String, dynamic>)
.toList();

List<Map<String, dynamic>> categories = data[EntityPaths.category.path]
.map<Map<String, dynamic>>((entry) => entry as Map<String, dynamic>)
.toList();

var pullData = InitialPullData(
recurringTransactions: [],
// activeAccounts: [],
activeAccounts: activeAccounts
.map((object) =>
ActiveAccountFactory(accountManager).deserialise(data: object))
.toList(),
passiveAccounts: passiveAccounts
.map((object) =>
PassiveAccountFactory(accountManager).deserialise(data: object))
.toList(),
transactions: transactions
.map((object) =>
TransactionsFactory(accountManager).deserialise(data: object))
.toList(),
categories: categories
.map((object) =>
CategoryFactory(accountManager).deserialise(data: object))
.toList(),
lastsync: DateTime.now());

return pullData;
}

@override
Expand Down
11 changes: 6 additions & 5 deletions client/cashcompass_hook/lib/src/connector/rest_client.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import 'package:cashcompass_hook/src/connector/error_handler.dart';
import 'package:http/http.dart' as http;

const defaultServerBaseUrl =
"https://9c632b52trial-dev-backend-cap-srv.cfapps.us10-001.hana.ondemand.com/odata/v4";

class RestClient {
final String baseUrl;
final String? port;
Expand All @@ -18,11 +21,9 @@ class RestClient {

Future<http.Response> post(String path, String body,
{Map<String, String>? headers, ErrorHandler? errorHandler}) async {
final response = await http.post(
Uri.parse('$_basetUrl$path'),
body: body,
headers: headers,
);
final response = await http.post(Uri.parse('$_basetUrl$path'),
body: body,
headers: {"content-type": "application/json", ...headers ?? {}});
(errorHandler ?? const ErrorHandler()).handle(response);
return response;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,12 @@ class TransactionsFactory extends Factory<Transaction, TransactionsSerializer,
@override
TransactionsFactory deserialise(
{required Map<String, dynamic> data, bool isRemote = false, String? id}) {
sollNr = data["soll"];
habenNr = data["haben"];
sollNr = data["soll"] ?? 0;
habenNr = data["haben"] ?? 0;
amount = 1.0 * data["amount"];
label = data["label"];
transactionNr = data["transactionNumber"];
this.id = id;
this.id = id ?? data["ID"];
this.isRemote = isRemote;
return this;
}
Expand Down
36 changes: 29 additions & 7 deletions client/cashcompass_hook/test/cashcompass_hook_test.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import 'dart:developer';

import 'package:cashcompass_hook/src/accounts/active_account/active_account.dart';
import 'package:cashcompass_hook/src/accounts/active_account/active_account_factory.dart';
import 'package:cashcompass_hook/src/accounts/active_account/active_account_serializer.dart';
Expand All @@ -11,6 +10,8 @@ import 'package:cashcompass_hook/src/accounts/passive_account/passive_account_fa
import 'package:cashcompass_hook/src/chart_of_accounts.dart/chart_of_accounts.dart';
import 'package:cashcompass_hook/src/connector/entity_paths.dart';
import 'package:cashcompass_hook/src/connector/mock_classes/mock_data_adapter.dart';
import 'package:cashcompass_hook/src/connector/remote_storage.dart';
import 'package:cashcompass_hook/src/connector/rest_client.dart';
import 'package:cashcompass_hook/src/data_storage/accout_manager.dart';
import 'package:cashcompass_hook/src/transactions/recurring_transactions/recurring_transactions_factory.dart';
import 'package:cashcompass_hook/src/transactions/transactions/transactions_factory.dart';
Expand Down Expand Up @@ -75,14 +76,14 @@ void main() {
var acc = ActiveAccountFactory(manager).create("test1").build();
var map = acc.getSerialiser().toJson();
assert(TestHelper.checkFields(
["id", "isUploaded", "soll", "haben", "name", "account_number"],
["ID", "isUploaded", "soll", "haben", "name", "account_number"],
map));
});
test('Passive Account', () {
var acc = PassiveAccountFactory(manager).create("test1").build();
var map = acc.getSerialiser().toJson();
assert(TestHelper.checkFields(
["id", "isUploaded", "soll", "haben", "name", "account_number"],
["ID", "isUploaded", "soll", "haben", "name", "account_number"],
map));
assert(map.keys.length == 6);
});
Expand All @@ -93,7 +94,7 @@ void main() {
.build();
var map = acc.getSerialiser().toJson();
assert(TestHelper.checkFields([
"id",
"ID",
"isUploaded",
"soll",
"haben",
Expand All @@ -118,7 +119,7 @@ void main() {
.build();
var map = tr.getSerialiser().toJson();
assert(TestHelper.checkFields([
"id",
"ID",
"isUploaded",
"soll",
"haben",
Expand Down Expand Up @@ -147,7 +148,7 @@ void main() {
.build();
var map = tr.getSerialiser().toJson();
assert(TestHelper.checkFields([
"id",
"ID",
"isUploaded",
"soll",
"haben",
Expand Down Expand Up @@ -247,9 +248,30 @@ void main() {
var fac = CategoryFactory(manager);
var f = fac.create("TestAccount", "#666666", "StopSign").build();
var data = f.getSerialiser().toJson();
data.removeWhere((key, value) => key == "id");
data.removeWhere((key, value) => key == "ID");
expect(() => CategoryFactory(manager).deserialise(data: data).build(),
throwsA(const TypeMatcher<Exception>()));
});
});

group("RemoteStorage", () {
RestClient restClient = RestClient(baseUrl: defaultServerBaseUrl);

Accountmanager accManager =
Accountmanager(dataAdapter: RemoteStorage(restClient));
late ChartOfAccounts accountChart;
setUp(() async {
await accManager.init();
accountChart = ChartOfAccounts(accManager);
});

test("Get All Categories", () {
expect(accountChart.getCategories().isNotEmpty, true);
// expect(chart.getCategories(matcher: (p0) => false).isEmpty, true);
});

test("Get All active Accounts", () {
expect(accountChart.getActiveAccounts().isNotEmpty, true);
});
});
}
6 changes: 3 additions & 3 deletions server/db/data/dhbw.caco.schema-Accounts.csv
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
ID;createdBy;accountType;name;user_username;
b2b97b50-a0ed-4884-a3b3-5603f660b86f;Simi;0;Active Account;Simi;
d688110f-ecbe-4e57-a134-7f86cae77a18;Simi;1;Passive Account;Simi;
ID;createdBy;accountType;name;user_username;account_number;
b2b97b50-a0ed-4884-a3b3-5603f660b86f;Simi;0;Active Account;Simi;0;
d688110f-ecbe-4e57-a134-7f86cae77a18;Simi;1;Passive Account;Simi;1;
2 changes: 2 additions & 0 deletions server/db/data/dhbw.caco.schema-Categories.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ID;accountType;name;user_username;account_number;icon;color;budget;
4781d902-90c0-41fc-9d6a-4aa684395439;2;eine cooole Kategorie;Simi;3;Groceries;Colors.green;55;
4 changes: 2 additions & 2 deletions server/db/data/dhbw.caco.schema-Transactions.csv
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
ID;timestamp;createdBy;activeAccount_ID;passiveAccount_ID;amount;
cd3f2329-026d-4d36-bb7a-5eea1b241288;2017-04-13T15:51:04.000Z;Simi;b2b97b50-a0ed-4884-a3b3-5603f660b86f;d688110f-ecbe-4e57-a134-7f86cae77a18;2.71;
ID;timestamp;createdBy;activeAccount_ID;passiveAccount_ID;amount;label;transactionNumber;
cd3f2329-026d-4d36-bb7a-5eea1b241288;2017-04-13T15:51:04.000Z;Simi;b2b97b50-a0ed-4884-a3b3-5603f660b86f;d688110f-ecbe-4e57-a134-7f86cae77a18;2.71;Essen;0;
Loading