| /* |
| * Copyright 2017 The Mifos Initiative. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package io.mifos.portfolio; |
| |
| import io.mifos.accounting.api.v1.client.LedgerManager; |
| import io.mifos.accounting.api.v1.domain.*; |
| import io.mifos.core.api.util.NotFoundException; |
| import io.mifos.core.lang.DateConverter; |
| import io.mifos.core.lang.TenantContextHolder; |
| import io.mifos.individuallending.api.v1.domain.workflow.Action; |
| import io.mifos.portfolio.service.internal.util.AccountingListener; |
| import org.hamcrest.Description; |
| import org.junit.Assert; |
| import org.mockito.AdditionalMatchers; |
| import org.mockito.ArgumentMatcher; |
| import org.mockito.Matchers; |
| import org.mockito.Mockito; |
| import org.mockito.invocation.InvocationOnMock; |
| import org.mockito.stubbing.Answer; |
| |
| import javax.validation.Validation; |
| import javax.validation.Validator; |
| import java.math.BigDecimal; |
| import java.time.LocalDateTime; |
| import java.util.*; |
| import java.util.stream.Collectors; |
| import java.util.stream.IntStream; |
| import java.util.stream.Stream; |
| |
| import static org.mockito.Matchers.argThat; |
| |
| /** |
| * @author Myrle Krantz |
| */ |
| @SuppressWarnings("Duplicates") |
| class AccountingFixture { |
| private static final LocalDateTime universalCreationDate = LocalDateTime.of(2017, 7, 18, 15, 16, 43, 10); |
| private static final String INCOME_LEDGER_IDENTIFIER = "1000"; |
| private static final String LOAN_INCOME_LEDGER_IDENTIFIER = "1100"; |
| private static final String FEES_AND_CHARGES_LEDGER_IDENTIFIER = "1300"; |
| private static final String ASSET_LEDGER_IDENTIFIER = "7000"; |
| private static final String CASH_LEDGER_IDENTIFIER = "7300"; |
| static final String CUSTOMER_LOAN_LEDGER_IDENTIFIER = "7353"; |
| private static final String ACCRUED_INCOME_LEDGER_IDENTIFIER = "7800"; |
| |
| static final String LOAN_FUNDS_SOURCE_ACCOUNT_IDENTIFIER = "7310"; |
| static final String LOAN_ORIGINATION_FEES_ACCOUNT_IDENTIFIER = "1310"; |
| static final String PROCESSING_FEE_INCOME_ACCOUNT_IDENTIFIER = "1312"; |
| static final String DISBURSEMENT_FEE_INCOME_ACCOUNT_IDENTIFIER = "1313"; |
| static final String TELLER_ONE_ACCOUNT_IDENTIFIER = "7352"; |
| static final String LOAN_INTEREST_ACCRUAL_ACCOUNT_IDENTIFIER = "7810"; |
| static final String CONSUMER_LOAN_INTEREST_ACCOUNT_IDENTIFIER = "1103"; |
| static final String LATE_FEE_INCOME_ACCOUNT_IDENTIFIER = "1311"; |
| static final String LATE_FEE_ACCRUAL_ACCOUNT_IDENTIFIER = "7840"; |
| static final String ARREARS_ALLOWANCE_ACCOUNT_IDENTIFIER = "3010"; |
| |
| static final Map<String, AccountData> accountMap = new HashMap<>(); |
| |
| private static class AccountData { |
| final Account account; |
| final List<AccountEntry> accountEntries = new ArrayList<>(); |
| |
| AccountData(final Account account) { |
| this.account = account; |
| } |
| |
| void setBalance(final double balance) { |
| this.account.setBalance(balance); |
| } |
| |
| synchronized void addAccountEntry(final String message, final String date, final double amount) { |
| final AccountEntry accountEntry = new AccountEntry(); |
| accountEntry.setAmount(amount); |
| accountEntry.setMessage(message); |
| accountEntry.setTransactionDate(date); |
| accountEntries.add(accountEntry); |
| } |
| |
| synchronized List<AccountEntry> copyAccountEntries() { |
| return new ArrayList<>(accountEntries); |
| } |
| } |
| |
| private static void makeAccountResponsive(final Account account, final LocalDateTime creationDate, final LedgerManager ledgerManagerMock) { |
| account.setCreatedOn(DateConverter.toIsoString(creationDate)); |
| final AccountData accountData = new AccountData(account); |
| accountMap.put(account.getIdentifier(), accountData); |
| Mockito.doAnswer(new AccountEntriesStreamAnswer(accountData)) |
| .when(ledgerManagerMock) |
| .fetchAccountEntriesStream(Mockito.eq(account.getIdentifier()), Matchers.anyString(), Matchers.anyString(), AdditionalMatchers.or(Matchers.eq("DESC"), Matchers.eq("ASC"))); |
| } |
| |
| private static void makeLedgerResponsive( |
| final Ledger ledger, |
| final LedgerManager ledgerManagerMock) |
| { |
| Mockito.doReturn(ledger).when(ledgerManagerMock).findLedger(ledger.getIdentifier()); |
| Mockito.doReturn(emptyAccountsPage()).when(ledgerManagerMock).fetchAccountsOfLedger(Mockito.eq(ledger.getIdentifier()), |
| Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any()); |
| } |
| |
| |
| private static Ledger cashLedger() { |
| final Ledger ret = new Ledger(); |
| ret.setIdentifier(CASH_LEDGER_IDENTIFIER); |
| ret.setParentLedgerIdentifier(ASSET_LEDGER_IDENTIFIER); |
| ret.setType(AccountType.ASSET.name()); |
| ret.setCreatedOn(DateConverter.toIsoString(universalCreationDate)); |
| return ret; |
| } |
| |
| private static Ledger incomeLedger() { |
| final Ledger ret = new Ledger(); |
| ret.setIdentifier(INCOME_LEDGER_IDENTIFIER); |
| ret.setType(AccountType.REVENUE.name()); |
| ret.setCreatedOn(DateConverter.toIsoString(universalCreationDate)); |
| return ret; |
| } |
| |
| private static Ledger feesAndChargesLedger() { |
| final Ledger ret = new Ledger(); |
| ret.setIdentifier(FEES_AND_CHARGES_LEDGER_IDENTIFIER); |
| ret.setParentLedgerIdentifier(INCOME_LEDGER_IDENTIFIER); |
| ret.setType(AccountType.REVENUE.name()); |
| ret.setCreatedOn(DateConverter.toIsoString(universalCreationDate)); |
| return ret; |
| } |
| |
| private static Ledger customerLoanLedger() { |
| final Ledger ret = new Ledger(); |
| ret.setIdentifier(CUSTOMER_LOAN_LEDGER_IDENTIFIER); |
| ret.setParentLedgerIdentifier(CASH_LEDGER_IDENTIFIER); |
| ret.setType(AccountType.ASSET.name()); |
| ret.setCreatedOn(DateConverter.toIsoString(universalCreationDate)); |
| return ret; |
| } |
| |
| private static Ledger loanIncomeLedger() { |
| final Ledger ret = new Ledger(); |
| ret.setIdentifier(LOAN_INCOME_LEDGER_IDENTIFIER); |
| ret.setParentLedgerIdentifier(INCOME_LEDGER_IDENTIFIER); |
| ret.setType(AccountType.REVENUE.name()); |
| ret.setCreatedOn(DateConverter.toIsoString(universalCreationDate)); |
| return ret; |
| |
| } |
| |
| private static Ledger accruedIncomeLedger() { |
| final Ledger ret = new Ledger(); |
| ret.setIdentifier(ACCRUED_INCOME_LEDGER_IDENTIFIER); |
| ret.setParentLedgerIdentifier(ASSET_LEDGER_IDENTIFIER); |
| ret.setType(AccountType.ASSET.name()); |
| ret.setCreatedOn(DateConverter.toIsoString(universalCreationDate)); |
| return ret; |
| |
| } |
| |
| private static Account loanFundsSourceAccount() { |
| final Account ret = new Account(); |
| ret.setIdentifier(LOAN_FUNDS_SOURCE_ACCOUNT_IDENTIFIER); |
| ret.setLedger(CASH_LEDGER_IDENTIFIER); |
| ret.setType(AccountType.ASSET.name()); |
| return ret; |
| } |
| |
| private static Account processingFeeIncomeAccount() { |
| final Account ret = new Account(); |
| ret.setIdentifier(PROCESSING_FEE_INCOME_ACCOUNT_IDENTIFIER); |
| ret.setLedger(FEES_AND_CHARGES_LEDGER_IDENTIFIER); |
| ret.setType(AccountType.REVENUE.name()); |
| return ret; |
| } |
| |
| private static Account loanOriginationFeesIncomeAccount() { |
| final Account ret = new Account(); |
| ret.setIdentifier(LOAN_ORIGINATION_FEES_ACCOUNT_IDENTIFIER); |
| ret.setLedger(FEES_AND_CHARGES_LEDGER_IDENTIFIER); |
| ret.setType(AccountType.REVENUE.name()); |
| return ret; |
| } |
| |
| private static Account disbursementFeeIncomeAccount() { |
| final Account ret = new Account(); |
| ret.setIdentifier(DISBURSEMENT_FEE_INCOME_ACCOUNT_IDENTIFIER); |
| ret.setLedger(FEES_AND_CHARGES_LEDGER_IDENTIFIER); |
| ret.setType(AccountType.REVENUE.name()); |
| return ret; |
| } |
| |
| private static Account tellerOneAccount() { |
| final Account ret = new Account(); |
| ret.setIdentifier(TELLER_ONE_ACCOUNT_IDENTIFIER); |
| ret.setLedger(CASH_LEDGER_IDENTIFIER); |
| ret.setType(AccountType.ASSET.name()); |
| return ret; |
| } |
| |
| private static Account loanInterestAccrualAccount() { |
| final Account ret = new Account(); |
| ret.setIdentifier(LOAN_INTEREST_ACCRUAL_ACCOUNT_IDENTIFIER); |
| ret.setLedger(ACCRUED_INCOME_LEDGER_IDENTIFIER); |
| ret.setType(AccountType.ASSET.name()); |
| return ret; |
| } |
| |
| private static Account consumerLoanInterestAccount() { |
| final Account ret = new Account(); |
| ret.setIdentifier(CONSUMER_LOAN_INTEREST_ACCOUNT_IDENTIFIER); |
| ret.setLedger(LOAN_INCOME_LEDGER_IDENTIFIER); |
| ret.setType(AccountType.REVENUE.name()); |
| return ret; |
| } |
| |
| private static Account lateFeeIncomeAccount() { |
| final Account ret = new Account(); |
| ret.setIdentifier(LATE_FEE_INCOME_ACCOUNT_IDENTIFIER); |
| ret.setLedger(FEES_AND_CHARGES_LEDGER_IDENTIFIER); |
| ret.setType(AccountType.REVENUE.name()); |
| return ret; |
| } |
| |
| private static Account lateFeeAccrualAccount() { |
| final Account ret = new Account(); |
| ret.setIdentifier(LATE_FEE_ACCRUAL_ACCOUNT_IDENTIFIER); |
| ret.setLedger(ACCRUED_INCOME_LEDGER_IDENTIFIER); |
| ret.setType(AccountType.REVENUE.name()); |
| return ret; |
| } |
| |
| private static Account arrearsAllowanceAccount() { |
| final Account ret = new Account(); |
| ret.setIdentifier(ARREARS_ALLOWANCE_ACCOUNT_IDENTIFIER); |
| //ret.setGroup(LOAN_INCOME_LEDGER_IDENTIFIER); //TODO: ?? |
| ret.setType(AccountType.LIABILITY.name()); //TODO: ?? |
| return ret; |
| } |
| |
| private static AccountPage customerLoanAccountsPage() { |
| final Account customerLoanAccount1 = new Account(); |
| customerLoanAccount1.setIdentifier("customerLoanAccount1"); |
| final Account customerLoanAccount2 = new Account(); |
| customerLoanAccount2.setIdentifier("customerLoanAccount2"); |
| final Account customerLoanAccount3 = new Account(); |
| customerLoanAccount3.setIdentifier("customerLoanAccount3"); |
| |
| final AccountPage ret = new AccountPage(); |
| ret.setTotalElements(3L); |
| ret.setTotalPages(1); |
| ret.setAccounts(Arrays.asList(customerLoanAccount1, customerLoanAccount2, customerLoanAccount3)); |
| return ret; |
| } |
| |
| private static AccountPage emptyAccountsPage() { |
| final AccountPage ret = new AccountPage(); |
| ret.setTotalElements(0L); |
| ret.setTotalPages(1); |
| ret.setAccounts(Collections.emptyList()); |
| return ret; |
| } |
| |
| private static <T> Valid<T> isValid() { |
| return new Valid<>(); |
| } |
| |
| private static class Valid<T> extends ArgumentMatcher<T> { |
| @Override |
| public boolean matches(final Object argument) { |
| if (argument == null) |
| return false; |
| final Validator validator = Validation.buildDefaultValidatorFactory().getValidator(); |
| final Set errors = validator.validate(argument); |
| |
| return errors.size() == 0; |
| } |
| } |
| |
| private static class AccountMatcher extends ArgumentMatcher<Account> { |
| private final String ledgerIdentifer; |
| private final String accountDesignator; |
| private final AccountType type; |
| private Account matchedArgument; |
| |
| private AccountMatcher( |
| final String ledgerIdentifier, |
| final String accountDesignator, |
| final AccountType type) { |
| this.ledgerIdentifer = ledgerIdentifier; |
| this.accountDesignator = accountDesignator; |
| this.type = type; |
| this.matchedArgument = null; //Set when matches called and returns true. |
| } |
| |
| @Override |
| public boolean matches(final Object argument) { |
| if (argument == null) |
| return false; |
| if (! (argument instanceof Account)) |
| return false; |
| |
| final Account checkedArgument = (Account) argument; |
| |
| final boolean ret = checkedArgument.getLedger().equals(ledgerIdentifer) && |
| checkedArgument.getIdentifier().contains(accountDesignator) && |
| checkedArgument.getType().equals(type.name()) && |
| checkedArgument.getBalance() == 0.0; |
| |
| if (ret) |
| matchedArgument = checkedArgument; |
| |
| return ret; |
| } |
| |
| @Override |
| public void describeTo(final Description description) { |
| description.appendText(this.toString()); |
| } |
| |
| Account getMatchedArgument() { |
| return matchedArgument; |
| } |
| |
| @Override |
| public String toString() { |
| return "AccountMatcher{" + |
| "ledgerIdentifer='" + ledgerIdentifer + '\'' + |
| ", accountDesignator='" + accountDesignator + '\'' + |
| ", type=" + type + |
| '}'; |
| } |
| } |
| |
| private static class LedgerMatcher extends ArgumentMatcher<Ledger> { |
| private final String ledgerIdentifer; |
| private final AccountType type; |
| private Ledger matchedArgument; |
| |
| LedgerMatcher(String ledgerIdentifier, AccountType type) { |
| this.ledgerIdentifer = ledgerIdentifier; |
| this.type = type; |
| this.matchedArgument = null; //Set when matches called and returns true. |
| } |
| |
| @Override |
| public boolean matches(final Object argument) { |
| if (argument == null) |
| return false; |
| if (! (argument instanceof Ledger)) |
| return false; |
| |
| final Ledger checkedArgument = (Ledger) argument; |
| |
| final Validator validator = Validation.buildDefaultValidatorFactory().getValidator(); |
| final Set errors = validator.validate(checkedArgument); |
| |
| Assert.assertEquals(0, errors.size()); |
| |
| final boolean ret = checkedArgument.getParentLedgerIdentifier().equals(ledgerIdentifer) && |
| checkedArgument.getType().equals(type.name()); |
| |
| if (ret) |
| matchedArgument = checkedArgument; |
| |
| return ret; |
| } |
| |
| @Override |
| public void describeTo(final Description description) { |
| description.appendText(this.toString()); |
| } |
| |
| Ledger getMatchedArgument() { |
| return matchedArgument; |
| } |
| |
| @Override |
| public String toString() { |
| return "LedgerMatcher{" + |
| "ledgerIdentifer='" + ledgerIdentifer + '\'' + |
| ", type=" + type + |
| '}'; |
| } |
| } |
| |
| private static class JournalEntryMatcher extends ArgumentMatcher<JournalEntry> { |
| private final Set<Debtor> debtors; |
| private final Set<Creditor> creditors; |
| private final String transactionPrefix; |
| private JournalEntry checkedArgument; |
| |
| private JournalEntryMatcher(final Set<Debtor> debtors, |
| final Set<Creditor> creditors, |
| final String productIdentifier, |
| final String caseIdentifier, |
| final Action action) { |
| this.debtors = debtors; |
| this.creditors = creditors; |
| this.checkedArgument = null; //Set when matches called. |
| this.transactionPrefix = "portfolio." + productIdentifier + "." + caseIdentifier + "." + action.name(); |
| } |
| |
| @Override |
| public boolean matches(final Object argument) { |
| if (argument == null) |
| return false; |
| if (! (argument instanceof JournalEntry)) |
| return false; |
| |
| checkedArgument = (JournalEntry) argument; |
| |
| return this.debtors.equals(checkedArgument.getDebtors()) && |
| this.creditors.equals(checkedArgument.getCreditors()) && |
| checkedArgument.getTransactionIdentifier().startsWith(transactionPrefix); |
| } |
| |
| @Override |
| public void describeTo(final Description description) { |
| description.appendText(this.toString()); |
| } |
| |
| @Override |
| public String toString() { |
| return "JournalEntryMatcher{" + |
| "debtors=" + debtors + |
| ", creditors=" + creditors + |
| '}'; |
| } |
| } |
| |
| private static class CreateJournalEntryAnswer implements Answer { |
| @Override |
| public Void answer(final InvocationOnMock invocation) throws Throwable { |
| final JournalEntry journalEntry = invocation.getArgumentAt(0, JournalEntry.class); |
| journalEntry.getCreditors().forEach(creditor -> |
| accountMap.get(creditor.getAccountNumber()).addAccountEntry( |
| journalEntry.getMessage(), |
| journalEntry.getTransactionDate(), |
| Double.valueOf(creditor.getAmount()))); |
| journalEntry.getDebtors().forEach(debtor -> |
| accountMap.get(debtor.getAccountNumber()).addAccountEntry( |
| journalEntry.getMessage(), |
| journalEntry.getTransactionDate(), |
| Double.valueOf(debtor.getAmount()))); |
| return null; |
| } |
| } |
| |
| private static class FindAccountAnswer implements Answer { |
| @Override |
| public Account answer(final InvocationOnMock invocation) throws Throwable { |
| final String identifier = invocation.getArgumentAt(0, String.class); |
| final AccountData ret = accountMap.get(identifier); |
| if (ret != null) |
| return ret.account; |
| else |
| throw new NotFoundException("Account '" + identifier + "' not found."); |
| } |
| } |
| |
| private static class CreateAccountAnswer implements Answer { |
| @Override |
| public Void answer(final InvocationOnMock invocation) throws Throwable { |
| final Account account = invocation.getArgumentAt(0, Account.class); |
| makeAccountResponsive(account, LocalDateTime.now(), (LedgerManager) invocation.getMock()); |
| return null; |
| } |
| } |
| |
| private static class CreateLedgerAnswer implements Answer { |
| private final AccountingListener accountingListener; |
| |
| CreateLedgerAnswer(AccountingListener accountingListener) { |
| this.accountingListener = accountingListener; |
| } |
| |
| @Override |
| public Void answer(final InvocationOnMock invocation) throws Throwable { |
| final Ledger ledger = invocation.getArgumentAt(0, Ledger.class); |
| makeLedgerResponsive(ledger, (LedgerManager) invocation.getMock()); |
| accountingListener.onPostLedger(TenantContextHolder.checkedGetIdentifier(), ledger.getIdentifier()); |
| return null; |
| } |
| } |
| |
| static class AccountEntriesStreamAnswer implements Answer { |
| private final AccountData accountData; |
| |
| AccountEntriesStreamAnswer(final AccountData accountData) { |
| this.accountData = accountData; |
| } |
| |
| @Override |
| public Stream<AccountEntry> answer(final InvocationOnMock invocation) throws Throwable { |
| final String message = invocation.getArgumentAt(2, String.class); |
| final String direction = invocation.getArgumentAt(3, String.class); |
| final boolean asc = direction == null || direction.equals("ASC"); |
| final List<AccountEntry> accountEntries = accountData.copyAccountEntries(); |
| final int entryCount = accountEntries.size(); |
| final Stream<AccountEntry> orderedCorrectly = asc ? |
| IntStream.rangeClosed(1, entryCount).mapToObj(i -> accountEntries.get(entryCount - i)) : |
| accountEntries.stream(); |
| |
| if (message != null) { |
| return orderedCorrectly.filter(x -> x.getMessage().equals(message)); |
| } |
| else { |
| return orderedCorrectly; |
| } |
| } |
| } |
| |
| static void mockAccountingPrereqs(final LedgerManager ledgerManagerMock, final AccountingListener accountingListener) { |
| makeAccountResponsive(loanFundsSourceAccount(), universalCreationDate, ledgerManagerMock); |
| makeAccountResponsive(loanOriginationFeesIncomeAccount(), universalCreationDate, ledgerManagerMock); |
| makeAccountResponsive(processingFeeIncomeAccount(), universalCreationDate, ledgerManagerMock); |
| makeAccountResponsive(disbursementFeeIncomeAccount(), universalCreationDate, ledgerManagerMock); |
| makeAccountResponsive(tellerOneAccount(), universalCreationDate, ledgerManagerMock); |
| makeAccountResponsive(loanInterestAccrualAccount(), universalCreationDate, ledgerManagerMock); |
| makeAccountResponsive(consumerLoanInterestAccount(), universalCreationDate, ledgerManagerMock); |
| makeAccountResponsive(lateFeeIncomeAccount(), universalCreationDate, ledgerManagerMock); |
| makeAccountResponsive(lateFeeAccrualAccount(), universalCreationDate, ledgerManagerMock); |
| makeAccountResponsive(arrearsAllowanceAccount(), universalCreationDate, ledgerManagerMock); |
| |
| Mockito.doReturn(incomeLedger()).when(ledgerManagerMock).findLedger(INCOME_LEDGER_IDENTIFIER); |
| Mockito.doReturn(feesAndChargesLedger()).when(ledgerManagerMock).findLedger(FEES_AND_CHARGES_LEDGER_IDENTIFIER); |
| Mockito.doReturn(cashLedger()).when(ledgerManagerMock).findLedger(CASH_LEDGER_IDENTIFIER); |
| Mockito.doReturn(customerLoanLedger()).when(ledgerManagerMock).findLedger(CUSTOMER_LOAN_LEDGER_IDENTIFIER); |
| Mockito.doReturn(loanIncomeLedger()).when(ledgerManagerMock).findLedger(LOAN_INCOME_LEDGER_IDENTIFIER); |
| Mockito.doReturn(accruedIncomeLedger()).when(ledgerManagerMock).findLedger(ACCRUED_INCOME_LEDGER_IDENTIFIER); |
| Mockito.doReturn(customerLoanAccountsPage()).when(ledgerManagerMock).fetchAccountsOfLedger(Mockito.eq(CUSTOMER_LOAN_LEDGER_IDENTIFIER), |
| Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any()); |
| |
| Mockito.doAnswer(new FindAccountAnswer()).when(ledgerManagerMock).findAccount(Matchers.anyString()); |
| Mockito.doAnswer(new CreateAccountAnswer()).when(ledgerManagerMock).createAccount(Matchers.any()); |
| Mockito.doAnswer(new CreateJournalEntryAnswer()).when(ledgerManagerMock).createJournalEntry(Matchers.any(JournalEntry.class)); |
| Mockito.doAnswer(new CreateLedgerAnswer(accountingListener)).when(ledgerManagerMock).createLedger(Matchers.any(Ledger.class)); |
| } |
| |
| static void mockBalance(final String accountIdentifier, final BigDecimal balance) { |
| accountMap.get(accountIdentifier).setBalance(balance.doubleValue()); |
| } |
| |
| static String verifyAccountCreationMatchingDesignator( |
| final LedgerManager ledgerManager, |
| final String ledgerIdentifier, |
| final String accountDesignator, |
| final AccountType type) { |
| final AccountMatcher specifiesCorrectAccount = new AccountMatcher(ledgerIdentifier, accountDesignator, type); |
| Mockito.verify(ledgerManager).createAccount(AdditionalMatchers.and(argThat(isValid()), argThat(specifiesCorrectAccount))); |
| return specifiesCorrectAccount.getMatchedArgument().getIdentifier(); |
| } |
| |
| static String verifyLedgerCreation( |
| final LedgerManager ledgerManager, |
| final String ledgerIdentifier, |
| final AccountType type) { |
| final LedgerMatcher specifiesCorrectLedger = new LedgerMatcher(ledgerIdentifier, type); |
| Mockito.verify(ledgerManager).createLedger(AdditionalMatchers.and(argThat(isValid()), argThat(specifiesCorrectLedger))); |
| makeLedgerResponsive(specifiesCorrectLedger.getMatchedArgument(), ledgerManager); |
| return specifiesCorrectLedger.getMatchedArgument().getIdentifier(); |
| } |
| |
| static void verifyTransfer(final LedgerManager ledgerManager, |
| final Set<Debtor> debtors, |
| final Set<Creditor> creditors, |
| final String productIdentifier, |
| final String caseIdentifier, |
| final Action action) { |
| final Set<Debtor> filteredDebtors = debtors.stream().filter(x -> BigDecimal.valueOf(Double.valueOf(x.getAmount())).compareTo(BigDecimal.ZERO) != 0).collect(Collectors.toSet()); |
| final Set<Creditor> filteredCreditors = creditors.stream().filter(x -> BigDecimal.valueOf(Double.valueOf(x.getAmount())).compareTo(BigDecimal.ZERO) != 0).collect(Collectors.toSet()); |
| if (filteredCreditors.size() == 0 && filteredDebtors.size() == 0) |
| return; |
| final JournalEntryMatcher specifiesCorrectJournalEntry = new JournalEntryMatcher(filteredDebtors, filteredCreditors, productIdentifier, caseIdentifier, action); |
| Mockito.verify(ledgerManager, Mockito.atLeastOnce()).createJournalEntry(AdditionalMatchers.and(argThat(isValid()), argThat(specifiesCorrectJournalEntry))); |
| |
| } |
| } |