added ceque receivable account for teller tx
diff --git a/api/src/main/java/io/mifos/teller/api/v1/domain/Teller.java b/api/src/main/java/io/mifos/teller/api/v1/domain/Teller.java
index dc59d4f..e807d85 100644
--- a/api/src/main/java/io/mifos/teller/api/v1/domain/Teller.java
+++ b/api/src/main/java/io/mifos/teller/api/v1/domain/Teller.java
@@ -38,10 +38,12 @@
@DecimalMin("0.00")
@DecimalMax("1000000000.00")
private BigDecimal cashdrawLimit;
- @ValidIdentifier
+ @ValidIdentifier(maxLength = 34)
private String tellerAccountIdentifier;
- @ValidIdentifier
+ @ValidIdentifier(maxLength = 34)
private String vaultAccountIdentifier;
+ @ValidIdentifier(maxLength = 34)
+ private String chequesReceivableAccount;
private String assignedEmployee;
private State state;
private String createdBy;
@@ -93,6 +95,14 @@
this.vaultAccountIdentifier = vaultAccountIdentifier;
}
+ public String getChequesReceivableAccount() {
+ return this.chequesReceivableAccount;
+ }
+
+ public void setChequesReceivableAccount(final String chequesReceivableAccount) {
+ this.chequesReceivableAccount = chequesReceivableAccount;
+ }
+
public String getAssignedEmployee() {
return this.assignedEmployee;
}
diff --git a/api/src/main/java/io/mifos/teller/api/v1/domain/TellerManagementCommand.java b/api/src/main/java/io/mifos/teller/api/v1/domain/TellerManagementCommand.java
index 387c4a3..f37bb9f 100644
--- a/api/src/main/java/io/mifos/teller/api/v1/domain/TellerManagementCommand.java
+++ b/api/src/main/java/io/mifos/teller/api/v1/domain/TellerManagementCommand.java
@@ -17,6 +17,7 @@
import io.mifos.core.lang.validation.constraints.ValidIdentifier;
+import javax.validation.constraints.DecimalMax;
import javax.validation.constraints.DecimalMin;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
@@ -39,6 +40,7 @@
@NotNull
private Adjustment adjustment;
@DecimalMin("0.00")
+ @DecimalMax("9999999999.99999")
private BigDecimal amount;
@ValidIdentifier(optional = true)
private String assignedEmployeeIdentifier;
diff --git a/api/src/main/java/io/mifos/teller/api/v1/domain/TellerTransaction.java b/api/src/main/java/io/mifos/teller/api/v1/domain/TellerTransaction.java
index 5079d01..9581f14 100644
--- a/api/src/main/java/io/mifos/teller/api/v1/domain/TellerTransaction.java
+++ b/api/src/main/java/io/mifos/teller/api/v1/domain/TellerTransaction.java
@@ -43,14 +43,14 @@
private String productIdentifier;
@ValidIdentifier(optional = true)
private String productCaseIdentifier;
- @ValidIdentifier
+ @ValidIdentifier(maxLength = 34)
private String customerAccountIdentifier;
- @ValidIdentifier(optional = true)
+ @ValidIdentifier(maxLength = 34, optional = true)
private String targetAccountIdentifier;
@ValidIdentifier
private String clerk;
@NotNull
- @DecimalMin(value = "0.001")
+ @DecimalMin(value = "0.000")
@DecimalMax(value = "9999999999.99999")
private BigDecimal amount;
private State state;
diff --git a/component-test/src/main/java/io/mifos/teller/TestTellerOperation.java b/component-test/src/main/java/io/mifos/teller/TestTellerOperation.java
index 39f8399..d3ac3f8 100644
--- a/component-test/src/main/java/io/mifos/teller/TestTellerOperation.java
+++ b/component-test/src/main/java/io/mifos/teller/TestTellerOperation.java
@@ -160,7 +160,75 @@
tellerTransaction.setCustomerAccountIdentifier(RandomStringUtils.randomAlphanumeric(32));
tellerTransaction.setCustomerIdentifier(RandomStringUtils.randomAlphanumeric(32));
tellerTransaction.setClerk(AbstractTellerTest.TEST_USER);
- tellerTransaction.setAmount(commonAmount);
+ tellerTransaction.setAmount(this.commonAmount);
+
+ final Account account = new Account();
+ account.setBalance(this.commonAmount.doubleValue());
+ account.setState(Account.State.OPEN.name());
+ Mockito.doAnswer(invocation -> Optional.of(account))
+ .when(super.accountingServiceSpy).findAccount(tellerTransaction.getCustomerAccountIdentifier());
+ Mockito.doAnswer(invocation -> Collections.emptyList())
+ .when(super.depositAccountManagementServiceSpy).getCharges(Matchers.eq(tellerTransaction));
+ Mockito.doAnswer(invocation -> Collections.emptyList())
+ .when(super.depositAccountManagementServiceSpy).fetchProductInstances(tellerTransaction.getCustomerIdentifier());
+
+ super.testSubject.post(teller.getCode(), tellerTransaction);
+ }
+
+ @Test
+ public void shouldCloseAccountZeroBalance() throws Exception {
+ final Teller teller = this.prepareTeller();
+
+ final UnlockDrawerCommand unlockDrawerCommand = new UnlockDrawerCommand();
+ unlockDrawerCommand.setEmployeeIdentifier(AbstractTellerTest.TEST_USER);
+ unlockDrawerCommand.setPassword(teller.getPassword());
+
+ super.testSubject.unlockDrawer(teller.getCode(), unlockDrawerCommand);
+
+ super.eventRecorder.wait(EventConstants.AUTHENTICATE_TELLER, teller.getCode());
+
+ final TellerTransaction tellerTransaction = new TellerTransaction();
+ tellerTransaction.setTransactionType(ServiceConstants.TX_CLOSE_ACCOUNT);
+ tellerTransaction.setTransactionDate(DateConverter.toIsoString(LocalDateTime.now(Clock.systemUTC())));
+ tellerTransaction.setProductIdentifier(RandomStringUtils.randomAlphanumeric(32));
+ tellerTransaction.setCustomerAccountIdentifier(RandomStringUtils.randomAlphanumeric(32));
+ tellerTransaction.setCustomerIdentifier(RandomStringUtils.randomAlphanumeric(32));
+ tellerTransaction.setClerk(AbstractTellerTest.TEST_USER);
+ tellerTransaction.setAmount(BigDecimal.ZERO);
+
+ final Account account = new Account();
+ account.setBalance(0.00D);
+ account.setState(Account.State.OPEN.name());
+ Mockito.doAnswer(invocation -> Optional.of(account))
+ .when(super.accountingServiceSpy).findAccount(tellerTransaction.getCustomerAccountIdentifier());
+ Mockito.doAnswer(invocation -> Collections.emptyList())
+ .when(super.depositAccountManagementServiceSpy).getCharges(Matchers.eq(tellerTransaction));
+ Mockito.doAnswer(invocation -> Collections.emptyList())
+ .when(super.depositAccountManagementServiceSpy).fetchProductInstances(tellerTransaction.getCustomerIdentifier());
+
+ super.testSubject.post(teller.getCode(), tellerTransaction);
+ }
+
+ @Test(expected = TransactionProcessingException.class)
+ public void shouldNotCloseAccountRemainingBalance() throws Exception {
+ final Teller teller = this.prepareTeller();
+
+ final UnlockDrawerCommand unlockDrawerCommand = new UnlockDrawerCommand();
+ unlockDrawerCommand.setEmployeeIdentifier(AbstractTellerTest.TEST_USER);
+ unlockDrawerCommand.setPassword(teller.getPassword());
+
+ super.testSubject.unlockDrawer(teller.getCode(), unlockDrawerCommand);
+
+ super.eventRecorder.wait(EventConstants.AUTHENTICATE_TELLER, teller.getCode());
+
+ final TellerTransaction tellerTransaction = new TellerTransaction();
+ tellerTransaction.setTransactionType(ServiceConstants.TX_CLOSE_ACCOUNT);
+ tellerTransaction.setTransactionDate(DateConverter.toIsoString(LocalDateTime.now(Clock.systemUTC())));
+ tellerTransaction.setProductIdentifier(RandomStringUtils.randomAlphanumeric(32));
+ tellerTransaction.setCustomerAccountIdentifier(RandomStringUtils.randomAlphanumeric(32));
+ tellerTransaction.setCustomerIdentifier(RandomStringUtils.randomAlphanumeric(32));
+ tellerTransaction.setClerk(AbstractTellerTest.TEST_USER);
+ tellerTransaction.setAmount(this.commonAmount);
final Account account = new Account();
account.setBalance(2000.00D);
diff --git a/component-test/src/main/java/io/mifos/teller/util/TellerGenerator.java b/component-test/src/main/java/io/mifos/teller/util/TellerGenerator.java
index 799f2b9..fbd029f 100644
--- a/component-test/src/main/java/io/mifos/teller/util/TellerGenerator.java
+++ b/component-test/src/main/java/io/mifos/teller/util/TellerGenerator.java
@@ -30,8 +30,9 @@
final Teller teller = new Teller();
teller.setCode(RandomStringUtils.randomAlphanumeric(32));
teller.setPassword(RandomStringUtils.randomAlphanumeric(12));
- teller.setTellerAccountIdentifier(RandomStringUtils.randomAlphanumeric(32));
- teller.setVaultAccountIdentifier(RandomStringUtils.randomAlphanumeric(32));
+ teller.setTellerAccountIdentifier(RandomStringUtils.randomAlphanumeric(34));
+ teller.setVaultAccountIdentifier(RandomStringUtils.randomAlphanumeric(34));
+ teller.setChequesReceivableAccount(RandomStringUtils.randomAlphanumeric(34));
teller.setCashdrawLimit(BigDecimal.valueOf(10000L));
return teller;
diff --git a/service/src/main/java/io/mifos/teller/service/internal/command/handler/TellerAggregate.java b/service/src/main/java/io/mifos/teller/service/internal/command/handler/TellerAggregate.java
index 67099ea..571b92f 100644
--- a/service/src/main/java/io/mifos/teller/service/internal/command/handler/TellerAggregate.java
+++ b/service/src/main/java/io/mifos/teller/service/internal/command/handler/TellerAggregate.java
@@ -124,6 +124,7 @@
tellerEntity.setTellerAccountIdentifier(teller.getTellerAccountIdentifier());
tellerEntity.setVaultAccountIdentifier(teller.getVaultAccountIdentifier());
+ tellerEntity.setChequesReceivableAccount(teller.getChequesReceivableAccount());
tellerEntity.setCashdrawLimit(teller.getCashdrawLimit());
tellerEntity.setLastModifiedBy(UserContextHolder.checkedGetUser());
tellerEntity.setLastModifiedOn(LocalDateTime.now(Clock.systemUTC()));
diff --git a/service/src/main/java/io/mifos/teller/service/internal/mapper/TellerMapper.java b/service/src/main/java/io/mifos/teller/service/internal/mapper/TellerMapper.java
index d1902a4..3ff7665 100644
--- a/service/src/main/java/io/mifos/teller/service/internal/mapper/TellerMapper.java
+++ b/service/src/main/java/io/mifos/teller/service/internal/mapper/TellerMapper.java
@@ -32,6 +32,7 @@
teller.setVaultAccountIdentifier(tellerEntity.getVaultAccountIdentifier());
teller.setCashdrawLimit(tellerEntity.getCashdrawLimit());
teller.setAssignedEmployee(tellerEntity.getAssignedEmployeeIdentifier());
+ teller.setChequesReceivableAccount(tellerEntity.getChequesReceivableAccount());
teller.setState(tellerEntity.getState());
if (tellerEntity.getCreatedBy() != null) {
teller.setCreatedBy(tellerEntity.getCreatedBy());
@@ -52,6 +53,7 @@
tellerEntity.setOfficeIdentifier(officeIdentifier);
tellerEntity.setTellerAccountIdentifier(teller.getTellerAccountIdentifier());
tellerEntity.setVaultAccountIdentifier(teller.getVaultAccountIdentifier());
+ tellerEntity.setChequesReceivableAccount(teller.getChequesReceivableAccount());
tellerEntity.setCashdrawLimit(teller.getCashdrawLimit());
tellerEntity.setAssignedEmployeeIdentifier(teller.getAssignedEmployee());
if (teller.getState() != null) {
diff --git a/service/src/main/java/io/mifos/teller/service/internal/processor/ChequeTransactionHandler.java b/service/src/main/java/io/mifos/teller/service/internal/processor/ChequeTransactionHandler.java
index 3951e0c..0456fa1 100644
--- a/service/src/main/java/io/mifos/teller/service/internal/processor/ChequeTransactionHandler.java
+++ b/service/src/main/java/io/mifos/teller/service/internal/processor/ChequeTransactionHandler.java
@@ -19,6 +19,7 @@
import io.mifos.teller.ServiceConstants;
import io.mifos.teller.api.v1.domain.TellerTransaction;
import io.mifos.teller.service.internal.mapper.ChequeMapper;
+import io.mifos.teller.service.internal.repository.TellerEntity;
import io.mifos.teller.service.internal.repository.TellerRepository;
import io.mifos.teller.service.internal.service.helper.ChequeService;
import org.slf4j.Logger;
@@ -26,6 +27,8 @@
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
+import java.util.Optional;
+
@Component
public class ChequeTransactionHandler {
@@ -42,8 +45,11 @@
this.tellerRepository = tellerRepository;
}
- public void processCheque(final TellerTransaction tellerTransaction) {
+ public void processCheque(final String tellerCode, final TellerTransaction tellerTransaction) {
+ final Optional<TellerEntity> optionalTeller = this.tellerRepository.findByIdentifier(tellerCode);
final ChequeTransaction chequeTransaction = new ChequeTransaction();
+ optionalTeller.ifPresent(tellerEntity ->
+ chequeTransaction.setChequesReceivableAccount(tellerEntity.getChequesReceivableAccount()));
chequeTransaction.setCreditorAccountNumber(tellerTransaction.getCustomerAccountIdentifier());
chequeTransaction.setCheque(ChequeMapper.map(tellerTransaction.getCheque()));
diff --git a/service/src/main/java/io/mifos/teller/service/internal/processor/TellerTransactionProcessor.java b/service/src/main/java/io/mifos/teller/service/internal/processor/TellerTransactionProcessor.java
index 48f5c38..efd6a69 100644
--- a/service/src/main/java/io/mifos/teller/service/internal/processor/TellerTransactionProcessor.java
+++ b/service/src/main/java/io/mifos/teller/service/internal/processor/TellerTransactionProcessor.java
@@ -64,7 +64,7 @@
this.portfolioTransactionHandler.processRepayment(tellerCode, tellerTransaction);
break;
case ServiceConstants.TX_CHEQUE:
- this.chequeTransactionHandler.processCheque(tellerTransaction);
+ this.chequeTransactionHandler.processCheque(tellerCode, tellerTransaction);
break;
default:
throw new IllegalArgumentException("Unsupported TX type " + tellerTransaction.getTransactionType());
diff --git a/service/src/main/java/io/mifos/teller/service/internal/repository/TellerEntity.java b/service/src/main/java/io/mifos/teller/service/internal/repository/TellerEntity.java
index 8cf0591..949abf1 100644
--- a/service/src/main/java/io/mifos/teller/service/internal/repository/TellerEntity.java
+++ b/service/src/main/java/io/mifos/teller/service/internal/repository/TellerEntity.java
@@ -45,10 +45,12 @@
private String officeIdentifier;
@Column(name = "cashdraw_limit", nullable = false)
private BigDecimal cashdrawLimit;
- @Column(name = "teller_account_identifier", nullable = false, length = 32)
+ @Column(name = "teller_account_identifier", nullable = false, length = 34)
private String tellerAccountIdentifier;
- @Column(name = "vault_account_identifier", nullable = false, length = 32)
+ @Column(name = "vault_account_identifier", nullable = false, length = 34)
private String vaultAccountIdentifier;
+ @Column(name = "cheques_receivable_account", nullable = false, length = 34)
+ private String chequesReceivableAccount;
@Column(name = "assigned_employee_identifier", nullable = true, length = 32)
private String assignedEmployeeIdentifier;
@Column(name = "a_state", nullable = false, length = 256)
@@ -132,6 +134,14 @@
this.vaultAccountIdentifier = vaultAccountIdentifier;
}
+ public String getChequesReceivableAccount() {
+ return this.chequesReceivableAccount;
+ }
+
+ public void setChequesReceivableAccount(final String chequesReceivableAccount) {
+ this.chequesReceivableAccount = chequesReceivableAccount;
+ }
+
public String getAssignedEmployeeIdentifier() {
return this.assignedEmployeeIdentifier;
}
diff --git a/service/src/main/java/io/mifos/teller/service/internal/service/helper/DepositAccountManagementService.java b/service/src/main/java/io/mifos/teller/service/internal/service/helper/DepositAccountManagementService.java
index 3c94a02..2d80e90 100644
--- a/service/src/main/java/io/mifos/teller/service/internal/service/helper/DepositAccountManagementService.java
+++ b/service/src/main/java/io/mifos/teller/service/internal/service/helper/DepositAccountManagementService.java
@@ -29,6 +29,8 @@
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
+import java.math.MathContext;
+import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -65,23 +67,28 @@
final HashMap<String, Action> mappedActions = new HashMap<>(actions.size());
actions.forEach(action -> mappedActions.put(action.getIdentifier(), action));
+ final MathContext mathContext = new MathContext(2, RoundingMode.HALF_EVEN);
final Set<io.mifos.deposit.api.v1.definition.domain.Charge> productCharges = productDefinition.getCharges();
productCharges.forEach(productCharge -> {
- final Action action = mappedActions.get(productCharge.getActionIdentifier());
- if (action != null
- && action.getTransactionType().equals(tellerTransaction.getTransactionType())) {
- final Charge charge = new Charge();
- charge.setCode(productCharge.getActionIdentifier());
- charge.setIncomeAccountIdentifier(productCharge.getIncomeAccountIdentifier());
- charge.setName(productCharge.getName());
- if (productCharge.getProportional()) {
- charge.setAmount(
- tellerTransaction.getAmount().divide(BigDecimal.valueOf(100)).multiply(BigDecimal.valueOf(productCharge.getAmount()))
- );
- } else {
- charge.setAmount(BigDecimal.valueOf(productCharge.getAmount()));
+ if (productCharge.getAmount() > 0.00D) {
+ final Action action = mappedActions.get(productCharge.getActionIdentifier());
+ if (action != null
+ && action.getTransactionType().equals(tellerTransaction.getTransactionType())) {
+ final Charge charge = new Charge();
+ charge.setCode(productCharge.getActionIdentifier());
+ charge.setIncomeAccountIdentifier(productCharge.getIncomeAccountIdentifier());
+ charge.setName(productCharge.getName());
+ if (productCharge.getProportional()) {
+ charge.setAmount(
+ tellerTransaction.getAmount().multiply(
+ BigDecimal.valueOf(productCharge.getAmount()).divide(BigDecimal.valueOf(100.00D), mathContext)
+ )
+ );
+ } else {
+ charge.setAmount(BigDecimal.valueOf(productCharge.getAmount()));
+ }
+ charges.add(charge);
}
- charges.add(charge);
}
});
return charges;
diff --git a/service/src/main/java/io/mifos/teller/service/rest/TellerOperationRestController.java b/service/src/main/java/io/mifos/teller/service/rest/TellerOperationRestController.java
index 0903f12..48ea9c0 100644
--- a/service/src/main/java/io/mifos/teller/service/rest/TellerOperationRestController.java
+++ b/service/src/main/java/io/mifos/teller/service/rest/TellerOperationRestController.java
@@ -20,6 +20,7 @@
import io.mifos.anubis.annotation.Permittable;
import io.mifos.core.api.util.UserContextHolder;
import io.mifos.core.command.gateway.CommandGateway;
+import io.mifos.core.lang.DateConverter;
import io.mifos.core.lang.ServiceException;
import io.mifos.teller.ServiceConstants;
import io.mifos.teller.api.v1.PermittableGroupIds;
@@ -50,6 +51,8 @@
import javax.validation.Valid;
import java.math.BigDecimal;
+import java.time.Clock;
+import java.time.LocalDate;
import java.util.List;
import java.util.Optional;
@@ -166,6 +169,14 @@
}
}
+ if (transactionType.equals(ServiceConstants.TX_CHEQUE)) {
+ final LocalDate dateIssued = DateConverter.dateFromIsoString(tellerTransaction.getCheque().getDateIssued());
+ final LocalDate sixMonth = LocalDate.now(Clock.systemUTC()).minusMonths(6);
+ if (dateIssued.isBefore(sixMonth)) {
+ throw ServiceException.conflict("Cheque is older than 6 month.");
+ }
+ }
+
final Optional<Account> optionalCustomerAccount =
this.accountingService.findAccount(tellerTransaction.getCustomerAccountIdentifier());
if (!optionalCustomerAccount.isPresent()) {
@@ -180,12 +191,18 @@
if (transactionType.equals(ServiceConstants.TX_ACCOUNT_TRANSFER)
|| transactionType.equals(ServiceConstants.TX_CASH_WITHDRAWAL)
|| transactionType.equals(ServiceConstants.TX_CLOSE_ACCOUNT)) {
-
-
if (tellerTransaction.getAmount().compareTo(BigDecimal.valueOf(customerAccount.getBalance())) > 0 ) {
throw ServiceException.conflict("Not enough balance.");
}
}
+
+ if (transactionType.equals(ServiceConstants.TX_CLOSE_ACCOUNT)) {
+ final BigDecimal newBalance =
+ BigDecimal.valueOf(customerAccount.getBalance()).subtract(tellerTransaction.getAmount());
+ if (newBalance.compareTo(BigDecimal.ZERO) > 0) {
+ throw ServiceException.conflict("Account has remaining balance");
+ }
+ }
}
if (tellerTransaction.getTargetAccountIdentifier() != null &&
diff --git a/service/src/main/resources/db/migrations/mariadb/V3__add_cheques_receivable_to_teller.sql b/service/src/main/resources/db/migrations/mariadb/V3__add_cheques_receivable_to_teller.sql
new file mode 100644
index 0000000..2d1b802
--- /dev/null
+++ b/service/src/main/resources/db/migrations/mariadb/V3__add_cheques_receivable_to_teller.sql
@@ -0,0 +1,23 @@
+--
+-- 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.
+--
+
+ALTER TABLE tajet_teller MODIFY teller_account_identifier VARCHAR(34);
+ALTER TABLE tajet_teller MODIFY vault_account_identifier VARCHAR(34);
+ALTER TABLE tajet_teller ADD cheques_receivable_account VARCHAR(34);
+
+
+ALTER TABLE tajet_teller_transactions MODIFY customer_account_identifier VARCHAR(34);
+ALTER TABLE tajet_teller_transactions MODIFY target_account_identifier VARCHAR(34);
\ No newline at end of file