Fixed logic for editing linked accounts.
Build and Deploy API / build-and-deploy (push) Successful in 1m44s Details

This commit is contained in:
andrewlalis 2025-11-22 13:53:26 -05:00
parent 8dd80d5c7e
commit 0e3b615684
1 changed files with 59 additions and 37 deletions

View File

@ -2,6 +2,7 @@ module transaction.service;
import handy_http_primitives; import handy_http_primitives;
import std.datetime; import std.datetime;
import slf4d;
import transaction.api; import transaction.api;
import transaction.model; import transaction.model;
@ -88,7 +89,6 @@ TransactionDetail updateTransaction(
TransactionCategoryRepository categoryRepo = ds.getTransactionCategoryRepository(); TransactionCategoryRepository categoryRepo = ds.getTransactionCategoryRepository();
AccountRepository accountRepo = ds.getAccountRepository(); AccountRepository accountRepo = ds.getAccountRepository();
TransactionRepository transactionRepo = ds.getTransactionRepository(); TransactionRepository transactionRepo = ds.getTransactionRepository();
AccountJournalEntryRepository jeRepo = ds.getAccountJournalEntryRepository();
TransactionTagRepository tagRepo = ds.getTransactionTagRepository(); TransactionTagRepository tagRepo = ds.getTransactionTagRepository();
AttachmentRepository attachmentRepo = ds.getAttachmentRepository(); AttachmentRepository attachmentRepo = ds.getAttachmentRepository();
@ -101,48 +101,70 @@ TransactionDetail updateTransaction(
// Update the transaction: // Update the transaction:
ds.doTransaction(() { ds.doTransaction(() {
TransactionDetail curr = transactionRepo.update(transactionId, payload); TransactionDetail curr = transactionRepo.update(transactionId, payload);
bool amountOrCurrencyChanged = prev.amount != curr.amount || prev.currency.code != curr.currency.code; updateLinkedAccountJournalEntries(prev, curr, payload, ds, timestamp);
bool updateCreditEntry = amountOrCurrencyChanged || (
prev.creditedAccount != curr.creditedAccount
);
bool updateDebitEntry = amountOrCurrencyChanged || (
prev.debitedAccount != curr.debitedAccount
);
// Update journal entries if necessary:
if (updateCreditEntry && !prev.creditedAccount.isNull) {
jeRepo.deleteByAccountIdAndTransactionId(prev.creditedAccount.get.id, transactionId);
}
if (updateCreditEntry && !curr.creditedAccount.isNull) {
jeRepo.insert(
timestamp,
curr.creditedAccount.get.id,
transactionId,
curr.amount,
AccountJournalEntryType.CREDIT,
curr.currency
);
}
if (updateDebitEntry && !prev.debitedAccount.isNull) {
jeRepo.deleteByAccountIdAndTransactionId(prev.debitedAccount.get.id, transactionId);
}
if (updateDebitEntry && !curr.debitedAccount.isNull) {
jeRepo.insert(
timestamp,
curr.debitedAccount.get.id,
transactionId,
curr.amount,
AccountJournalEntryType.DEBIT,
curr.currency
);
}
tagRepo.updateTags(transactionId, payload.tags); tagRepo.updateTags(transactionId, payload.tags);
updateAttachments(curr.id, timestamp, payload.attachmentIdsToRemove, files, attachmentRepo, transactionRepo); updateAttachments(curr.id, timestamp, payload.attachmentIdsToRemove, files, attachmentRepo, transactionRepo);
}); });
return getTransaction(ds, transactionId); return getTransaction(ds, transactionId);
} }
private void updateLinkedAccountJournalEntries(
in TransactionDetail prev,
in TransactionDetail curr,
in AddTransactionPayload payload,
ProfileDataSource ds,
in SysTime timestamp
) {
AccountJournalEntryRepository jeRepo = ds.getAccountJournalEntryRepository();
const bool amountOrCurrencyChanged = prev.amount != curr.amount || prev.currency.code != curr.currency.code;
const bool updateCreditEntry = amountOrCurrencyChanged || (
(prev.creditedAccount.isNull && !payload.creditedAccountId.isNull) ||
(!prev.creditedAccount.isNull && payload.creditedAccountId.isNull) ||
(
!prev.creditedAccount.isNull &&
!payload.creditedAccountId.isNull &&
prev.creditedAccount.get.id != payload.creditedAccountId.get
)
);
const bool updateDebitEntry = amountOrCurrencyChanged || (
(prev.debitedAccount.isNull && !payload.creditedAccountId.isNull) ||
(!prev.debitedAccount.isNull && payload.debitedAccountId.isNull) ||
(
!prev.debitedAccount.isNull &&
!payload.debitedAccountId.isNull &&
prev.debitedAccount.get.id != payload.debitedAccountId.get
)
);
// Update journal entries if necessary:
if (updateCreditEntry && !prev.creditedAccount.isNull) {
jeRepo.deleteByAccountIdAndTransactionId(prev.creditedAccount.get.id, prev.id);
}
if (updateCreditEntry && !payload.creditedAccountId.isNull) {
jeRepo.insert(
timestamp,
payload.creditedAccountId.get,
curr.id,
curr.amount,
AccountJournalEntryType.CREDIT,
curr.currency
);
}
if (updateDebitEntry && !prev.debitedAccount.isNull) {
jeRepo.deleteByAccountIdAndTransactionId(prev.debitedAccount.get.id, prev.id);
}
if (updateDebitEntry && !payload.debitedAccountId.isNull) {
jeRepo.insert(
timestamp,
payload.debitedAccountId.get,
curr.id,
curr.amount,
AccountJournalEntryType.DEBIT,
curr.currency
);
}
}
void deleteTransaction(ProfileDataSource ds, ulong transactionId) { void deleteTransaction(ProfileDataSource ds, ulong transactionId) {
TransactionRepository txnRepo = ds.getTransactionRepository(); TransactionRepository txnRepo = ds.getTransactionRepository();
AttachmentRepository attachmentRepo = ds.getAttachmentRepository(); AttachmentRepository attachmentRepo = ds.getAttachmentRepository();