module transaction.service; import handy_httpd.components.optional; import std.datetime; import transaction.model; import transaction.data; import profile.data; import util.money; import account.model; 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 // TODO: Add attachments and tags! ) { if (creditedAccountId.isNull && debitedAccountId.isNull) { throw new Exception("At least one account must be linked to a transaction."); } ds.doTransaction(() { 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 ); } }); }