114 lines
3.3 KiB
D
114 lines
3.3 KiB
D
module transaction.service;
|
|
|
|
import handy_http_primitives;
|
|
import std.datetime;
|
|
|
|
import transaction.api;
|
|
import transaction.model;
|
|
import transaction.data;
|
|
import profile.data;
|
|
import account.model;
|
|
import util.money;
|
|
import util.pagination;
|
|
|
|
// Transactions Services
|
|
|
|
Page!TransactionsListItem getTransactions(ProfileDataSource ds, in PageRequest pageRequest) {
|
|
Page!TransactionsListItem page = ds.getTransactionRepository()
|
|
.findAll(pageRequest);
|
|
return page; // Return an empty page for now!
|
|
}
|
|
|
|
void addTransaction2(ProfileDataSource ds, in AddTransactionPayload payload) {
|
|
// TODO
|
|
}
|
|
|
|
void addTransaction(
|
|
ProfileDataSource ds,
|
|
SysTime timestamp,
|
|
SysTime addedAt,
|
|
ulong amount,
|
|
Currency currency,
|
|
string description,
|
|
Optional!ulong vendorId,
|
|
Optional!ulong categoryId,
|
|
Optional!ulong creditedAccountId,
|
|
Optional!ulong debitedAccountId,
|
|
TransactionLineItem[] lineItems,
|
|
string[] tags
|
|
) {
|
|
if (creditedAccountId.isNull && debitedAccountId.isNull) {
|
|
throw new Exception("At least one account must be linked to a transaction.");
|
|
}
|
|
auto journalEntryRepo = ds.getAccountJournalEntryRepository();
|
|
auto txRepo = ds.getTransactionRepository();
|
|
Transaction tx = txRepo.insert(
|
|
timestamp,
|
|
addedAt,
|
|
amount,
|
|
currency,
|
|
description,
|
|
vendorId,
|
|
categoryId
|
|
);
|
|
if (creditedAccountId) {
|
|
journalEntryRepo.insert(
|
|
timestamp,
|
|
creditedAccountId.value,
|
|
tx.id,
|
|
amount,
|
|
AccountJournalEntryType.CREDIT,
|
|
currency
|
|
);
|
|
}
|
|
if (debitedAccountId) {
|
|
journalEntryRepo.insert(
|
|
timestamp,
|
|
debitedAccountId.value,
|
|
tx.id,
|
|
amount,
|
|
AccountJournalEntryType.DEBIT,
|
|
currency
|
|
);
|
|
}
|
|
if (tags.length > 0) {
|
|
ds.getTransactionTagRepository().updateTags(tx.id, tags);
|
|
}
|
|
}
|
|
|
|
// Vendors Services
|
|
|
|
TransactionVendor[] getAllVendors(ProfileDataSource ds) {
|
|
return ds.getTransactionVendorRepository().findAll();
|
|
}
|
|
|
|
TransactionVendor getVendor(ProfileDataSource ds, ulong vendorId) {
|
|
return ds.getTransactionVendorRepository().findById(vendorId)
|
|
.orElseThrow(() => new HttpStatusException(HttpStatus.NOT_FOUND));
|
|
}
|
|
|
|
TransactionVendor createVendor(ProfileDataSource ds, in VendorPayload payload) {
|
|
auto vendorRepo = ds.getTransactionVendorRepository();
|
|
if (vendorRepo.existsByName(payload.name)) {
|
|
throw new HttpStatusException(HttpStatus.BAD_REQUEST, "Vendor name is already in use.");
|
|
}
|
|
return vendorRepo.insert(payload.name, payload.description);
|
|
}
|
|
|
|
TransactionVendor updateVendor(ProfileDataSource ds, ulong vendorId, in VendorPayload payload) {
|
|
TransactionVendorRepository repo = ds.getTransactionVendorRepository();
|
|
TransactionVendor existingVendor = repo.findById(vendorId)
|
|
.orElseThrow(() => new HttpStatusException(HttpStatus.NOT_FOUND));
|
|
if (payload.name != existingVendor.name && repo.existsByName(payload.name)) {
|
|
throw new HttpStatusException(
|
|
HttpStatus.BAD_REQUEST,
|
|
"Vendor name is already in use."
|
|
);
|
|
}
|
|
return repo.updateById(vendorId, payload.name, payload.description);
|
|
}
|
|
|
|
void deleteVendor(ProfileDataSource ds, ulong vendorId) {
|
|
ds.getTransactionVendorRepository().deleteById(vendorId);
|
|
}
|