formatting changes for savings related code.

This commit is contained in:
Keith Woodlock
2012-12-04 15:29:11 +00:00
parent d1a1ed60ab
commit 37ae6dae9e
66 changed files with 4414 additions and 4441 deletions
@@ -1,4 +1,4 @@
DROP TABLE IF EXISTS `m_saving_schedule` DROP TABLE IF EXISTS `m_saving_schedule`;
CREATE TABLE `m_saving_schedule` ( CREATE TABLE `m_saving_schedule` (
`id` bigint(20) NOT NULL AUTO_INCREMENT, `id` bigint(20) NOT NULL AUTO_INCREMENT,
`saving_account_id` bigint(20) NOT NULL, `saving_account_id` bigint(20) NOT NULL,
@@ -60,17 +60,19 @@ public class SavingsAccountApiResource {
@Autowired @Autowired
private CalculateSavingSchedule calculateSavingSchedule; private CalculateSavingSchedule calculateSavingSchedule;
private static final Set<String> typicalResponseParameters = new HashSet<String>( private static final Set<String> typicalResponseParameters = new HashSet<String>(Arrays.asList("id", "status", "externalId",
Arrays.asList("id", "status", "externalId", "clientId", "clientName", "productId", "productName", "productType", "currencyData", "savingsDepostiAmountPerPeriod", "savingsFrequencyType", "clientId", "clientName", "productId", "productName", "productType", "currencyData", "savingsDepostiAmountPerPeriod",
"totalDepositAmount", "reccuringInterestRate", "savingInterestRate", "interestType", "interestCalculationMethod", "tenure", "tenureType", "projectedCommencementDate", "savingsFrequencyType", "totalDepositAmount", "reccuringInterestRate", "savingInterestRate", "interestType",
"actualCommencementDate", "maturesOnDate", "projectedInterestAccuredOnMaturity", "actualInterestAccured", "projectedMaturityAmount", "actualMaturityAmount", "preClosureAllowed", "interestCalculationMethod", "tenure", "tenureType", "projectedCommencementDate", "actualCommencementDate", "maturesOnDate",
"preClosureInterestRate", "withdrawnonDate", "rejectedonDate", "closedonDate", "isLockinPeriodAllowed", "lockinPeriod", "lockinPeriodType")); "projectedInterestAccuredOnMaturity", "actualInterestAccured", "projectedMaturityAmount", "actualMaturityAmount",
"preClosureAllowed", "preClosureInterestRate", "withdrawnonDate", "rejectedonDate", "closedonDate", "isLockinPeriodAllowed",
"lockinPeriod", "lockinPeriodType"));
@POST @POST
@Consumes({ MediaType.APPLICATION_JSON }) @Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON })
public String createSavingAccount(@QueryParam("command") final String commandParam, public String createSavingAccount(@QueryParam("command") final String commandParam, @Context final UriInfo uriInfo,
@Context final UriInfo uriInfo,final String jsonRequestBody){ final String jsonRequestBody) {
final SavingAccountCommand command = this.apiDataConversionService.convertJsonToSavingAccountCommand(null, jsonRequestBody); final SavingAccountCommand command = this.apiDataConversionService.convertJsonToSavingAccountCommand(null, jsonRequestBody);
@@ -149,10 +151,8 @@ public class SavingsAccountApiResource {
@Path("template") @Path("template")
@Consumes({ MediaType.APPLICATION_JSON }) @Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON })
public String retrieveNewDepositAccountDetails( public String retrieveNewDepositAccountDetails(@QueryParam("clientId") final Long clientId,
@QueryParam("clientId") final Long clientId, @QueryParam("productId") final Long productId, @Context final UriInfo uriInfo) {
@QueryParam("productId") final Long productId,
@Context final UriInfo uriInfo) {
context.authenticatedUser().validateHasReadPermission(entityType); context.authenticatedUser().validateHasReadPermission(entityType);
@@ -163,7 +163,8 @@ public class SavingsAccountApiResource {
boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters()); boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters());
SavingAccountData account = null; SavingAccountData account = null;
// this.savingAccountReadPlatformService.retrieveNewSavingsAccountDetails(clientId, productId); // this.savingAccountReadPlatformService.retrieveNewSavingsAccountDetails(clientId,
// productId);
return this.apiJsonSerializerService.serializeSavingAccountsDataToJson(prettyPrint, responseParameters, account); return this.apiJsonSerializerService.serializeSavingAccountsDataToJson(prettyPrint, responseParameters, account);
} }
@@ -14,12 +14,8 @@ public class CalculateSavingScheduleCommand {
private final LocalDate paymentsStartingFromDate; private final LocalDate paymentsStartingFromDate;
private final Integer tenure; private final Integer tenure;
public CalculateSavingScheduleCommand(final Long productId, public CalculateSavingScheduleCommand(final Long productId, final BigDecimal deposit, final Integer payEvery,
final BigDecimal deposit, final Integer paymentFrequencyType, final BigDecimal interestRate, final LocalDate paymentsStartingFromDate,
final Integer payEvery,
final Integer paymentFrequencyType,
final BigDecimal interestRate,
final LocalDate paymentsStartingFromDate,
final Integer tenure) { final Integer tenure) {
this.productId = productId; this.productId = productId;
@@ -7,7 +7,6 @@ import org.joda.time.LocalDate;
public class SavingAccountCommand { public class SavingAccountCommand {
private final Long id; private final Long id;
private final Long clientId; private final Long clientId;
private final Long productId; private final Long productId;
@@ -37,18 +36,13 @@ public class SavingAccountCommand {
private final Set<String> modifiedParameters; private final Set<String> modifiedParameters;
public SavingAccountCommand(final Set<String> modifiedParameters, public SavingAccountCommand(final Set<String> modifiedParameters, final Long id, final Long clientId, final Long productId,
final Long id, final String externalId, final String currencyCode, final Integer digitsAfterDecimal, final BigDecimal savingsDepositAmount,
final Long clientId, final BigDecimal recurringInterestRate, final BigDecimal savingInterestRate, final Integer tenure,
final Long productId, final LocalDate commencementDate, final Integer savingProductType, final Integer tenureType, final Integer frequency,
final String externalId,final String currencyCode, final Integer digitsAfterDecimal, final Integer interestType, final BigDecimal minimumBalanceForWithdrawal, final Integer interestCalculationMethod,
final BigDecimal savingsDepositAmount, final boolean isLockinPeriodAllowed, final boolean isPartialDepositAllowed, final Integer lockInPeriod,
final BigDecimal recurringInterestRate, final BigDecimal savingInterestRate, final Integer lockinPeriodType, final Integer payEvery) {
final Integer tenure, final LocalDate commencementDate,
final Integer savingProductType, final Integer tenureType, final Integer frequency, final Integer interestType,
final BigDecimal minimumBalanceForWithdrawal, final Integer interestCalculationMethod,
final boolean isLockinPeriodAllowed, final boolean isPartialDepositAllowed, final Integer lockInPeriod, final Integer lockinPeriodType,
final Integer payEvery) {
this.id = id; this.id = id;
this.clientId = clientId; this.clientId = clientId;
this.productId = productId; this.productId = productId;
@@ -70,7 +64,6 @@ public class SavingAccountCommand {
this.interestType = interestType; this.interestType = interestType;
this.isPartialDepositAllowed = isPartialDepositAllowed; this.isPartialDepositAllowed = isPartialDepositAllowed;
this.isLockinPeriodAllowed = isLockinPeriodAllowed; this.isLockinPeriodAllowed = isLockinPeriodAllowed;
this.lockinPeriod = lockInPeriod; this.lockinPeriod = lockInPeriod;
this.lockinPeriodType = lockinPeriodType; this.lockinPeriodType = lockinPeriodType;
@@ -244,7 +237,8 @@ public class SavingAccountCommand {
} }
public CalculateSavingScheduleCommand toCalculateSavingScheduleCommand() { public CalculateSavingScheduleCommand toCalculateSavingScheduleCommand() {
return new CalculateSavingScheduleCommand(productId, savingsDepositAmount, payEvery, frequency, recurringInterestRate, commencementDate,tenure); return new CalculateSavingScheduleCommand(productId, savingsDepositAmount, payEvery, frequency, recurringInterestRate,
commencementDate, tenure);
} }
} }
@@ -18,7 +18,8 @@ public class SavingSchedulePeriodData {
this.depositPaid = depositPaid; this.depositPaid = depositPaid;
} }
public static SavingSchedulePeriodData addScheduleInformation(int periodNumber, LocalDate scheduleDate, BigDecimal depositAmountPerPeriod){ public static SavingSchedulePeriodData addScheduleInformation(int periodNumber, LocalDate scheduleDate,
BigDecimal depositAmountPerPeriod) {
return new SavingSchedulePeriodData(periodNumber, scheduleDate, depositAmountPerPeriod, BigDecimal.ZERO); return new SavingSchedulePeriodData(periodNumber, scheduleDate, depositAmountPerPeriod, BigDecimal.ZERO);
} }
@@ -8,5 +8,4 @@ import org.mifosplatform.portfolio.loanproduct.domain.PeriodFrequencyType;
public interface DepositScheduleDateGenerator { public interface DepositScheduleDateGenerator {
List<LocalDate> generate(LocalDate startDate, Integer paymentPeriods, Integer depositFrequency, PeriodFrequencyType depositFrequencyType); List<LocalDate> generate(LocalDate startDate, Integer paymentPeriods, Integer depositFrequency, PeriodFrequencyType depositFrequencyType);
} }
@@ -48,7 +48,8 @@ public class SavingAccount extends AbstractAuditableCustom<AppUser, Long> {
@JoinColumn(name = "product_id") @JoinColumn(name = "product_id")
private SavingProduct product; private SavingProduct product;
// FIXME - MADHUKAR - Do not use the actual enum type here but instead use Integer e.g. private Integer savingProductType; // FIXME - MADHUKAR - Do not use the actual enum type here but instead use
// Integer e.g. private Integer savingProductType;
@Column(name = "savings_product_type", nullable = false) @Column(name = "savings_product_type", nullable = false)
private SavingProductType savingProductType; private SavingProductType savingProductType;
@@ -78,15 +79,18 @@ public class SavingAccount extends AbstractAuditableCustom<AppUser, Long> {
@Column(name = "tenure_type", nullable = false) @Column(name = "tenure_type", nullable = false)
private TenureTypeEnum tenureType; private TenureTypeEnum tenureType;
// FIXME - MADHUKAR - Do not use the actual enum type here but instead use Integer e.g. private Integer savingProductType; // FIXME - MADHUKAR - Do not use the actual enum type here but instead use
// Integer e.g. private Integer savingProductType;
@Column(name = "frequency", nullable = false) @Column(name = "frequency", nullable = false)
private SavingFrequencyType frequency; private SavingFrequencyType frequency;
// FIXME - MADHUKAR - Do not use the actual enum type here but instead use Integer e.g. private Integer savingProductType; // FIXME - MADHUKAR - Do not use the actual enum type here but instead use
// Integer e.g. private Integer savingProductType;
@Column(name = "interest_type", nullable = false) @Column(name = "interest_type", nullable = false)
private SavingsInterestType interestType; private SavingsInterestType interestType;
// FIXME - MADHUKAR - Do not use the actual enum type here but instead use Integer e.g. private Integer savingProductType; // FIXME - MADHUKAR - Do not use the actual enum type here but instead use
// Integer e.g. private Integer savingProductType;
@Column(name = "interest_calculation_method") @Column(name = "interest_calculation_method")
private SavingInterestCalculationMethod interestCalculationMethod; private SavingInterestCalculationMethod interestCalculationMethod;
@@ -161,34 +165,20 @@ public class SavingAccount extends AbstractAuditableCustom<AppUser, Long> {
@OneToMany(cascade = CascadeType.ALL, mappedBy = "savingAccount", orphanRemoval = true) @OneToMany(cascade = CascadeType.ALL, mappedBy = "savingAccount", orphanRemoval = true)
private final List<SavingScheduleInstallments> savingScheduleInstallments = new ArrayList<SavingScheduleInstallments>(); private final List<SavingScheduleInstallments> savingScheduleInstallments = new ArrayList<SavingScheduleInstallments>();
public static SavingAccount openNew(Client client, SavingProduct product, String externalId, Money savingsDeposit,
public static SavingAccount openNew( BigDecimal reccuringInterestRate, BigDecimal savingInterestRate, Integer tenure, LocalDate commencementDate,
Client client, TenureTypeEnum tenureTypeEnum, SavingProductType savingProductType, SavingFrequencyType savingFrequencyType,
SavingProduct product, SavingsInterestType interestType, SavingInterestCalculationMethod savingInterestCalculationMethod,
String externalId, boolean isLockinPeriodAllowed, Integer lockinPeriod, PeriodFrequencyType lockinPeriodType,
Money savingsDeposit, ReccuringDepositInterestCalculator reccuringDepositInterestCalculator, final DepositLifecycleStateMachine lifecycleStateMachine) {
BigDecimal reccuringInterestRate,
BigDecimal savingInterestRate,
Integer tenure,
LocalDate commencementDate,
TenureTypeEnum tenureTypeEnum,
SavingProductType savingProductType,
SavingFrequencyType savingFrequencyType,
SavingsInterestType interestType,
SavingInterestCalculationMethod savingInterestCalculationMethod,
boolean isLockinPeriodAllowed,
Integer lockinPeriod,
PeriodFrequencyType lockinPeriodType,
ReccuringDepositInterestCalculator reccuringDepositInterestCalculator,
final DepositLifecycleStateMachine lifecycleStateMachine) {
Money futureValueOnMaturity = null; Money futureValueOnMaturity = null;
if (savingProductType.isReccuring()) { if (savingProductType.isReccuring()) {
futureValueOnMaturity = reccuringDepositInterestCalculator.calculateInterestOnMaturityFor(savingsDeposit, tenure, reccuringInterestRate, futureValueOnMaturity = reccuringDepositInterestCalculator.calculateInterestOnMaturityFor(savingsDeposit, tenure,
commencementDate, tenureTypeEnum, savingFrequencyType, savingInterestCalculationMethod); reccuringInterestRate, commencementDate, tenureTypeEnum, savingFrequencyType, savingInterestCalculationMethod);
} else if (savingProductType.isRegular()) { } else if (savingProductType.isRegular()) {
futureValueOnMaturity = reccuringDepositInterestCalculator.calculateInterestOnMaturityFor(savingsDeposit, tenure, savingInterestRate, futureValueOnMaturity = reccuringDepositInterestCalculator.calculateInterestOnMaturityFor(savingsDeposit, tenure,
commencementDate, tenureTypeEnum, savingFrequencyType, savingInterestCalculationMethod); savingInterestRate, commencementDate, tenureTypeEnum, savingFrequencyType, savingInterestCalculationMethod);
} }
return new SavingAccount(client, externalId, product, savingsDeposit, reccuringInterestRate, savingInterestRate, tenure, return new SavingAccount(client, externalId, product, savingsDeposit, reccuringInterestRate, savingInterestRate, tenure,
@@ -196,17 +186,11 @@ public class SavingAccount extends AbstractAuditableCustom<AppUser, Long> {
isLockinPeriodAllowed, lockinPeriod, lockinPeriodType, futureValueOnMaturity, lifecycleStateMachine); isLockinPeriodAllowed, lockinPeriod, lockinPeriodType, futureValueOnMaturity, lifecycleStateMachine);
} }
public SavingAccount(Client client, String externalId, public SavingAccount(Client client, String externalId, SavingProduct product, Money savingsDeposit, BigDecimal reccuringInterestRate,
SavingProduct product, Money savingsDeposit, BigDecimal savingInterestRate, Integer tenure, LocalDate commencementDate, TenureTypeEnum tenureTypeEnum,
BigDecimal reccuringInterestRate, BigDecimal savingInterestRate, SavingProductType savingProductType, SavingFrequencyType savingFrequencyType, SavingsInterestType interestType,
Integer tenure, LocalDate commencementDate, SavingInterestCalculationMethod savingInterestCalculationMethod, boolean isLockinPeriodAllowed, Integer lockinPeriod,
TenureTypeEnum tenureTypeEnum, PeriodFrequencyType lockinPeriodType, Money futureValueOnMaturity, final DepositLifecycleStateMachine lifecycleStateMachine) {
SavingProductType savingProductType,
SavingFrequencyType savingFrequencyType, SavingsInterestType interestType,
SavingInterestCalculationMethod savingInterestCalculationMethod,
boolean isLockinPeriodAllowed, Integer lockinPeriod,
PeriodFrequencyType lockinPeriodType, Money futureValueOnMaturity,
final DepositLifecycleStateMachine lifecycleStateMachine) {
DepositAccountStatus from = null; DepositAccountStatus from = null;
if (accountStatus != null) { if (accountStatus != null) {
@@ -239,34 +223,23 @@ public class SavingAccount extends AbstractAuditableCustom<AppUser, Long> {
this.lockinPeriod = lockinPeriod; this.lockinPeriod = lockinPeriod;
this.lockinPeriodType = lockinPeriodType; this.lockinPeriodType = lockinPeriodType;
this.projectedTotalOnMaturity = futureValueOnMaturity.getAmount(); this.projectedTotalOnMaturity = futureValueOnMaturity.getAmount();
this.projectedInterestAccruedOnMaturity =futureValueOnMaturity.getAmount().subtract(BigDecimal.valueOf(savingsDeposit.getAmount().doubleValue()*tenure.doubleValue())); this.projectedInterestAccruedOnMaturity = futureValueOnMaturity.getAmount().subtract(
BigDecimal.valueOf(savingsDeposit.getAmount().doubleValue() * tenure.doubleValue()));
} }
public void modifyAccount( public void modifyAccount(SavingProduct product, String externalId, Money savingsDeposit, BigDecimal reccuringInterestRate,
SavingProduct product, BigDecimal savingInterestRate, Integer tenure, LocalDate commencementDate, TenureTypeEnum tenureTypeEnum,
String externalId, SavingProductType savingProductType, SavingFrequencyType savingFrequencyType,
Money savingsDeposit, SavingInterestCalculationMethod savingInterestCalculationMethod, boolean isLockinPeriodAllowed, Integer lockinPeriod,
BigDecimal reccuringInterestRate, PeriodFrequencyType lockinPeriodType, ReccuringDepositInterestCalculator reccuringDepositInterestCalculator) {
BigDecimal savingInterestRate,
Integer tenure,
LocalDate commencementDate,
TenureTypeEnum tenureTypeEnum,
SavingProductType savingProductType,
SavingFrequencyType savingFrequencyType,
SavingInterestCalculationMethod savingInterestCalculationMethod,
boolean isLockinPeriodAllowed,
Integer lockinPeriod,
PeriodFrequencyType lockinPeriodType,
ReccuringDepositInterestCalculator reccuringDepositInterestCalculator) {
Money futureValueOnMaturity = null; Money futureValueOnMaturity = null;
if (savingProductType.isReccuring()) { if (savingProductType.isReccuring()) {
futureValueOnMaturity = reccuringDepositInterestCalculator.calculateInterestOnMaturityFor(savingsDeposit, tenure, reccuringInterestRate, futureValueOnMaturity = reccuringDepositInterestCalculator.calculateInterestOnMaturityFor(savingsDeposit, tenure,
commencementDate, tenureTypeEnum, savingFrequencyType, savingInterestCalculationMethod); reccuringInterestRate, commencementDate, tenureTypeEnum, savingFrequencyType, savingInterestCalculationMethod);
} else if (savingProductType.isRegular()) { } else if (savingProductType.isRegular()) {
futureValueOnMaturity = reccuringDepositInterestCalculator.calculateInterestOnMaturityFor(savingsDeposit, tenure, savingInterestRate, futureValueOnMaturity = reccuringDepositInterestCalculator.calculateInterestOnMaturityFor(savingsDeposit, tenure,
commencementDate, tenureTypeEnum, savingFrequencyType, savingInterestCalculationMethod); savingInterestRate, commencementDate, tenureTypeEnum, savingFrequencyType, savingInterestCalculationMethod);
} }
this.product = product; this.product = product;
@@ -286,7 +259,8 @@ public class SavingAccount extends AbstractAuditableCustom<AppUser, Long> {
// FIXME - MADHUKAR - futureValueOnMaturity is possibly null // FIXME - MADHUKAR - futureValueOnMaturity is possibly null
this.projectedTotalOnMaturity = futureValueOnMaturity.getAmount(); this.projectedTotalOnMaturity = futureValueOnMaturity.getAmount();
this.projectedInterestAccruedOnMaturity =futureValueOnMaturity.getAmount().subtract(BigDecimal.valueOf(savingsDeposit.getAmount().doubleValue()*tenure.doubleValue())); this.projectedInterestAccruedOnMaturity = futureValueOnMaturity.getAmount().subtract(
BigDecimal.valueOf(savingsDeposit.getAmount().doubleValue() * tenure.doubleValue()));
} }
public boolean isDeleted() { public boolean isDeleted() {
@@ -3,8 +3,6 @@ package org.mifosplatform.portfolio.savingsaccount.domain;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
public interface SavingAccountRepository extends public interface SavingAccountRepository extends JpaRepository<SavingAccount, Long>, JpaSpecificationExecutor<SavingAccount> {
JpaRepository<SavingAccount, Long>,
JpaSpecificationExecutor<SavingAccount>{
} }
@@ -42,8 +42,7 @@ public class SavingScheduleInstallments extends AbstractAuditableCustom<AppUser,
@Column(name = "completed_derived", nullable = false) @Column(name = "completed_derived", nullable = false)
private boolean completed; private boolean completed;
public SavingScheduleInstallments(SavingAccount account, Date dueDate, public SavingScheduleInstallments(SavingAccount account, Date dueDate, Integer installmentNumber, BigDecimal deposit) {
Integer installmentNumber, BigDecimal deposit) {
this.savingAccount = account; this.savingAccount = account;
this.dueDate = dueDate; this.dueDate = dueDate;
this.installmentNumber = installmentNumber; this.installmentNumber = installmentNumber;
@@ -7,5 +7,4 @@ public class SavingAccountNotFoundException extends AbstractPlatformResourceNotF
public SavingAccountNotFoundException(final Long id) { public SavingAccountNotFoundException(final Long id) {
super("error.msg.saving.account.id.invalid", "Saving account with identifier " + id + " does not exist", id); super("error.msg.saving.account.id.invalid", "Saving account with identifier " + id + " does not exist", id);
} }
} }
@@ -6,5 +6,4 @@ import org.mifosplatform.portfolio.savingsaccount.data.SavingScheduleData;
public interface CalculateSavingSchedule { public interface CalculateSavingSchedule {
SavingScheduleData calculateSavingSchedule(CalculateSavingScheduleCommand command); SavingScheduleData calculateSavingSchedule(CalculateSavingScheduleCommand command);
} }
@@ -24,9 +24,7 @@ public class CalculateSavingScheduleImpl implements CalculateSavingSchedule {
private final ApplicationCurrencyRepository applicationCurrencyRepository; private final ApplicationCurrencyRepository applicationCurrencyRepository;
@Autowired @Autowired
public CalculateSavingScheduleImpl( public CalculateSavingScheduleImpl(final PlatformSecurityContext context, final SavingProductRepository savingProductRepository,
final PlatformSecurityContext context,
final SavingProductRepository savingProductRepository,
final ApplicationCurrencyRepository applicationCurrencyRepository) { final ApplicationCurrencyRepository applicationCurrencyRepository) {
this.context = context; this.context = context;
this.savingProductRepository = savingProductRepository; this.savingProductRepository = savingProductRepository;
@@ -41,8 +39,7 @@ public class CalculateSavingScheduleImpl implements CalculateSavingSchedule {
// FIXME Validations should write here // FIXME Validations should write here
final SavingProduct savingProduct = this.savingProductRepository.findOne(command.getProductId()); final SavingProduct savingProduct = this.savingProductRepository.findOne(command.getProductId());
if (savingProduct == null) if (savingProduct == null) throw new SavingProductNotFoundException(command.getProductId());
throw new SavingProductNotFoundException(command.getProductId());
final Integer depositFrequency = command.getPayEvery(); final Integer depositFrequency = command.getPayEvery();
final PeriodFrequencyType depositFrequencyType = PeriodFrequencyType.fromInt(command.getPaymentFrequencyType()); final PeriodFrequencyType depositFrequencyType = PeriodFrequencyType.fromInt(command.getPaymentFrequencyType());
@@ -51,7 +48,8 @@ public class CalculateSavingScheduleImpl implements CalculateSavingSchedule {
final BigDecimal interestRate = command.getInterestRate(); final BigDecimal interestRate = command.getInterestRate();
final BigDecimal depositAmountPerPeriod = command.getDeposit(); final BigDecimal depositAmountPerPeriod = command.getDeposit();
final Integer tenure = command.getTenure(); final Integer tenure = command.getTenure();
final ApplicationCurrency applicationCurrency = this.applicationCurrencyRepository.findOneByCode(savingProduct.getCurrency().getCode()); final ApplicationCurrency applicationCurrency = this.applicationCurrencyRepository.findOneByCode(savingProduct.getCurrency()
.getCode());
SavingScheduleData savingScheduleData = savingScheduleGenerator.generate(scheduleStartDate, depositAmountPerPeriod, SavingScheduleData savingScheduleData = savingScheduleGenerator.generate(scheduleStartDate, depositAmountPerPeriod,
depositFrequency, depositFrequencyType, savingProduct, tenure, applicationCurrency); depositFrequency, depositFrequencyType, savingProduct, tenure, applicationCurrency);
@@ -10,7 +10,8 @@ import org.mifosplatform.portfolio.savingsaccount.domain.DepositScheduleDateGene
public class DefaultDepositScheduleDateGenerator implements DepositScheduleDateGenerator { public class DefaultDepositScheduleDateGenerator implements DepositScheduleDateGenerator {
@Override @Override
public List<LocalDate> generate(LocalDate scheuleStartDate, Integer paymentPeriods, Integer depositFrequency, PeriodFrequencyType depositFrequencyType) { public List<LocalDate> generate(LocalDate scheuleStartDate, Integer paymentPeriods, Integer depositFrequency,
PeriodFrequencyType depositFrequencyType) {
List<LocalDate> duePaymentPeriodDates = new ArrayList<LocalDate>(depositFrequency); List<LocalDate> duePaymentPeriodDates = new ArrayList<LocalDate>(depositFrequency);
LocalDate startDate = scheuleStartDate; LocalDate startDate = scheuleStartDate;
@@ -41,24 +41,22 @@ public class SavingAccountAssembler {
@Autowired @Autowired
public SavingAccountAssembler(final ClientRepository clientRepository, final SavingProductRepository savingProductRepository, public SavingAccountAssembler(final ClientRepository clientRepository, final SavingProductRepository savingProductRepository,
final ReccuringDepositInterestCalculator reccuringDepositInterestCalculator,final CalculateSavingSchedule calculateSavingSchedule) { final ReccuringDepositInterestCalculator reccuringDepositInterestCalculator,
final CalculateSavingSchedule calculateSavingSchedule) {
this.clientRepository = clientRepository; this.clientRepository = clientRepository;
this.savingProductRepository = savingProductRepository; this.savingProductRepository = savingProductRepository;
this.reccuringDepositInterestCalculator = reccuringDepositInterestCalculator; this.reccuringDepositInterestCalculator = reccuringDepositInterestCalculator;
this.calculateSavingSchedule = calculateSavingSchedule; this.calculateSavingSchedule = calculateSavingSchedule;
} }
// minimumBalanceForWithdrawal,isPartialDepositAllowed // minimumBalanceForWithdrawal,isPartialDepositAllowed
public SavingAccount assembleFrom(SavingAccountCommand command) { public SavingAccount assembleFrom(SavingAccountCommand command) {
Client client = this.clientRepository.findOne(command.getClientId()); Client client = this.clientRepository.findOne(command.getClientId());
if (client == null || client.isDeleted()) { if (client == null || client.isDeleted()) { throw new ClientNotFoundException(command.getClientId()); }
throw new ClientNotFoundException(command.getClientId());
}
SavingProduct product = this.savingProductRepository.findOne(command.getProductId()); SavingProduct product = this.savingProductRepository.findOne(command.getProductId());
if(product == null || product.isDeleted()){ if (product == null || product.isDeleted()) { throw new SavingProductNotFoundException(command.getProductId()); }
throw new SavingProductNotFoundException(command.getProductId());
}
MonetaryCurrency currency = product.getCurrency(); MonetaryCurrency currency = product.getCurrency();
if (command.getCurrencyCode() != null && command.getDigitsAfterDecimal() != null) { if (command.getCurrencyCode() != null && command.getDigitsAfterDecimal() != null) {
@@ -87,7 +85,8 @@ public class SavingAccountAssembler {
savingFrequencyType = SavingFrequencyType.fromInt(command.getFrequency()); savingFrequencyType = SavingFrequencyType.fromInt(command.getFrequency());
} }
SavingInterestCalculationMethod savingInterestCalculationMethod = product.getSavingProductRelatedDetail().getInterestCalculationMethod(); SavingInterestCalculationMethod savingInterestCalculationMethod = product.getSavingProductRelatedDetail()
.getInterestCalculationMethod();
if (command.getInterestCalculationMethod() != null) { if (command.getInterestCalculationMethod() != null) {
savingInterestCalculationMethod = SavingInterestCalculationMethod.fromInt(command.getInterestCalculationMethod()); savingInterestCalculationMethod = SavingInterestCalculationMethod.fromInt(command.getInterestCalculationMethod());
} }
@@ -99,8 +98,7 @@ public class SavingAccountAssembler {
BigDecimal reccuringInterestRate = command.getRecurringInterestRate(); BigDecimal reccuringInterestRate = command.getRecurringInterestRate();
BigDecimal savingInterestRate = product.getInterestRate(); BigDecimal savingInterestRate = product.getInterestRate();
if(command.getSavingInterestRate() != null) if (command.getSavingInterestRate() != null) savingInterestRate = command.getSavingInterestRate();
savingInterestRate = command.getSavingInterestRate();
boolean isLockinPeriodAllowed = product.getSavingProductRelatedDetail().isLockinPeriodAllowed(); boolean isLockinPeriodAllowed = product.getSavingProductRelatedDetail().isLockinPeriodAllowed();
if (command.isLockinPeriodChanged()) { if (command.isLockinPeriodChanged()) {
@@ -117,19 +115,17 @@ public class SavingAccountAssembler {
lockinPeriodType = PeriodFrequencyType.fromInt(command.getLockinPeriodType()); lockinPeriodType = PeriodFrequencyType.fromInt(command.getLockinPeriodType());
} }
SavingAccount account = SavingAccount.openNew(client, product, command.getExternalId(),savingsDeposit, SavingAccount account = SavingAccount.openNew(client, product, command.getExternalId(), savingsDeposit, reccuringInterestRate,
reccuringInterestRate,savingInterestRate,tenure,command.getCommencementDate(),tenureTypeEnum, savingProductType, savingInterestRate, tenure, command.getCommencementDate(), tenureTypeEnum, savingProductType, savingFrequencyType,
savingFrequencyType, interestType, savingInterestCalculationMethod, isLockinPeriodAllowed,lockinPeriod, lockinPeriodType, interestType, savingInterestCalculationMethod, isLockinPeriodAllowed, lockinPeriod, lockinPeriodType,
this.reccuringDepositInterestCalculator, defaultDepositLifecycleStateMachine()); this.reccuringDepositInterestCalculator, defaultDepositLifecycleStateMachine());
SavingScheduleData savingScheduleData = this.calculateSavingSchedule.calculateSavingSchedule(command.toCalculateSavingScheduleCommand()); SavingScheduleData savingScheduleData = this.calculateSavingSchedule.calculateSavingSchedule(command
.toCalculateSavingScheduleCommand());
for (SavingSchedulePeriodData savingSchedulePeriodData : savingScheduleData.getPeriods()) { for (SavingSchedulePeriodData savingSchedulePeriodData : savingScheduleData.getPeriods()) {
final SavingScheduleInstallments installment = new SavingScheduleInstallments( final SavingScheduleInstallments installment = new SavingScheduleInstallments(account, savingSchedulePeriodData.getDueDate()
account, .toDate(), savingSchedulePeriodData.getPeriod(), savingSchedulePeriodData.getDepositDue());
savingSchedulePeriodData.getDueDate().toDate(),
savingSchedulePeriodData.getPeriod(),
savingSchedulePeriodData.getDepositDue());
account.addSavingScheduleInstallment(installment); account.addSavingScheduleInstallment(installment);
} }
@@ -142,8 +138,7 @@ public class SavingAccountAssembler {
if (command.isProductIdChanged()) { if (command.isProductIdChanged()) {
if (product.getId() != command.getProductId()) { if (product.getId() != command.getProductId()) {
product = this.savingProductRepository.findOne(command.getProductId()); product = this.savingProductRepository.findOne(command.getProductId());
if(product == null || product.isDeleted()) if (product == null || product.isDeleted()) throw new SavingProductNotFoundException(command.getProductId());
throw new SavingProductNotFoundException(command.getProductId());
} }
} }
@@ -210,9 +205,9 @@ public class SavingAccountAssembler {
if (command.isLockinPeriodTypeChanged()) { if (command.isLockinPeriodTypeChanged()) {
lockinPeriodType = PeriodFrequencyType.fromInt(command.getLockinPeriodType()); lockinPeriodType = PeriodFrequencyType.fromInt(command.getLockinPeriodType());
} }
account.modifyAccount(product, externalId, savingsDeposit, reccuringInterestRate, savingInterestRate, tenure, account.modifyAccount(product, externalId, savingsDeposit, reccuringInterestRate, savingInterestRate, tenure, commencementDate,
commencementDate, tenureTypeEnum, savingProductType, savingFrequencyType, savingInterestCalculationMethod, tenureTypeEnum, savingProductType, savingFrequencyType, savingInterestCalculationMethod, isLockinPeriodAllowed,
isLockinPeriodAllowed, lockinPeriod, lockinPeriodType, this.reccuringDepositInterestCalculator); lockinPeriod, lockinPeriodType, this.reccuringDepositInterestCalculator);
} }
@@ -30,15 +30,11 @@ public class SavingProductRelatedDetailAssembler {
final Integer payEvery = command.getPayEvery(); final Integer payEvery = command.getPayEvery();
final Integer paymentFrequencyType = command.getPaymentFrequencyType(); final Integer paymentFrequencyType = command.getPaymentFrequencyType();
final SavingProduct savingProduct = this.savingProductRepository.findOne(command.getProductId()); final SavingProduct savingProduct = this.savingProductRepository.findOne(command.getProductId());
if (savingProduct == null) { if (savingProduct == null) { throw new SavingProductNotFoundException(command.getProductId()); }
throw new SavingProductNotFoundException(command.getProductId());
}
final MonetaryCurrency currency = savingProduct.getCurrency(); final MonetaryCurrency currency = savingProduct.getCurrency();
return null; return null;
} }
} }
@@ -20,37 +20,30 @@ public class SavingScheduleGenerator {
private final DepositScheduleDateGenerator scheduledDateGenerator = new DefaultDepositScheduleDateGenerator(); private final DepositScheduleDateGenerator scheduledDateGenerator = new DefaultDepositScheduleDateGenerator();
public SavingScheduleData generate( public SavingScheduleData generate(final LocalDate scheduleStartDate, final BigDecimal depositAmountPerPeriod,
final LocalDate scheduleStartDate, final Integer depositFrequency, final PeriodFrequencyType depositFrequencyType, final SavingProduct savingProduct,
final BigDecimal depositAmountPerPeriod, final Integer tenure, final ApplicationCurrency applicationCurrency) {
final Integer depositFrequency,
final PeriodFrequencyType depositFrequencyType,
final SavingProduct savingProduct,
final Integer tenure,
final ApplicationCurrency applicationCurrency) {
LocalDate startDate = scheduleStartDate; LocalDate startDate = scheduleStartDate;
int periodNumber = 1; int periodNumber = 1;
Integer paymentPeriods = tenure / depositFrequency; Integer paymentPeriods = tenure / depositFrequency;
final Collection<SavingSchedulePeriodData> periods = new ArrayList<SavingSchedulePeriodData>(); final Collection<SavingSchedulePeriodData> periods = new ArrayList<SavingSchedulePeriodData>();
final List<LocalDate> scheduledDates = this.scheduledDateGenerator.generate(startDate,paymentPeriods,depositFrequency,depositFrequencyType); final List<LocalDate> scheduledDates = this.scheduledDateGenerator.generate(startDate, paymentPeriods, depositFrequency,
depositFrequencyType);
final MonetaryCurrency currency = savingProduct.getCurrency(); final MonetaryCurrency currency = savingProduct.getCurrency();
final Money depositAmount = Money.of(currency, depositAmountPerPeriod); final Money depositAmount = Money.of(currency, depositAmountPerPeriod);
Money totalDeposit = Money.zero(currency); Money totalDeposit = Money.zero(currency);
for (LocalDate scheduleDate : scheduledDates) { for (LocalDate scheduleDate : scheduledDates) {
totalDeposit = totalDeposit.plus(depositAmount); totalDeposit = totalDeposit.plus(depositAmount);
SavingSchedulePeriodData installment = SavingSchedulePeriodData.addScheduleInformation(periodNumber, scheduleDate, depositAmount.getAmount()); SavingSchedulePeriodData installment = SavingSchedulePeriodData.addScheduleInformation(periodNumber, scheduleDate,
depositAmount.getAmount());
periods.add(installment); periods.add(installment);
periodNumber++; periodNumber++;
} }
CurrencyData currencyData = new CurrencyData( CurrencyData currencyData = new CurrencyData(applicationCurrency.getCode(), applicationCurrency.getName(),
applicationCurrency.getCode(), currency.getDigitsAfterDecimal(), applicationCurrency.getDisplaySymbol(), applicationCurrency.getNameCode());
applicationCurrency.getName(),
currency.getDigitsAfterDecimal(),
applicationCurrency.getDisplaySymbol(),
applicationCurrency.getNameCode());
return new SavingScheduleData(currencyData, totalDeposit.getAmount(), periods); return new SavingScheduleData(currencyData, totalDeposit.getAmount(), periods);
} }
@@ -96,10 +96,11 @@ public class SavingProductsApiResource {
context.authenticatedUser().validateHasReadPermission(entityType); context.authenticatedUser().validateHasReadPermission(entityType);
Set<String> typicalResponseParameters = new HashSet<String>(Arrays.asList("id", "createdOn", "lastModifedOn", Set<String> typicalResponseParameters = new HashSet<String>(Arrays.asList("id", "createdOn", "lastModifedOn", "locale", "name",
"locale", "name", "description","currencyCode", "digitsAfterDecimal","interstRate", "minInterestRate","maxInterestRate", "description", "currencyCode", "digitsAfterDecimal", "interstRate", "minInterestRate", "maxInterestRate",
"savingsDepositAmount","savingProductType","tenureType","tenure", "frequency","interestType","interestCalculationMethod", "savingsDepositAmount", "savingProductType", "tenureType", "tenure", "frequency", "interestType",
"minimumBalanceForWithdrawal","isPartialDepositAllowed","isLockinPeriodAllowed","lockinPeriod","lockinPeriodType")); "interestCalculationMethod", "minimumBalanceForWithdrawal", "isPartialDepositAllowed", "isLockinPeriodAllowed",
"lockinPeriod", "lockinPeriodType"));
Set<String> responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters()); Set<String> responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters());
if (responseParameters.isEmpty()) { if (responseParameters.isEmpty()) {
@@ -120,10 +121,11 @@ public class SavingProductsApiResource {
context.authenticatedUser().validateHasReadPermission(entityType); context.authenticatedUser().validateHasReadPermission(entityType);
Set<String> typicalResponseParameters = new HashSet<String>(Arrays.asList("id", "createdOn", "lastModifedOn", Set<String> typicalResponseParameters = new HashSet<String>(Arrays.asList("id", "createdOn", "lastModifedOn", "locale", "name",
"locale", "name", "description","currencyCode", "digitsAfterDecimal","interstRate", "minInterestRate","maxInterestRate", "description", "currencyCode", "digitsAfterDecimal", "interstRate", "minInterestRate", "maxInterestRate",
"savingsDepositAmount","savingProductType","tenureType","tenure", "frequency","interestType","interestCalculationMethod", "savingsDepositAmount", "savingProductType", "tenureType", "tenure", "frequency", "interestType",
"minimumBalanceForWithdrawal","isPartialDepositAllowed","isLockinPeriodAllowed","lockinPeriod","lockinPeriodType")); "interestCalculationMethod", "minimumBalanceForWithdrawal", "isPartialDepositAllowed", "isLockinPeriodAllowed",
"lockinPeriod", "lockinPeriodType"));
Set<String> responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters()); Set<String> responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters());
if (responseParameters.isEmpty()) { if (responseParameters.isEmpty()) {
@@ -148,11 +150,10 @@ public class SavingProductsApiResource {
context.authenticatedUser().validateHasReadPermission(entityType); context.authenticatedUser().validateHasReadPermission(entityType);
Set<String> typicalResponseParameters = new HashSet<String>( Set<String> typicalResponseParameters = new HashSet<String>(Arrays.asList("id", "createdOn", "lastModifedOn", "locale", "name",
Arrays.asList("id", "createdOn", "lastModifedOn", "description", "currencyCode", "digitsAfterDecimal", "interstRate", "savingsDepositAmount", "savingProductType",
"locale", "name", "description","currencyCode", "digitsAfterDecimal","interstRate", "tenureType", "tenure", "frequency", "interestType", "interestCalculationMethod", "minimumBalanceForWithdrawal",
"savingsDepositAmount","savingProductType","tenureType","tenure", "frequency","interestType","interestCalculationMethod", "isPartialDepositAllowed", "isLockinPeriodAllowed", "lockinPeriod", "lockinPeriodType", "currencyOptions"));
"minimumBalanceForWithdrawal","isPartialDepositAllowed","isLockinPeriodAllowed","lockinPeriod","lockinPeriodType","currencyOptions"));
Set<String> responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters()); Set<String> responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters());
if (responseParameters.isEmpty()) { if (responseParameters.isEmpty()) {
@@ -167,8 +168,8 @@ public class SavingProductsApiResource {
private SavingProductData handleTemplateRelatedData(Set<String> responseParameters, SavingProductData savingProduct) { private SavingProductData handleTemplateRelatedData(Set<String> responseParameters, SavingProductData savingProduct) {
responseParameters.addAll(Arrays.asList("currencyOptions", "savingsProductTypeOptions", "tenureTypeOptions", "savingFrequencyOptions", "savingsInterestTypeOptions", responseParameters.addAll(Arrays.asList("currencyOptions", "savingsProductTypeOptions", "tenureTypeOptions",
"lockinPeriodTypeOptions", "interestCalculationOptions")); "savingFrequencyOptions", "savingsInterestTypeOptions", "lockinPeriodTypeOptions", "interestCalculationOptions"));
List<CurrencyData> currencyOptions = this.currencyReadPlatformService.retrieveAllowedCurrencies(); List<CurrencyData> currencyOptions = this.currencyReadPlatformService.retrieveAllowedCurrencies();
EnumOptionData reccuring = SavingProductEnumerations.savingProductType(SavingProductType.RECCURING); EnumOptionData reccuring = SavingProductEnumerations.savingProductType(SavingProductType.RECCURING);
@@ -191,10 +192,12 @@ public class SavingProductsApiResource {
EnumOptionData averagebal = SavingProductEnumerations.savingInterestCalculationMethod(SavingInterestCalculationMethod.AVERAGEBAL); EnumOptionData averagebal = SavingProductEnumerations.savingInterestCalculationMethod(SavingInterestCalculationMethod.AVERAGEBAL);
EnumOptionData minbal = SavingProductEnumerations.savingInterestCalculationMethod(SavingInterestCalculationMethod.MINBAL); EnumOptionData minbal = SavingProductEnumerations.savingInterestCalculationMethod(SavingInterestCalculationMethod.MINBAL);
EnumOptionData monthlyCollection = SavingProductEnumerations.savingInterestCalculationMethod(SavingInterestCalculationMethod.MONTHLYCOLLECTION); EnumOptionData monthlyCollection = SavingProductEnumerations
.savingInterestCalculationMethod(SavingInterestCalculationMethod.MONTHLYCOLLECTION);
List<EnumOptionData> interestCalculationOptions = Arrays.asList(averagebal, minbal, monthlyCollection); List<EnumOptionData> interestCalculationOptions = Arrays.asList(averagebal, minbal, monthlyCollection);
return new SavingProductData(savingProduct,currencyOptions,savingsProductTypeOptions,tenureTypeOptions,savingFrequencyOptions,savingsInterestTypeOptions,lockinPeriodTypeOptions,interestCalculationOptions); return new SavingProductData(savingProduct, currencyOptions, savingsProductTypeOptions, tenureTypeOptions, savingFrequencyOptions,
savingsInterestTypeOptions, lockinPeriodTypeOptions, interestCalculationOptions);
} }
@DELETE @DELETE
@@ -4,6 +4,7 @@ import java.math.BigDecimal;
import java.util.Set; import java.util.Set;
public class SavingProductCommand { public class SavingProductCommand {
private final Long id; private final Long id;
private final String name; private final String name;
private final String description; private final String description;
@@ -27,20 +28,13 @@ public class SavingProductCommand {
private final Integer lockinPeriod; private final Integer lockinPeriod;
private final Integer lockinPeriodType; private final Integer lockinPeriodType;
private final Set<String> modifiedParameters; private final Set<String> modifiedParameters;
public SavingProductCommand(Set<String> modifiedParameters, public SavingProductCommand(Set<String> modifiedParameters, Long id, String name, String description, String currencyCode,
Long id, String name, String description, Integer digitsAfterDecimal, BigDecimal interestRate, BigDecimal minInterestRate, BigDecimal maxInterestRate,
String currencyCode, Integer digitsAfterDecimal, BigDecimal savingsDepositAmount, Integer savingProductType, Integer tenureType, Integer tenure, Integer frequency,
BigDecimal interestRate, BigDecimal minInterestRate, Integer interestType, Integer interestCalculationMethod, BigDecimal minimumBalanceForWithdrawal,
BigDecimal maxInterestRate, BigDecimal savingsDepositAmount, boolean isPartialDepositAllowed, boolean isLockinPeriodAllowed, Integer lockinPeriod, Integer lockinPeriodType) {
Integer savingProductType, Integer tenureType, Integer tenure,
Integer frequency, Integer interestType,
Integer interestCalculationMethod,
BigDecimal minimumBalanceForWithdrawal,
boolean isPartialDepositAllowed, boolean isLockinPeriodAllowed,
Integer lockinPeriod, Integer lockinPeriodType) {
this.id = id; this.id = id;
this.name = name; this.name = name;
@@ -69,18 +69,12 @@ public class SavingProductData implements Serializable {
this.lockinPeriodType = null; this.lockinPeriodType = null;
} }
public SavingProductData(DateTime createdOn, DateTime lastModifedOn, public SavingProductData(DateTime createdOn, DateTime lastModifedOn, Long id, String name, String description, BigDecimal interestRate,
Long id, String name, String description, BigDecimal minInterestRate, BigDecimal maxInterestRate, CurrencyData currency, Integer digitsAfterDecimal,
BigDecimal interestRate, BigDecimal minInterestRate, BigDecimal maxInterestRate, CurrencyData currency, BigDecimal savingsDepositAmount, EnumOptionData savingProductType, EnumOptionData tenureType, Integer tenure,
Integer digitsAfterDecimal, BigDecimal savingsDepositAmount, EnumOptionData savingFrequencyType, EnumOptionData savingInterestType, EnumOptionData interestCalculationMethod,
EnumOptionData savingProductType, BigDecimal minimumBalanceForWithdrawal, boolean isPartialDepositAllowed, boolean isLockinPeriodAllowed, Integer lockinPeriod,
EnumOptionData tenureType, Integer tenure, EnumOptionData lockinPeriodType) {
EnumOptionData savingFrequencyType,
EnumOptionData savingInterestType,
EnumOptionData interestCalculationMethod,
BigDecimal minimumBalanceForWithdrawal,
boolean isPartialDepositAllowed, boolean isLockinPeriodAllowed,
Integer lockinPeriod, EnumOptionData lockinPeriodType) {
this.createdOn = createdOn; this.createdOn = createdOn;
this.lastModifedOn = lastModifedOn; this.lastModifedOn = lastModifedOn;
this.id = id; this.id = id;
@@ -105,13 +99,9 @@ public class SavingProductData implements Serializable {
this.lockinPeriodType = lockinPeriodType; this.lockinPeriodType = lockinPeriodType;
} }
public SavingProductData(SavingProductData product, public SavingProductData(SavingProductData product, List<CurrencyData> currencyOptions, List<EnumOptionData> savingsProductTypeOptions,
List<CurrencyData> currencyOptions, List<EnumOptionData> tenureTypeOptions, List<EnumOptionData> savingFrequencyOptions,
List<EnumOptionData> savingsProductTypeOptions, List<EnumOptionData> savingsInterestTypeOptions, List<EnumOptionData> lockinPeriodTypeOptions,
List<EnumOptionData> tenureTypeOptions,
List<EnumOptionData> savingFrequencyOptions,
List<EnumOptionData> savingsInterestTypeOptions,
List<EnumOptionData> lockinPeriodTypeOptions,
List<EnumOptionData> interestCalculationOptions) { List<EnumOptionData> interestCalculationOptions) {
this.createdOn = product.getCreatedOn(); this.createdOn = product.getCreatedOn();
@@ -3,6 +3,7 @@ package org.mifosplatform.portfolio.savingsaccountproduct.data;
import java.io.Serializable; import java.io.Serializable;
public class SavingProductLookup implements Serializable { public class SavingProductLookup implements Serializable {
private Long id; private Long id;
private String name; private String name;
@@ -1,14 +1,9 @@
package org.mifosplatform.portfolio.savingsaccountproduct.domain; package org.mifosplatform.portfolio.savingsaccountproduct.domain;
public enum SavingFrequencyType { public enum SavingFrequencyType {
INVALID(0,"savingFrequencyType.invalid"), INVALID(0, "savingFrequencyType.invalid"), DAILY(1, "savingFrequencyType.daily"), MONTHLY(2, "savingFrequencyType.monthly"), QUATERLY(
DAILY(1,"savingFrequencyType.daily"), 3, "savingFrequencyType.quaterly"), HALFYEARLY(4, "savingFrequencyType.halfyearly"), YEARLY(5, "savingFrequencyType.yearly");
MONTHLY(2,"savingFrequencyType.monthly"),
QUATERLY(3,"savingFrequencyType.quaterly"),
HALFYEARLY(4,"savingFrequencyType.halfyearly"),
YEARLY(5,"savingFrequencyType.yearly");
private final Integer value; private final Integer value;
private final String code; private final String code;
@@ -21,6 +16,7 @@ public enum SavingFrequencyType {
public Integer getValue() { public Integer getValue() {
return value; return value;
} }
public String getCode() { public String getCode() {
return code; return code;
} }
@@ -2,10 +2,8 @@ package org.mifosplatform.portfolio.savingsaccountproduct.domain;
public enum SavingInterestCalculationMethod { public enum SavingInterestCalculationMethod {
AVERAGEBAL(1,"savinginterest.calculation.method.averagebal"), AVERAGEBAL(1, "savinginterest.calculation.method.averagebal"), MINBAL(2, "savinginterest.calculation.method.minbal"), MONTHLYCOLLECTION(
MINBAL(2,"savinginterest.calculation.method.minbal"), 3, "savinginterest.calculation.method.monthlycllection"), INVALID(0, "savinginterest.calculation.method.invalid");
MONTHLYCOLLECTION(3,"savinginterest.calculation.method.monthlycllection"),
INVALID(0,"savinginterest.calculation.method.invalid");
private final Integer value; private final Integer value;
private final String code; private final String code;
@@ -22,6 +20,7 @@ public enum SavingInterestCalculationMethod {
public String getCode() { public String getCode() {
return code; return code;
} }
public static SavingInterestCalculationMethod fromInt(final Integer frequency) { public static SavingInterestCalculationMethod fromInt(final Integer frequency) {
SavingInterestCalculationMethod savingInterestCalculationMethod = SavingInterestCalculationMethod.INVALID; SavingInterestCalculationMethod savingInterestCalculationMethod = SavingInterestCalculationMethod.INVALID;
@@ -37,10 +37,13 @@ public class SavingProduct extends AbstractAuditableCustom<AppUser, Long> {
this.savingProductRelatedDetail = null; this.savingProductRelatedDetail = null;
} }
public SavingProduct(final String name, final String description, final MonetaryCurrency currency,final BigDecimal interestRate, final BigDecimal minInterestRate, final BigDecimal maxInterestRate, final BigDecimal savingsDepositAmount, public SavingProduct(final String name, final String description, final MonetaryCurrency currency, final BigDecimal interestRate,
final SavingProductType savingProductType, final TenureTypeEnum tenureType, final Integer tenure, final SavingFrequencyType savingFrequencyType, final BigDecimal minInterestRate, final BigDecimal maxInterestRate, final BigDecimal savingsDepositAmount,
final SavingsInterestType savingsInterestType, SavingInterestCalculationMethod savingInterestCalculationMethod, final BigDecimal minimumBalanceForWithdrawal, final SavingProductType savingProductType, final TenureTypeEnum tenureType, final Integer tenure,
final boolean isPartialDepositAllowed, final boolean isLockinPeriodAllowed, final Integer lockinPeriod, final PeriodFrequencyType lockinPeriodType){ final SavingFrequencyType savingFrequencyType, final SavingsInterestType savingsInterestType,
SavingInterestCalculationMethod savingInterestCalculationMethod, final BigDecimal minimumBalanceForWithdrawal,
final boolean isPartialDepositAllowed, final boolean isLockinPeriodAllowed, final Integer lockinPeriod,
final PeriodFrequencyType lockinPeriodType) {
this.name = name.trim(); this.name = name.trim();
if (StringUtils.isNotBlank(description)) { if (StringUtils.isNotBlank(description)) {
@@ -48,8 +51,10 @@ public class SavingProduct extends AbstractAuditableCustom<AppUser, Long> {
} else { } else {
this.description = null; this.description = null;
} }
this.savingProductRelatedDetail = new SavingProductRelatedDetail(currency, interestRate, minInterestRate, maxInterestRate, savingsDepositAmount, savingProductType, tenureType, tenure, this.savingProductRelatedDetail = new SavingProductRelatedDetail(currency, interestRate, minInterestRate, maxInterestRate,
savingFrequencyType, savingsInterestType, savingInterestCalculationMethod, minimumBalanceForWithdrawal, isPartialDepositAllowed, isLockinPeriodAllowed, lockinPeriod, lockinPeriodType); savingsDepositAmount, savingProductType, tenureType, tenure, savingFrequencyType, savingsInterestType,
savingInterestCalculationMethod, minimumBalanceForWithdrawal, isPartialDepositAllowed, isLockinPeriodAllowed, lockinPeriod,
lockinPeriodType);
} }
public String getName() { public String getName() {
@@ -69,13 +69,11 @@ public class SavingProductRelatedDetail {
this.savingsDepositAmount = null; this.savingsDepositAmount = null;
} }
public SavingProductRelatedDetail(final MonetaryCurrency currency,final BigDecimal interestRate, final BigDecimal minInterestRate, final BigDecimal maxInterestRate, public SavingProductRelatedDetail(final MonetaryCurrency currency, final BigDecimal interestRate, final BigDecimal minInterestRate,
final BigDecimal savingsDepositAmount, final SavingProductType savingProductType, final BigDecimal maxInterestRate, final BigDecimal savingsDepositAmount, final SavingProductType savingProductType,
final TenureTypeEnum tenureType, final Integer tenure, final TenureTypeEnum tenureType, final Integer tenure, final SavingFrequencyType frequency,
final SavingFrequencyType frequency, final SavingsInterestType interestType, final SavingsInterestType interestType, final SavingInterestCalculationMethod interestCalculationMethod,
final SavingInterestCalculationMethod interestCalculationMethod, final BigDecimal minimumBalanceForWithdrawal, final boolean isPartialDepositAllowed, final boolean isLockinPeriodAllowed,
final BigDecimal minimumBalanceForWithdrawal,
final boolean isPartialDepositAllowed, final boolean isLockinPeriodAllowed,
final Integer lockinPeriod, final PeriodFrequencyType lockinPeriodType) { final Integer lockinPeriod, final PeriodFrequencyType lockinPeriodType) {
this.currency = currency; this.currency = currency;
this.interestRate = interestRate; this.interestRate = interestRate;
@@ -3,8 +3,6 @@ package org.mifosplatform.portfolio.savingsaccountproduct.domain;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
public interface SavingProductRepository extends public interface SavingProductRepository extends JpaRepository<SavingProduct, Long>, JpaSpecificationExecutor<SavingProduct> {
JpaRepository<SavingProduct, Long>, //
JpaSpecificationExecutor<SavingProduct> {
} }
@@ -1,11 +1,8 @@
package org.mifosplatform.portfolio.savingsaccountproduct.domain; package org.mifosplatform.portfolio.savingsaccountproduct.domain;
public enum SavingProductType { public enum SavingProductType {
INVALID(0,"savingProductType.invalid"), INVALID(0, "savingProductType.invalid"), RECCURING(1, "savingProductType.reccuring"), REGULAR(2, "savingProductType.regular");
RECCURING(1,"savingProductType.reccuring"),
REGULAR(2,"savingProductType.regular");
private final Integer value; private final Integer value;
private final String code; private final String code;
@@ -18,6 +15,7 @@ public enum SavingProductType {
public Integer getValue() { public Integer getValue() {
return value; return value;
} }
public String getCode() { public String getCode() {
return code; return code;
} }
@@ -1,11 +1,8 @@
package org.mifosplatform.portfolio.savingsaccountproduct.domain; package org.mifosplatform.portfolio.savingsaccountproduct.domain;
public enum SavingsInterestType { public enum SavingsInterestType {
INVALID(0,"savingsInterestType.invalid"), INVALID(0, "savingsInterestType.invalid"), SIMPLE(1, "savingsInterestType.simple"), COMPOUNDING(2, "savingsInterestType.compounding");
SIMPLE(1,"savingsInterestType.simple"),
COMPOUNDING(2,"savingsInterestType.compounding");
private final Integer value; private final Integer value;
private final String code; private final String code;
@@ -18,6 +15,7 @@ public enum SavingsInterestType {
public Integer getValue() { public Integer getValue() {
return value; return value;
} }
public String getCode() { public String getCode() {
return code; return code;
} }
@@ -1,6 +1,5 @@
package org.mifosplatform.portfolio.savingsaccountproduct.domain; package org.mifosplatform.portfolio.savingsaccountproduct.domain;
public enum SavingsLockinPeriodEnum { public enum SavingsLockinPeriodEnum {
DAYS(0, "lockin.period.type.days"), // DAYS(0, "lockin.period.type.days"), //
@@ -48,5 +47,4 @@ public enum SavingsLockinPeriodEnum {
return lockinPeriodType; return lockinPeriodType;
} }
} }
@@ -2,11 +2,9 @@ package org.mifosplatform.portfolio.savingsaccountproduct.exception;
import org.mifosplatform.infrastructure.core.exception.AbstractPlatformResourceNotFoundException; import org.mifosplatform.infrastructure.core.exception.AbstractPlatformResourceNotFoundException;
public class SavingProductNotFoundException extends public class SavingProductNotFoundException extends AbstractPlatformResourceNotFoundException {
AbstractPlatformResourceNotFoundException {
public SavingProductNotFoundException(Long id) { public SavingProductNotFoundException(Long id) {
super("error.msg.savingproduct.id.invalid", "Saving product with identifier " + id + " does not exist", id); super("error.msg.savingproduct.id.invalid", "Saving product with identifier " + id + " does not exist", id);
} }
} }
@@ -29,25 +29,31 @@ public class SavingProductCommandValidator {
baseDataValidator.reset().parameter("interestRate").value(command.getInterestRate()).ignoreIfNull().notBlank(); baseDataValidator.reset().parameter("interestRate").value(command.getInterestRate()).ignoreIfNull().notBlank();
baseDataValidator.reset().parameter("minInterestRate").value(command.getMinInterestRate()).ignoreIfNull().notBlank(); baseDataValidator.reset().parameter("minInterestRate").value(command.getMinInterestRate()).ignoreIfNull().notBlank();
baseDataValidator.reset().parameter("maxInterestRate").value(command.getMaxInterestRate()).ignoreIfNull().notBlank(); baseDataValidator.reset().parameter("maxInterestRate").value(command.getMaxInterestRate()).ignoreIfNull().notBlank();
baseDataValidator.reset().parameter("minInterestRate").comapareMinAndMaxOfTwoBigDecmimalNos(command.getMinInterestRate(), command.getMaxInterestRate()); baseDataValidator.reset().parameter("minInterestRate")
baseDataValidator.reset().parameter("interestRate").comapareMinAndMaxOfTwoBigDecmimalNos(command.getInterestRate(), command.getMaxInterestRate()); .comapareMinAndMaxOfTwoBigDecmimalNos(command.getMinInterestRate(), command.getMaxInterestRate());
baseDataValidator.reset().parameter("minInterestRate").comapareMinAndMaxOfTwoBigDecmimalNos(command.getMinInterestRate(), command.getInterestRate()); baseDataValidator.reset().parameter("interestRate")
baseDataValidator.reset().parameter("savingsDepositAmount").value(command.getSavingsDepositAmount()).ignoreIfNull().zeroOrPositiveAmount(); .comapareMinAndMaxOfTwoBigDecmimalNos(command.getInterestRate(), command.getMaxInterestRate());
baseDataValidator.reset().parameter("minInterestRate")
.comapareMinAndMaxOfTwoBigDecmimalNos(command.getMinInterestRate(), command.getInterestRate());
baseDataValidator.reset().parameter("savingsDepositAmount").value(command.getSavingsDepositAmount()).ignoreIfNull()
.zeroOrPositiveAmount();
baseDataValidator.reset().parameter("savingProductType").value(command.getSavingProductType()).ignoreIfNull(); baseDataValidator.reset().parameter("savingProductType").value(command.getSavingProductType()).ignoreIfNull();
baseDataValidator.reset().parameter("tenureType").value(command.getTenureType()).ignoreIfNull(); baseDataValidator.reset().parameter("tenureType").value(command.getTenureType()).ignoreIfNull();
baseDataValidator.reset().parameter("tenure").value(command.getTenure()).ignoreIfNull(); baseDataValidator.reset().parameter("tenure").value(command.getTenure()).ignoreIfNull();
baseDataValidator.reset().parameter("frequency").value(command.getFrequency()).ignoreIfNull(); baseDataValidator.reset().parameter("frequency").value(command.getFrequency()).ignoreIfNull();
baseDataValidator.reset().parameter("interestType").value(command.getInterestType()).ignoreIfNull(); baseDataValidator.reset().parameter("interestType").value(command.getInterestType()).ignoreIfNull();
baseDataValidator.reset().parameter("interestCalculationMethod").value(command.getInterestCalculationMethod()).ignoreIfNull(); baseDataValidator.reset().parameter("interestCalculationMethod").value(command.getInterestCalculationMethod()).ignoreIfNull();
baseDataValidator.reset().parameter("minimumBalanceForWithdrawal").value(command.getMinimumBalanceForWithdrawal()).ignoreIfNull().zeroOrPositiveAmount(); baseDataValidator.reset().parameter("minimumBalanceForWithdrawal").value(command.getMinimumBalanceForWithdrawal()).ignoreIfNull()
baseDataValidator.reset().parameter("isPartialDepositAllowed").value(command.isPartialDepositAllowed()).trueOrFalseRequired(command.isPartialDepositAllowedChanged()).ignoreIfNull(); .zeroOrPositiveAmount();
baseDataValidator.reset().parameter("isLockinPeriodAllowed").value(command.isLockinPeriodAllowed()).trueOrFalseRequired(command.isLockinPeriodAllowedChanged()).ignoreIfNull(); baseDataValidator.reset().parameter("isPartialDepositAllowed").value(command.isPartialDepositAllowed())
.trueOrFalseRequired(command.isPartialDepositAllowedChanged()).ignoreIfNull();
baseDataValidator.reset().parameter("isLockinPeriodAllowed").value(command.isLockinPeriodAllowed())
.trueOrFalseRequired(command.isLockinPeriodAllowedChanged()).ignoreIfNull();
baseDataValidator.reset().parameter("lockinPeriod").value(command.getLockinPeriod()).ignoreIfNull(); baseDataValidator.reset().parameter("lockinPeriod").value(command.getLockinPeriod()).ignoreIfNull();
baseDataValidator.reset().parameter("lockinPeriodType").value(command.getLockinPeriodType()).ignoreIfNull(); baseDataValidator.reset().parameter("lockinPeriodType").value(command.getLockinPeriodType()).ignoreIfNull();
if (!dataValidationErrors.isEmpty()) { if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.", dataValidationErrors); "Validation errors exist.", dataValidationErrors); }
}
} }
public void validateForCreate() { public void validateForCreate() {
@@ -62,24 +68,30 @@ public class SavingProductCommandValidator {
baseDataValidator.reset().parameter("interestRate").value(command.getInterestRate()).notNull().zeroOrPositiveAmount(); baseDataValidator.reset().parameter("interestRate").value(command.getInterestRate()).notNull().zeroOrPositiveAmount();
baseDataValidator.reset().parameter("minInterestRate").value(command.getMinInterestRate()).notNull().zeroOrPositiveAmount(); baseDataValidator.reset().parameter("minInterestRate").value(command.getMinInterestRate()).notNull().zeroOrPositiveAmount();
baseDataValidator.reset().parameter("maxInterestRate").value(command.getMaxInterestRate()).notNull().zeroOrPositiveAmount(); baseDataValidator.reset().parameter("maxInterestRate").value(command.getMaxInterestRate()).notNull().zeroOrPositiveAmount();
baseDataValidator.reset().parameter("minInterestRate").comapareMinAndMaxOfTwoBigDecmimalNos(command.getMinInterestRate(), command.getMaxInterestRate()); baseDataValidator.reset().parameter("minInterestRate")
baseDataValidator.reset().parameter("interestRate").comapareMinAndMaxOfTwoBigDecmimalNos(command.getInterestRate(), command.getMaxInterestRate()); .comapareMinAndMaxOfTwoBigDecmimalNos(command.getMinInterestRate(), command.getMaxInterestRate());
baseDataValidator.reset().parameter("minInterestRate").comapareMinAndMaxOfTwoBigDecmimalNos(command.getMinInterestRate(), command.getInterestRate()); baseDataValidator.reset().parameter("interestRate")
baseDataValidator.reset().parameter("savingsDepositAmount").value(command.getSavingsDepositAmount()).notNull().zeroOrPositiveAmount(); .comapareMinAndMaxOfTwoBigDecmimalNos(command.getInterestRate(), command.getMaxInterestRate());
baseDataValidator.reset().parameter("minInterestRate")
.comapareMinAndMaxOfTwoBigDecmimalNos(command.getMinInterestRate(), command.getInterestRate());
baseDataValidator.reset().parameter("savingsDepositAmount").value(command.getSavingsDepositAmount()).notNull()
.zeroOrPositiveAmount();
baseDataValidator.reset().parameter("savingProductType").value(command.getSavingProductType()).notNull(); baseDataValidator.reset().parameter("savingProductType").value(command.getSavingProductType()).notNull();
baseDataValidator.reset().parameter("tenureType").value(command.getTenureType()).notNull(); baseDataValidator.reset().parameter("tenureType").value(command.getTenureType()).notNull();
baseDataValidator.reset().parameter("tenure").value(command.getTenure()).notNull(); baseDataValidator.reset().parameter("tenure").value(command.getTenure()).notNull();
baseDataValidator.reset().parameter("frequency").value(command.getFrequency()).notNull(); baseDataValidator.reset().parameter("frequency").value(command.getFrequency()).notNull();
baseDataValidator.reset().parameter("interestType").value(command.getInterestType()).notNull(); baseDataValidator.reset().parameter("interestType").value(command.getInterestType()).notNull();
baseDataValidator.reset().parameter("interestCalculationMethod").value(command.getInterestCalculationMethod()).notNull(); baseDataValidator.reset().parameter("interestCalculationMethod").value(command.getInterestCalculationMethod()).notNull();
baseDataValidator.reset().parameter("minimumBalanceForWithdrawal").value(command.getMinimumBalanceForWithdrawal()).notNull().zeroOrPositiveAmount(); baseDataValidator.reset().parameter("minimumBalanceForWithdrawal").value(command.getMinimumBalanceForWithdrawal()).notNull()
baseDataValidator.reset().parameter("isPartialDepositAllowed").value(command.isPartialDepositAllowed()).trueOrFalseRequired(command.isPartialDepositAllowedChanged()).notNull(); .zeroOrPositiveAmount();
baseDataValidator.reset().parameter("isLockinPeriodAllowed").value(command.isLockinPeriodAllowed()).trueOrFalseRequired(command.isLockinPeriodAllowedChanged()).notNull(); baseDataValidator.reset().parameter("isPartialDepositAllowed").value(command.isPartialDepositAllowed())
.trueOrFalseRequired(command.isPartialDepositAllowedChanged()).notNull();
baseDataValidator.reset().parameter("isLockinPeriodAllowed").value(command.isLockinPeriodAllowed())
.trueOrFalseRequired(command.isLockinPeriodAllowedChanged()).notNull();
baseDataValidator.reset().parameter("lockinPeriod").value(command.getLockinPeriod()).notNull(); baseDataValidator.reset().parameter("lockinPeriod").value(command.getLockinPeriod()).notNull();
baseDataValidator.reset().parameter("lockinPeriodType").value(command.getLockinPeriodType()).notNull(); baseDataValidator.reset().parameter("lockinPeriodType").value(command.getLockinPeriodType()).notNull();
if (!dataValidationErrors.isEmpty()) { if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.", dataValidationErrors); "Validation errors exist.", dataValidationErrors); }
}
} }
} }
@@ -39,19 +39,24 @@ public class SavingProductEnumerations {
EnumOptionData optionData = null; EnumOptionData optionData = null;
switch (type) { switch (type) {
case DAYS: case DAYS:
optionData = new EnumOptionData(SavingsLockinPeriodEnum.DAYS.getValue().longValue(), codePrefix+SavingsLockinPeriodEnum.DAYS.getCode(), "Days"); optionData = new EnumOptionData(SavingsLockinPeriodEnum.DAYS.getValue().longValue(), codePrefix
+ SavingsLockinPeriodEnum.DAYS.getCode(), "Days");
break; break;
case MONTHS: case MONTHS:
optionData = new EnumOptionData(SavingsLockinPeriodEnum.MONTHS.getValue().longValue(), codePrefix+SavingsLockinPeriodEnum.MONTHS.getCode(), "Months"); optionData = new EnumOptionData(SavingsLockinPeriodEnum.MONTHS.getValue().longValue(), codePrefix
+ SavingsLockinPeriodEnum.MONTHS.getCode(), "Months");
break; break;
case WEEKS: case WEEKS:
optionData = new EnumOptionData(SavingsLockinPeriodEnum.WEEKS.getValue().longValue(), codePrefix+SavingsLockinPeriodEnum.WEEKS.getCode(), "Weeks"); optionData = new EnumOptionData(SavingsLockinPeriodEnum.WEEKS.getValue().longValue(), codePrefix
+ SavingsLockinPeriodEnum.WEEKS.getCode(), "Weeks");
break; break;
case YEARS: case YEARS:
optionData = new EnumOptionData(SavingsLockinPeriodEnum.YEARS.getValue().longValue(), codePrefix+SavingsLockinPeriodEnum.YEARS.getCode(), "Years"); optionData = new EnumOptionData(SavingsLockinPeriodEnum.YEARS.getValue().longValue(), codePrefix
+ SavingsLockinPeriodEnum.YEARS.getCode(), "Years");
break; break;
default: default:
optionData = new EnumOptionData(SavingsLockinPeriodEnum.INVALID.getValue().longValue(), codePrefix+SavingsLockinPeriodEnum.INVALID.getCode(), "Invalid"); optionData = new EnumOptionData(SavingsLockinPeriodEnum.INVALID.getValue().longValue(), codePrefix
+ SavingsLockinPeriodEnum.INVALID.getCode(), "Invalid");
break; break;
} }
return optionData; return optionData;
@@ -62,19 +67,24 @@ public class SavingProductEnumerations {
EnumOptionData optionData = null; EnumOptionData optionData = null;
switch (type) { switch (type) {
case MINBAL: case MINBAL:
optionData = new EnumOptionData(SavingInterestCalculationMethod.MINBAL.getValue().longValue(), codePrefix+SavingInterestCalculationMethod.MINBAL.getCode(), "Minimumbalance"); optionData = new EnumOptionData(SavingInterestCalculationMethod.MINBAL.getValue().longValue(), codePrefix
+ SavingInterestCalculationMethod.MINBAL.getCode(), "Minimumbalance");
break; break;
case AVERAGEBAL: case AVERAGEBAL:
optionData = new EnumOptionData(SavingInterestCalculationMethod.AVERAGEBAL.getValue().longValue(), codePrefix+SavingInterestCalculationMethod.AVERAGEBAL.getCode(), "AverageBalance"); optionData = new EnumOptionData(SavingInterestCalculationMethod.AVERAGEBAL.getValue().longValue(), codePrefix
+ SavingInterestCalculationMethod.AVERAGEBAL.getCode(), "AverageBalance");
break; break;
case INVALID: case INVALID:
optionData = new EnumOptionData(SavingInterestCalculationMethod.INVALID.getValue().longValue(), codePrefix+SavingInterestCalculationMethod.INVALID.getCode(), "Invalid"); optionData = new EnumOptionData(SavingInterestCalculationMethod.INVALID.getValue().longValue(), codePrefix
+ SavingInterestCalculationMethod.INVALID.getCode(), "Invalid");
break; break;
case MONTHLYCOLLECTION: case MONTHLYCOLLECTION:
optionData = new EnumOptionData(SavingInterestCalculationMethod.MONTHLYCOLLECTION.getValue().longValue(), codePrefix+SavingInterestCalculationMethod.MONTHLYCOLLECTION.getCode(), "MonthlyCollection"); optionData = new EnumOptionData(SavingInterestCalculationMethod.MONTHLYCOLLECTION.getValue().longValue(), codePrefix
+ SavingInterestCalculationMethod.MONTHLYCOLLECTION.getCode(), "MonthlyCollection");
break; break;
default: default:
optionData = new EnumOptionData(SavingInterestCalculationMethod.INVALID.getValue().longValue(), codePrefix+SavingInterestCalculationMethod.INVALID.getCode(), "Invalid"); optionData = new EnumOptionData(SavingInterestCalculationMethod.INVALID.getValue().longValue(), codePrefix
+ SavingInterestCalculationMethod.INVALID.getCode(), "Invalid");
break; break;
} }
return optionData; return optionData;
@@ -85,13 +95,16 @@ public class SavingProductEnumerations {
EnumOptionData optionData = null; EnumOptionData optionData = null;
switch (type) { switch (type) {
case COMPOUNDING: case COMPOUNDING:
optionData = new EnumOptionData(SavingsInterestType.COMPOUNDING.getValue().longValue(), codePrefix+SavingsInterestType.COMPOUNDING.getCode(), "Compounding"); optionData = new EnumOptionData(SavingsInterestType.COMPOUNDING.getValue().longValue(), codePrefix
+ SavingsInterestType.COMPOUNDING.getCode(), "Compounding");
break; break;
case SIMPLE: case SIMPLE:
optionData = new EnumOptionData(SavingsInterestType.SIMPLE.getValue().longValue(), codePrefix+SavingsInterestType.SIMPLE.getCode(), "Simple"); optionData = new EnumOptionData(SavingsInterestType.SIMPLE.getValue().longValue(), codePrefix
+ SavingsInterestType.SIMPLE.getCode(), "Simple");
break; break;
default: default:
optionData = new EnumOptionData(SavingsInterestType.INVALID.getValue().longValue(), codePrefix+SavingsInterestType.INVALID.getCode(), "Invalid"); optionData = new EnumOptionData(SavingsInterestType.INVALID.getValue().longValue(), codePrefix
+ SavingsInterestType.INVALID.getCode(), "Invalid");
break; break;
} }
return optionData; return optionData;
@@ -102,22 +115,28 @@ public class SavingProductEnumerations {
EnumOptionData optionData = null; EnumOptionData optionData = null;
switch (type) { switch (type) {
case DAILY: case DAILY:
optionData = new EnumOptionData(SavingFrequencyType.DAILY.getValue().longValue(), codePrefix + SavingFrequencyType.DAILY.getCode(), "Days"); optionData = new EnumOptionData(SavingFrequencyType.DAILY.getValue().longValue(), codePrefix
+ SavingFrequencyType.DAILY.getCode(), "Days");
break; break;
case MONTHLY: case MONTHLY:
optionData = new EnumOptionData(SavingFrequencyType.MONTHLY.getValue().longValue(), codePrefix + SavingFrequencyType.MONTHLY.getCode(), "Weeks"); optionData = new EnumOptionData(SavingFrequencyType.MONTHLY.getValue().longValue(), codePrefix
+ SavingFrequencyType.MONTHLY.getCode(), "Weeks");
break; break;
case QUATERLY: case QUATERLY:
optionData = new EnumOptionData(SavingFrequencyType.QUATERLY.getValue().longValue(), codePrefix + SavingFrequencyType.QUATERLY.getCode(), "Months"); optionData = new EnumOptionData(SavingFrequencyType.QUATERLY.getValue().longValue(), codePrefix
+ SavingFrequencyType.QUATERLY.getCode(), "Months");
break; break;
case HALFYEARLY: case HALFYEARLY:
optionData = new EnumOptionData(SavingFrequencyType.HALFYEARLY.getValue().longValue(), codePrefix + SavingFrequencyType.HALFYEARLY.getCode(), "Months"); optionData = new EnumOptionData(SavingFrequencyType.HALFYEARLY.getValue().longValue(), codePrefix
+ SavingFrequencyType.HALFYEARLY.getCode(), "Months");
break; break;
case YEARLY: case YEARLY:
optionData = new EnumOptionData(SavingFrequencyType.YEARLY.getValue().longValue(), codePrefix + SavingFrequencyType.YEARLY.getCode(), "Yearly"); optionData = new EnumOptionData(SavingFrequencyType.YEARLY.getValue().longValue(), codePrefix
+ SavingFrequencyType.YEARLY.getCode(), "Yearly");
break; break;
default: default:
optionData = new EnumOptionData(SavingFrequencyType.INVALID.getValue().longValue(), SavingFrequencyType.INVALID.getCode(), "Invalid"); optionData = new EnumOptionData(SavingFrequencyType.INVALID.getValue().longValue(), SavingFrequencyType.INVALID.getCode(),
"Invalid");
break; break;
} }
return optionData; return optionData;
@@ -128,13 +147,16 @@ public class SavingProductEnumerations {
EnumOptionData optionData = null; EnumOptionData optionData = null;
switch (type) { switch (type) {
case FIXED_PERIOD: case FIXED_PERIOD:
optionData = new EnumOptionData(TenureTypeEnum.FIXED_PERIOD.getValue().longValue(), codePrefix+TenureTypeEnum.FIXED_PERIOD.getCode(), "FixedPeriod"); optionData = new EnumOptionData(TenureTypeEnum.FIXED_PERIOD.getValue().longValue(), codePrefix
+ TenureTypeEnum.FIXED_PERIOD.getCode(), "FixedPeriod");
break; break;
case PERPETUAL: case PERPETUAL:
optionData = new EnumOptionData(TenureTypeEnum.PERPETUAL.getValue().longValue(), codePrefix+TenureTypeEnum.PERPETUAL.getCode(), "Perpetual"); optionData = new EnumOptionData(TenureTypeEnum.PERPETUAL.getValue().longValue(), codePrefix
+ TenureTypeEnum.PERPETUAL.getCode(), "Perpetual");
break; break;
default: default:
optionData = new EnumOptionData(TenureTypeEnum.INVALID.getValue().longValue(), codePrefix+TenureTypeEnum.INVALID.getCode(), "Invalid"); optionData = new EnumOptionData(TenureTypeEnum.INVALID.getValue().longValue(), codePrefix
+ TenureTypeEnum.INVALID.getCode(), "Invalid");
break; break;
} }
return optionData; return optionData;
@@ -145,16 +167,20 @@ public class SavingProductEnumerations {
EnumOptionData optionData = null; EnumOptionData optionData = null;
switch (type) { switch (type) {
case RECCURING: case RECCURING:
optionData = new EnumOptionData(SavingProductType.RECCURING.getValue().longValue(), codePrefix + SavingProductType.RECCURING.getCode(), "Reccuring"); optionData = new EnumOptionData(SavingProductType.RECCURING.getValue().longValue(), codePrefix
+ SavingProductType.RECCURING.getCode(), "Reccuring");
break; break;
case REGULAR: case REGULAR:
optionData = new EnumOptionData(SavingProductType.REGULAR.getValue().longValue(), codePrefix + SavingProductType.REGULAR.getCode(), "Regular"); optionData = new EnumOptionData(SavingProductType.REGULAR.getValue().longValue(), codePrefix
+ SavingProductType.REGULAR.getCode(), "Regular");
break; break;
case INVALID: case INVALID:
optionData = new EnumOptionData(SavingProductType.INVALID.getValue().longValue(), codePrefix + SavingProductType.INVALID.getCode(), "Invalid"); optionData = new EnumOptionData(SavingProductType.INVALID.getValue().longValue(), codePrefix
+ SavingProductType.INVALID.getCode(), "Invalid");
break; break;
default: default:
optionData = new EnumOptionData(SavingProductType.INVALID.getValue().longValue(), SavingProductType.INVALID.getCode(), "Invalid"); optionData = new EnumOptionData(SavingProductType.INVALID.getValue().longValue(), SavingProductType.INVALID.getCode(),
"Invalid");
break; break;
} }
return optionData; return optionData;
@@ -25,15 +25,15 @@ import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@Service @Service
public class SavingProductReadPlatformServiceImpl implements public class SavingProductReadPlatformServiceImpl implements SavingProductReadPlatformService {
SavingProductReadPlatformService {
private final PlatformSecurityContext context; private final PlatformSecurityContext context;
private final JdbcTemplate jdbcTemplate; private final JdbcTemplate jdbcTemplate;
private final CurrencyReadPlatformService currencyReadPlatformService; private final CurrencyReadPlatformService currencyReadPlatformService;
@Autowired @Autowired
public SavingProductReadPlatformServiceImpl(final PlatformSecurityContext context,final TenantAwareRoutingDataSource dataSource,final CurrencyReadPlatformService currencyReadPlatformService) { public SavingProductReadPlatformServiceImpl(final PlatformSecurityContext context, final TenantAwareRoutingDataSource dataSource,
final CurrencyReadPlatformService currencyReadPlatformService) {
this.context = context; this.context = context;
jdbcTemplate = new JdbcTemplate(dataSource); jdbcTemplate = new JdbcTemplate(dataSource);
@@ -70,10 +70,8 @@ public class SavingProductReadPlatformServiceImpl implements
try { try {
this.context.authenticatedUser(); this.context.authenticatedUser();
SavingProductMapper savingProductMapper = new SavingProductMapper(); SavingProductMapper savingProductMapper = new SavingProductMapper();
String sql = "select " + savingProductMapper.savingProductSchema() String sql = "select " + savingProductMapper.savingProductSchema() + " where sp.id = ? and sp.is_deleted=0";
+ " where sp.id = ? and sp.is_deleted=0"; SavingProductData productData = this.jdbcTemplate.queryForObject(sql, savingProductMapper, new Object[] { savingProductId });
SavingProductData productData = this.jdbcTemplate.queryForObject(sql,
savingProductMapper, new Object[] { savingProductId });
populateProductDataWithDropdownOptions(productData); populateProductDataWithDropdownOptions(productData);
@@ -107,8 +105,7 @@ public class SavingProductReadPlatformServiceImpl implements
} }
@Override @Override
public SavingProductData mapRow(ResultSet rs, @SuppressWarnings("unused") int rowNum) public SavingProductData mapRow(ResultSet rs, @SuppressWarnings("unused") int rowNum) throws SQLException {
throws SQLException {
Long id = rs.getLong("id"); Long id = rs.getLong("id");
String name = rs.getString("name"); String name = rs.getString("name");
@@ -120,7 +117,8 @@ public class SavingProductReadPlatformServiceImpl implements
String currencyDisplaySymbol = rs.getString("currencyDisplaySymbol"); String currencyDisplaySymbol = rs.getString("currencyDisplaySymbol");
Integer currencyDigits = JdbcSupport.getInteger(rs, "currencyDigits"); Integer currencyDigits = JdbcSupport.getInteger(rs, "currencyDigits");
CurrencyData currencyData = new CurrencyData(currencyCode,currencyName, currencyDigits, currencyDisplaySymbol,currencyNameCode); CurrencyData currencyData = new CurrencyData(currencyCode, currencyName, currencyDigits, currencyDisplaySymbol,
currencyNameCode);
BigDecimal interestRate = rs.getBigDecimal("interestRate"); BigDecimal interestRate = rs.getBigDecimal("interestRate");
BigDecimal minInterestRate = rs.getBigDecimal("minInterestRate"); BigDecimal minInterestRate = rs.getBigDecimal("minInterestRate");
BigDecimal maxInterestRate = rs.getBigDecimal("maxInterstRate"); BigDecimal maxInterestRate = rs.getBigDecimal("maxInterstRate");
@@ -129,34 +127,36 @@ public class SavingProductReadPlatformServiceImpl implements
DateTime lastModifedOn = JdbcSupport.getDateTime(rs, "modifiedon"); DateTime lastModifedOn = JdbcSupport.getDateTime(rs, "modifiedon");
BigDecimal savingsDepositAmount = rs.getBigDecimal("savingsDepositAmount"); BigDecimal savingsDepositAmount = rs.getBigDecimal("savingsDepositAmount");
EnumOptionData savingProductTypeEnum=SavingProductEnumerations.savingProductType(SavingProductType.fromInt(JdbcSupport.getInteger(rs, "savingProductType"))); EnumOptionData savingProductTypeEnum = SavingProductEnumerations.savingProductType(SavingProductType.fromInt(JdbcSupport
.getInteger(rs, "savingProductType")));
EnumOptionData tenureTypeEnum = SavingProductEnumerations.tenureTypeEnum(JdbcSupport.getInteger(rs, "tenureType")); EnumOptionData tenureTypeEnum = SavingProductEnumerations.tenureTypeEnum(JdbcSupport.getInteger(rs, "tenureType"));
Integer tenure = JdbcSupport.getInteger(rs, "tenure"); Integer tenure = JdbcSupport.getInteger(rs, "tenure");
EnumOptionData savingFrequencyType = SavingProductEnumerations.interestFrequencyType(JdbcSupport.getInteger(rs, "frequency")); EnumOptionData savingFrequencyType = SavingProductEnumerations.interestFrequencyType(JdbcSupport.getInteger(rs, "frequency"));
EnumOptionData savingInterestType = SavingProductEnumerations.savingInterestType(JdbcSupport.getInteger(rs, "interestType")); EnumOptionData savingInterestType = SavingProductEnumerations.savingInterestType(JdbcSupport.getInteger(rs, "interestType"));
EnumOptionData interestCalculationMethodEnum=SavingProductEnumerations.savingInterestCalculationMethod(JdbcSupport.getInteger(rs, "interestCalculationMethod")); EnumOptionData interestCalculationMethodEnum = SavingProductEnumerations.savingInterestCalculationMethod(JdbcSupport
.getInteger(rs, "interestCalculationMethod"));
BigDecimal minimumBalanceForWithdrawal = rs.getBigDecimal("minimumBalanceForWithdrawal"); BigDecimal minimumBalanceForWithdrawal = rs.getBigDecimal("minimumBalanceForWithdrawal");
boolean isPartialDepositAllowed = rs.getBoolean("isPartialDepositAllowed"); boolean isPartialDepositAllowed = rs.getBoolean("isPartialDepositAllowed");
boolean isLockinPeriodAllowed = rs.getBoolean("isLockinPeriodAllowed"); boolean isLockinPeriodAllowed = rs.getBoolean("isLockinPeriodAllowed");
Integer lockinPeriod = JdbcSupport.getInteger(rs, "lockinPeriod"); Integer lockinPeriod = JdbcSupport.getInteger(rs, "lockinPeriod");
EnumOptionData lockinPeriodType= SavingsDepositEnumerations.interestCompoundingPeriodType(PeriodFrequencyType.fromInt(JdbcSupport.getInteger(rs, "lockinPeriodType"))); EnumOptionData lockinPeriodType = SavingsDepositEnumerations.interestCompoundingPeriodType(PeriodFrequencyType
.fromInt(JdbcSupport.getInteger(rs, "lockinPeriodType")));
return new SavingProductData(createdOn, lastModifedOn, id, name, description, interestRate, minInterestRate, maxInterestRate, currencyData, currencyDigits, savingsDepositAmount, return new SavingProductData(createdOn, lastModifedOn, id, name, description, interestRate, minInterestRate, maxInterestRate,
savingProductTypeEnum, tenureTypeEnum, tenure, savingFrequencyType, savingInterestType, interestCalculationMethodEnum, currencyData, currencyDigits, savingsDepositAmount, savingProductTypeEnum, tenureTypeEnum, tenure, savingFrequencyType,
minimumBalanceForWithdrawal, isPartialDepositAllowed, isLockinPeriodAllowed, lockinPeriod, lockinPeriodType); savingInterestType, interestCalculationMethodEnum, minimumBalanceForWithdrawal, isPartialDepositAllowed,
isLockinPeriodAllowed, lockinPeriod, lockinPeriodType);
} }
} }
private static final class SavingProductLookupMapper implements private static final class SavingProductLookupMapper implements RowMapper<SavingProductLookup> {
RowMapper<SavingProductLookup> {
public String savingProductLookupSchema() { public String savingProductLookupSchema() {
return "sp.id as id, sp.name as name from m_product_savings sp"; return "sp.id as id, sp.name as name from m_product_savings sp";
} }
@Override @Override
public SavingProductLookup mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) public SavingProductLookup mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {
throws SQLException {
Long id = rs.getLong("id"); Long id = rs.getLong("id");
String name = rs.getString("name"); String name = rs.getString("name");
@@ -165,6 +165,7 @@ public class SavingProductReadPlatformServiceImpl implements
} }
} }
private void populateProductDataWithDropdownOptions(final SavingProductData productData) { private void populateProductDataWithDropdownOptions(final SavingProductData productData) {
List<CurrencyData> currencyOptions = currencyReadPlatformService.retrieveAllowedCurrencies(); List<CurrencyData> currencyOptions = currencyReadPlatformService.retrieveAllowedCurrencies();
@@ -25,7 +25,8 @@ public class SavingProductWritePlatformServiceJpaRepositoryImpl implements Savin
private final SavingProductRepository savingProductRepository; private final SavingProductRepository savingProductRepository;
@Autowired @Autowired
public SavingProductWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, final SavingProductRepository savingProductRepository) { public SavingProductWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context,
final SavingProductRepository savingProductRepository) {
this.context = context; this.context = context;
this.savingProductRepository = savingProductRepository; this.savingProductRepository = savingProductRepository;
} }
@@ -43,13 +44,15 @@ public class SavingProductWritePlatformServiceJpaRepositoryImpl implements Savin
SavingFrequencyType savingFrequencyType = SavingFrequencyType.fromInt(command.getFrequency()); SavingFrequencyType savingFrequencyType = SavingFrequencyType.fromInt(command.getFrequency());
SavingsInterestType interestType = SavingsInterestType.fromInt(command.getInterestType()); SavingsInterestType interestType = SavingsInterestType.fromInt(command.getInterestType());
PeriodFrequencyType lockinPeriodType = PeriodFrequencyType.fromInt(command.getLockinPeriodType()); PeriodFrequencyType lockinPeriodType = PeriodFrequencyType.fromInt(command.getLockinPeriodType());
SavingInterestCalculationMethod savingInterestCalculationMethod=SavingInterestCalculationMethod.fromInt(command.getInterestCalculationMethod()); SavingInterestCalculationMethod savingInterestCalculationMethod = SavingInterestCalculationMethod.fromInt(command
.getInterestCalculationMethod());
MonetaryCurrency currency = new MonetaryCurrency(command.getCurrencyCode(), command.getDigitsAfterDecimal()); MonetaryCurrency currency = new MonetaryCurrency(command.getCurrencyCode(), command.getDigitsAfterDecimal());
SavingProduct product = new SavingProduct(command.getName(), command.getDescription(), currency, command.getInterestRate(), command.getMinInterestRate(), command.getMaxInterestRate(), SavingProduct product = new SavingProduct(command.getName(), command.getDescription(), currency, command.getInterestRate(),
command.getSavingsDepositAmount(), savingProductType, tenureType, command.getTenure(), savingFrequencyType, interestType, command.getMinInterestRate(), command.getMaxInterestRate(), command.getSavingsDepositAmount(), savingProductType,
savingInterestCalculationMethod, command.getMinimumBalanceForWithdrawal(), command.isPartialDepositAllowed(), tenureType, command.getTenure(), savingFrequencyType, interestType, savingInterestCalculationMethod,
command.isLockinPeriodAllowed(), command.getLockinPeriod(), lockinPeriodType); command.getMinimumBalanceForWithdrawal(), command.isPartialDepositAllowed(), command.isLockinPeriodAllowed(),
command.getLockinPeriod(), lockinPeriodType);
this.savingProductRepository.save(product); this.savingProductRepository.save(product);
return new EntityIdentifier(product.getId()); return new EntityIdentifier(product.getId());
@@ -64,9 +67,7 @@ public class SavingProductWritePlatformServiceJpaRepositoryImpl implements Savin
validator.validateForUpdate(); validator.validateForUpdate();
SavingProduct product = this.savingProductRepository.findOne(command.getId()); SavingProduct product = this.savingProductRepository.findOne(command.getId());
if (product == null) { if (product == null) { throw new SavingProductNotFoundException(command.getId()); }
throw new SavingProductNotFoundException(command.getId());
}
product.update(command); product.update(command);
this.savingProductRepository.save(product); this.savingProductRepository.save(product);
return new EntityIdentifier(Long.valueOf(product.getId())); return new EntityIdentifier(Long.valueOf(product.getId()));
@@ -78,13 +79,10 @@ public class SavingProductWritePlatformServiceJpaRepositoryImpl implements Savin
this.context.authenticatedUser(); this.context.authenticatedUser();
SavingProduct product = this.savingProductRepository.findOne(productId); SavingProduct product = this.savingProductRepository.findOne(productId);
if (product==null || product.isDeleted()) { if (product == null || product.isDeleted()) { throw new SavingsProductNotFoundException(productId); }
throw new SavingsProductNotFoundException(productId);
}
product.delete(); product.delete();
this.savingProductRepository.save(product); this.savingProductRepository.save(product);
return new EntityIdentifier(Long.valueOf(product.getId())); return new EntityIdentifier(Long.valueOf(product.getId()));
} }
} }
@@ -14,16 +14,20 @@ public class SavingsDepositEnumerations {
EnumOptionData optionData = null; EnumOptionData optionData = null;
switch (type) { switch (type) {
case DAYS: case DAYS:
optionData = new EnumOptionData(PeriodFrequencyType.DAYS.getValue().longValue(), codePrefix + PeriodFrequencyType.DAYS.getCode(), "Days"); optionData = new EnumOptionData(PeriodFrequencyType.DAYS.getValue().longValue(), codePrefix
+ PeriodFrequencyType.DAYS.getCode(), "Days");
break; break;
case WEEKS: case WEEKS:
optionData = new EnumOptionData(PeriodFrequencyType.WEEKS.getValue().longValue(), codePrefix + PeriodFrequencyType.WEEKS.getCode(), "Weeks"); optionData = new EnumOptionData(PeriodFrequencyType.WEEKS.getValue().longValue(), codePrefix
+ PeriodFrequencyType.WEEKS.getCode(), "Weeks");
break; break;
case MONTHS: case MONTHS:
optionData = new EnumOptionData(PeriodFrequencyType.MONTHS.getValue().longValue(), codePrefix + PeriodFrequencyType.MONTHS.getCode(), "Months"); optionData = new EnumOptionData(PeriodFrequencyType.MONTHS.getValue().longValue(), codePrefix
+ PeriodFrequencyType.MONTHS.getCode(), "Months");
break; break;
default: default:
optionData = new EnumOptionData(PeriodFrequencyType.INVALID.getValue().longValue(), PeriodFrequencyType.INVALID.getCode(), "Invalid"); optionData = new EnumOptionData(PeriodFrequencyType.INVALID.getValue().longValue(), PeriodFrequencyType.INVALID.getCode(),
"Invalid");
break; break;
} }
return optionData; return optionData;
@@ -259,13 +259,13 @@ public class DepositAccountsApiResource {
private boolean is(final String commandParam, final String commandValue) { private boolean is(final String commandParam, final String commandValue) {
return StringUtils.isNotBlank(commandParam) && commandParam.trim().equalsIgnoreCase(commandValue); return StringUtils.isNotBlank(commandParam) && commandParam.trim().equalsIgnoreCase(commandValue);
} }
@POST @POST
@Path("postinterest") @Path("postinterest")
@Consumes({ MediaType.APPLICATION_JSON }) @Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON })
public Response postInterest() { public Response postInterest() {
Collection<DepositAccountsForLookup> accounts = this.depositAccountReadPlatformService.retrieveDepositAccountForLookup(); Collection<DepositAccountsForLookup> accounts = this.depositAccountReadPlatformService.retrieveDepositAccountForLookup();
@SuppressWarnings("unused")
EntityIdentifier entityIdentifier = this.depositAccountWritePlatformService.postInterestToDepositAccount(accounts); EntityIdentifier entityIdentifier = this.depositAccountWritePlatformService.postInterestToDepositAccount(accounts);
return Response.ok().entity(entityIdentifier).build(); return Response.ok().entity(entityIdentifier).build();
@@ -523,21 +523,26 @@ public class DepositAccountData {
public LocalDate getNextInterestPostedDate() { public LocalDate getNextInterestPostedDate() {
return this.nextInterestPostedDate; return this.nextInterestPostedDate;
} }
private BigDecimal determineAvailableInterestForWithdrawal(final DepositAccountData account) { private BigDecimal determineAvailableInterestForWithdrawal(final DepositAccountData account) {
BigDecimal availableInterestForWithdrawal = BigDecimal.ZERO; BigDecimal availableInterestForWithdrawal = BigDecimal.ZERO;
if (this.status != null) { if (this.status != null) {
if (account.getStatus().getId() == 300) { if (account.getStatus().getId() == 300) {
BigDecimal interestGettingForPeriod = BigDecimal.valueOf(account.getActualInterestAccrued().doubleValue()/ new Double(account.getTenureInMonths())); BigDecimal interestGettingForPeriod = BigDecimal.valueOf(account.getActualInterestAccrued().doubleValue()
/ new Double(account.getTenureInMonths()));
LocalDate interestWithdrawingDate = new LocalDate().isBefore(getMaturedOn()) ? new LocalDate() : getMaturedOn().plusDays(1); LocalDate interestWithdrawingDate = new LocalDate().isBefore(getMaturedOn()) ? new LocalDate() : getMaturedOn().plusDays(1);
Integer noOfMonthsforInterestCal = Months.monthsBetween(account.getActualCommencementDate(), interestWithdrawingDate).getMonths(); Integer noOfMonthsforInterestCal = Months.monthsBetween(account.getActualCommencementDate(), interestWithdrawingDate)
.getMonths();
Integer noOfPeriods = noOfMonthsforInterestCal / account.getInterestCompoundedEvery(); Integer noOfPeriods = noOfMonthsforInterestCal / account.getInterestCompoundedEvery();
availableInterestForWithdrawal = BigDecimal.valueOf(interestGettingForPeriod.multiply(new BigDecimal(noOfPeriods)).doubleValue()- account.getInterestPaid().doubleValue()); availableInterestForWithdrawal = BigDecimal.valueOf(interestGettingForPeriod.multiply(new BigDecimal(noOfPeriods))
.doubleValue() - account.getInterestPaid().doubleValue());
} else { } else {
return BigDecimal.ZERO; return BigDecimal.ZERO;
} }
}else return BigDecimal.ZERO; } else
return BigDecimal.ZERO;
return availableInterestForWithdrawal; return availableInterestForWithdrawal;
} }
@@ -547,13 +552,18 @@ public class DepositAccountData {
BigDecimal avalablePreclosureWithdrawalAmount = BigDecimal.ZERO; BigDecimal avalablePreclosureWithdrawalAmount = BigDecimal.ZERO;
if (this.status != null) { if (this.status != null) {
if (account.getStatus().getId() == 300) { if (account.getStatus().getId() == 300) {
// if(new LocalDate().isBefore(account.getMaturedOn()) || new LocalDate().isEqual(account.getMaturedOn())){ // if(new LocalDate().isBefore(account.getMaturedOn()) || new
// LocalDate().isEqual(account.getMaturedOn())){
Integer days = Days.daysBetween(account.getLastInterestPostedDate(), new LocalDate()).getDays(); Integer days = Days.daysBetween(account.getLastInterestPostedDate(), new LocalDate()).getDays();
avalablePreclosureWithdrawalAmount=account.getAvailableInterest().add(account.getDeposit()).add(determineRemainInerestAmount(account.getDeposit(), account.getPreClosureInterestRate(), days)); avalablePreclosureWithdrawalAmount = account.getAvailableInterest().add(account.getDeposit())
.add(determineRemainInerestAmount(account.getDeposit(), account.getPreClosureInterestRate(), days));
// }else if(new LocalDate().isAfter(account.getMaturedOn())){ // }else if(new LocalDate().isAfter(account.getMaturedOn())){
// Integer days = Days.daysBetween(account.getLastInterestPostedDate(), new LocalDate()).getDays(); // Integer days =
// avalablePreclosureWithdrawalAmount=account.getAvailableInterest().add(account.getDeposit()).add(determineRemainInerestAmount(account.getDeposit(), account.getPreClosureInterestRate(), days)); // Days.daysBetween(account.getLastInterestPostedDate(), new
// LocalDate()).getDays();
// avalablePreclosureWithdrawalAmount=account.getAvailableInterest().add(account.getDeposit()).add(determineRemainInerestAmount(account.getDeposit(),
// account.getPreClosureInterestRate(), days));
// } // }
} else { } else {
avalablePreclosureWithdrawalAmount = account.getDeposit(); avalablePreclosureWithdrawalAmount = account.getDeposit();
@@ -562,7 +572,8 @@ public class DepositAccountData {
return avalablePreclosureWithdrawalAmount; return avalablePreclosureWithdrawalAmount;
} }
private BigDecimal determineRemainInerestAmount(final BigDecimal depsoitAmount, final BigDecimal interstRateApplicable, final Integer days){ private BigDecimal determineRemainInerestAmount(final BigDecimal depsoitAmount, final BigDecimal interstRateApplicable,
final Integer days) {
MathContext mc = new MathContext(8, RoundingMode.HALF_EVEN); MathContext mc = new MathContext(8, RoundingMode.HALF_EVEN);
Integer daysInYear = 365; Integer daysInYear = 365;
@@ -18,8 +18,7 @@ public class DepositAccountTransactionData {
private final BigDecimal interestAmount; private final BigDecimal interestAmount;
private final BigDecimal total; private final BigDecimal total;
public DepositAccountTransactionData( public DepositAccountTransactionData(final Long transactionId, final Long accountId, final EnumOptionData transactionType,
final Long transactionId, final Long accountId, final EnumOptionData transactionType,
final LocalDate transactionDate, final BigDecimal transactionAmount, final BigDecimal interstAmount, final BigDecimal total) { final LocalDate transactionDate, final BigDecimal transactionAmount, final BigDecimal interstAmount, final BigDecimal total) {
this.transactionId = transactionId; this.transactionId = transactionId;
this.accountId = accountId; this.accountId = accountId;
@@ -12,9 +12,9 @@ public class DepositPermissionData {
private final boolean anyActionOnAccountAllowed; private final boolean anyActionOnAccountAllowed;
public DepositPermissionData(final boolean rejectAllowed, final boolean withdrawnByApplicantAllowed, final boolean undoApprovalAllowed, public DepositPermissionData(final boolean rejectAllowed, final boolean withdrawnByApplicantAllowed, final boolean undoApprovalAllowed,
final boolean pendingApproval,final boolean interestWithdrawalAllowed, final boolean renewelAllowed, final boolean isMaturedDepositAccount) { final boolean pendingApproval, final boolean interestWithdrawalAllowed, final boolean renewelAllowed,
final boolean isMaturedDepositAccount) {
this.rejectAllowed = rejectAllowed; this.rejectAllowed = rejectAllowed;
this.withdrawnByApplicantAllowed = withdrawnByApplicantAllowed; this.withdrawnByApplicantAllowed = withdrawnByApplicantAllowed;
this.undoApprovalAllowed = undoApprovalAllowed; this.undoApprovalAllowed = undoApprovalAllowed;
@@ -22,8 +22,8 @@ public class DepositPermissionData {
this.isInterestWithdrawalAllowed = interestWithdrawalAllowed; this.isInterestWithdrawalAllowed = interestWithdrawalAllowed;
this.renewelAllowed = renewelAllowed; this.renewelAllowed = renewelAllowed;
this.isMaturedDepositAccount = isMaturedDepositAccount; this.isMaturedDepositAccount = isMaturedDepositAccount;
this.anyActionOnAccountAllowed = isRejectAllowed() || isPendingApproval() || isUndoApprovalAllowed() || isWithdrawnByApplicantAllowed() || this.anyActionOnAccountAllowed = isRejectAllowed() || isPendingApproval() || isUndoApprovalAllowed()
isInterestWithdrawalAllowed() || isRenewelAllowed() || isMaturedDepositAccount(); || isWithdrawnByApplicantAllowed() || isInterestWithdrawalAllowed() || isRenewelAllowed() || isMaturedDepositAccount();
} }
public boolean isRejectAllowed() { public boolean isRejectAllowed() {
@@ -167,33 +167,23 @@ public class DepositAccount extends AbstractAuditableCustom<AppUser, Long> {
@Column(name = "next_interest_posting_date") @Column(name = "next_interest_posting_date")
private Date nextInterestPostingDate; private Date nextInterestPostingDate;
public DepositAccount openNew(final Client client, final DepositProduct product, final String externalId, final Money deposit,
public DepositAccount openNew( final BigDecimal maturityInterestRate, final BigDecimal preClosureInterestRate, final Integer tenureInMonths,
final Client client, final DepositProduct product, final Integer interestCompoundedEvery, final PeriodFrequencyType interestCompoundedFrequencyPeriodType,
final String externalId, final Money deposit, final BigDecimal maturityInterestRate, final BigDecimal preClosureInterestRate, final Integer tenureInMonths, final LocalDate commencementDate, final boolean renewalAllowed, final boolean preClosureAllowed,
final Integer interestCompoundedEvery,
final PeriodFrequencyType interestCompoundedFrequencyPeriodType,
final LocalDate commencementDate,
final boolean renewalAllowed,
final boolean preClosureAllowed,
final FixedTermDepositInterestCalculator fixedTermDepositInterestCalculator, final FixedTermDepositInterestCalculator fixedTermDepositInterestCalculator,
final DepositLifecycleStateMachine depositLifecycleStateMachine, final DepositLifecycleStateMachine depositLifecycleStateMachine, final boolean isInterstWithdrawable,
final boolean isInterstWithdrawable,final boolean interestCompoundingAllowed, final boolean interestCompoundingAllowed, final boolean isLockinPeriodAllowed, final Integer lockinPeriod,
final boolean isLockinPeriodAllowed, final Integer lockinPeriod, final PeriodFrequencyType lockinPeriodType) { final PeriodFrequencyType lockinPeriodType) {
Money futureValueOnMaturity = null; Money futureValueOnMaturity = null;
if (interestCompoundingAllowed) { if (interestCompoundingAllowed) {
futureValueOnMaturity = fixedTermDepositInterestCalculator futureValueOnMaturity = fixedTermDepositInterestCalculator.calculateInterestOnMaturityFor(deposit, tenureInMonths,
.calculateInterestOnMaturityFor(deposit, tenureInMonths, maturityInterestRate, interestCompoundedEvery, interestCompoundedFrequencyPeriodType);
maturityInterestRate, interestCompoundedEvery,
interestCompoundedFrequencyPeriodType);
} else { } else {
futureValueOnMaturity = fixedTermDepositInterestCalculator futureValueOnMaturity = fixedTermDepositInterestCalculator.calculateInterestOnMaturityForSimpleInterest(deposit,
.calculateInterestOnMaturityForSimpleInterest(deposit, tenureInMonths, maturityInterestRate, interestCompoundedEvery, interestCompoundedFrequencyPeriodType);
tenureInMonths, maturityInterestRate,
interestCompoundedEvery,
interestCompoundedFrequencyPeriodType);
} }
DepositAccountStatus from = null; DepositAccountStatus from = null;
@@ -206,27 +196,20 @@ public class DepositAccount extends AbstractAuditableCustom<AppUser, Long> {
return new DepositAccount(client, product, externalId, deposit, maturityInterestRate, preClosureInterestRate, tenureInMonths, return new DepositAccount(client, product, externalId, deposit, maturityInterestRate, preClosureInterestRate, tenureInMonths,
interestCompoundedEvery, interestCompoundedFrequencyPeriodType, commencementDate, renewalAllowed, preClosureAllowed, interestCompoundedEvery, interestCompoundedFrequencyPeriodType, commencementDate, renewalAllowed, preClosureAllowed,
futureValueOnMaturity,depositStatus,isInterstWithdrawable, interestCompoundingAllowed,isLockinPeriodAllowed,lockinPeriod,lockinPeriodType); futureValueOnMaturity, depositStatus, isInterstWithdrawable, interestCompoundingAllowed, isLockinPeriodAllowed,
lockinPeriod, lockinPeriodType);
} }
public DepositAccount() { public DepositAccount() {
this.product = null; this.product = null;
} }
public DepositAccount( public DepositAccount(final Client client, final DepositProduct product, final String externalId, final Money deposit,
final Client client, final DepositProduct product, final BigDecimal interestRate, final BigDecimal preClosureInterestRate, final Integer termInMonths,
final String externalId, final Money deposit, final BigDecimal interestRate, final BigDecimal preClosureInterestRate, final Integer termInMonths, final Integer interestCompoundedEvery, final PeriodFrequencyType interestCompoundedFrequencyPeriodType,
final Integer interestCompoundedEvery, final LocalDate commencementDate, final boolean renewalAllowed, final boolean preClosureAllowed,
final PeriodFrequencyType interestCompoundedFrequencyPeriodType, final Money futureValueOnMaturity, final Integer depositStatus, final boolean isInterestWithdrawable,
final LocalDate commencementDate, final boolean interestCompoundingAllowed, final boolean isLockinPeriodAllowed, final Integer lockinPeriod,
final boolean renewalAllowed,
final boolean preClosureAllowed,
final Money futureValueOnMaturity,
final Integer depositStatus,
final boolean isInterestWithdrawable,
final boolean interestCompoundingAllowed,
final boolean isLockinPeriodAllowed,
final Integer lockinPeriod,
final PeriodFrequencyType lockinPeriodType) { final PeriodFrequencyType lockinPeriodType) {
this.client = client; this.client = client;
this.product = product; this.product = product;
@@ -278,7 +261,8 @@ public class DepositAccount extends AbstractAuditableCustom<AppUser, Long> {
} }
/** /**
* Delete is a <i>soft delete</i>. Updates flag on account so it wont appear in query/report results. * Delete is a <i>soft delete</i>. Updates flag on account so it wont appear
* in query/report results.
* *
* Any fields with unique constraints and prepended with id of record. * Any fields with unique constraints and prepended with id of record.
*/ */
@@ -287,13 +271,11 @@ public class DepositAccount extends AbstractAuditableCustom<AppUser, Long> {
this.externalId = this.getId() + "_" + this.externalId; this.externalId = this.getId() + "_" + this.externalId;
} }
public void approve( public void approve(final LocalDate actualCommencementDate, final DepositLifecycleStateMachine depositLifecycleStateMachine,
final LocalDate actualCommencementDate, final DepositStateTransitionApprovalCommand command, final FixedTermDepositInterestCalculator calculator) {
final DepositLifecycleStateMachine depositLifecycleStateMachine,
final DepositStateTransitionApprovalCommand command,
final FixedTermDepositInterestCalculator calculator) {
DepositAccountStatus statusEnum = depositLifecycleStateMachine.transition(DepositAccountEvent.DEPOSIT_APPROVED, DepositAccountStatus.fromInt(this.depositStatus)); DepositAccountStatus statusEnum = depositLifecycleStateMachine.transition(DepositAccountEvent.DEPOSIT_APPROVED,
DepositAccountStatus.fromInt(this.depositStatus));
this.depositStatus = statusEnum.getValue(); this.depositStatus = statusEnum.getValue();
if (command.getTenureInMonths() != null) { if (command.getTenureInMonths() != null) {
@@ -322,21 +304,17 @@ public class DepositAccount extends AbstractAuditableCustom<AppUser, Long> {
Money futureValueOnMaturity = null; Money futureValueOnMaturity = null;
if (this.interestCompoundingAllowed) { if (this.interestCompoundingAllowed) {
futureValueOnMaturity = calculator.calculateInterestOnMaturityFor( futureValueOnMaturity = calculator.calculateInterestOnMaturityFor(getDeposit(), this.tenureInMonths, this.interestRate,
getDeposit(), this.tenureInMonths, this.interestRate, this.interestCompoundedEvery, getInterestCompoundedFrequencyType());
this.interestCompoundedEvery,
getInterestCompoundedFrequencyType());
} else { } else {
futureValueOnMaturity = calculator futureValueOnMaturity = calculator.calculateInterestOnMaturityForSimpleInterest(getDeposit(), this.tenureInMonths,
.calculateInterestOnMaturityForSimpleInterest(getDeposit(), this.interestRate, this.interestCompoundedEvery, getInterestCompoundedFrequencyType());
this.tenureInMonths, this.interestRate,
this.interestCompoundedEvery,
getInterestCompoundedFrequencyType());
} }
this.interestAccrued = futureValueOnMaturity.minus(getDeposit()).getAmount(); this.interestAccrued = futureValueOnMaturity.minus(getDeposit()).getAmount();
this.total = futureValueOnMaturity.getAmount(); this.total = futureValueOnMaturity.getAmount();
DepositAccountTransaction depositaccountTransaction = DepositAccountTransaction.deposit(getDeposit(), getActualCommencementDate(),getAccuredInterest()); DepositAccountTransaction depositaccountTransaction = DepositAccountTransaction.deposit(getDeposit(), getActualCommencementDate(),
getAccuredInterest());
depositaccountTransaction.updateAccount(this); depositaccountTransaction.updateAccount(this);
this.depositaccountTransactions.add(depositaccountTransaction); this.depositaccountTransactions.add(depositaccountTransaction);
@@ -348,13 +326,16 @@ public class DepositAccount extends AbstractAuditableCustom<AppUser, Long> {
LocalDate submittalDate = new LocalDate(this.projectedCommencementDate); LocalDate submittalDate = new LocalDate(this.projectedCommencementDate);
if (actualCommencementDate.isBefore(submittalDate)) { if (actualCommencementDate.isBefore(submittalDate)) {
final String errorMessage = "The date on which a deposit is approved cannot be before its submittal date: " + submittalDate.toString(); final String errorMessage = "The date on which a deposit is approved cannot be before its submittal date: "
throw new InvalidDepositStateTransitionException("approval", "cannot.be.before.submittal.date", errorMessage, getActualCommencementDate(), submittalDate); + submittalDate.toString();
throw new InvalidDepositStateTransitionException("approval", "cannot.be.before.submittal.date", errorMessage,
getActualCommencementDate(), submittalDate);
} }
if (actualCommencementDate.isAfter(new LocalDate())) { if (actualCommencementDate.isAfter(new LocalDate())) {
final String errorMessage = "The date on which a deposit is approved cannot be in the future."; final String errorMessage = "The date on which a deposit is approved cannot be in the future.";
throw new InvalidDepositStateTransitionException("approval", "cannot.be.a.future.date", errorMessage, getActualCommencementDate()); throw new InvalidDepositStateTransitionException("approval", "cannot.be.a.future.date", errorMessage,
getActualCommencementDate());
} }
} }
@@ -410,11 +391,9 @@ public class DepositAccount extends AbstractAuditableCustom<AppUser, Long> {
return lockinPeriodType; return lockinPeriodType;
} }
public void reject(final LocalDate rejectedOn, public void reject(final LocalDate rejectedOn, final DepositLifecycleStateMachine depositLifecycleStateMachine) {
final DepositLifecycleStateMachine depositLifecycleStateMachine) {
DepositAccountStatus statusEnum = depositLifecycleStateMachine.transition( DepositAccountStatus statusEnum = depositLifecycleStateMachine.transition(DepositAccountEvent.DEPOSIT_REJECTED,
DepositAccountEvent.DEPOSIT_REJECTED,
DepositAccountStatus.fromInt(this.depositStatus)); DepositAccountStatus.fromInt(this.depositStatus));
this.depositStatus = statusEnum.getValue(); this.depositStatus = statusEnum.getValue();
@@ -426,26 +405,22 @@ public class DepositAccount extends AbstractAuditableCustom<AppUser, Long> {
final String errorMessage = "The date on which a deposit is rejected cannot be before its submittal date: " final String errorMessage = "The date on which a deposit is rejected cannot be before its submittal date: "
+ getProjectedCommencementDate().toString(); + getProjectedCommencementDate().toString();
throw new InvalidDepositStateTransitionException("reject", throw new InvalidDepositStateTransitionException("reject", "cannot.be.before.submittal.date", errorMessage, rejectedOn,
"cannot.be.before.submittal.date", errorMessage, getProjectedCommencementDate());
rejectedOn, getProjectedCommencementDate());
} }
if (rejectedOn.isAfter(new LocalDate())) { if (rejectedOn.isAfter(new LocalDate())) {
final String errorMessage = "The date on which a deposit is rejected cannot be in the future."; final String errorMessage = "The date on which a deposit is rejected cannot be in the future.";
throw new InvalidDepositStateTransitionException("reject", throw new InvalidDepositStateTransitionException("reject", "cannot.be.a.future.date", errorMessage, rejectedOn);
"cannot.be.a.future.date", errorMessage, rejectedOn);
} }
} }
public void withdrawnByApplicant(final LocalDate withdrawnOn, public void withdrawnByApplicant(final LocalDate withdrawnOn, final DepositLifecycleStateMachine depositLifecycleStateMachine) {
final DepositLifecycleStateMachine depositLifecycleStateMachine) {
DepositAccountStatus statusEnum = depositLifecycleStateMachine.transition( DepositAccountStatus statusEnum = depositLifecycleStateMachine.transition(DepositAccountEvent.DEPOSIT_WITHDRAWN,
DepositAccountEvent.DEPOSIT_WITHDRAWN,
DepositAccountStatus.fromInt(this.depositStatus)); DepositAccountStatus.fromInt(this.depositStatus));
this.depositStatus = statusEnum.getValue(); this.depositStatus = statusEnum.getValue();
@@ -457,23 +432,20 @@ public class DepositAccount extends AbstractAuditableCustom<AppUser, Long> {
final String errorMessage = "The date on which a deposit is rejected cannot be before its submittal date: " final String errorMessage = "The date on which a deposit is rejected cannot be before its submittal date: "
+ getProjectedCommencementDate().toString(); + getProjectedCommencementDate().toString();
throw new InvalidDepositStateTransitionException("reject", throw new InvalidDepositStateTransitionException("reject", "cannot.be.before.submittal.date", errorMessage, withdrawnOn,
"cannot.be.before.submittal.date", errorMessage, getProjectedCommencementDate());
withdrawnOn, getProjectedCommencementDate());
} }
if (withdrawnOn.isAfter(new LocalDate())) { if (withdrawnOn.isAfter(new LocalDate())) {
final String errorMessage = "The date on which a deposit is rejected cannot be in the future."; final String errorMessage = "The date on which a deposit is rejected cannot be in the future.";
throw new InvalidDepositStateTransitionException("reject", throw new InvalidDepositStateTransitionException("reject", "cannot.be.a.future.date", errorMessage, withdrawnOn);
"cannot.be.a.future.date", errorMessage, withdrawnOn);
} }
} }
public void undoDepositApproval(final DepositLifecycleStateMachine depositLifecycleStateMachine) { public void undoDepositApproval(final DepositLifecycleStateMachine depositLifecycleStateMachine) {
DepositAccountStatus statusEnum = depositLifecycleStateMachine.transition( DepositAccountStatus statusEnum = depositLifecycleStateMachine.transition(DepositAccountEvent.DEPOSIT_APPROVAL_UNDO,
DepositAccountEvent.DEPOSIT_APPROVAL_UNDO,
DepositAccountStatus.fromInt(this.depositStatus)); DepositAccountStatus.fromInt(this.depositStatus));
this.depositStatus = statusEnum.getValue(); this.depositStatus = statusEnum.getValue();
@@ -564,25 +536,32 @@ public class DepositAccount extends AbstractAuditableCustom<AppUser, Long> {
} }
public void withdrawDepositAccountMoney(DepositLifecycleStateMachine depositLifecycleStateMachine, FixedTermDepositInterestCalculator fixedTermDepositInterestCalculator,LocalDate eventDate) { public void withdrawDepositAccountMoney(DepositLifecycleStateMachine depositLifecycleStateMachine,
FixedTermDepositInterestCalculator fixedTermDepositInterestCalculator, LocalDate eventDate) {
if (eventDate.isBefore(getLastInterestPostedDate())) { if (eventDate.isBefore(getLastInterestPostedDate())) {
final String errorMessage = "Deposit Account Preclosed date \"" +eventDate+ "\"cannot before last interest posted date \"" + getLastInterestPostedDate()+"\""; final String errorMessage = "Deposit Account Preclosed date \"" + eventDate + "\"cannot before last interest posted date \""
throw new InvalidDepositStateTransitionException("withdraw", "event.date.cannot.before.last.interest.posted.date",errorMessage, getLastInterestPostedDate(), eventDate); + getLastInterestPostedDate() + "\"";
throw new InvalidDepositStateTransitionException("withdraw", "event.date.cannot.before.last.interest.posted.date",
errorMessage, getLastInterestPostedDate(), eventDate);
} }
if (eventDate.isAfter(maturesOnDate()) || eventDate.equals(maturesOnDate())) { if (eventDate.isAfter(maturesOnDate()) || eventDate.equals(maturesOnDate())) {
DepositAccountStatus statusEnum = depositLifecycleStateMachine.transition(DepositAccountEvent.DEPOSIT_CLOSED, DepositAccountStatus.fromInt(this.depositStatus)); DepositAccountStatus statusEnum = depositLifecycleStateMachine.transition(DepositAccountEvent.DEPOSIT_CLOSED,
DepositAccountStatus.fromInt(this.depositStatus));
this.depositStatus = statusEnum.getValue(); this.depositStatus = statusEnum.getValue();
} else if (eventDate.isBefore(maturesOnDate())) { } else if (eventDate.isBefore(maturesOnDate())) {
DepositAccountStatus statusEnum = depositLifecycleStateMachine.transition(DepositAccountEvent.DEPOSIT_PRECLOSED, DepositAccountStatus.fromInt(this.depositStatus)); DepositAccountStatus statusEnum = depositLifecycleStateMachine.transition(DepositAccountEvent.DEPOSIT_PRECLOSED,
DepositAccountStatus.fromInt(this.depositStatus));
this.depositStatus = statusEnum.getValue(); this.depositStatus = statusEnum.getValue();
} }
Integer days = Days.daysBetween(getLastInterestPostedDate(), eventDate).getDays(); Integer days = Days.daysBetween(getLastInterestPostedDate(), eventDate).getDays();
Money accuredInterestAfterMaturityToTillDate = fixedTermDepositInterestCalculator.calculateRemainInterest(getDeposit(), days, preClosureInterestRate); Money accuredInterestAfterMaturityToTillDate = fixedTermDepositInterestCalculator.calculateRemainInterest(getDeposit(), days,
preClosureInterestRate);
this.interestAccrued = this.interestAccrued.add(accuredInterestAfterMaturityToTillDate.getAmount()); this.interestAccrued = this.interestAccrued.add(accuredInterestAfterMaturityToTillDate.getAmount());
DepositAccountTransaction depositaccountTransaction = DepositAccountTransaction.withdraw(getDeposit(), eventDate,getAccuredInterest()); DepositAccountTransaction depositaccountTransaction = DepositAccountTransaction.withdraw(getDeposit(), eventDate,
getAccuredInterest());
depositaccountTransaction.updateAccount(this); depositaccountTransaction.updateAccount(this);
this.depositaccountTransactions.add(depositaccountTransaction); this.depositaccountTransactions.add(depositaccountTransaction);
@@ -592,41 +571,49 @@ public class DepositAccount extends AbstractAuditableCustom<AppUser, Long> {
} }
/*public void adjustTotalAmountForPreclosureInterest(DepositAccount account, FixedTermDepositInterestCalculator fixedTermDepositInterestCalculator,LocalDate eventDate) { /*
* public void adjustTotalAmountForPreclosureInterest(DepositAccount
LocalDate commnencementDate = getActualCommencementDate(); * account, FixedTermDepositInterestCalculator
LocalDate lastInterestPosedDate = getLastInterestPostedDate(); * fixedTermDepositInterestCalculator,LocalDate eventDate) {
LocalDate preClosedDate = eventDate; *
* LocalDate commnencementDate = getActualCommencementDate(); LocalDate
if (preClosedDate.isBefore(lastInterestPosedDate)) { * lastInterestPosedDate = getLastInterestPostedDate(); LocalDate
throw new DepositAccountTransactionsException("deposit.account.preclosed.date.should.be.after.last.interest.posted.date", null); * preClosedDate = eventDate;
} *
* if (preClosedDate.isBefore(lastInterestPosedDate)) { throw new
Integer tenure = Months.monthsBetween(lastInterestPosedDate, preClosedDate).getMonths(); * DepositAccountTransactionsException
LocalDate actualPrecloseCalculationDate = lastInterestPosedDate.plusMonths(tenure); * ("deposit.account.preclosed.date.should.be.after.last.interest.posted.date"
Integer missedDays = Days.daysBetween(actualPrecloseCalculationDate, preClosedDate).getDays(); * , null); }
*
Money deposit = Money.of(account.getDeposit().getCurrency(), account.getDeposit().getAmount()); * Integer tenure = Months.monthsBetween(lastInterestPosedDate,
Money accuredtotalAmount = null; * preClosedDate).getMonths(); LocalDate actualPrecloseCalculationDate =
Money remainDaysAmount = fixedTermDepositInterestCalculator.calculateRemainInterest(deposit, missedDays, preClosureInterestRate); * lastInterestPosedDate.plusMonths(tenure); Integer missedDays =
if (account.isInterestCompoundingAllowed()) { * Days.daysBetween(actualPrecloseCalculationDate, preClosedDate).getDays();
accuredtotalAmount = fixedTermDepositInterestCalculator *
.calculateInterestOnMaturityFor(deposit, tenure, * Money deposit = Money.of(account.getDeposit().getCurrency(),
preClosureInterestRate, interestCompoundedEvery, * account.getDeposit().getAmount()); Money accuredtotalAmount = null; Money
this.product.getInterestCompoundedEveryPeriodType()); * remainDaysAmount =
accuredtotalAmount = accuredtotalAmount.plus(remainDaysAmount); * fixedTermDepositInterestCalculator.calculateRemainInterest(deposit,
} else { * missedDays, preClosureInterestRate); if
accuredtotalAmount = fixedTermDepositInterestCalculator * (account.isInterestCompoundingAllowed()) { accuredtotalAmount =
.calculateInterestOnMaturityForSimpleInterest(deposit, * fixedTermDepositInterestCalculator
tenure, preClosureInterestRate, * .calculateInterestOnMaturityFor(deposit, tenure, preClosureInterestRate,
interestCompoundedEvery, * interestCompoundedEvery,
this.product.getInterestCompoundedEveryPeriodType()); * this.product.getInterestCompoundedEveryPeriodType()); accuredtotalAmount
accuredtotalAmount = accuredtotalAmount.plus(remainDaysAmount); * = accuredtotalAmount.plus(remainDaysAmount); } else { accuredtotalAmount
} * = fixedTermDepositInterestCalculator
this.total = account.isInterestCompoundingAllowed()?accuredtotalAmount.getAmount():BigDecimal.valueOf(accuredtotalAmount.getAmount().doubleValue()-this.interstPaid.doubleValue()); * .calculateInterestOnMaturityForSimpleInterest(deposit, tenure,
this.interestAccrued = accuredtotalAmount.minus(deposit).getAmount(); * preClosureInterestRate, interestCompoundedEvery,
* this.product.getInterestCompoundedEveryPeriodType()); accuredtotalAmount
}*/ * = accuredtotalAmount.plus(remainDaysAmount); } this.total =
* account.isInterestCompoundingAllowed
* ()?accuredtotalAmount.getAmount():BigDecimal
* .valueOf(accuredtotalAmount.getAmount
* ().doubleValue()-this.interstPaid.doubleValue()); this.interestAccrued =
* accuredtotalAmount.minus(deposit).getAmount();
*
* }
*/
public void withdrawInterest(Money interest) { public void withdrawInterest(Money interest) {
@SuppressWarnings("unused") @SuppressWarnings("unused")
@@ -641,40 +628,35 @@ public class DepositAccount extends AbstractAuditableCustom<AppUser, Long> {
} }
} }
public void closeDepositAccount(DepositLifecycleStateMachine depositLifecycleStateMachine) { public void closeDepositAccount(DepositLifecycleStateMachine depositLifecycleStateMachine) {
DepositAccountStatus statusEnumForClose = depositLifecycleStateMachine.transition(DepositAccountEvent.DEPOSIT_CLOSED, DepositAccountStatus.fromInt(this.depositStatus)); DepositAccountStatus statusEnumForClose = depositLifecycleStateMachine.transition(DepositAccountEvent.DEPOSIT_CLOSED,
DepositAccountStatus.fromInt(this.depositStatus));
this.depositStatus = statusEnumForClose.getValue(); this.depositStatus = statusEnumForClose.getValue();
DepositAccountTransaction depositaccountTransaction = DepositAccountTransaction.withdraw(getDeposit(), new LocalDate(),Money.of(getDeposit().getCurrency(), getTotal()).minus(getDeposit())); DepositAccountTransaction depositaccountTransaction = DepositAccountTransaction.withdraw(getDeposit(), new LocalDate(),
Money.of(getDeposit().getCurrency(), getTotal()).minus(getDeposit()));
depositaccountTransaction.updateAccount(this); depositaccountTransaction.updateAccount(this);
this.depositaccountTransactions.add(depositaccountTransaction); this.depositaccountTransactions.add(depositaccountTransaction);
this.closedOnDate = new LocalDate().toDate(); this.closedOnDate = new LocalDate().toDate();
} }
public void update(final DepositProduct product, final String externalId, public void update(final DepositProduct product, final String externalId, final LocalDate commencementDate, final Money deposit,
final LocalDate commencementDate, final Money deposit, final Integer tenureInMonths, final BigDecimal maturityInterestRate, final BigDecimal preClosureInterestRate,
final Integer tenureInMonths, final BigDecimal maturityInterestRate, final Integer interestCompoundedEvery, final PeriodFrequencyType compoundingInterestFrequency, final boolean renewalAllowed,
final BigDecimal preClosureInterestRate, final Integer interestCompoundedEvery, final boolean preClosureAllowed, final boolean isInterestWithdrawable, final boolean isInterestCompoundingAllowed,
final PeriodFrequencyType compoundingInterestFrequency, final FixedTermDepositInterestCalculator fixedTermDepositInterestCalculator, final boolean isLockinPeriodAllowed,
final boolean renewalAllowed, final boolean preClosureAllowed, final Integer lockinPeriod, final PeriodFrequencyType lockinPeriodType) {
final boolean isInterestWithdrawable, final boolean isInterestCompoundingAllowed,
final FixedTermDepositInterestCalculator fixedTermDepositInterestCalculator,
final boolean isLockinPeriodAllowed,
final Integer lockinPeriod,
final PeriodFrequencyType lockinPeriodType) {
Money futureValueOnMaturity = null; Money futureValueOnMaturity = null;
if (isInterestCompoundingAllowed) { if (isInterestCompoundingAllowed) {
futureValueOnMaturity = fixedTermDepositInterestCalculator.calculateInterestOnMaturityFor(deposit, tenureInMonths, futureValueOnMaturity = fixedTermDepositInterestCalculator.calculateInterestOnMaturityFor(deposit, tenureInMonths,
maturityInterestRate, interestCompoundedEvery, maturityInterestRate, interestCompoundedEvery, compoundingInterestFrequency);
compoundingInterestFrequency);
} else { } else {
futureValueOnMaturity = fixedTermDepositInterestCalculator.calculateInterestOnMaturityForSimpleInterest(deposit, futureValueOnMaturity = fixedTermDepositInterestCalculator.calculateInterestOnMaturityForSimpleInterest(deposit,
tenureInMonths, maturityInterestRate, tenureInMonths, maturityInterestRate, interestCompoundedEvery, compoundingInterestFrequency);
interestCompoundedEvery,
compoundingInterestFrequency);
} }
setExternalId(externalId); setExternalId(externalId);
@@ -736,9 +718,13 @@ public class DepositAccount extends AbstractAuditableCustom<AppUser, Long> {
if (noOfMonthsBeforeMaturity > 0) { if (noOfMonthsBeforeMaturity > 0) {
if (this.interestCompoundingAllowed) { if (this.interestCompoundingAllowed) {
futureValueOnMaturity = fixedTermDepositInterestCalculator.calculateInterestOnMaturityFor(deposit, noOfMonthsBeforeMaturity,this.interestRate, this.interestCompoundedEvery, getInterestCompoundedFrequencyType()); futureValueOnMaturity = fixedTermDepositInterestCalculator.calculateInterestOnMaturityFor(deposit,
noOfMonthsBeforeMaturity, this.interestRate, this.interestCompoundedEvery,
getInterestCompoundedFrequencyType());
} else { } else {
futureValueOnMaturity = fixedTermDepositInterestCalculator.calculateInterestOnMaturityForSimpleInterest(deposit, noOfMonthsBeforeMaturity, this.interestRate, this.interestCompoundedEvery, getInterestCompoundedFrequencyType()); futureValueOnMaturity = fixedTermDepositInterestCalculator.calculateInterestOnMaturityForSimpleInterest(
deposit, noOfMonthsBeforeMaturity, this.interestRate, this.interestCompoundedEvery,
getInterestCompoundedFrequencyType());
} }
this.interestPostedAmount = this.interestPostedAmount.add(futureValueOnMaturity.minus(deposit).getAmount()); this.interestPostedAmount = this.interestPostedAmount.add(futureValueOnMaturity.minus(deposit).getAmount());
this.availableInterest = this.availableInterest.add(futureValueOnMaturity.minus(deposit).getAmount()); this.availableInterest = this.availableInterest.add(futureValueOnMaturity.minus(deposit).getAmount());
@@ -749,9 +735,13 @@ public class DepositAccount extends AbstractAuditableCustom<AppUser, Long> {
if (noofRemainMonthsAfterMaturity > 0) { if (noofRemainMonthsAfterMaturity > 0) {
if (this.interestCompoundingAllowed) { if (this.interestCompoundingAllowed) {
futureValueOnMaturity = fixedTermDepositInterestCalculator.calculateInterestOnMaturityFor(deposit, noofRemainMonthsAfterMaturity, this.preClosureInterestRate, this.interestCompoundedEvery, getInterestCompoundedFrequencyType()); futureValueOnMaturity = fixedTermDepositInterestCalculator.calculateInterestOnMaturityFor(deposit,
noofRemainMonthsAfterMaturity, this.preClosureInterestRate, this.interestCompoundedEvery,
getInterestCompoundedFrequencyType());
} else { } else {
futureValueOnMaturity = fixedTermDepositInterestCalculator.calculateInterestOnMaturityForSimpleInterest(deposit, noofRemainMonthsAfterMaturity, this.preClosureInterestRate, this.interestCompoundedEvery, getInterestCompoundedFrequencyType()); futureValueOnMaturity = fixedTermDepositInterestCalculator.calculateInterestOnMaturityForSimpleInterest(
deposit, noofRemainMonthsAfterMaturity, this.preClosureInterestRate, this.interestCompoundedEvery,
getInterestCompoundedFrequencyType());
} }
this.interestPostedAmount = this.interestPostedAmount.add(futureValueOnMaturity.minus(deposit).getAmount()); this.interestPostedAmount = this.interestPostedAmount.add(futureValueOnMaturity.minus(deposit).getAmount());
this.availableInterest = this.availableInterest.add(futureValueOnMaturity.minus(deposit).getAmount()); this.availableInterest = this.availableInterest.add(futureValueOnMaturity.minus(deposit).getAmount());
@@ -760,15 +750,20 @@ public class DepositAccount extends AbstractAuditableCustom<AppUser, Long> {
} }
// add transaction entry for each interest posting // add transaction entry for each interest posting
DepositAccountTransaction depositaccountTransaction = DepositAccountTransaction.postInterest(null, nextInterestPostingDate,futureValueOnMaturity.minus(deposit)); DepositAccountTransaction depositaccountTransaction = DepositAccountTransaction.postInterest(null,
nextInterestPostingDate, futureValueOnMaturity.minus(deposit));
depositaccountTransaction.updateAccount(this); depositaccountTransaction.updateAccount(this);
this.depositaccountTransactions.add(depositaccountTransaction); this.depositaccountTransactions.add(depositaccountTransaction);
} else { } else {
Money futureValueOnMaturity = null; Money futureValueOnMaturity = null;
if (this.interestCompoundingAllowed) { if (this.interestCompoundingAllowed) {
futureValueOnMaturity = fixedTermDepositInterestCalculator.calculateInterestOnMaturityFor(deposit, this.interestCompoundedEvery, this.interestRate, this.interestCompoundedEvery, getInterestCompoundedFrequencyType()); futureValueOnMaturity = fixedTermDepositInterestCalculator.calculateInterestOnMaturityFor(deposit,
this.interestCompoundedEvery, this.interestRate, this.interestCompoundedEvery,
getInterestCompoundedFrequencyType());
} else { } else {
futureValueOnMaturity = fixedTermDepositInterestCalculator.calculateInterestOnMaturityForSimpleInterest(deposit, this.interestCompoundedEvery, this.interestRate, this.interestCompoundedEvery, getInterestCompoundedFrequencyType()); futureValueOnMaturity = fixedTermDepositInterestCalculator.calculateInterestOnMaturityForSimpleInterest(deposit,
this.interestCompoundedEvery, this.interestRate, this.interestCompoundedEvery,
getInterestCompoundedFrequencyType());
} }
this.interestPostedAmount = this.interestPostedAmount.add(futureValueOnMaturity.minus(deposit).getAmount()); this.interestPostedAmount = this.interestPostedAmount.add(futureValueOnMaturity.minus(deposit).getAmount());
this.availableInterest = this.availableInterest.add(futureValueOnMaturity.minus(deposit).getAmount()); this.availableInterest = this.availableInterest.add(futureValueOnMaturity.minus(deposit).getAmount());
@@ -776,16 +771,21 @@ public class DepositAccount extends AbstractAuditableCustom<AppUser, Long> {
this.nextInterestPostingDate = nextInterestPostingDate.plusMonths(this.interestCompoundedEvery).toDate(); this.nextInterestPostingDate = nextInterestPostingDate.plusMonths(this.interestCompoundedEvery).toDate();
// add transaction entry for each interest posting // add transaction entry for each interest posting
DepositAccountTransaction depositaccountTransaction = DepositAccountTransaction.postInterest(null, nextInterestPostingDate,futureValueOnMaturity.minus(deposit)); DepositAccountTransaction depositaccountTransaction = DepositAccountTransaction.postInterest(null,
nextInterestPostingDate, futureValueOnMaturity.minus(deposit));
depositaccountTransaction.updateAccount(this); depositaccountTransaction.updateAccount(this);
this.depositaccountTransactions.add(depositaccountTransaction); this.depositaccountTransactions.add(depositaccountTransaction);
} }
} else { } else {
Money futureValueOnMaturity = null; Money futureValueOnMaturity = null;
if (this.interestCompoundingAllowed) { if (this.interestCompoundingAllowed) {
futureValueOnMaturity = fixedTermDepositInterestCalculator.calculateInterestOnMaturityFor(deposit, this.interestCompoundedEvery, this.preClosureInterestRate, this.interestCompoundedEvery, getInterestCompoundedFrequencyType()); futureValueOnMaturity = fixedTermDepositInterestCalculator.calculateInterestOnMaturityFor(deposit,
this.interestCompoundedEvery, this.preClosureInterestRate, this.interestCompoundedEvery,
getInterestCompoundedFrequencyType());
} else { } else {
futureValueOnMaturity = fixedTermDepositInterestCalculator.calculateInterestOnMaturityForSimpleInterest(deposit, this.interestCompoundedEvery, this.preClosureInterestRate, this.interestCompoundedEvery, getInterestCompoundedFrequencyType()); futureValueOnMaturity = fixedTermDepositInterestCalculator.calculateInterestOnMaturityForSimpleInterest(deposit,
this.interestCompoundedEvery, this.preClosureInterestRate, this.interestCompoundedEvery,
getInterestCompoundedFrequencyType());
} }
this.interestPostedAmount = this.interestPostedAmount.add(futureValueOnMaturity.minus(deposit).getAmount()); this.interestPostedAmount = this.interestPostedAmount.add(futureValueOnMaturity.minus(deposit).getAmount());
this.availableInterest = this.availableInterest.add(futureValueOnMaturity.minus(deposit).getAmount()); this.availableInterest = this.availableInterest.add(futureValueOnMaturity.minus(deposit).getAmount());
@@ -793,7 +793,8 @@ public class DepositAccount extends AbstractAuditableCustom<AppUser, Long> {
this.nextInterestPostingDate = nextInterestPostingDate.plusMonths(this.interestCompoundedEvery).toDate(); this.nextInterestPostingDate = nextInterestPostingDate.plusMonths(this.interestCompoundedEvery).toDate();
// add transaction entry for each interest posting // add transaction entry for each interest posting
DepositAccountTransaction depositaccountTransaction = DepositAccountTransaction.postInterest(null, nextInterestPostingDate,futureValueOnMaturity.minus(deposit)); DepositAccountTransaction depositaccountTransaction = DepositAccountTransaction.postInterest(null, nextInterestPostingDate,
futureValueOnMaturity.minus(deposit));
depositaccountTransaction.updateAccount(this); depositaccountTransaction.updateAccount(this);
this.depositaccountTransactions.add(depositaccountTransaction); this.depositaccountTransactions.add(depositaccountTransaction);
} }
@@ -830,5 +831,4 @@ public class DepositAccount extends AbstractAuditableCustom<AppUser, Long> {
return interestPostedAmount; return interestPostedAmount;
} }
} }
@@ -3,5 +3,4 @@ package org.mifosplatform.portfolio.savingsdepositaccount.domain;
public enum DepositAccountEvent { public enum DepositAccountEvent {
DEPOSIT_CREATED, DEPOSIT_REJECTED, DEPOSIT_APPROVED, DEPOSIT_APPROVAL_UNDO, DEPOSIT_WITHDRAWN, DEPOSIT_MATURED, DEPOSIT_CLOSED, DEPOSIT_PRECLOSED; DEPOSIT_CREATED, DEPOSIT_REJECTED, DEPOSIT_APPROVED, DEPOSIT_APPROVAL_UNDO, DEPOSIT_WITHDRAWN, DEPOSIT_MATURED, DEPOSIT_CLOSED, DEPOSIT_PRECLOSED;
} }
@@ -3,8 +3,6 @@ package org.mifosplatform.portfolio.savingsdepositaccount.domain;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
public interface DepositAccountRepository extends public interface DepositAccountRepository extends JpaRepository<DepositAccount, Long>, JpaSpecificationExecutor<DepositAccount> {
JpaRepository<DepositAccount, Long>, //
JpaSpecificationExecutor<DepositAccount> {
} }
@@ -9,8 +9,7 @@ public enum DepositAccountStatus {
WITHDRAWN_BY_CLIENT(400, "depositStatusType.withdrawn.by.client"), // WITHDRAWN_BY_CLIENT(400, "depositStatusType.withdrawn.by.client"), //
REJECTED(500, "depositStatusType.rejected"), // REJECTED(500, "depositStatusType.rejected"), //
CLOSED(600, "depositStatusType.closed"), // CLOSED(600, "depositStatusType.closed"), //
MATURED(700,"depositStatusType.matured"), MATURED(700, "depositStatusType.matured"), PRECLOSED(800, "depositStatusType.preclosed");
PRECLOSED(800,"depositStatusType.preclosed");
private final Integer value; private final Integer value;
private final String code; private final String code;
@@ -36,9 +35,10 @@ public enum DepositAccountStatus {
return this.value.equals(DepositAccountStatus.SUBMITED_AND_PENDING_APPROVAL.getValue()); return this.value.equals(DepositAccountStatus.SUBMITED_AND_PENDING_APPROVAL.getValue());
} }
/*public boolean isApproved() { /*
return this.value.equals(DepositAccountStatus.APPROVED.getValue()); * public boolean isApproved() { return
}*/ * this.value.equals(DepositAccountStatus.APPROVED.getValue()); }
*/
public boolean isActive() { public boolean isActive() {
return this.value.equals(DepositAccountStatus.ACTIVE.getValue()); return this.value.equals(DepositAccountStatus.ACTIVE.getValue());
@@ -67,9 +67,9 @@ public enum DepositAccountStatus {
case 100: case 100:
enumeration = DepositAccountStatus.SUBMITED_AND_PENDING_APPROVAL; enumeration = DepositAccountStatus.SUBMITED_AND_PENDING_APPROVAL;
break; break;
/*case 200: /*
enumeration = DepositAccountStatus.APPROVED; * case 200: enumeration = DepositAccountStatus.APPROVED; break;
break;*/ */
case 300: case 300:
enumeration = DepositAccountStatus.ACTIVE; enumeration = DepositAccountStatus.ACTIVE;
break; break;
@@ -62,7 +62,8 @@ public class DepositAccountTransaction extends AbstractPersistable<Long> {
this.total = null; this.total = null;
} }
private DepositAccountTransaction(DepositAccountTransactionType type, final BigDecimal amount, final LocalDate date, final BigDecimal interest) { private DepositAccountTransaction(DepositAccountTransactionType type, final BigDecimal amount, final LocalDate date,
final BigDecimal interest) {
this.typeOf = type; this.typeOf = type;
this.amount = amount; this.amount = amount;
this.dateOf = date.toDateMidnight().toDate(); this.dateOf = date.toDateMidnight().toDate();
@@ -95,15 +96,19 @@ public class DepositAccountTransaction extends AbstractPersistable<Long> {
} }
public static DepositAccountTransaction deposit(Money amount, LocalDate paymentDate, Money interest) { public static DepositAccountTransaction deposit(Money amount, LocalDate paymentDate, Money interest) {
return new DepositAccountTransaction(DepositAccountTransactionType.DEPOSIT, amount == null ? new BigDecimal(0) : amount.getAmount(), paymentDate, interest==null ? new BigDecimal(0) : interest.getAmount()); return new DepositAccountTransaction(DepositAccountTransactionType.DEPOSIT,
amount == null ? new BigDecimal(0) : amount.getAmount(), paymentDate, interest == null ? new BigDecimal(0)
: interest.getAmount());
} }
public static DepositAccountTransaction withdraw(Money amount, LocalDate paymentDate, Money interest) { public static DepositAccountTransaction withdraw(Money amount, LocalDate paymentDate, Money interest) {
return new DepositAccountTransaction(DepositAccountTransactionType.WITHDRAW, amount == null ? new BigDecimal(0) : amount.getAmount(), paymentDate, interest==null ? new BigDecimal(0) : interest.getAmount()); return new DepositAccountTransaction(DepositAccountTransactionType.WITHDRAW, amount == null ? new BigDecimal(0)
: amount.getAmount(), paymentDate, interest == null ? new BigDecimal(0) : interest.getAmount());
} }
public static DepositAccountTransaction postInterest(Money depositAmount, LocalDate paymentDate, Money interest) { public static DepositAccountTransaction postInterest(Money depositAmount, LocalDate paymentDate, Money interest) {
return new DepositAccountTransaction(DepositAccountTransactionType.INTEREST_POSTING, depositAmount == null ? new BigDecimal(0) : depositAmount.getAmount(), paymentDate, interest==null ? new BigDecimal(0) : interest.getAmount()); return new DepositAccountTransaction(DepositAccountTransactionType.INTEREST_POSTING, depositAmount == null ? new BigDecimal(0)
: depositAmount.getAmount(), paymentDate, interest == null ? new BigDecimal(0) : interest.getAmount());
} }
public void updateAccount(DepositAccount depositAccount) { public void updateAccount(DepositAccount depositAccount) {
@@ -5,8 +5,7 @@ public enum DepositAccountTransactionType {
INVALID(0, "depositTransactionType.invalid"), // INVALID(0, "depositTransactionType.invalid"), //
DEPOSIT(1, "depositTransactionType.deposit"), // DEPOSIT(1, "depositTransactionType.deposit"), //
WITHDRAW(2, "depositTransactionType.withdraw"), // WITHDRAW(2, "depositTransactionType.withdraw"), //
REVERSAL(3, "depositTransactionType.reversal"), REVERSAL(3, "depositTransactionType.reversal"), INTEREST_POSTING(4, "depositTransactionType.interestPosting");
INTEREST_POSTING(4,"depositTransactionType.interestPosting");
private final Integer value; private final Integer value;
private final String code; private final String code;
@@ -26,9 +25,7 @@ public enum DepositAccountTransactionType {
public static DepositAccountTransactionType fromInt(final Integer transactionType) { public static DepositAccountTransactionType fromInt(final Integer transactionType) {
if (transactionType == null) { if (transactionType == null) { return DepositAccountTransactionType.INVALID; }
return DepositAccountTransactionType.INVALID;
}
DepositAccountTransactionType depositTransactionType = null; DepositAccountTransactionType depositTransactionType = null;
switch (transactionType) { switch (transactionType) {
@@ -1,8 +1,6 @@
package org.mifosplatform.portfolio.savingsdepositaccount.domain; package org.mifosplatform.portfolio.savingsdepositaccount.domain;
public interface DepositLifecycleStateMachine { public interface DepositLifecycleStateMachine {
DepositAccountStatus transition(DepositAccountEvent loanEvent, DepositAccountStatus from); DepositAccountStatus transition(DepositAccountEvent loanEvent, DepositAccountStatus from);
} }
@@ -4,8 +4,7 @@ import java.util.List;
import org.mifosplatform.portfolio.savingsdepositaccount.exception.InvalidDepositStateTransitionException; import org.mifosplatform.portfolio.savingsdepositaccount.exception.InvalidDepositStateTransitionException;
public class DepositLifecycleStateMachineImpl implements public class DepositLifecycleStateMachineImpl implements DepositLifecycleStateMachine {
DepositLifecycleStateMachine {
private final List<DepositAccountStatus> allowedDepositStatuses; private final List<DepositAccountStatus> allowedDepositStatuses;
@@ -27,8 +26,7 @@ public class DepositLifecycleStateMachineImpl implements
case DEPOSIT_REJECTED: case DEPOSIT_REJECTED:
if (from.hasStateOf(DepositAccountStatus.SUBMITED_AND_PENDING_APPROVAL)) { if (from.hasStateOf(DepositAccountStatus.SUBMITED_AND_PENDING_APPROVAL)) {
newState = stateOf(DepositAccountStatus.REJECTED, allowedDepositStatuses); newState = stateOf(DepositAccountStatus.REJECTED, allowedDepositStatuses);
} } else {
else{
final String errorMessage = "The DepositApplication can not be rejected from " + from.getCode(); final String errorMessage = "The DepositApplication can not be rejected from " + from.getCode();
throw new InvalidDepositStateTransitionException("rejection", "failed", errorMessage, from); throw new InvalidDepositStateTransitionException("rejection", "failed", errorMessage, from);
} }
@@ -36,8 +34,7 @@ public class DepositLifecycleStateMachineImpl implements
case DEPOSIT_APPROVED: case DEPOSIT_APPROVED:
if (from.hasStateOf(DepositAccountStatus.SUBMITED_AND_PENDING_APPROVAL)) { if (from.hasStateOf(DepositAccountStatus.SUBMITED_AND_PENDING_APPROVAL)) {
newState = stateOf(DepositAccountStatus.ACTIVE, allowedDepositStatuses); newState = stateOf(DepositAccountStatus.ACTIVE, allowedDepositStatuses);
} } else {
else{
final String errorMessage = "The DepositApplication can not be approved from " + from.getCode(); final String errorMessage = "The DepositApplication can not be approved from " + from.getCode();
throw new InvalidDepositStateTransitionException("approve", "failed", errorMessage, from); throw new InvalidDepositStateTransitionException("approve", "failed", errorMessage, from);
} }
@@ -45,8 +42,7 @@ public class DepositLifecycleStateMachineImpl implements
case DEPOSIT_WITHDRAWN: case DEPOSIT_WITHDRAWN:
if (this.anyOfAllowedWhenComingFrom(from, DepositAccountStatus.SUBMITED_AND_PENDING_APPROVAL, DepositAccountStatus.ACTIVE)) { if (this.anyOfAllowedWhenComingFrom(from, DepositAccountStatus.SUBMITED_AND_PENDING_APPROVAL, DepositAccountStatus.ACTIVE)) {
newState = stateOf(DepositAccountStatus.WITHDRAWN_BY_CLIENT, allowedDepositStatuses); newState = stateOf(DepositAccountStatus.WITHDRAWN_BY_CLIENT, allowedDepositStatuses);
} } else {
else{
final String errorMessage = "The DepositApplication can not be withdrawn from " + from.getCode(); final String errorMessage = "The DepositApplication can not be withdrawn from " + from.getCode();
throw new InvalidDepositStateTransitionException("withdrawbyclient", "failed", errorMessage, from); throw new InvalidDepositStateTransitionException("withdrawbyclient", "failed", errorMessage, from);
} }
@@ -54,8 +50,7 @@ public class DepositLifecycleStateMachineImpl implements
case DEPOSIT_APPROVAL_UNDO: case DEPOSIT_APPROVAL_UNDO:
if (from.hasStateOf(DepositAccountStatus.ACTIVE)) { if (from.hasStateOf(DepositAccountStatus.ACTIVE)) {
newState = stateOf(DepositAccountStatus.SUBMITED_AND_PENDING_APPROVAL, allowedDepositStatuses); newState = stateOf(DepositAccountStatus.SUBMITED_AND_PENDING_APPROVAL, allowedDepositStatuses);
} } else {
else{
final String errorMessage = "The DepositApplication can not be unapproved from " + from.getCode(); final String errorMessage = "The DepositApplication can not be unapproved from " + from.getCode();
throw new InvalidDepositStateTransitionException("unapprove", "failed", errorMessage, from); throw new InvalidDepositStateTransitionException("unapprove", "failed", errorMessage, from);
} }
@@ -63,8 +58,7 @@ public class DepositLifecycleStateMachineImpl implements
case DEPOSIT_MATURED: case DEPOSIT_MATURED:
if (from.hasStateOf(DepositAccountStatus.ACTIVE)) { if (from.hasStateOf(DepositAccountStatus.ACTIVE)) {
newState = stateOf(DepositAccountStatus.MATURED, allowedDepositStatuses); newState = stateOf(DepositAccountStatus.MATURED, allowedDepositStatuses);
} } else {
else{
final String errorMessage = "The DepositApplication can not be matured from " + from.getCode(); final String errorMessage = "The DepositApplication can not be matured from " + from.getCode();
throw new InvalidDepositStateTransitionException("mature", "failed", errorMessage, from); throw new InvalidDepositStateTransitionException("mature", "failed", errorMessage, from);
} }
@@ -72,8 +66,7 @@ public class DepositLifecycleStateMachineImpl implements
case DEPOSIT_CLOSED: case DEPOSIT_CLOSED:
if (from.hasStateOf(DepositAccountStatus.ACTIVE)) { if (from.hasStateOf(DepositAccountStatus.ACTIVE)) {
newState = stateOf(DepositAccountStatus.CLOSED, allowedDepositStatuses); newState = stateOf(DepositAccountStatus.CLOSED, allowedDepositStatuses);
} } else {
else{
final String errorMessage = "The DepositApplication can not be closed from " + from.getCode(); final String errorMessage = "The DepositApplication can not be closed from " + from.getCode();
throw new InvalidDepositStateTransitionException("closed", "failed", errorMessage, from); throw new InvalidDepositStateTransitionException("closed", "failed", errorMessage, from);
} }
@@ -81,8 +74,7 @@ public class DepositLifecycleStateMachineImpl implements
case DEPOSIT_PRECLOSED: case DEPOSIT_PRECLOSED:
if (from.hasStateOf(DepositAccountStatus.ACTIVE)) { if (from.hasStateOf(DepositAccountStatus.ACTIVE)) {
newState = stateOf(DepositAccountStatus.PRECLOSED, allowedDepositStatuses); newState = stateOf(DepositAccountStatus.PRECLOSED, allowedDepositStatuses);
} } else {
else{
final String errorMessage = "The DepositApplication can not be matured from " + from.getCode(); final String errorMessage = "The DepositApplication can not be matured from " + from.getCode();
throw new InvalidDepositStateTransitionException("preclosure", "failed", errorMessage, from); throw new InvalidDepositStateTransitionException("preclosure", "failed", errorMessage, from);
} }
@@ -12,16 +12,16 @@ import org.springframework.stereotype.Service;
public class FixedTermDepositInterestCalculator { public class FixedTermDepositInterestCalculator {
// FIXME - MADHUKAR - Are the unused field here needed? // FIXME - MADHUKAR - Are the unused field here needed?
public Money calculateInterestOnMaturityFor( public Money calculateInterestOnMaturityFor(final Money deposit, final Integer tenureInMonths, final BigDecimal maturityInterestRate,
final Money deposit, final Integer interestCompoundedEvery, final PeriodFrequencyType interestCompoundedFrequencyPeriodType) {
final Integer tenureInMonths,
final BigDecimal maturityInterestRate,
final Integer interestCompoundedEvery,
final PeriodFrequencyType interestCompoundedFrequencyPeriodType) {
// TODO - Can change 'interest compounding' fields into something simpler like interestCompoundedFrequency {None (Simple Interest), Monthly, Quarterly, Half-Yearly, Annually} // TODO - Can change 'interest compounding' fields into something
// - the 'interestCompoundedEvery' would then be inferred form the selected type. // simpler like interestCompoundedFrequency {None (Simple Interest),
// - the special case of 'simple interest' or 'no compounding' would use simple formula rather than 'future value' function. // Monthly, Quarterly, Half-Yearly, Annually}
// - the 'interestCompoundedEvery' would then be inferred form the
// selected type.
// - the special case of 'simple interest' or 'no compounding' would use
// simple formula rather than 'future value' function.
// FIXME - assuming only monthly compounding period for now // FIXME - assuming only monthly compounding period for now
MathContext mc = new MathContext(8, RoundingMode.HALF_EVEN); MathContext mc = new MathContext(8, RoundingMode.HALF_EVEN);
@@ -30,7 +30,8 @@ public class FixedTermDepositInterestCalculator {
BigDecimal interestRateAsFraction = maturityInterestRate.divide(BigDecimal.valueOf(100), mc); BigDecimal interestRateAsFraction = maturityInterestRate.divide(BigDecimal.valueOf(100), mc);
BigDecimal interestRateForOneMonth = interestRateAsFraction.divide(BigDecimal.valueOf(monthsInYear.doubleValue()), mc); BigDecimal interestRateForOneMonth = interestRateAsFraction.divide(BigDecimal.valueOf(monthsInYear.doubleValue()), mc);
BigDecimal ratePerCompoundingPeriod = interestRateForOneMonth.multiply(BigDecimal.valueOf(interestCompoundedEvery.doubleValue()), mc); BigDecimal ratePerCompoundingPeriod = interestRateForOneMonth.multiply(BigDecimal.valueOf(interestCompoundedEvery.doubleValue()),
mc);
Integer numberOfPeriods = tenureInMonths / interestCompoundedEvery; Integer numberOfPeriods = tenureInMonths / interestCompoundedEvery;
@@ -53,32 +54,33 @@ public class FixedTermDepositInterestCalculator {
* payments are due at the beginning of period (false => payments are due at * payments are due at the beginning of period (false => payments are due at
* end of period) * end of period)
*/ */
private static double fv(double ratePeriodCompoundingPeriod, double numberOfCompoundingPeriods, double pmtPerPeriod, double presentValue, boolean type) { private static double fv(double ratePeriodCompoundingPeriod, double numberOfCompoundingPeriods, double pmtPerPeriod,
double presentValue, boolean type) {
double retval = 0; double retval = 0;
if (ratePeriodCompoundingPeriod == 0) { if (ratePeriodCompoundingPeriod == 0) {
retval = -1 * (presentValue + (numberOfCompoundingPeriods * pmtPerPeriod)); retval = -1 * (presentValue + (numberOfCompoundingPeriods * pmtPerPeriod));
} else { } else {
double r1 = ratePeriodCompoundingPeriod + 1; double r1 = ratePeriodCompoundingPeriod + 1;
retval = ((1 - Math.pow(r1, numberOfCompoundingPeriods)) * (type ? r1 : 1) * pmtPerPeriod) / ratePeriodCompoundingPeriod - presentValue retval = ((1 - Math.pow(r1, numberOfCompoundingPeriods)) * (type ? r1 : 1) * pmtPerPeriod) / ratePeriodCompoundingPeriod
* Math.pow(r1, numberOfCompoundingPeriods); - presentValue * Math.pow(r1, numberOfCompoundingPeriods);
} }
return retval; return retval;
} }
public Money calculateInterestOnMaturityForSimpleInterest(Money deposit, public Money calculateInterestOnMaturityForSimpleInterest(Money deposit, Integer tenureInMonths, BigDecimal maturityInterestRate,
Integer tenureInMonths, BigDecimal maturityInterestRate, Integer interestCompoundedEvery, PeriodFrequencyType interestCompoundedFrequencyPeriodType) {
Integer interestCompoundedEvery,
PeriodFrequencyType interestCompoundedFrequencyPeriodType) {
MathContext mc = new MathContext(8, RoundingMode.HALF_EVEN); MathContext mc = new MathContext(8, RoundingMode.HALF_EVEN);
Integer monthsInYear = 12; Integer monthsInYear = 12;
BigDecimal interestRateAsFraction = maturityInterestRate.divide(BigDecimal.valueOf(100), mc); BigDecimal interestRateAsFraction = maturityInterestRate.divide(BigDecimal.valueOf(100), mc);
BigDecimal interestRateForOneMonth = interestRateAsFraction.divide(BigDecimal.valueOf(monthsInYear.doubleValue()), mc); BigDecimal interestRateForOneMonth = interestRateAsFraction.divide(BigDecimal.valueOf(monthsInYear.doubleValue()), mc);
BigDecimal ratePerCompoundingPeriod = interestRateForOneMonth.multiply(BigDecimal.valueOf(interestCompoundedEvery.doubleValue()), mc); BigDecimal ratePerCompoundingPeriod = interestRateForOneMonth.multiply(BigDecimal.valueOf(interestCompoundedEvery.doubleValue()),
mc);
Integer numberOfPeriods = tenureInMonths / interestCompoundedEvery; Integer numberOfPeriods = tenureInMonths / interestCompoundedEvery;
BigDecimal interest = ratePerCompoundingPeriod.multiply(deposit.getAmount()).multiply(BigDecimal.valueOf(new Double(numberOfPeriods))); BigDecimal interest = ratePerCompoundingPeriod.multiply(deposit.getAmount()).multiply(
BigDecimal.valueOf(new Double(numberOfPeriods)));
BigDecimal totalAmount = deposit.getAmount().add(interest); BigDecimal totalAmount = deposit.getAmount().add(interest);
return Money.of(deposit.getCurrency(), totalAmount); return Money.of(deposit.getCurrency(), totalAmount);
@@ -91,7 +93,8 @@ public class FixedTermDepositInterestCalculator {
BigDecimal interestRateAsFraction = interestRate.divide(BigDecimal.valueOf(100), mc); BigDecimal interestRateAsFraction = interestRate.divide(BigDecimal.valueOf(100), mc);
BigDecimal interestRateForOneDay = interestRateAsFraction.divide(BigDecimal.valueOf(daysInYear.doubleValue()), mc); BigDecimal interestRateForOneDay = interestRateAsFraction.divide(BigDecimal.valueOf(daysInYear.doubleValue()), mc);
BigDecimal interest = BigDecimal.valueOf(deposit.getAmount().doubleValue()*days.doubleValue()*interestRateForOneDay.doubleValue()); BigDecimal interest = BigDecimal.valueOf(deposit.getAmount().doubleValue() * days.doubleValue()
* interestRateForOneDay.doubleValue());
return Money.of(deposit.getCurrency(), interest); return Money.of(deposit.getCurrency(), interest);
} }
@@ -4,11 +4,11 @@ import java.math.BigDecimal;
import org.mifosplatform.infrastructure.core.exception.AbstractPlatformDomainRuleException; import org.mifosplatform.infrastructure.core.exception.AbstractPlatformDomainRuleException;
public class DepositAccounDataValidationtException extends public class DepositAccounDataValidationtException extends AbstractPlatformDomainRuleException {
AbstractPlatformDomainRuleException {
public DepositAccounDataValidationtException(BigDecimal preClosureInterestRate, BigDecimal maturityMinInterestRate) { public DepositAccounDataValidationtException(BigDecimal preClosureInterestRate, BigDecimal maturityMinInterestRate) {
super("error.msg.deposit.account.preClosureInterestRate.should.lessthanOrEqualTo.maturityMinInterestRate", "PreClosureInterestRate : "+preClosureInterestRate+"should lessthan or equal to maturityMinInterestRate : "+maturityMinInterestRate, preClosureInterestRate,maturityMinInterestRate); super("error.msg.deposit.account.preClosureInterestRate.should.lessthanOrEqualTo.maturityMinInterestRate",
"PreClosureInterestRate : " + preClosureInterestRate + "should lessthan or equal to maturityMinInterestRate : "
+ maturityMinInterestRate, preClosureInterestRate, maturityMinInterestRate);
} }
} }
@@ -7,5 +7,4 @@ public class DepositAccountNotFoundException extends AbstractPlatformResourceNot
public DepositAccountNotFoundException(final Long id) { public DepositAccountNotFoundException(final Long id) {
super("error.msg.deposit.account.id.invalid", "Deposit account with identifier " + id + " does not exist", id); super("error.msg.deposit.account.id.invalid", "Deposit account with identifier " + id + " does not exist", id);
} }
} }
@@ -8,5 +8,4 @@ public class DepositAccountReopenException extends AbstractPlatformDomainRuleExc
public DepositAccountReopenException(LocalDate maturedDate) { public DepositAccountReopenException(LocalDate maturedDate) {
super("error.msg.depositaccount.cannot.reopen.before.mature", "You cannot renew the account that is not matured:" + maturedDate); super("error.msg.depositaccount.cannot.reopen.before.mature", "You cannot renew the account that is not matured:" + maturedDate);
} }
} }
@@ -2,11 +2,9 @@ package org.mifosplatform.portfolio.savingsdepositaccount.exception;
import org.mifosplatform.infrastructure.core.exception.AbstractPlatformDomainRuleException; import org.mifosplatform.infrastructure.core.exception.AbstractPlatformDomainRuleException;
public class DepositAccountTransactionsException extends AbstractPlatformDomainRuleException { public class DepositAccountTransactionsException extends AbstractPlatformDomainRuleException {
public DepositAccountTransactionsException(String errorcode, String remainInterestForWithdrawal) { public DepositAccountTransactionsException(String errorcode, String remainInterestForWithdrawal) {
super(errorcode, "You can Withdraw " + remainInterestForWithdrawal + " only", remainInterestForWithdrawal); super(errorcode, "You can Withdraw " + remainInterestForWithdrawal + " only", remainInterestForWithdrawal);
} }
} }
@@ -8,5 +8,4 @@ public class InvalidDepositStateTransitionException extends AbstractPlatformDoma
Object... defaultUserMessageArgs) { Object... defaultUserMessageArgs) {
super("error.msg.deposit." + action + "." + postFix, defaultUserMessage, defaultUserMessageArgs); super("error.msg.deposit." + action + "." + postFix, defaultUserMessage, defaultUserMessageArgs);
} }
} }
@@ -24,7 +24,8 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
/** /**
* An assembler for turning {@link DepositAccountCommand} into {@link DepositAccount}'s. * An assembler for turning {@link DepositAccountCommand} into
* {@link DepositAccount}'s.
*/ */
@Service @Service
public class DepositAccountAssembler { public class DepositAccountAssembler {
@@ -44,18 +45,15 @@ public class DepositAccountAssembler {
public DepositAccount assembleFrom(final DepositAccountCommand command) { public DepositAccount assembleFrom(final DepositAccountCommand command) {
Client client = this.clientRepository.findOne(command.getClientId()); Client client = this.clientRepository.findOne(command.getClientId());
if (client == null || client.isDeleted()) { if (client == null || client.isDeleted()) { throw new ClientNotFoundException(command.getClientId()); }
throw new ClientNotFoundException(command.getClientId());
}
DepositProduct product = this.depositProductRepository.findOne(command.getProductId()); DepositProduct product = this.depositProductRepository.findOne(command.getProductId());
if (product == null || product.isDeleted()) { if (product == null || product.isDeleted()) { throw new DepositProductNotFoundException(command.getProductId()); }
throw new DepositProductNotFoundException(command.getProductId());
}
boolean isInterestWithdrawable = command.isInterestWithdrawable(); boolean isInterestWithdrawable = command.isInterestWithdrawable();
// details inherited from product setting (unless allowed to be overridden through account creation api // details inherited from product setting (unless allowed to be
// overridden through account creation api
Money deposit = Money.of(product.getCurrency(), command.getDepositAmount()); Money deposit = Money.of(product.getCurrency(), command.getDepositAmount());
Integer tenureInMonths = product.getTenureInMonths(); Integer tenureInMonths = product.getTenureInMonths();
@@ -73,9 +71,8 @@ public class DepositAccountAssembler {
preClosureInterestRate = command.getPreClosureInterestRate(); preClosureInterestRate = command.getPreClosureInterestRate();
} }
if(product.getMaturityMinInterestRate().compareTo(preClosureInterestRate)==-1){ if (product.getMaturityMinInterestRate().compareTo(preClosureInterestRate) == -1) { throw new DepositAccounDataValidationtException(
throw new DepositAccounDataValidationtException(preClosureInterestRate, product.getMaturityMinInterestRate()); preClosureInterestRate, product.getMaturityMinInterestRate()); }
}
Integer compoundingInterestEvery = product.getInterestCompoundedEvery(); Integer compoundingInterestEvery = product.getInterestCompoundedEvery();
if (command.getInterestCompoundedEvery() != null) { if (command.getInterestCompoundedEvery() != null) {
@@ -118,14 +115,11 @@ public class DepositAccountAssembler {
} }
// end of details allowed to be overriden from product // end of details allowed to be overriden from product
DepositAccount account =new DepositAccount().openNew(client, product, command.getExternalId(), DepositAccount account = new DepositAccount().openNew(client, product, command.getExternalId(), deposit, maturityInterestRate,
deposit, preClosureInterestRate, tenureInMonths, compoundingInterestEvery, compoundingInterestFrequency,
maturityInterestRate, preClosureInterestRate, command.getCommencementDate(), renewalAllowed, preClosureAllowed, this.fixedTermDepositInterestCalculator,
tenureInMonths, compoundingInterestEvery, compoundingInterestFrequency, defaultDepositLifecycleStateMachine(), isInterestWithdrawable, interestCompoundingAllowed, isLockinPeriodAllowed,
command.getCommencementDate(), lockinPeriod, lockinPeriodType);
renewalAllowed, preClosureAllowed, this.fixedTermDepositInterestCalculator,
defaultDepositLifecycleStateMachine(),isInterestWithdrawable,interestCompoundingAllowed,
isLockinPeriodAllowed,lockinPeriod,lockinPeriodType);
return account; return account;
} }
@@ -142,9 +136,7 @@ public class DepositAccountAssembler {
DepositProduct product = account.product(); DepositProduct product = account.product();
if (command.getProductId() != null) { if (command.getProductId() != null) {
product = this.depositProductRepository.findOne(command.getProductId()); product = this.depositProductRepository.findOne(command.getProductId());
if (product == null || product.isDeleted()) { if (product == null || product.isDeleted()) { throw new DepositProductNotFoundException(command.getProductId()); }
throw new DepositProductNotFoundException(command.getProductId());
}
} }
Money deposit = account.getDeposit(); Money deposit = account.getDeposit();
@@ -167,10 +159,8 @@ public class DepositAccountAssembler {
preClosureInterestRate = command.getPreClosureInterestRate(); preClosureInterestRate = command.getPreClosureInterestRate();
} }
if (product.getMaturityMinInterestRate().compareTo(preClosureInterestRate) == -1) { throw new DepositAccounDataValidationtException(
if(product.getMaturityMinInterestRate().compareTo(preClosureInterestRate)==-1){ preClosureInterestRate, product.getMaturityMinInterestRate()); }
throw new DepositAccounDataValidationtException(preClosureInterestRate, product.getMaturityMinInterestRate());
}
Integer compoundingInterestEvery = account.getInterestCompoundedEvery(); Integer compoundingInterestEvery = account.getInterestCompoundedEvery();
if (command.getInterestCompoundedEvery() != null) { if (command.getInterestCompoundedEvery() != null) {
@@ -217,31 +207,30 @@ public class DepositAccountAssembler {
lockinPeriodType = PeriodFrequencyType.fromInt(command.getLockinPeriodType()); lockinPeriodType = PeriodFrequencyType.fromInt(command.getLockinPeriodType());
} }
DepositAccount newAccount =new DepositAccount().openNew(client, product, null, DepositAccount newAccount = new DepositAccount().openNew(client, product, null, deposit, maturityInterestRate,
deposit, preClosureInterestRate, tenureInMonths, compoundingInterestEvery, compoundingInterestFrequency, account.maturesOnDate()
maturityInterestRate, preClosureInterestRate, .plusDays(1), renewalAllowed, preClosureAllowed, this.fixedTermDepositInterestCalculator,
tenureInMonths, compoundingInterestEvery, compoundingInterestFrequency, defaultDepositLifecycleStateMachine(), isInterestWithdrawable, isInterestCompoundingAllowed, isLockinPeriodAllowed,
account.maturesOnDate().plusDays(1), lockinPeriod, lockinPeriodType);
renewalAllowed, preClosureAllowed, this.fixedTermDepositInterestCalculator, defaultDepositLifecycleStateMachine(),
isInterestWithdrawable,isInterestCompoundingAllowed,isLockinPeriodAllowed,lockinPeriod,lockinPeriodType);
newAccount.updateAccount(account); newAccount.updateAccount(account);
return newAccount; return newAccount;
} }
/*public void adjustTotalAmountForPreclosureInterest(DepositAccount account,LocalDate eventDate) { /*
account.adjustTotalAmountForPreclosureInterest(account,this.fixedTermDepositInterestCalculator,eventDate); * public void adjustTotalAmountForPreclosureInterest(DepositAccount
}*/ * account,LocalDate eventDate) {
* account.adjustTotalAmountForPreclosureInterest
* (account,this.fixedTermDepositInterestCalculator,eventDate); }
*/
public void assembleUpdatedDepositAccount(DepositAccount account, DepositAccountCommand command) { public void assembleUpdatedDepositAccount(DepositAccount account, DepositAccountCommand command) {
DepositProduct product = account.product(); DepositProduct product = account.product();
if (command.getProductId() != null) { if (command.getProductId() != null) {
product = this.depositProductRepository.findOne(command.getProductId()); product = this.depositProductRepository.findOne(command.getProductId());
if (product == null || product.isDeleted()) { if (product == null || product.isDeleted()) { throw new DepositProductNotFoundException(command.getProductId()); }
throw new DepositProductNotFoundException(command.getProductId());
}
} }
String externalId = account.getExternalId(); String externalId = account.getExternalId();
@@ -274,9 +263,8 @@ public class DepositAccountAssembler {
preClosureInterestRate = command.getPreClosureInterestRate(); preClosureInterestRate = command.getPreClosureInterestRate();
} }
if(product.getMaturityMinInterestRate().compareTo(preClosureInterestRate)==-1){ if (product.getMaturityMinInterestRate().compareTo(preClosureInterestRate) == -1) { throw new DepositAccounDataValidationtException(
throw new DepositAccounDataValidationtException(preClosureInterestRate, product.getMaturityMinInterestRate()); preClosureInterestRate, product.getMaturityMinInterestRate()); }
}
Integer compoundingInterestEvery = account.getInterestCompoundedEvery(); Integer compoundingInterestEvery = account.getInterestCompoundedEvery();
if (command.isCompoundingInterestEveryChanged()) { if (command.isCompoundingInterestEveryChanged()) {
@@ -322,8 +310,10 @@ public class DepositAccountAssembler {
if (command.getLockinPeriodType() != null) { if (command.getLockinPeriodType() != null) {
lockinPeriodType = PeriodFrequencyType.fromInt(command.getLockinPeriodType()); lockinPeriodType = PeriodFrequencyType.fromInt(command.getLockinPeriodType());
} }
account.update(product,externalId,commencementDate,deposit,tenureInMonths,maturityInterestRate,preClosureInterestRate,compoundingInterestEvery,compoundingInterestFrequency,renewalAllowed, account.update(product, externalId, commencementDate, deposit, tenureInMonths, maturityInterestRate, preClosureInterestRate,
preClosureAllowed,isInterestWithdrawable,isInterestCompoundingAllowed,this.fixedTermDepositInterestCalculator,isLockinPeriodAllowed,lockinPeriod,lockinPeriodType); compoundingInterestEvery, compoundingInterestFrequency, renewalAllowed, preClosureAllowed, isInterestWithdrawable,
isInterestCompoundingAllowed, this.fixedTermDepositInterestCalculator, isLockinPeriodAllowed, lockinPeriod,
lockinPeriodType);
} }
public void updateApprovedDepositAccount(DepositAccount account, DepositAccountCommand command) { public void updateApprovedDepositAccount(DepositAccount account, DepositAccountCommand command) {
@@ -13,31 +13,42 @@ public class DepositAccountEnumerations {
EnumOptionData optionData = null; EnumOptionData optionData = null;
switch (status) { switch (status) {
case SUBMITED_AND_PENDING_APPROVAL: case SUBMITED_AND_PENDING_APPROVAL:
optionData = new EnumOptionData(DepositAccountStatus.SUBMITED_AND_PENDING_APPROVAL.getValue().longValue(), DepositAccountStatus.SUBMITED_AND_PENDING_APPROVAL.getCode(), "Submitted and pending approval"); optionData = new EnumOptionData(DepositAccountStatus.SUBMITED_AND_PENDING_APPROVAL.getValue().longValue(),
DepositAccountStatus.SUBMITED_AND_PENDING_APPROVAL.getCode(), "Submitted and pending approval");
break; break;
/*case APPROVED: /*
optionData = new EnumOptionData(DepositAccountStatus.APPROVED.getValue().longValue(), DepositAccountStatus.APPROVED.getCode(), "Approved"); * case APPROVED: optionData = new
break;*/ * EnumOptionData(DepositAccountStatus
* .APPROVED.getValue().longValue(),
* DepositAccountStatus.APPROVED.getCode(), "Approved"); break;
*/
case ACTIVE: case ACTIVE:
optionData = new EnumOptionData(DepositAccountStatus.ACTIVE.getValue().longValue(), DepositAccountStatus.ACTIVE.getCode(), "Active"); optionData = new EnumOptionData(DepositAccountStatus.ACTIVE.getValue().longValue(), DepositAccountStatus.ACTIVE.getCode(),
"Active");
break; break;
case REJECTED: case REJECTED:
optionData = new EnumOptionData(DepositAccountStatus.REJECTED.getValue().longValue(), DepositAccountStatus.REJECTED.getCode(), "Rejected"); optionData = new EnumOptionData(DepositAccountStatus.REJECTED.getValue().longValue(),
DepositAccountStatus.REJECTED.getCode(), "Rejected");
break; break;
case WITHDRAWN_BY_CLIENT: case WITHDRAWN_BY_CLIENT:
optionData = new EnumOptionData(DepositAccountStatus.WITHDRAWN_BY_CLIENT.getValue().longValue(), DepositAccountStatus.WITHDRAWN_BY_CLIENT.getCode(), "Withdrawn by applicant"); optionData = new EnumOptionData(DepositAccountStatus.WITHDRAWN_BY_CLIENT.getValue().longValue(),
DepositAccountStatus.WITHDRAWN_BY_CLIENT.getCode(), "Withdrawn by applicant");
break; break;
case MATURED: case MATURED:
optionData = new EnumOptionData(DepositAccountStatus.MATURED.getValue().longValue(), DepositAccountStatus.MATURED.getCode(), "Matured"); optionData = new EnumOptionData(DepositAccountStatus.MATURED.getValue().longValue(),
DepositAccountStatus.MATURED.getCode(), "Matured");
break; break;
case CLOSED: case CLOSED:
optionData = new EnumOptionData(DepositAccountStatus.CLOSED.getValue().longValue(), DepositAccountStatus.CLOSED.getCode(), "Closed"); optionData = new EnumOptionData(DepositAccountStatus.CLOSED.getValue().longValue(), DepositAccountStatus.CLOSED.getCode(),
"Closed");
break; break;
case PRECLOSED: case PRECLOSED:
optionData = new EnumOptionData(DepositAccountStatus.PRECLOSED.getValue().longValue(), DepositAccountStatus.PRECLOSED.getCode(), "Preclosed"); optionData = new EnumOptionData(DepositAccountStatus.PRECLOSED.getValue().longValue(),
DepositAccountStatus.PRECLOSED.getCode(), "Preclosed");
break; break;
default: default:
optionData = new EnumOptionData(DepositAccountStatus.INVALID.getValue().longValue(), DepositAccountStatus.INVALID.getCode(), "Invalid"); optionData = new EnumOptionData(DepositAccountStatus.INVALID.getValue().longValue(),
DepositAccountStatus.INVALID.getCode(), "Invalid");
break; break;
} }
return optionData; return optionData;
@@ -219,7 +219,8 @@ public class DepositAccountReadPlatformServiceImpl implements DepositAccountRead
projectedInterestAccrued, actualInterestAccrued, projectedMaturityAmount, actualMaturityAmount, projectedInterestAccrued, actualInterestAccrued, projectedMaturityAmount, actualMaturityAmount,
interestCompoundedEvery, interestCompoundedEveryPeriodType, renewalAllowed, preClosureAllowed, preClosureInterestRate, interestCompoundedEvery, interestCompoundedEveryPeriodType, renewalAllowed, preClosureAllowed, preClosureInterestRate,
withdrawnonDate, rejectedonDate, closedonDate, isInterestWithdrawable, interestPaid, interestCompoundingAllowed, withdrawnonDate, rejectedonDate, closedonDate, isInterestWithdrawable, interestPaid, interestCompoundingAllowed,
isLockinPeriodAllowed, lockinPeriod, lockinPeriodType, availableInterest, interestPostedAmount, lastInterestPostedDate, nextInterestPostedDate); isLockinPeriodAllowed, lockinPeriod, lockinPeriodType, availableInterest, interestPostedAmount, lastInterestPostedDate,
nextInterestPostedDate);
} }
} }
@@ -254,7 +255,18 @@ public class DepositAccountReadPlatformServiceImpl implements DepositAccountRead
boolean undoApprovalAllowed = (depositAccountData.getStatus().getId().equals(300L)); boolean undoApprovalAllowed = (depositAccountData.getStatus().getId().equals(300L));
boolean renewelAllowed = false; boolean renewelAllowed = false;
if (depositAccountData.getMaturedOn() != null) { if (depositAccountData.getMaturedOn() != null) {
if (new LocalDate().isAfter(depositAccountData.getMaturedOn())/* || depositAccountData.getMaturedOn().isEqual(new LocalDate()) */) { if (new LocalDate().isAfter(depositAccountData.getMaturedOn())/*
* ||
* depositAccountData
* .
* getMaturedOn
* ().
* isEqual
* (
* new
* LocalDate
* ())
*/) {
renewelAllowed = depositAccountData.isRenewalAllowed(); renewelAllowed = depositAccountData.isRenewalAllowed();
} }
} }
@@ -294,7 +306,7 @@ public class DepositAccountReadPlatformServiceImpl implements DepositAccountRead
} }
@Override @Override
public DepositAccountsForLookup mapRow(ResultSet rs, int rowNum) throws SQLException { public DepositAccountsForLookup mapRow(ResultSet rs, @SuppressWarnings("unused") int rowNum) throws SQLException {
Long id = rs.getLong("id"); Long id = rs.getLong("id");
return new DepositAccountsForLookup(id); return new DepositAccountsForLookup(id);
} }
@@ -14,18 +14,22 @@ public class DepositAccountTransactionEnumerations {
EnumOptionData optionData = null; EnumOptionData optionData = null;
switch (transactionType) { switch (transactionType) {
case DEPOSIT: case DEPOSIT:
optionData=new EnumOptionData(DepositAccountTransactionType.DEPOSIT.getValue().longValue(), DepositAccountTransactionType.DEPOSIT.getCode(), "Deposit"); optionData = new EnumOptionData(DepositAccountTransactionType.DEPOSIT.getValue().longValue(),
DepositAccountTransactionType.DEPOSIT.getCode(), "Deposit");
break; break;
case WITHDRAW: case WITHDRAW:
optionData=new EnumOptionData(DepositAccountTransactionType.WITHDRAW.getValue().longValue(), DepositAccountTransactionType.WITHDRAW.getCode(), "Withdraw"); optionData = new EnumOptionData(DepositAccountTransactionType.WITHDRAW.getValue().longValue(),
DepositAccountTransactionType.WITHDRAW.getCode(), "Withdraw");
break; break;
case REVERSAL: case REVERSAL:
optionData=new EnumOptionData(DepositAccountTransactionType.REVERSAL.getValue().longValue(), DepositAccountTransactionType.REVERSAL.getCode(), "Revarsal"); optionData = new EnumOptionData(DepositAccountTransactionType.REVERSAL.getValue().longValue(),
DepositAccountTransactionType.REVERSAL.getCode(), "Revarsal");
break; break;
default: default:
optionData=new EnumOptionData(DepositAccountTransactionType.INVALID.getValue().longValue(), DepositAccountTransactionType.INVALID.getCode(), "Invalid Transaction"); optionData = new EnumOptionData(DepositAccountTransactionType.INVALID.getValue().longValue(),
DepositAccountTransactionType.INVALID.getCode(), "Invalid Transaction");
break; break;
} }
return optionData; return optionData;
@@ -306,7 +306,8 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
"You can not withdraw your application before maturity date reached"); } "You can not withdraw your application before maturity date reached"); }
} }
// if (eventDate.isBefore(account.maturesOnDate())) { // if (eventDate.isBefore(account.maturesOnDate())) {
// this.depositAccountAssembler.adjustTotalAmountForPreclosureInterest(account, eventDate); // this.depositAccountAssembler.adjustTotalAmountForPreclosureInterest(account,
// eventDate);
// } // }
account.withdrawDepositAccountMoney(defaultDepositLifecycleStateMachine(), fixedTermDepositInterestCalculator, eventDate); account.withdrawDepositAccountMoney(defaultDepositLifecycleStateMachine(), fixedTermDepositInterestCalculator, eventDate);
this.depositAccountRepository.save(account); this.depositAccountRepository.save(account);
@@ -428,12 +429,9 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
try { try {
for (DepositAccountsForLookup accountData : accounts) for (DepositAccountsForLookup accountData : accounts) {
{
DepositAccount account = this.depositAccountRepository.findOne(accountData.getId()); DepositAccount account = this.depositAccountRepository.findOne(accountData.getId());
if (account == null || account.isDeleted()) { if (account == null || account.isDeleted()) { throw new DepositAccountNotFoundException(accountData.getId()); }
throw new DepositAccountNotFoundException(accountData.getId());
}
this.depositAccountAssembler.postInterest(account); this.depositAccountAssembler.postInterest(account);
this.depositAccountRepository.save(account); this.depositAccountRepository.save(account);
} }
@@ -24,9 +24,7 @@ public class DepositStateTransitionCommandValidator {
baseDataValidator.reset().parameter("eventDate").value(command.getEventDate()).notNull(); baseDataValidator.reset().parameter("eventDate").value(command.getEventDate()).notNull();
baseDataValidator.reset().parameter("note").value(command.getNote()).notNull(); baseDataValidator.reset().parameter("note").value(command.getNote()).notNull();
if (!dataValidationErrors.isEmpty()) { if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.", dataValidationErrors); "Validation errors exist.", dataValidationErrors); }
} }
} }
}
@@ -27,17 +27,20 @@ public class RenewDepositAccountCommandValidator {
baseDataValidator.reset().parameter("externalId").value(command.getExternalId()).ignoreIfNull().notExceedingLengthOf(100); baseDataValidator.reset().parameter("externalId").value(command.getExternalId()).ignoreIfNull().notExceedingLengthOf(100);
baseDataValidator.reset().parameter("deposit").value(command.getDepositAmount()).ignoreIfNull().zeroOrPositiveAmount(); baseDataValidator.reset().parameter("deposit").value(command.getDepositAmount()).ignoreIfNull().zeroOrPositiveAmount();
baseDataValidator.reset().parameter("maturityInterestRate").value(command.getMaturityInterestRate()).ignoreIfNull().zeroOrPositiveAmount(); baseDataValidator.reset().parameter("maturityInterestRate").value(command.getMaturityInterestRate()).ignoreIfNull()
baseDataValidator.reset().parameter("preClosureInterestRate").value(command.getPreClosureInterestRate()).ignoreIfNull().zeroOrPositiveAmount(); .zeroOrPositiveAmount();
baseDataValidator.reset().parameter("preClosureInterestRate").value(command.getPreClosureInterestRate()).ignoreIfNull()
.zeroOrPositiveAmount();
baseDataValidator.reset().parameter("tenureInMonths").value(command.getTenureInMonths()).ignoreIfNull().integerGreaterThanZero(); baseDataValidator.reset().parameter("tenureInMonths").value(command.getTenureInMonths()).ignoreIfNull().integerGreaterThanZero();
baseDataValidator.reset().parameter("interestCompoundedEvery").value(command.getInterestCompoundedEvery()).ignoreIfNull().integerGreaterThanZero(); baseDataValidator.reset().parameter("interestCompoundedEvery").value(command.getInterestCompoundedEvery()).ignoreIfNull()
baseDataValidator.reset().parameter("interestCompoundedEveryPeriodType").value(command.getInterestCompoundedEveryPeriodType()).ignoreIfNull().inMinMaxRange(2, 2); .integerGreaterThanZero();
baseDataValidator.reset().parameter("interestCompoundedEveryPeriodType").value(command.getInterestCompoundedEveryPeriodType())
.ignoreIfNull().inMinMaxRange(2, 2);
baseDataValidator.reset().parameter("commencementDate").value(command.getCommencementDate()).ignoreIfNull(); baseDataValidator.reset().parameter("commencementDate").value(command.getCommencementDate()).ignoreIfNull();
if (!dataValidationErrors.isEmpty()) { if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.", dataValidationErrors); "Validation errors exist.", dataValidationErrors); }
}
} }
} }