finnow/finnow-api/source/transaction/api.d

127 lines
4.4 KiB
D

module transaction.api;
import handy_http_primitives;
import handy_http_data.json;
import handy_http_handlers.path_handler;
import transaction.model;
import transaction.data;
import transaction.service;
import profile.data;
import profile.service;
import util.money;
import util.pagination;
import util.data;
immutable DEFAULT_TRANSACTION_PAGE = PageRequest(0, 10, [Sort("created_at", SortDir.DESC)]);
struct TransactionResponse {
import std.typecons : Nullable, nullable;
ulong id;
string timestamp;
string addedAt;
ulong amount;
string currency;
string description;
Nullable!ulong vendorId;
Nullable!ulong categoryId;
static TransactionResponse of(in Transaction tx) {
return TransactionResponse(
tx.id,
tx.timestamp.toISOExtString(),
tx.addedAt.toISOExtString(),
tx.amount,
tx.currency.code.idup,
tx.description,
tx.vendorId.toNullable,
tx.categoryId.toNullable
);
}
}
void getTransactions(ref ServerHttpRequest request, ref ServerHttpResponse response) {
ProfileDataSource ds = getProfileDataSource(request);
PageRequest pr = PageRequest.parse(request, DEFAULT_TRANSACTION_PAGE);
Page!Transaction page = ds.getTransactionRepository().findAll(pr);
writeJsonBody(response, page.mapItems(&TransactionResponse.of));
}
void getVendors(ref ServerHttpRequest request, ref ServerHttpResponse response) {
ProfileDataSource ds = getProfileDataSource(request);
auto vendorRepo = ds.getTransactionVendorRepository();
TransactionVendor[] vendors = vendorRepo.findAll();
writeJsonBody(response, vendors);
}
void getVendor(ref ServerHttpRequest request, ref ServerHttpResponse response) {
long vendorId = request.getPathParamAs!long("vendorId", -1);
if (vendorId == -1) {
response.status = HttpStatus.NOT_FOUND;
response.writeBodyString("Missing vendorId path parameter.");
return;
}
ProfileDataSource ds = getProfileDataSource(request);
auto vendorRepo = ds.getTransactionVendorRepository();
TransactionVendor vendor = vendorRepo.findById(vendorId)
.orElseThrow(() => new HttpStatusException(HttpStatus.NOT_FOUND));
writeJsonBody(response, vendor);
}
struct VendorPayload {
string name;
string description;
}
void createVendor(ref ServerHttpRequest request, ref ServerHttpResponse response) {
VendorPayload payload = readJsonBodyAs!VendorPayload(request);
ProfileDataSource ds = getProfileDataSource(request);
auto vendorRepo = ds.getTransactionVendorRepository();
if (vendorRepo.existsByName(payload.name)) {
response.status = HttpStatus.BAD_REQUEST;
response.writeBodyString("Vendor name is already in use.");
return;
}
TransactionVendor vendor = vendorRepo.insert(payload.name, payload.description);
writeJsonBody(response, vendor);
}
void updateVendor(ref ServerHttpRequest request, ref ServerHttpResponse response) {
VendorPayload payload = readJsonBodyAs!VendorPayload(request);
long vendorId = request.getPathParamAs!long("vendorId", -1);
if (vendorId == -1) {
response.status = HttpStatus.NOT_FOUND;
response.writeBodyString("Missing vendorId path parameter.");
return;
}
ProfileDataSource ds = getProfileDataSource(request);
auto vendorRepo = ds.getTransactionVendorRepository();
TransactionVendor existingVendor = vendorRepo.findById(vendorId)
.orElseThrow(() => new HttpStatusException(HttpStatus.NOT_FOUND));
if (payload.name != existingVendor.name && vendorRepo.existsByName(payload.name)) {
response.status = HttpStatus.BAD_REQUEST;
response.writeBodyString("Vendor name is already in use.");
return;
}
TransactionVendor updated = vendorRepo.updateById(
vendorId,
payload.name,
payload.description
);
writeJsonBody(response, updated);
}
void deleteVendor(ref ServerHttpRequest request, ref ServerHttpResponse response) {
long vendorId = request.getPathParamAs!long("vendorId", -1);
if (vendorId == -1) {
response.status = HttpStatus.NOT_FOUND;
response.writeBodyString("Missing vendorId path parameter.");
return;
}
ProfileDataSource ds = getProfileDataSource(request);
auto vendorRepo = ds.getTransactionVendorRepository();
vendorRepo.deleteById(vendorId);
}