85 lines
2.5 KiB
D
85 lines
2.5 KiB
D
|
module account.api;
|
||
|
|
||
|
import handy_httpd;
|
||
|
import asdf;
|
||
|
|
||
|
import profile.service;
|
||
|
import account.model;
|
||
|
import money.currency;
|
||
|
|
||
|
struct AccountResponse {
|
||
|
ulong id;
|
||
|
string createdAt;
|
||
|
bool archived;
|
||
|
string type;
|
||
|
string numberSuffix;
|
||
|
string name;
|
||
|
string currency;
|
||
|
string description;
|
||
|
|
||
|
static AccountResponse of(in Account account) {
|
||
|
AccountResponse r;
|
||
|
r.id = account.id;
|
||
|
r.createdAt = account.createdAt.toISOExtString();
|
||
|
r.archived = account.archived;
|
||
|
r.type = account.type.id;
|
||
|
r.numberSuffix = account.numberSuffix;
|
||
|
r.name = account.name;
|
||
|
r.currency = account.currency.code.dup;
|
||
|
r.description = account.description;
|
||
|
return r;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void handleGetAccounts(ref HttpRequestContext ctx) {
|
||
|
import std.algorithm;
|
||
|
auto ds = getProfileDataSource(ctx);
|
||
|
auto accounts = ds.getAccountRepository().findAll()
|
||
|
.map!(a => AccountResponse.of(a));
|
||
|
ctx.response.writeBodyString(serializeToJson(accounts), "application/json");
|
||
|
}
|
||
|
|
||
|
void handleGetAccount(ref HttpRequestContext ctx) {
|
||
|
ulong accountId = ctx.request.getPathParamAs!ulong("accountId");
|
||
|
auto ds = getProfileDataSource(ctx);
|
||
|
auto account = ds.getAccountRepository().findById(accountId)
|
||
|
.orElseThrow(() => new HttpStatusException(HttpStatus.NOT_FOUND));
|
||
|
ctx.response.writeBodyString(serializeToJson(AccountResponse.of(account)), "application/json");
|
||
|
}
|
||
|
|
||
|
struct AccountCreationPayload {
|
||
|
string type;
|
||
|
string numberSuffix;
|
||
|
string name;
|
||
|
string currency;
|
||
|
string description;
|
||
|
}
|
||
|
|
||
|
void handleCreateAccount(ref HttpRequestContext ctx) {
|
||
|
auto ds = getProfileDataSource(ctx);
|
||
|
AccountCreationPayload payload;
|
||
|
try {
|
||
|
payload = deserialize!(AccountCreationPayload)(ctx.request.readBodyAsString());
|
||
|
} catch (SerdeException e) {
|
||
|
ctx.response.status = HttpStatus.BAD_REQUEST;
|
||
|
ctx.response.writeBodyString("Invalid account payload.");
|
||
|
return;
|
||
|
}
|
||
|
AccountType type = AccountType.fromId(payload.type);
|
||
|
Currency currency = Currency.ofCode(payload.currency);
|
||
|
Account account = ds.getAccountRepository().insert(
|
||
|
type,
|
||
|
payload.numberSuffix,
|
||
|
payload.name,
|
||
|
currency,
|
||
|
payload.description
|
||
|
);
|
||
|
ctx.response.writeBodyString(serializeToJson(AccountResponse.of(account)), "application/json");
|
||
|
}
|
||
|
|
||
|
void handleDeleteAccount(ref HttpRequestContext ctx) {
|
||
|
ulong accountId = ctx.request.getPathParamAs!ulong("accountId");
|
||
|
auto ds = getProfileDataSource(ctx);
|
||
|
ds.getAccountRepository().deleteById(accountId);
|
||
|
}
|