implemented loading of accounts
Signed-off-by: Stephan Richter <s.richter@srsoftware.de>
This commit is contained in:
@@ -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<Account> listAccounts(long userId);
|
||||
Account save(Account account);
|
||||
|
||||
Transaction save(Transaction transaction);
|
||||
}
|
||||
|
||||
@@ -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> 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);
|
||||
|
||||
@@ -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<Account> listAccounts(long userId) {
|
||||
try {
|
||||
var accountIds = new HashSet<Long>();
|
||||
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<Account>();
|
||||
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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,28 @@
|
||||
<script>
|
||||
import { onMount } from 'svelte';
|
||||
import { useTinyRouter } from 'svelte-tiny-router';
|
||||
import { t } from '../../translations.svelte';
|
||||
import { api, get } from '../../urls.svelte';
|
||||
import { error, yikes } from '../../warn.svelte';
|
||||
|
||||
const router = useTinyRouter();
|
||||
|
||||
let accounts = [];
|
||||
|
||||
async function load(){
|
||||
let url = api('accounting');
|
||||
let res = await get(url);
|
||||
if (res.ok){
|
||||
yikes();
|
||||
accounts = await res.json();
|
||||
} else error(res);
|
||||
}
|
||||
|
||||
function newAccount(){
|
||||
router.navigate('/accounting/new');
|
||||
}
|
||||
|
||||
|
||||
onMount(load);
|
||||
</script>
|
||||
|
||||
<fieldset>
|
||||
|
||||
Reference in New Issue
Block a user