This is an automated email from the ASF dual-hosted git repository. myrle pushed a commit to branch develop in repository https://gitbox.apache.org/repos/asf/fineract-cn-accounting.git
commit 7443f9e9dd63ef4f2aba91729e5a1e97a98720ef Author: mgeiss <[email protected]> AuthorDate: Mon Sep 4 19:44:45 2017 +0200 added ability to search journal entries by account and amount validate that debtors and creditors for a journal entry are set --- .../accounting/api/v1/client/LedgerManager.java | 24 ++- .../main/java/io/mifos/accounting/TestAccount.java | 14 +- .../java/io/mifos/accounting/TestJournalEntry.java | 212 ++++++++++++++++++++- .../accounting/util/JournalEntryGenerator.java | 25 ++- .../mifos/accounting/importer/AccountImporter.java | 7 +- .../internal/repository/JournalEntryEntity.java | 2 - .../repository/JournalEntryRepository.java | 14 +- .../service/internal/service/AccountService.java | 13 +- .../internal/service/JournalEntryService.java | 54 +++++- .../service/rest/AccountRestController.java | 22 ++- .../service/rest/JournalRestController.java | 22 ++- .../service/rest/LedgerRestController.java | 8 +- .../rest/TransactionTypeRestController.java | 8 +- 13 files changed, 388 insertions(+), 37 deletions(-) diff --git a/api/src/main/java/io/mifos/accounting/api/v1/client/LedgerManager.java b/api/src/main/java/io/mifos/accounting/api/v1/client/LedgerManager.java index 0859281..62e10a3 100644 --- a/api/src/main/java/io/mifos/accounting/api/v1/client/LedgerManager.java +++ b/api/src/main/java/io/mifos/accounting/api/v1/client/LedgerManager.java @@ -15,16 +15,32 @@ */ package io.mifos.accounting.api.v1.client; -import io.mifos.accounting.api.v1.domain.*; +import io.mifos.accounting.api.v1.domain.Account; +import io.mifos.accounting.api.v1.domain.AccountCommand; +import io.mifos.accounting.api.v1.domain.AccountEntry; +import io.mifos.accounting.api.v1.domain.AccountEntryPage; +import io.mifos.accounting.api.v1.domain.AccountPage; +import io.mifos.accounting.api.v1.domain.ChartOfAccountEntry; +import io.mifos.accounting.api.v1.domain.JournalEntry; +import io.mifos.accounting.api.v1.domain.Ledger; +import io.mifos.accounting.api.v1.domain.LedgerPage; +import io.mifos.accounting.api.v1.domain.TransactionType; +import io.mifos.accounting.api.v1.domain.TransactionTypePage; +import io.mifos.accounting.api.v1.domain.TrialBalance; import io.mifos.core.api.annotation.ThrowsException; import io.mifos.core.api.annotation.ThrowsExceptions; import io.mifos.core.api.util.CustomFeignClientsConfiguration; import org.springframework.cloud.netflix.feign.FeignClient; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; import javax.validation.Valid; +import java.math.BigDecimal; import java.util.Collections; import java.util.List; import java.util.stream.Stream; @@ -260,7 +276,9 @@ public interface LedgerManager { produces = {MediaType.ALL_VALUE}, consumes = {MediaType.APPLICATION_JSON_VALUE} ) - List<JournalEntry> fetchJournalEntries(@RequestParam(value = "dateRange", required = false) final String dateRange); + List<JournalEntry> fetchJournalEntries(@RequestParam(value = "dateRange", required = false) final String dateRange, + @RequestParam(value = "account", required = false) final String accountNumber, + @RequestParam(value = "amount", required = false) final BigDecimal amount); @RequestMapping( value = "/journal/{transactionIdentifier}", diff --git a/component-test/src/main/java/io/mifos/accounting/TestAccount.java b/component-test/src/main/java/io/mifos/accounting/TestAccount.java index 3a425bb..63bae84 100644 --- a/component-test/src/main/java/io/mifos/accounting/TestAccount.java +++ b/component-test/src/main/java/io/mifos/accounting/TestAccount.java @@ -19,7 +19,13 @@ import io.mifos.accounting.api.v1.EventConstants; import io.mifos.accounting.api.v1.client.AccountAlreadyExistsException; import io.mifos.accounting.api.v1.client.AccountNotFoundException; import io.mifos.accounting.api.v1.client.AccountReferenceException; -import io.mifos.accounting.api.v1.domain.*; +import io.mifos.accounting.api.v1.domain.Account; +import io.mifos.accounting.api.v1.domain.AccountCommand; +import io.mifos.accounting.api.v1.domain.AccountEntry; +import io.mifos.accounting.api.v1.domain.AccountPage; +import io.mifos.accounting.api.v1.domain.AccountType; +import io.mifos.accounting.api.v1.domain.JournalEntry; +import io.mifos.accounting.api.v1.domain.Ledger; import io.mifos.accounting.util.AccountGenerator; import io.mifos.accounting.util.JournalEntryGenerator; import io.mifos.accounting.util.LedgerGenerator; @@ -30,7 +36,11 @@ import org.junit.Test; import java.time.Clock; import java.time.LocalDate; -import java.util.*; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Optional; +import java.util.Set; import java.util.stream.Collectors; import java.util.stream.Stream; diff --git a/component-test/src/main/java/io/mifos/accounting/TestJournalEntry.java b/component-test/src/main/java/io/mifos/accounting/TestJournalEntry.java index ccf7d04..2f49c4f 100644 --- a/component-test/src/main/java/io/mifos/accounting/TestJournalEntry.java +++ b/component-test/src/main/java/io/mifos/accounting/TestJournalEntry.java @@ -16,7 +16,12 @@ package io.mifos.accounting; import io.mifos.accounting.api.v1.EventConstants; -import io.mifos.accounting.api.v1.domain.*; +import io.mifos.accounting.api.v1.client.JournalEntryValidationException; +import io.mifos.accounting.api.v1.domain.Account; +import io.mifos.accounting.api.v1.domain.AccountEntryPage; +import io.mifos.accounting.api.v1.domain.AccountType; +import io.mifos.accounting.api.v1.domain.JournalEntry; +import io.mifos.accounting.api.v1.domain.Ledger; import io.mifos.accounting.util.AccountGenerator; import io.mifos.accounting.util.JournalEntryGenerator; import io.mifos.accounting.util.LedgerGenerator; @@ -25,6 +30,7 @@ import org.apache.commons.lang.RandomStringUtils; import org.junit.Assert; import org.junit.Test; +import java.math.BigDecimal; import java.text.MessageFormat; import java.time.LocalDate; import java.time.OffsetDateTime; @@ -33,6 +39,7 @@ import java.time.format.DateTimeFormatter; import java.util.List; public class TestJournalEntry extends AbstractAccountingTest { + @Test public void shouldCreateJournalEntry() throws Exception { final Ledger assetLedger = LedgerGenerator.createRandomLedger(); @@ -126,13 +133,214 @@ public class TestJournalEntry extends AbstractAccountingTest { DateConverter.toIsoString(beginDate), DateConverter.toIsoString(endDate)); - final List<JournalEntry> journalEntries = this.testSubject.fetchJournalEntries(dateRange); + final List<JournalEntry> journalEntries = this.testSubject.fetchJournalEntries(dateRange, null, null); + + Assert.assertTrue(journalEntries.size() >= 2); + + checkAccountEntries(debtorAccount, creditorAccount, journalEntryOne, journalEntryTwo, dateRange); + } + + @Test + public void shouldFetchJournalEntriesWithDateRangeAndAccount() throws Exception{ + final Ledger assetLedger = LedgerGenerator.createRandomLedger(); + assetLedger.setType(AccountType.ASSET.name()); + this.testSubject.createLedger(assetLedger); + this.eventRecorder.wait(EventConstants.POST_LEDGER, assetLedger.getIdentifier()); + + final Account debtorAccount = AccountGenerator.createRandomAccount(assetLedger.getIdentifier()); + debtorAccount.setType(AccountType.ASSET.name()); + debtorAccount.setBalance(100.00D); + this.testSubject.createAccount(debtorAccount); + this.eventRecorder.wait(EventConstants.POST_ACCOUNT, debtorAccount.getIdentifier()); + + final Ledger liabilityLedger = LedgerGenerator.createRandomLedger(); + liabilityLedger.setType(AccountType.LIABILITY.name()); + this.testSubject.createLedger(liabilityLedger); + this.eventRecorder.wait(EventConstants.POST_LEDGER, liabilityLedger.getIdentifier()); + + final Account creditorAccount = AccountGenerator.createRandomAccount(liabilityLedger.getIdentifier()); + creditorAccount.setType(AccountType.LIABILITY.name()); + creditorAccount.setBalance(100.00D); + this.testSubject.createAccount(creditorAccount); + this.eventRecorder.wait(EventConstants.POST_ACCOUNT, creditorAccount.getIdentifier()); + + final JournalEntry journalEntryOne = JournalEntryGenerator.createRandomJournalEntry(debtorAccount, "50.00", + creditorAccount, "50.00"); + final OffsetDateTime start = OffsetDateTime.of(1982, 6, 24, 1, 0, 0, 0, ZoneOffset.UTC); + journalEntryOne.setTransactionDate(start.format(DateTimeFormatter.ISO_ZONED_DATE_TIME)); + + this.testSubject.createJournalEntry(journalEntryOne); + this.eventRecorder.wait(EventConstants.POST_JOURNAL_ENTRY, journalEntryOne.getTransactionIdentifier()); + this.eventRecorder.wait(EventConstants.RELEASE_JOURNAL_ENTRY, journalEntryOne.getTransactionIdentifier()); + + final JournalEntry journalEntryTwo = JournalEntryGenerator.createRandomJournalEntry(debtorAccount, "50.00", + creditorAccount, "50.00"); + final OffsetDateTime end = OffsetDateTime.of(1982, 6, 26, 1, 0, 0, 0, ZoneOffset.UTC); + journalEntryTwo.setTransactionDate(end.format(DateTimeFormatter.ISO_ZONED_DATE_TIME)); + + this.testSubject.createJournalEntry(journalEntryTwo); + this.eventRecorder.wait(EventConstants.POST_JOURNAL_ENTRY, journalEntryTwo.getTransactionIdentifier()); + this.eventRecorder.wait(EventConstants.RELEASE_JOURNAL_ENTRY, journalEntryTwo.getTransactionIdentifier()); + + final LocalDate beginDate = LocalDate.of(1982, 6, 24); + final LocalDate endDate = LocalDate.of(1982, 6, 26); + final String dateRange = MessageFormat.format("{0}..{1}", + DateConverter.toIsoString(beginDate), + DateConverter.toIsoString(endDate)); + + final List<JournalEntry> journalEntries = this.testSubject.fetchJournalEntries(dateRange, debtorAccount.getIdentifier(), null); Assert.assertEquals(2, journalEntries.size()); checkAccountEntries(debtorAccount, creditorAccount, journalEntryOne, journalEntryTwo, dateRange); } + @Test + public void shouldFetchJournalEntriesWithDateRangeAndAmount() throws Exception{ + final Ledger assetLedger = LedgerGenerator.createRandomLedger(); + assetLedger.setType(AccountType.ASSET.name()); + this.testSubject.createLedger(assetLedger); + this.eventRecorder.wait(EventConstants.POST_LEDGER, assetLedger.getIdentifier()); + + final Account debtorAccount = AccountGenerator.createRandomAccount(assetLedger.getIdentifier()); + debtorAccount.setType(AccountType.ASSET.name()); + debtorAccount.setBalance(100.00D); + this.testSubject.createAccount(debtorAccount); + this.eventRecorder.wait(EventConstants.POST_ACCOUNT, debtorAccount.getIdentifier()); + + final Ledger liabilityLedger = LedgerGenerator.createRandomLedger(); + liabilityLedger.setType(AccountType.LIABILITY.name()); + this.testSubject.createLedger(liabilityLedger); + this.eventRecorder.wait(EventConstants.POST_LEDGER, liabilityLedger.getIdentifier()); + + final Account creditorAccount = AccountGenerator.createRandomAccount(liabilityLedger.getIdentifier()); + creditorAccount.setType(AccountType.LIABILITY.name()); + creditorAccount.setBalance(100.00D); + this.testSubject.createAccount(creditorAccount); + this.eventRecorder.wait(EventConstants.POST_ACCOUNT, creditorAccount.getIdentifier()); + + final JournalEntry journalEntryOne = JournalEntryGenerator.createRandomJournalEntry(debtorAccount, "50.00", + creditorAccount, "50.00"); + final OffsetDateTime start = OffsetDateTime.of(1982, 6, 24, 1, 0, 0, 0, ZoneOffset.UTC); + journalEntryOne.setTransactionDate(start.format(DateTimeFormatter.ISO_ZONED_DATE_TIME)); + + this.testSubject.createJournalEntry(journalEntryOne); + this.eventRecorder.wait(EventConstants.POST_JOURNAL_ENTRY, journalEntryOne.getTransactionIdentifier()); + this.eventRecorder.wait(EventConstants.RELEASE_JOURNAL_ENTRY, journalEntryOne.getTransactionIdentifier()); + + final JournalEntry journalEntryTwo = JournalEntryGenerator.createRandomJournalEntry(debtorAccount, "50.00", + creditorAccount, "50.00"); + final OffsetDateTime end = OffsetDateTime.of(1982, 6, 26, 1, 0, 0, 0, ZoneOffset.UTC); + journalEntryTwo.setTransactionDate(end.format(DateTimeFormatter.ISO_ZONED_DATE_TIME)); + + this.testSubject.createJournalEntry(journalEntryTwo); + this.eventRecorder.wait(EventConstants.POST_JOURNAL_ENTRY, journalEntryTwo.getTransactionIdentifier()); + this.eventRecorder.wait(EventConstants.RELEASE_JOURNAL_ENTRY, journalEntryTwo.getTransactionIdentifier()); + + final LocalDate beginDate = LocalDate.of(1982, 6, 24); + final LocalDate endDate = LocalDate.of(1982, 6, 26); + final String dateRange = MessageFormat.format("{0}..{1}", + DateConverter.toIsoString(beginDate), + DateConverter.toIsoString(endDate)); + + final List<JournalEntry> journalEntries = this.testSubject.fetchJournalEntries(dateRange, null, BigDecimal.valueOf(50.00D)); + + Assert.assertEquals(2, journalEntries.size()); + + checkAccountEntries(debtorAccount, creditorAccount, journalEntryOne, journalEntryTwo, dateRange); + } + + @Test + public void shouldFetchJournalEntriesWithDateRangeAndAccountAndAmount() throws Exception{ + final Ledger assetLedger = LedgerGenerator.createRandomLedger(); + assetLedger.setType(AccountType.ASSET.name()); + this.testSubject.createLedger(assetLedger); + this.eventRecorder.wait(EventConstants.POST_LEDGER, assetLedger.getIdentifier()); + + final Account debtorAccount = AccountGenerator.createRandomAccount(assetLedger.getIdentifier()); + debtorAccount.setType(AccountType.ASSET.name()); + debtorAccount.setBalance(100.00D); + this.testSubject.createAccount(debtorAccount); + this.eventRecorder.wait(EventConstants.POST_ACCOUNT, debtorAccount.getIdentifier()); + + final Ledger liabilityLedger = LedgerGenerator.createRandomLedger(); + liabilityLedger.setType(AccountType.LIABILITY.name()); + this.testSubject.createLedger(liabilityLedger); + this.eventRecorder.wait(EventConstants.POST_LEDGER, liabilityLedger.getIdentifier()); + + final Account creditorAccount = AccountGenerator.createRandomAccount(liabilityLedger.getIdentifier()); + creditorAccount.setType(AccountType.LIABILITY.name()); + creditorAccount.setBalance(100.00D); + this.testSubject.createAccount(creditorAccount); + this.eventRecorder.wait(EventConstants.POST_ACCOUNT, creditorAccount.getIdentifier()); + + final JournalEntry journalEntryOne = JournalEntryGenerator.createRandomJournalEntry(debtorAccount, "50.00", + creditorAccount, "50.00"); + final OffsetDateTime start = OffsetDateTime.of(1982, 6, 24, 1, 0, 0, 0, ZoneOffset.UTC); + journalEntryOne.setTransactionDate(start.format(DateTimeFormatter.ISO_ZONED_DATE_TIME)); + + this.testSubject.createJournalEntry(journalEntryOne); + this.eventRecorder.wait(EventConstants.POST_JOURNAL_ENTRY, journalEntryOne.getTransactionIdentifier()); + this.eventRecorder.wait(EventConstants.RELEASE_JOURNAL_ENTRY, journalEntryOne.getTransactionIdentifier()); + + final JournalEntry journalEntryTwo = JournalEntryGenerator.createRandomJournalEntry(debtorAccount, "50.00", + creditorAccount, "50.00"); + final OffsetDateTime end = OffsetDateTime.of(1982, 6, 26, 1, 0, 0, 0, ZoneOffset.UTC); + journalEntryTwo.setTransactionDate(end.format(DateTimeFormatter.ISO_ZONED_DATE_TIME)); + + this.testSubject.createJournalEntry(journalEntryTwo); + this.eventRecorder.wait(EventConstants.POST_JOURNAL_ENTRY, journalEntryTwo.getTransactionIdentifier()); + this.eventRecorder.wait(EventConstants.RELEASE_JOURNAL_ENTRY, journalEntryTwo.getTransactionIdentifier()); + + final LocalDate beginDate = LocalDate.of(1982, 6, 24); + final LocalDate endDate = LocalDate.of(1982, 6, 26); + final String dateRange = MessageFormat.format("{0}..{1}", + DateConverter.toIsoString(beginDate), + DateConverter.toIsoString(endDate)); + + final List<JournalEntry> journalEntries = this.testSubject.fetchJournalEntries(dateRange, creditorAccount.getIdentifier(), BigDecimal.valueOf(50.00D)); + + Assert.assertEquals(2, journalEntries.size()); + + checkAccountEntries(debtorAccount, creditorAccount, journalEntryOne, journalEntryTwo, dateRange); + } + + @Test(expected = JournalEntryValidationException.class) + public void shouldNotCreateJournalEntryMissingDebtors() throws Exception { + final Ledger liabilityLedger = LedgerGenerator.createRandomLedger(); + liabilityLedger.setType(AccountType.LIABILITY.name()); + this.testSubject.createLedger(liabilityLedger); + this.eventRecorder.wait(EventConstants.POST_LEDGER, liabilityLedger.getIdentifier()); + + final Account creditorAccount = AccountGenerator.createRandomAccount(liabilityLedger.getIdentifier()); + creditorAccount.setType(AccountType.LIABILITY.name()); + creditorAccount.setBalance(100.00D); + this.testSubject.createAccount(creditorAccount); + this.eventRecorder.wait(EventConstants.POST_ACCOUNT, creditorAccount.getIdentifier()); + + final JournalEntry journalEntry = JournalEntryGenerator.createRandomJournalEntry(null, null, + creditorAccount, "50.00"); + this.testSubject.createJournalEntry(journalEntry); + } + + @Test(expected = JournalEntryValidationException.class) + public void shouldNotCreateJournalEntryMissingCreditors() throws Exception { + final Ledger assetLedger = LedgerGenerator.createRandomLedger(); + assetLedger.setType(AccountType.ASSET.name()); + this.testSubject.createLedger(assetLedger); + this.eventRecorder.wait(EventConstants.POST_LEDGER, assetLedger.getIdentifier()); + + final Account debtorAccount = AccountGenerator.createRandomAccount(assetLedger.getIdentifier()); + debtorAccount.setType(AccountType.ASSET.name()); + debtorAccount.setBalance(100.00D); + this.testSubject.createAccount(debtorAccount); + this.eventRecorder.wait(EventConstants.POST_ACCOUNT, debtorAccount.getIdentifier()); + + final JournalEntry journalEntry = JournalEntryGenerator.createRandomJournalEntry(debtorAccount, "50.00", + null, null); + this.testSubject.createJournalEntry(journalEntry); + } + private void checkAccountEntries( final Account debtorAccount, final Account creditorAccount, diff --git a/component-test/src/main/java/io/mifos/accounting/util/JournalEntryGenerator.java b/component-test/src/main/java/io/mifos/accounting/util/JournalEntryGenerator.java index 32067ea..1a3a4e5 100644 --- a/component-test/src/main/java/io/mifos/accounting/util/JournalEntryGenerator.java +++ b/component-test/src/main/java/io/mifos/accounting/util/JournalEntryGenerator.java @@ -15,6 +15,7 @@ */ package io.mifos.accounting.util; +import com.google.common.collect.Sets; import io.mifos.accounting.api.v1.domain.Account; import io.mifos.accounting.api.v1.domain.Creditor; import io.mifos.accounting.api.v1.domain.Debtor; @@ -42,14 +43,22 @@ public class JournalEntryGenerator { journalEntry.setTransactionDate(ZonedDateTime.now(Clock.systemUTC()).format(DateTimeFormatter.ISO_ZONED_DATE_TIME)); journalEntry.setTransactionType(RandomStringUtils.randomAlphabetic(4)); journalEntry.setClerk("clark"); - final Debtor debtor = new Debtor(); - debtor.setAccountNumber(debtorAccount.getIdentifier()); - debtor.setAmount(debtorAmount); - journalEntry.setDebtors(new HashSet<>(Collections.singletonList(debtor))); - final Creditor creditor = new Creditor(); - creditor.setAccountNumber(creditorAccount.getIdentifier()); - creditor.setAmount(creditorAmount); - journalEntry.setCreditors(new HashSet<>(Collections.singletonList(creditor))); + if (debtorAccount != null) { + final Debtor debtor = new Debtor(); + debtor.setAccountNumber(debtorAccount.getIdentifier()); + debtor.setAmount(debtorAmount); + journalEntry.setDebtors(new HashSet<>(Collections.singletonList(debtor))); + } else { + journalEntry.setDebtors(Sets.newHashSet()); + } + if (creditorAccount != null) { + final Creditor creditor = new Creditor(); + creditor.setAccountNumber(creditorAccount.getIdentifier()); + creditor.setAmount(creditorAmount); + journalEntry.setCreditors(new HashSet<>(Collections.singletonList(creditor))); + } else { + journalEntry.setCreditors(Sets.newHashSet()); + } journalEntry.setNote(RandomStringUtils.randomAlphanumeric(512)); journalEntry.setMessage(RandomStringUtils.randomAlphanumeric(512)); return journalEntry; diff --git a/importer/src/main/java/io/mifos/accounting/importer/AccountImporter.java b/importer/src/main/java/io/mifos/accounting/importer/AccountImporter.java index 412f1aa..66766c3 100644 --- a/importer/src/main/java/io/mifos/accounting/importer/AccountImporter.java +++ b/importer/src/main/java/io/mifos/accounting/importer/AccountImporter.java @@ -27,7 +27,12 @@ import org.slf4j.Logger; import java.io.IOException; import java.net.URL; import java.nio.charset.StandardCharsets; -import java.util.*; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Objects; +import java.util.Set; import java.util.stream.Collectors; import java.util.stream.StreamSupport; diff --git a/service/src/main/java/io/mifos/accounting/service/internal/repository/JournalEntryEntity.java b/service/src/main/java/io/mifos/accounting/service/internal/repository/JournalEntryEntity.java index 557b1f6..e0fbdf8 100644 --- a/service/src/main/java/io/mifos/accounting/service/internal/repository/JournalEntryEntity.java +++ b/service/src/main/java/io/mifos/accounting/service/internal/repository/JournalEntryEntity.java @@ -20,9 +20,7 @@ import com.datastax.driver.mapping.annotations.Column; import com.datastax.driver.mapping.annotations.Frozen; import com.datastax.driver.mapping.annotations.PartitionKey; import com.datastax.driver.mapping.annotations.Table; -import io.mifos.core.mariadb.util.LocalDateTimeConverter; -import javax.persistence.Convert; import java.time.LocalDateTime; import java.util.Set; diff --git a/service/src/main/java/io/mifos/accounting/service/internal/repository/JournalEntryRepository.java b/service/src/main/java/io/mifos/accounting/service/internal/repository/JournalEntryRepository.java index 950b0f6..e0737a0 100644 --- a/service/src/main/java/io/mifos/accounting/service/internal/repository/JournalEntryRepository.java +++ b/service/src/main/java/io/mifos/accounting/service/internal/repository/JournalEntryRepository.java @@ -17,6 +17,8 @@ package io.mifos.accounting.service.internal.repository; import com.datastax.driver.core.ResultSet; import com.datastax.driver.core.Session; +import com.datastax.driver.core.SimpleStatement; +import com.datastax.driver.core.Statement; import com.datastax.driver.core.querybuilder.QueryBuilder; import com.datastax.driver.mapping.Mapper; import com.datastax.driver.mapping.Result; @@ -67,14 +69,16 @@ public class JournalEntryRepository { .map(DateConverter::toIsoString) .collect(Collectors.toList()); - final ResultSet resultSet = tenantSession.execute(QueryBuilder - .select() - .all() + final Statement stmt = new SimpleStatement( + QueryBuilder + .select().all() .from("thoth_journal_entries") - .where(QueryBuilder.in("date_bucket", datesInBetweenRange)) - .getQueryString(), datesInBetweenRange.toArray() + .where(QueryBuilder.in("date_bucket", datesInBetweenRange)).getQueryString(), + datesInBetweenRange.toArray() ); + final ResultSet resultSet = tenantSession.execute(stmt); + final Mapper<JournalEntryEntity> mapper = this.tenantAwareCassandraMapperProvider.getMapper(JournalEntryEntity.class); final Result<JournalEntryEntity> journalEntryEntities = mapper.map(resultSet); return journalEntryEntities.all(); diff --git a/service/src/main/java/io/mifos/accounting/service/internal/service/AccountService.java b/service/src/main/java/io/mifos/accounting/service/internal/service/AccountService.java index 70cdab3..8665f23 100644 --- a/service/src/main/java/io/mifos/accounting/service/internal/service/AccountService.java +++ b/service/src/main/java/io/mifos/accounting/service/internal/service/AccountService.java @@ -15,11 +15,20 @@ */ package io.mifos.accounting.service.internal.service; -import io.mifos.accounting.api.v1.domain.*; +import io.mifos.accounting.api.v1.domain.Account; +import io.mifos.accounting.api.v1.domain.AccountCommand; +import io.mifos.accounting.api.v1.domain.AccountEntry; +import io.mifos.accounting.api.v1.domain.AccountEntryPage; +import io.mifos.accounting.api.v1.domain.AccountPage; import io.mifos.accounting.service.internal.mapper.AccountCommandMapper; import io.mifos.accounting.service.internal.mapper.AccountEntryMapper; import io.mifos.accounting.service.internal.mapper.AccountMapper; -import io.mifos.accounting.service.internal.repository.*; +import io.mifos.accounting.service.internal.repository.AccountEntity; +import io.mifos.accounting.service.internal.repository.AccountEntryEntity; +import io.mifos.accounting.service.internal.repository.AccountEntryRepository; +import io.mifos.accounting.service.internal.repository.AccountRepository; +import io.mifos.accounting.service.internal.repository.CommandEntity; +import io.mifos.accounting.service.internal.repository.CommandRepository; import io.mifos.accounting.service.internal.repository.specification.AccountSpecification; import io.mifos.core.lang.DateRange; import org.springframework.beans.factory.annotation.Autowired; diff --git a/service/src/main/java/io/mifos/accounting/service/internal/service/JournalEntryService.java b/service/src/main/java/io/mifos/accounting/service/internal/service/JournalEntryService.java index a3f3caf..3f56da2 100644 --- a/service/src/main/java/io/mifos/accounting/service/internal/service/JournalEntryService.java +++ b/service/src/main/java/io/mifos/accounting/service/internal/service/JournalEntryService.java @@ -16,14 +16,23 @@ package io.mifos.accounting.service.internal.service; import io.mifos.accounting.api.v1.domain.JournalEntry; +import io.mifos.accounting.service.ServiceConstants; import io.mifos.accounting.service.internal.mapper.JournalEntryMapper; +import io.mifos.accounting.service.internal.repository.DebtorType; import io.mifos.accounting.service.internal.repository.JournalEntryEntity; import io.mifos.accounting.service.internal.repository.JournalEntryRepository; +import io.mifos.accounting.service.internal.repository.TransactionTypeEntity; +import io.mifos.accounting.service.internal.repository.TransactionTypeRepository; +import io.mifos.core.api.annotation.ThrowsException; import io.mifos.core.lang.DateRange; +import org.slf4j.Logger; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Service; +import java.math.BigDecimal; import java.util.Collections; +import java.util.HashMap; import java.util.List; import java.util.Optional; import java.util.stream.Collectors; @@ -31,22 +40,59 @@ import java.util.stream.Collectors; @Service public class JournalEntryService { + private Logger logger; private final JournalEntryRepository journalEntryRepository; + private final TransactionTypeRepository transactionTypeRepository; @Autowired - public JournalEntryService(final JournalEntryRepository journalEntryRepository) { + public JournalEntryService(@Qualifier(ServiceConstants.LOGGER_NAME) final Logger logger, + final JournalEntryRepository journalEntryRepository, + final TransactionTypeRepository transactionTypeRepository) { super(); + this.logger = logger; this.journalEntryRepository = journalEntryRepository; + this.transactionTypeRepository = transactionTypeRepository; } - public List<JournalEntry> fetchJournalEntries(final DateRange range) { + public List<JournalEntry> fetchJournalEntries(final DateRange range, final String accountNumber, final BigDecimal amount) { final List<JournalEntryEntity> journalEntryEntities = this.journalEntryRepository.fetchJournalEntries(range); if (journalEntryEntities != null) { - return journalEntryEntities + + final List<JournalEntryEntity> filteredList = + journalEntryEntities + .stream() + .filter(journalEntryEntity -> + accountNumber == null + || journalEntryEntity.getDebtors().stream() + .anyMatch(debtorType -> debtorType.getAccountNumber().equals(accountNumber)) + || journalEntryEntity.getCreditors().stream() + .anyMatch(creditorType -> creditorType.getAccountNumber().equals(accountNumber)) + ) + .filter(journalEntryEntity -> + amount == null + || amount.compareTo( + BigDecimal.valueOf( + journalEntryEntity.getDebtors().stream().mapToDouble(DebtorType::getAmount).sum() + ) + ) == 0 + ) + .collect(Collectors.toList()); + + final List<TransactionTypeEntity> transactionTypes = this.transactionTypeRepository.findAll(); + final HashMap<String, String> mappedTransactionTypes = new HashMap<>(transactionTypes.size()); + transactionTypes.forEach(transactionTypeEntity -> + mappedTransactionTypes.put(transactionTypeEntity.getIdentifier(), transactionTypeEntity.getName()) + ); + + return filteredList .stream() - .map(JournalEntryMapper::map) + .map(journalEntryEntity -> { + final JournalEntry journalEntry = JournalEntryMapper.map(journalEntryEntity); + journalEntry.setTransactionType(mappedTransactionTypes.get(journalEntry.getTransactionType())); + return journalEntry; + }) .collect(Collectors.toList()); } else { return Collections.emptyList(); diff --git a/service/src/main/java/io/mifos/accounting/service/rest/AccountRestController.java b/service/src/main/java/io/mifos/accounting/service/rest/AccountRestController.java index bd59e6e..00a7f74 100644 --- a/service/src/main/java/io/mifos/accounting/service/rest/AccountRestController.java +++ b/service/src/main/java/io/mifos/accounting/service/rest/AccountRestController.java @@ -17,8 +17,18 @@ package io.mifos.accounting.service.rest; import io.mifos.accounting.api.v1.PermittableGroupIds; import io.mifos.accounting.api.v1.client.AccountNotFoundException; -import io.mifos.accounting.api.v1.domain.*; -import io.mifos.accounting.service.internal.command.*; +import io.mifos.accounting.api.v1.domain.Account; +import io.mifos.accounting.api.v1.domain.AccountCommand; +import io.mifos.accounting.api.v1.domain.AccountEntryPage; +import io.mifos.accounting.api.v1.domain.AccountPage; +import io.mifos.accounting.api.v1.domain.Ledger; +import io.mifos.accounting.service.internal.command.CloseAccountCommand; +import io.mifos.accounting.service.internal.command.CreateAccountCommand; +import io.mifos.accounting.service.internal.command.DeleteAccountCommand; +import io.mifos.accounting.service.internal.command.LockAccountCommand; +import io.mifos.accounting.service.internal.command.ModifyAccountCommand; +import io.mifos.accounting.service.internal.command.ReopenAccountCommand; +import io.mifos.accounting.service.internal.command.UnlockAccountCommand; import io.mifos.accounting.service.internal.service.AccountService; import io.mifos.accounting.service.internal.service.LedgerService; import io.mifos.accounting.service.rest.paging.PageableBuilder; @@ -32,7 +42,13 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; import javax.annotation.Nullable; import javax.validation.Valid; diff --git a/service/src/main/java/io/mifos/accounting/service/rest/JournalRestController.java b/service/src/main/java/io/mifos/accounting/service/rest/JournalRestController.java index b476b01..56648ce 100644 --- a/service/src/main/java/io/mifos/accounting/service/rest/JournalRestController.java +++ b/service/src/main/java/io/mifos/accounting/service/rest/JournalRestController.java @@ -29,9 +29,16 @@ import io.mifos.core.lang.ServiceException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; import javax.validation.Valid; +import java.math.BigDecimal; import java.util.List; import java.util.Optional; @@ -62,6 +69,13 @@ public class JournalRestController { ) @ResponseBody ResponseEntity<Void> createJournalEntry(@RequestBody @Valid final JournalEntry journalEntry) { + if (journalEntry.getDebtors().size() == 0) { + throw ServiceException.badRequest("Debtors must be given."); + } + if (journalEntry.getCreditors().size() == 0) { + throw ServiceException.badRequest("Creditors must be given."); + } + final Double debtorAmountSum = journalEntry.getDebtors() .stream() .peek(debtor -> { @@ -107,11 +121,13 @@ public class JournalRestController { ) @ResponseBody ResponseEntity<List<JournalEntry>> fetchJournalEntries( - @RequestParam(value = "dateRange", required = false) final String dateRange + @RequestParam(value = "dateRange", required = false) final String dateRange, + @RequestParam(value = "account", required = false) final String accountNumber, + @RequestParam(value = "amount", required = false) final BigDecimal amount ) { final DateRange range = DateRange.fromIsoString(dateRange); - return ResponseEntity.ok(this.journalEntryService.fetchJournalEntries(range)); + return ResponseEntity.ok(this.journalEntryService.fetchJournalEntries(range, accountNumber, amount)); } @Permittable(value = AcceptedTokenType.TENANT, groupId = PermittableGroupIds.THOTH_JOURNAL) diff --git a/service/src/main/java/io/mifos/accounting/service/rest/LedgerRestController.java b/service/src/main/java/io/mifos/accounting/service/rest/LedgerRestController.java index c6523bf..28b1f60 100644 --- a/service/src/main/java/io/mifos/accounting/service/rest/LedgerRestController.java +++ b/service/src/main/java/io/mifos/accounting/service/rest/LedgerRestController.java @@ -32,7 +32,13 @@ import io.mifos.core.lang.ServiceException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; import javax.validation.Valid; import java.util.Optional; diff --git a/service/src/main/java/io/mifos/accounting/service/rest/TransactionTypeRestController.java b/service/src/main/java/io/mifos/accounting/service/rest/TransactionTypeRestController.java index 57e5045..be47cf9 100644 --- a/service/src/main/java/io/mifos/accounting/service/rest/TransactionTypeRestController.java +++ b/service/src/main/java/io/mifos/accounting/service/rest/TransactionTypeRestController.java @@ -29,7 +29,13 @@ import io.mifos.core.lang.ServiceException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; import javax.validation.Valid; -- To stop receiving notification emails like this one, please contact [email protected].
