diff --git a/accounting/src/main/java/de/srsoftware/umbrella/accounting/AccountDb.java b/accounting/src/main/java/de/srsoftware/umbrella/accounting/AccountDb.java index 550e2c97..8dab5dce 100644 --- a/accounting/src/main/java/de/srsoftware/umbrella/accounting/AccountDb.java +++ b/accounting/src/main/java/de/srsoftware/umbrella/accounting/AccountDb.java @@ -3,7 +3,11 @@ package de.srsoftware.umbrella.accounting; import de.srsoftware.umbrella.core.model.Account; import de.srsoftware.umbrella.core.model.Transaction; +import java.util.Collection; + public interface AccountDb { + Collection listAccounts(long userId); Account save(Account account); + Transaction save(Transaction transaction); } diff --git a/accounting/src/main/java/de/srsoftware/umbrella/accounting/AccountingModule.java b/accounting/src/main/java/de/srsoftware/umbrella/accounting/AccountingModule.java index c5c809ca..2b3d9552 100644 --- a/accounting/src/main/java/de/srsoftware/umbrella/accounting/AccountingModule.java +++ b/accounting/src/main/java/de/srsoftware/umbrella/accounting/AccountingModule.java @@ -42,6 +42,25 @@ public class AccountingModule extends BaseHandler implements AccountingService { ModuleRegistry.add(this); } + @Override + public boolean doGet(Path path, HttpExchange ex) throws IOException { + addCors(ex); + try { + Optional token = SessionToken.from(ex).map(Token::of); + var user = userService().loadUser(token); + if (user.isEmpty()) return unauthorized(ex); + var head = path.pop(); + return switch (head) { + case null -> getAccounts(user.get(),ex); + default -> super.doGet(path,ex); + }; + } catch (NumberFormatException e){ + return sendContent(ex,HTTP_BAD_REQUEST,"Invalid project id"); + } catch (UmbrellaException e){ + return send(ex,e); + } + } + @Override public boolean doPost(Path path, HttpExchange ex) throws IOException { addCors(ex); @@ -61,6 +80,12 @@ public class AccountingModule extends BaseHandler implements AccountingService { } } + private boolean getAccounts(UmbrellaUser user, HttpExchange ex) throws IOException { + return sendContent(ex,accountDb.listAccounts(user.id())); + } + + + private boolean postEntry(UmbrellaUser user, HttpExchange ex) throws IOException { var json = json(ex); if (!json.has(Field.ACCOUNT)) throw missingField(Field.ACCOUNT); diff --git a/accounting/src/main/java/de/srsoftware/umbrella/accounting/SqliteDb.java b/accounting/src/main/java/de/srsoftware/umbrella/accounting/SqliteDb.java index 46dbd4d3..a1b805c7 100644 --- a/accounting/src/main/java/de/srsoftware/umbrella/accounting/SqliteDb.java +++ b/accounting/src/main/java/de/srsoftware/umbrella/accounting/SqliteDb.java @@ -1,20 +1,24 @@ package de.srsoftware.umbrella.accounting; +import de.srsoftware.tools.jdbc.Condition; import de.srsoftware.tools.jdbc.Query; import de.srsoftware.umbrella.core.BaseDb; import de.srsoftware.umbrella.core.constants.Field; +import de.srsoftware.umbrella.core.constants.Text; import de.srsoftware.umbrella.core.model.Account; import de.srsoftware.umbrella.core.model.Transaction; import java.sql.Connection; import java.sql.SQLException; import java.time.ZoneOffset; +import java.util.HashSet; import static de.srsoftware.tools.NotImplemented.notImplemented; +import static de.srsoftware.tools.jdbc.Condition.equal; +import static de.srsoftware.tools.jdbc.Query.SelectQuery.ALL; import static de.srsoftware.umbrella.accounting.Constants.TABLE_ACCOUNTS; import static de.srsoftware.umbrella.accounting.Constants.TABLE_TRANSACTIONS; -import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.failedToCreateTable; -import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.failedToStoreObject; +import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.*; import static java.text.MessageFormat.format; public class SqliteDb extends BaseDb implements AccountDb { @@ -72,6 +76,26 @@ public class SqliteDb extends BaseDb implements AccountDb { } } + @Override + public HashSet listAccounts(long userId) { + try { + var accountIds = new HashSet(); + var rs = Query.select("DISTINCT " + Field.ACCOUNT).from(TABLE_TRANSACTIONS).where(Field.SOURCE, equal(userId)).exec(db); + while (rs.next()) accountIds.add(rs.getLong(1)); + rs.close(); + rs = Query.select("DISTINCT " + Field.ACCOUNT).from(TABLE_TRANSACTIONS).where(Field.DESTINATION, equal(userId)).exec(db); + while (rs.next()) accountIds.add(rs.getLong(1)); + rs.close(); + var accounts = new HashSet(); + rs = Query.select(ALL).from(TABLE_ACCOUNTS).where(Field.ID, Condition.in(accountIds.toArray())).exec(db); + while (rs.next()) accounts.add(Account.of(rs)); + rs.close(); + return accounts; + } catch (SQLException e){ + throw failedToLoadObject(Text.ACCOUNTING).causedBy(e); + } + } + @Override public Account save(Account account) { if (account.id() == 0) try { // new account diff --git a/core/src/main/java/de/srsoftware/umbrella/core/model/Account.java b/core/src/main/java/de/srsoftware/umbrella/core/model/Account.java index a3f19152..4a520312 100644 --- a/core/src/main/java/de/srsoftware/umbrella/core/model/Account.java +++ b/core/src/main/java/de/srsoftware/umbrella/core/model/Account.java @@ -3,13 +3,19 @@ package de.srsoftware.umbrella.core.model; import de.srsoftware.tools.Mappable; import de.srsoftware.umbrella.core.constants.Field; +import java.sql.ResultSet; +import java.sql.SQLException; import java.util.Map; import static de.srsoftware.umbrella.core.ModuleRegistry.userService; public record Account(long id, String name, String currency, long ownerId) implements Mappable { - public Account withId(long newId) { - return new Account(newId,name,currency,ownerId); + public static Account of(ResultSet rs) throws SQLException { + var id = rs.getLong(Field.ID); + var name = rs.getString(Field.NAME); + var owner = rs.getLong(Field.OWNER); + var currency = rs.getString(Field.CURRENCY); + return new Account(id,name,currency,owner); } @Override @@ -22,4 +28,8 @@ public record Account(long id, String name, String currency, long ownerId) imple Field.OWNER, owner.toMap() ); } + + public Account withId(long newId) { + return new Account(newId,name,currency,ownerId); + } } diff --git a/frontend/src/routes/accounting/index.svelte b/frontend/src/routes/accounting/index.svelte index 08882cde..6c9d140c 100644 --- a/frontend/src/routes/accounting/index.svelte +++ b/frontend/src/routes/accounting/index.svelte @@ -1,14 +1,28 @@