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.Account;
|
||||||
import de.srsoftware.umbrella.core.model.Transaction;
|
import de.srsoftware.umbrella.core.model.Transaction;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
public interface AccountDb {
|
public interface AccountDb {
|
||||||
|
Collection<Account> listAccounts(long userId);
|
||||||
Account save(Account account);
|
Account save(Account account);
|
||||||
|
|
||||||
Transaction save(Transaction transaction);
|
Transaction save(Transaction transaction);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,6 +42,25 @@ public class AccountingModule extends BaseHandler implements AccountingService {
|
|||||||
ModuleRegistry.add(this);
|
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
|
@Override
|
||||||
public boolean doPost(Path path, HttpExchange ex) throws IOException {
|
public boolean doPost(Path path, HttpExchange ex) throws IOException {
|
||||||
addCors(ex);
|
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 {
|
private boolean postEntry(UmbrellaUser user, HttpExchange ex) throws IOException {
|
||||||
var json = json(ex);
|
var json = json(ex);
|
||||||
if (!json.has(Field.ACCOUNT)) throw missingField(Field.ACCOUNT);
|
if (!json.has(Field.ACCOUNT)) throw missingField(Field.ACCOUNT);
|
||||||
|
|||||||
@@ -1,20 +1,24 @@
|
|||||||
package de.srsoftware.umbrella.accounting;
|
package de.srsoftware.umbrella.accounting;
|
||||||
|
|
||||||
|
import de.srsoftware.tools.jdbc.Condition;
|
||||||
import de.srsoftware.tools.jdbc.Query;
|
import de.srsoftware.tools.jdbc.Query;
|
||||||
import de.srsoftware.umbrella.core.BaseDb;
|
import de.srsoftware.umbrella.core.BaseDb;
|
||||||
import de.srsoftware.umbrella.core.constants.Field;
|
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.Account;
|
||||||
import de.srsoftware.umbrella.core.model.Transaction;
|
import de.srsoftware.umbrella.core.model.Transaction;
|
||||||
|
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.time.ZoneOffset;
|
import java.time.ZoneOffset;
|
||||||
|
import java.util.HashSet;
|
||||||
|
|
||||||
import static de.srsoftware.tools.NotImplemented.notImplemented;
|
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_ACCOUNTS;
|
||||||
import static de.srsoftware.umbrella.accounting.Constants.TABLE_TRANSACTIONS;
|
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.*;
|
||||||
import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.failedToStoreObject;
|
|
||||||
import static java.text.MessageFormat.format;
|
import static java.text.MessageFormat.format;
|
||||||
|
|
||||||
public class SqliteDb extends BaseDb implements AccountDb {
|
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
|
@Override
|
||||||
public Account save(Account account) {
|
public Account save(Account account) {
|
||||||
if (account.id() == 0) try { // new 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.tools.Mappable;
|
||||||
import de.srsoftware.umbrella.core.constants.Field;
|
import de.srsoftware.umbrella.core.constants.Field;
|
||||||
|
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import static de.srsoftware.umbrella.core.ModuleRegistry.userService;
|
import static de.srsoftware.umbrella.core.ModuleRegistry.userService;
|
||||||
|
|
||||||
public record Account(long id, String name, String currency, long ownerId) implements Mappable {
|
public record Account(long id, String name, String currency, long ownerId) implements Mappable {
|
||||||
public Account withId(long newId) {
|
public static Account of(ResultSet rs) throws SQLException {
|
||||||
return new Account(newId,name,currency,ownerId);
|
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
|
@Override
|
||||||
@@ -22,4 +28,8 @@ public record Account(long id, String name, String currency, long ownerId) imple
|
|||||||
Field.OWNER, owner.toMap()
|
Field.OWNER, owner.toMap()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Account withId(long newId) {
|
||||||
|
return new Account(newId,name,currency,ownerId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,28 @@
|
|||||||
<script>
|
<script>
|
||||||
|
import { onMount } from 'svelte';
|
||||||
import { useTinyRouter } from 'svelte-tiny-router';
|
import { useTinyRouter } from 'svelte-tiny-router';
|
||||||
import { t } from '../../translations.svelte';
|
import { t } from '../../translations.svelte';
|
||||||
|
import { api, get } from '../../urls.svelte';
|
||||||
|
import { error, yikes } from '../../warn.svelte';
|
||||||
|
|
||||||
const router = useTinyRouter();
|
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(){
|
function newAccount(){
|
||||||
router.navigate('/accounting/new');
|
router.navigate('/accounting/new');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onMount(load);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<fieldset>
|
<fieldset>
|
||||||
|
|||||||
Reference in New Issue
Block a user