blob: 5c6f77f3559efcb51501ecc9ae2c217dacf618dc [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 org.apache.fineract.cn.cheque;
import com.google.common.collect.Sets;
import org.apache.fineract.cn.cheque.api.v1.EventConstants;
import org.apache.fineract.cn.cheque.api.v1.domain.Action;
import org.apache.fineract.cn.cheque.api.v1.domain.Cheque;
import org.apache.fineract.cn.cheque.api.v1.domain.ChequeProcessingCommand;
import org.apache.fineract.cn.cheque.api.v1.domain.ChequeTransaction;
import org.apache.fineract.cn.cheque.api.v1.domain.IssuingCount;
import org.apache.fineract.cn.cheque.api.v1.domain.State;
import org.apache.fineract.cn.cheque.service.internal.format.MICRParser;
import org.apache.fineract.cn.cheque.service.internal.service.helper.AccountingService;
import org.apache.fineract.cn.cheque.service.internal.service.helper.DepositService;
import org.apache.fineract.cn.cheque.service.internal.service.helper.OrganizationService;
import java.util.Collections;
import java.util.Optional;
import java.util.UUID;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.fineract.cn.accounting.api.v1.domain.Account;
import org.apache.fineract.cn.accounting.api.v1.domain.Creditor;
import org.apache.fineract.cn.accounting.api.v1.domain.Debtor;
import org.apache.fineract.cn.accounting.api.v1.domain.JournalEntry;
import org.junit.Assert;
import org.junit.Test;
import org.mockito.Matchers;
import org.mockito.Mockito;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.validation.BeanPropertyBindingResult;
import org.springframework.validation.Validator;
public class TestCheques extends AbstractChequeTest {
@MockBean
private OrganizationService organizationServiceSpy;
@MockBean
private DepositService depositServiceSpy;
@MockBean
private AccountingService accountingServiceSpy;
@Autowired
private Validator validator;
public TestCheques() {
super();
}
@Test
public void shouldProcessChequeOnUs() throws Exception {
final Cheque randomCheque = Fixture.createRandomCheque();
final IssuingCount issuingCount = new IssuingCount();
issuingCount.setAccountIdentifier(randomCheque.getMicr().getAccountNumber());
issuingCount.setAmount(100);
Mockito
.doAnswer(invocation -> Collections.emptyList())
.when(this.depositServiceSpy).getIssueChequeCharges(randomCheque.getMicr().getAccountNumber());
super.chequeManager.issue(issuingCount);
Assert.assertTrue(
super.eventRecorder.wait(EventConstants.ISSUE_CHEQUES, randomCheque.getMicr().getAccountNumber())
);
Mockito
.doAnswer(invocation -> true)
.when(this.organizationServiceSpy).officeExistsByBranchSortCode(randomCheque.getMicr().getBranchSortCode());
Mockito
.doAnswer(invocation -> true)
.when(this.accountingServiceSpy).accountExists(randomCheque.getMicr().getAccountNumber());
final Account mockedAccount = new Account();
mockedAccount.setIdentifier(randomCheque.getMicr().getAccountNumber());
Mockito
.doAnswer(invocation -> Optional.of(mockedAccount))
.when(this.accountingServiceSpy).findAccount(randomCheque.getMicr().getAccountNumber());
final ChequeTransaction chequeTransaction = new ChequeTransaction();
chequeTransaction.setCheque(randomCheque);
chequeTransaction.setChequesReceivableAccount(RandomStringUtils.randomAlphabetic(34));
chequeTransaction.setCreditorAccountNumber(RandomStringUtils.randomAlphanumeric(34));
super.chequeManager.process(chequeTransaction);
Assert.assertTrue(
super.eventRecorder.wait(EventConstants.CHEQUE_TRANSACTION, MICRParser.toIdentifier(randomCheque.getMicr()))
);
final Cheque fetchedCheque = super.chequeManager.get(MICRParser.toIdentifier(randomCheque.getMicr()));
Assert.assertNotNull(fetchedCheque);
Assert.assertEquals(State.PROCESSED.name(), fetchedCheque.getState());
Mockito
.verify(this.accountingServiceSpy, Mockito.times(1))
.processJournalEntry(Matchers.any(JournalEntry.class));
}
@Test
public void shouldApproveChequeNotOnUs() throws Exception {
final Cheque randomCheque = Fixture.createRandomCheque();
Mockito
.doAnswer(invocation -> false)
.when(this.organizationServiceSpy).officeExistsByBranchSortCode(randomCheque.getMicr().getBranchSortCode());
Mockito
.doAnswer(invocation -> false)
.when(this.accountingServiceSpy).accountExists(randomCheque.getMicr().getAccountNumber());
final ChequeTransaction chequeTransaction = new ChequeTransaction();
chequeTransaction.setCheque(randomCheque);
chequeTransaction.setChequesReceivableAccount(RandomStringUtils.randomAlphabetic(34));
chequeTransaction.setCreditorAccountNumber(RandomStringUtils.randomAlphanumeric(34));
super.chequeManager.process(chequeTransaction);
Assert.assertTrue(
super.eventRecorder.wait(EventConstants.CHEQUE_TRANSACTION, MICRParser.toIdentifier(randomCheque.getMicr()))
);
final Cheque fetchedCheque = super.chequeManager.get(MICRParser.toIdentifier(randomCheque.getMicr()));
Assert.assertNotNull(fetchedCheque);
Assert.assertEquals(State.PENDING.name(), fetchedCheque.getState());
final ChequeProcessingCommand chequeProcessingCommand = new ChequeProcessingCommand();
chequeProcessingCommand.setAction(Action.APPROVE.name());
super.chequeManager.process(MICRParser.toIdentifier(fetchedCheque.getMicr()), chequeProcessingCommand);
Assert.assertTrue(
super.eventRecorder.wait(EventConstants.CHEQUE_TRANSACTION_APPROVED,
MICRParser.toIdentifier(fetchedCheque.getMicr()))
);
final Cheque approvedCheque = super.chequeManager.get(MICRParser.toIdentifier(randomCheque.getMicr()));
Assert.assertNotNull(approvedCheque);
Assert.assertEquals(State.PROCESSED.name(), approvedCheque.getState());
Mockito
.verify(this.accountingServiceSpy, Mockito.times(1))
.processJournalEntry(Matchers.any(JournalEntry.class));
}
@Test
public void shouldCancelChequeNotOnUs() throws Exception {
final Cheque randomCheque = Fixture.createRandomCheque();
Mockito
.doAnswer(invocation -> false)
.when(this.organizationServiceSpy).officeExistsByBranchSortCode(randomCheque.getMicr().getBranchSortCode());
Mockito
.doAnswer(invocation -> false)
.when(this.accountingServiceSpy).accountExists(randomCheque.getMicr().getAccountNumber());
final ChequeTransaction chequeTransaction = new ChequeTransaction();
chequeTransaction.setChequesReceivableAccount(RandomStringUtils.randomAlphabetic(34));
chequeTransaction.setCheque(randomCheque);
chequeTransaction.setCreditorAccountNumber(RandomStringUtils.randomAlphanumeric(34));
super.chequeManager.process(chequeTransaction);
Assert.assertTrue(
super.eventRecorder.wait(EventConstants.CHEQUE_TRANSACTION, MICRParser.toIdentifier(randomCheque.getMicr()))
);
final Cheque fetchedCheque = super.chequeManager.get(MICRParser.toIdentifier(randomCheque.getMicr()));
Assert.assertNotNull(fetchedCheque);
Assert.assertEquals(State.PENDING.name(), fetchedCheque.getState());
final ChequeProcessingCommand chequeProcessingCommand = new ChequeProcessingCommand();
chequeProcessingCommand.setAction(Action.CANCEL.name());
Mockito
.doAnswer(invocation -> {
final JournalEntry journalEntry = new JournalEntry();
journalEntry.setTransactionIdentifier(UUID.randomUUID().toString());
final Debtor debtor = new Debtor();
debtor.setAccountNumber(RandomStringUtils.randomAlphanumeric(34));
debtor.setAmount("100.00");
journalEntry.setDebtors(Sets.newHashSet(debtor));
final Creditor creditor = new Creditor();
creditor.setAccountNumber(RandomStringUtils.randomAlphanumeric(34));
creditor.setAmount("100.00");
journalEntry.setCreditors(Sets.newHashSet(creditor));
return journalEntry;
})
.when(this.accountingServiceSpy).findJournalEntry(Matchers.anyString());
super.chequeManager.process(MICRParser.toIdentifier(fetchedCheque.getMicr()), chequeProcessingCommand);
Assert.assertTrue(
super.eventRecorder.wait(EventConstants.CHEQUE_TRANSACTION_CANCELED,
MICRParser.toIdentifier(fetchedCheque.getMicr()))
);
final Cheque canceledCheque = super.chequeManager.get(MICRParser.toIdentifier(randomCheque.getMicr()));
Assert.assertNotNull(canceledCheque);
Assert.assertEquals(State.CANCELED.name(), canceledCheque.getState());
Mockito
.verify(this.accountingServiceSpy, Mockito.times(2))
.processJournalEntry(Matchers.any(JournalEntry.class));
}
@Test
public void shouldProcessOpenCheque() throws Exception {
final Cheque randomCheque = Fixture.createRandomCheque();
randomCheque.setOpenCheque(Boolean.TRUE);
Mockito
.doAnswer(invocation -> false)
.when(this.organizationServiceSpy).officeExistsByBranchSortCode(randomCheque.getMicr().getBranchSortCode());
Mockito
.doAnswer(invocation -> false)
.when(this.accountingServiceSpy).accountExists(randomCheque.getMicr().getAccountNumber());
Mockito.doAnswer(invocation -> {
final JournalEntry journalEntry = invocation.getArgument(0);
final BeanPropertyBindingResult bindingResult = new BeanPropertyBindingResult(journalEntry, "journalEntry");
this.validator.validate(journalEntry, bindingResult);
if (bindingResult.getErrorCount() != 0) {
bindingResult.getAllErrors().forEach(objectError -> {
System.out.println(objectError.toString());
});
}
return invocation.getMethod().getReturnType();
}).when(this.accountingServiceSpy).processJournalEntry(Matchers.any(JournalEntry.class));
final ChequeTransaction chequeTransaction = new ChequeTransaction();
chequeTransaction.setChequesReceivableAccount(RandomStringUtils.randomAlphabetic(34));
chequeTransaction.setCheque(randomCheque);
chequeTransaction.setCreditorAccountNumber(RandomStringUtils.randomAlphanumeric(34));
super.chequeManager.process(chequeTransaction);
Assert.assertTrue(
super.eventRecorder.wait(EventConstants.CHEQUE_TRANSACTION, MICRParser.toIdentifier(randomCheque.getMicr()))
);
}
}