|
|
|
|
@@ -1,8 +1,85 @@
|
|
|
|
|
package de.srsoftware.umbrella.accounting;
|
|
|
|
|
|
|
|
|
|
import com.sun.net.httpserver.HttpExchange;
|
|
|
|
|
import de.srsoftware.configuration.Configuration;
|
|
|
|
|
import de.srsoftware.tools.Path;
|
|
|
|
|
import de.srsoftware.tools.SessionToken;
|
|
|
|
|
import de.srsoftware.umbrella.core.BaseHandler;
|
|
|
|
|
import de.srsoftware.umbrella.core.ModuleRegistry;
|
|
|
|
|
import de.srsoftware.umbrella.core.api.AccountingService;
|
|
|
|
|
import de.srsoftware.umbrella.core.constants.Field;
|
|
|
|
|
import de.srsoftware.umbrella.core.constants.Text;
|
|
|
|
|
import de.srsoftware.umbrella.core.exceptions.UmbrellaException;
|
|
|
|
|
import de.srsoftware.umbrella.core.model.Account;
|
|
|
|
|
import de.srsoftware.umbrella.core.model.Token;
|
|
|
|
|
import de.srsoftware.umbrella.core.model.UmbrellaUser;
|
|
|
|
|
import org.json.JSONObject;
|
|
|
|
|
|
|
|
|
|
import java.io.IOException;
|
|
|
|
|
import java.util.Optional;
|
|
|
|
|
|
|
|
|
|
import static de.srsoftware.tools.Optionals.nullIfEmpty;
|
|
|
|
|
import static de.srsoftware.umbrella.core.ConnectionProvider.connect;
|
|
|
|
|
import static de.srsoftware.umbrella.core.constants.Path.JSON;
|
|
|
|
|
import static de.srsoftware.umbrella.core.constants.Path.SEARCH;
|
|
|
|
|
import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.invalidField;
|
|
|
|
|
import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.missingField;
|
|
|
|
|
import static java.net.HttpURLConnection.HTTP_BAD_REQUEST;
|
|
|
|
|
|
|
|
|
|
public class AccountingModule extends BaseHandler implements AccountingService {
|
|
|
|
|
public static final String CONFIG_DATABASE = "umbrella.modules.accounting.database";
|
|
|
|
|
private final AccountDb accountDb;
|
|
|
|
|
|
|
|
|
|
public AccountingModule(Configuration config) throws UmbrellaException {
|
|
|
|
|
super();
|
|
|
|
|
var dbFile = config.get(CONFIG_DATABASE).orElseThrow(() -> missingField(CONFIG_DATABASE));
|
|
|
|
|
accountDb = new SqliteDb(connect(dbFile));
|
|
|
|
|
ModuleRegistry.add(this);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public boolean doPost(Path path, HttpExchange ex) throws IOException {
|
|
|
|
|
addCors(ex);
|
|
|
|
|
try {
|
|
|
|
|
Optional<Token> token = SessionToken.from(ex).map(Token::of);
|
|
|
|
|
var user = ModuleRegistry.userService().loadUser(token);
|
|
|
|
|
if (user.isEmpty()) return unauthorized(ex);
|
|
|
|
|
var head = path.pop();
|
|
|
|
|
return switch (head) {
|
|
|
|
|
case null -> postEntry(user.get(),ex);
|
|
|
|
|
default -> super.doPost(path,ex);
|
|
|
|
|
};
|
|
|
|
|
} catch (NumberFormatException e){
|
|
|
|
|
return sendContent(ex,HTTP_BAD_REQUEST,"Invalid project id");
|
|
|
|
|
} catch (UmbrellaException e){
|
|
|
|
|
return send(ex,e);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private boolean postEntry(UmbrellaUser user, HttpExchange ex) throws IOException {
|
|
|
|
|
var json = json(ex);
|
|
|
|
|
if (!json.has(Field.ACCOUNT)) throw missingField(Field.ACCOUNT);
|
|
|
|
|
if (!(json.get(Field.ACCOUNT) instanceof JSONObject acc)) throw invalidField(Field.ACCOUNT,JSON);
|
|
|
|
|
// TODO more tests
|
|
|
|
|
|
|
|
|
|
Long accountId = null;
|
|
|
|
|
if (acc.has(Field.ID)) {
|
|
|
|
|
if (!(acc.get(Field.ID) instanceof Number accId)) throw invalidField(String.join(".",Field.ACCOUNT,Field.ID), Text.NUMBER);
|
|
|
|
|
if (accId.longValue() != 0) accountId = accId.longValue();
|
|
|
|
|
}
|
|
|
|
|
if (accountId == null){
|
|
|
|
|
if (!acc.has(Field.NAME)) throw missingField(String.join(".",Field.ACCOUNT,Field.NAME));
|
|
|
|
|
var accountName = acc.getString(Field.NAME);
|
|
|
|
|
if (accountName.isBlank()) throw invalidField(String.join(".",Field.ACCOUNT,Field.NAME),Text.STRING);
|
|
|
|
|
|
|
|
|
|
var currency = acc.has(Field.CURRENCY) ? nullIfEmpty(acc.getString(Field.CURRENCY)) : null;
|
|
|
|
|
|
|
|
|
|
var account = accountDb.save(new Account(0, accountName, currency));
|
|
|
|
|
accountId = account.id();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// TODO: save entry
|
|
|
|
|
|
|
|
|
|
return notFound(ex);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|