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,23 +60,25 @@ 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);
if (is(commandParam, "calculateSavingSchedule")) { if (is(commandParam, "calculateSavingSchedule")) {
CalculateSavingScheduleCommand calculateSavingScheduleCommand = command.toCalculateSavingScheduleCommand(); CalculateSavingScheduleCommand calculateSavingScheduleCommand = command.toCalculateSavingScheduleCommand();
return calculateSavingSchedule(uriInfo,calculateSavingScheduleCommand); return calculateSavingSchedule(uriInfo, calculateSavingScheduleCommand);
} }
EntityIdentifier entityIdentifier = this.savingAccountWritePlatformService.createSavingAccount(command); EntityIdentifier entityIdentifier = this.savingAccountWritePlatformService.createSavingAccount(command);
@@ -95,9 +97,9 @@ public class SavingsAccountApiResource {
@PUT @PUT
@Path("{accountId}") @Path("{accountId}")
@Consumes({MediaType.APPLICATION_JSON}) @Consumes({ MediaType.APPLICATION_JSON })
@Produces({MediaType.APPLICATION_JSON}) @Produces({ MediaType.APPLICATION_JSON })
public Response updateSavingAccount(@PathParam("accountId") final Long accountId,final String jsonRequestBody){ public Response updateSavingAccount(@PathParam("accountId") final Long accountId, final String jsonRequestBody) {
final SavingAccountCommand command = this.apiDataConversionService.convertJsonToSavingAccountCommand(accountId, jsonRequestBody); final SavingAccountCommand command = this.apiDataConversionService.convertJsonToSavingAccountCommand(accountId, jsonRequestBody);
@@ -107,8 +109,8 @@ public class SavingsAccountApiResource {
} }
@GET @GET
@Consumes({MediaType.APPLICATION_JSON}) @Consumes({ MediaType.APPLICATION_JSON })
@Produces({MediaType.APPLICATION_JSON}) @Produces({ MediaType.APPLICATION_JSON })
public String retrieveAllDepositAccounts(@Context final UriInfo uriInfo) { public String retrieveAllDepositAccounts(@Context final UriInfo uriInfo) {
context.authenticatedUser().validateHasReadPermission(entityType); context.authenticatedUser().validateHasReadPermission(entityType);
@@ -126,8 +128,8 @@ public class SavingsAccountApiResource {
@GET @GET
@Path("{accountId}") @Path("{accountId}")
@Consumes({MediaType.APPLICATION_JSON}) @Consumes({ MediaType.APPLICATION_JSON })
@Produces({MediaType.APPLICATION_JSON}) @Produces({ MediaType.APPLICATION_JSON })
public String retrieveDepositAccount(@PathParam("accountId") final Long accountId, @Context final UriInfo uriInfo) { public String retrieveDepositAccount(@PathParam("accountId") final Long accountId, @Context final UriInfo uriInfo) {
context.authenticatedUser().validateHasReadPermission(entityType); context.authenticatedUser().validateHasReadPermission(entityType);
@@ -147,12 +149,10 @@ public class SavingsAccountApiResource {
@SuppressWarnings("unused") @SuppressWarnings("unused")
@GET @GET
@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,20 +14,16 @@ 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;
this.deposit = deposit; this.deposit = deposit;
this.payEvery = payEvery; this.payEvery = payEvery;
this.paymentFrequencyType=paymentFrequencyType; this.paymentFrequencyType = paymentFrequencyType;
this.interestRate= interestRate; this.interestRate = interestRate;
this.paymentsStartingFromDate=paymentsStartingFromDate; this.paymentsStartingFromDate = paymentsStartingFromDate;
this.tenure = tenure; this.tenure = tenure;
} }
@@ -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;
@@ -64,18 +58,17 @@ public class SavingAccountCommand {
this.modifiedParameters = modifiedParameters; this.modifiedParameters = modifiedParameters;
this.commencementDate = commencementDate; this.commencementDate = commencementDate;
this.savingProductType=savingProductType; this.savingProductType = savingProductType;
this.tenureType=tenureType; this.tenureType = tenureType;
this.frequency=frequency; this.frequency = frequency;
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;
this.minimumBalanceForWithdrawal=minimumBalanceForWithdrawal; this.minimumBalanceForWithdrawal = minimumBalanceForWithdrawal;
this.interestCalculationMethod=interestCalculationMethod; this.interestCalculationMethod = interestCalculationMethod;
this.payEvery = payEvery; this.payEvery = payEvery;
} }
@@ -171,15 +164,15 @@ public class SavingAccountCommand {
return this.modifiedParameters.isEmpty(); return this.modifiedParameters.isEmpty();
} }
public boolean isProductIdChanged(){ public boolean isProductIdChanged() {
return this.modifiedParameters.contains("productId"); return this.modifiedParameters.contains("productId");
} }
public boolean isExternalIdChanged(){ public boolean isExternalIdChanged() {
return this.modifiedParameters.contains("externalId"); return this.modifiedParameters.contains("externalId");
} }
public boolean isDepositAmountChanged(){ public boolean isDepositAmountChanged() {
return this.modifiedParameters.contains("deposit"); return this.modifiedParameters.contains("deposit");
} }
@@ -191,7 +184,7 @@ public class SavingAccountCommand {
return this.modifiedParameters.contains("lockinPeriod"); return this.modifiedParameters.contains("lockinPeriod");
} }
public boolean isPreClosureInterestRateChanged(){ public boolean isPreClosureInterestRateChanged() {
return this.modifiedParameters.contains("preClosureInterestRate"); return this.modifiedParameters.contains("preClosureInterestRate");
} }
@@ -239,12 +232,13 @@ public class SavingAccountCommand {
return this.modifiedParameters.contains("isPartialDepositAllowed"); return this.modifiedParameters.contains("isPartialDepositAllowed");
} }
public boolean isPayEveryChanged(){ public boolean isPayEveryChanged() {
return this.modifiedParameters.contains("payEvery"); return this.modifiedParameters.contains("payEvery");
} }
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);
} }
} }
@@ -14,8 +14,8 @@ public class SavingScheduleData {
public SavingScheduleData(final CurrencyData currency, final BigDecimal cumulativeDepositDue, public SavingScheduleData(final CurrencyData currency, final BigDecimal cumulativeDepositDue,
final Collection<SavingSchedulePeriodData> periods) { final Collection<SavingSchedulePeriodData> periods) {
this.currency = currency; this.currency = currency;
this.cumulativeDepositDue= cumulativeDepositDue; this.cumulativeDepositDue = cumulativeDepositDue;
this.periods= periods; this.periods = periods;
} }
@@ -14,11 +14,12 @@ public class SavingSchedulePeriodData {
public SavingSchedulePeriodData(final Integer period, final LocalDate dueDate, final BigDecimal depositDue, final BigDecimal depositPaid) { public SavingSchedulePeriodData(final Integer period, final LocalDate dueDate, final BigDecimal depositDue, final BigDecimal depositPaid) {
this.period = period; this.period = period;
this.dueDate = dueDate; this.dueDate = dueDate;
this.depositDue= depositDue; this.depositDue = depositDue;
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);
} }
@@ -37,7 +37,7 @@ import org.mifosplatform.portfolio.savingsdepositproduct.domain.TenureTypeEnum;
import org.mifosplatform.useradministration.domain.AppUser; import org.mifosplatform.useradministration.domain.AppUser;
@Entity @Entity
@Table(name = "m_saving_account", uniqueConstraints = @UniqueConstraint(name="saving_acc_external_id", columnNames = { "external_id" })) @Table(name = "m_saving_account", uniqueConstraints = @UniqueConstraint(name = "saving_acc_external_id", columnNames = { "external_id" }))
public class SavingAccount extends AbstractAuditableCustom<AppUser, Long> { public class SavingAccount extends AbstractAuditableCustom<AppUser, Long> {
@ManyToOne @ManyToOne
@@ -48,8 +48,9 @@ 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
@Column(name = "savings_product_type", nullable=false) // Integer e.g. private Integer savingProductType;
@Column(name = "savings_product_type", nullable = false)
private SavingProductType savingProductType; private SavingProductType savingProductType;
@Column(name = "external_id") @Column(name = "external_id")
@@ -72,21 +73,24 @@ public class SavingAccount extends AbstractAuditableCustom<AppUser, Long> {
@Column(name = "regular_saving_nominal_interest_rate", scale = 6, precision = 19, nullable = false) @Column(name = "regular_saving_nominal_interest_rate", scale = 6, precision = 19, nullable = false)
private BigDecimal savingInterestRate; private BigDecimal savingInterestRate;
@Column(name = "tenure", nullable=false) @Column(name = "tenure", nullable = false)
private Integer tenure; private Integer tenure;
@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
@Column(name = "frequency", nullable=false) // Integer e.g. private Integer savingProductType;
@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
@Column(name = "interest_type", nullable=false) // Integer e.g. private Integer savingProductType;
@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;
@@ -126,7 +130,7 @@ public class SavingAccount extends AbstractAuditableCustom<AppUser, Long> {
@Column(name = "is_preclosure_allowed", nullable = false) @Column(name = "is_preclosure_allowed", nullable = false)
private boolean preClosureAllowed = false; private boolean preClosureAllowed = false;
@Column(name = "is_deleted", nullable=false) @Column(name = "is_deleted", nullable = false)
private boolean deleted = false; private boolean deleted = false;
@Column(name = "status_enum", nullable = false) @Column(name = "status_enum", nullable = false)
@@ -146,13 +150,13 @@ public class SavingAccount extends AbstractAuditableCustom<AppUser, Long> {
@Column(name = "withdrawnon_date") @Column(name = "withdrawnon_date")
private Date withdrawnOnDate; private Date withdrawnOnDate;
@Column(name = "is_lock_in_period_allowed", nullable=false) @Column(name = "is_lock_in_period_allowed", nullable = false)
private boolean isLockinPeriodAllowed = false; private boolean isLockinPeriodAllowed = false;
@Column(name = "lock_in_period", nullable=false) @Column(name = "lock_in_period", nullable = false)
private Integer lockinPeriod; private Integer lockinPeriod;
@Column(name = "lock_in_period_type", nullable=false) @Column(name = "lock_in_period_type", nullable = false)
private PeriodFrequencyType lockinPeriodType; private PeriodFrequencyType lockinPeriodType;
// see // see
@@ -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) {
@@ -216,8 +200,8 @@ public class SavingAccount extends AbstractAuditableCustom<AppUser, Long> {
DepositAccountStatus statusEnum = lifecycleStateMachine.transition(DepositAccountEvent.DEPOSIT_CREATED, from); DepositAccountStatus statusEnum = lifecycleStateMachine.transition(DepositAccountEvent.DEPOSIT_CREATED, from);
accountStatus = statusEnum.getValue(); accountStatus = statusEnum.getValue();
this.total=BigDecimal.ZERO; this.total = BigDecimal.ZERO;
this.preClosureInterestRate=BigDecimal.ZERO; this.preClosureInterestRate = BigDecimal.ZERO;
this.totalSavingsAmount = BigDecimal.ZERO; this.totalSavingsAmount = BigDecimal.ZERO;
this.interestAccrued = BigDecimal.ZERO; this.interestAccrued = BigDecimal.ZERO;
@@ -228,57 +212,46 @@ public class SavingAccount extends AbstractAuditableCustom<AppUser, Long> {
this.currency = savingsDeposit.getCurrency(); this.currency = savingsDeposit.getCurrency();
this.reccuringInterestRate = reccuringInterestRate; this.reccuringInterestRate = reccuringInterestRate;
this.savingInterestRate = savingInterestRate; this.savingInterestRate = savingInterestRate;
this.tenure =tenure; this.tenure = tenure;
this.projectedCommencementDate=commencementDate.toDate(); this.projectedCommencementDate = commencementDate.toDate();
this.tenureType = tenureTypeEnum; this.tenureType = tenureTypeEnum;
this.savingProductType = savingProductType; this.savingProductType = savingProductType;
this.frequency = savingFrequencyType; this.frequency = savingFrequencyType;
this.interestType = interestType; this.interestType = interestType;
this.interestCalculationMethod= savingInterestCalculationMethod; this.interestCalculationMethod = savingInterestCalculationMethod;
this.isLockinPeriodAllowed = isLockinPeriodAllowed; this.isLockinPeriodAllowed = isLockinPeriodAllowed;
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;
this.externalId=externalId; this.externalId = externalId;
this.savingsDepositAmountPerPeriod=savingsDeposit.getAmount(); this.savingsDepositAmountPerPeriod = savingsDeposit.getAmount();
this.reccuringInterestRate=reccuringInterestRate; this.reccuringInterestRate = reccuringInterestRate;
this.savingInterestRate = savingInterestRate; this.savingInterestRate = savingInterestRate;
this.tenure = tenure; this.tenure = tenure;
this.projectedCommencementDate = commencementDate.toDate(); this.projectedCommencementDate = commencementDate.toDate();
this.tenureType = tenureTypeEnum; this.tenureType = tenureTypeEnum;
this.savingProductType = savingProductType; this.savingProductType = savingProductType;
this.frequency =savingFrequencyType; this.frequency = savingFrequencyType;
this.interestCalculationMethod = savingInterestCalculationMethod; this.interestCalculationMethod = savingInterestCalculationMethod;
this.isLockinPeriodAllowed = isLockinPeriodAllowed; this.isLockinPeriodAllowed = isLockinPeriodAllowed;
this.lockinPeriod = lockinPeriod; this.lockinPeriod = lockinPeriod;
@@ -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>{
} }
@@ -15,35 +15,34 @@ import org.mifosplatform.infrastructure.core.domain.AbstractAuditableCustom;
import org.mifosplatform.useradministration.domain.AppUser; import org.mifosplatform.useradministration.domain.AppUser;
@Entity @Entity
@Table(name="m_saving_schedule") @Table(name = "m_saving_schedule")
public class SavingScheduleInstallments extends AbstractAuditableCustom<AppUser, Long> { public class SavingScheduleInstallments extends AbstractAuditableCustom<AppUser, Long> {
@ManyToOne(optional = false) @ManyToOne(optional = false)
@JoinColumn(name = "saving_account_id", nullable=false) @JoinColumn(name = "saving_account_id", nullable = false)
private SavingAccount savingAccount; private SavingAccount savingAccount;
@Temporal(TemporalType.DATE) @Temporal(TemporalType.DATE)
@Column(name = "duedate", nullable=false) @Column(name = "duedate", nullable = false)
private final Date dueDate; private final Date dueDate;
@Column(name = "installment", nullable=false) @Column(name = "installment", nullable = false)
private final Integer installmentNumber; private final Integer installmentNumber;
@Column(name = "deposit", scale=6, precision=19, nullable=false) @Column(name = "deposit", scale = 6, precision = 19, nullable = false)
private BigDecimal deposit; private BigDecimal deposit;
@Temporal(TemporalType.DATE) @Temporal(TemporalType.DATE)
@Column(name = "payment_date", nullable=true) @Column(name = "payment_date", nullable = true)
private final Date paymentDate; private final Date paymentDate;
@Column(name = "deposit_paid", scale=6, precision=19, nullable=true) @Column(name = "deposit_paid", scale = 6, precision = 19, nullable = true)
private BigDecimal depositPaid; private BigDecimal depositPaid;
@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;
@@ -53,7 +52,7 @@ public class SavingScheduleInstallments extends AbstractAuditableCustom<AppUser,
this.completed = false; this.completed = false;
} }
public void updateAccount(SavingAccount account){ public void updateAccount(SavingAccount account) {
this.savingAccount = account; this.savingAccount = account;
} }
@@ -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,10 +48,11 @@ 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);
return savingScheduleData; return savingScheduleData;
} }
@@ -10,12 +10,13 @@ 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;
for (int period=1; period <= paymentPeriods; period++){ for (int period = 1; period <= paymentPeriods; period++) {
LocalDate duePaymentPeriodDate = startDate; LocalDate duePaymentPeriodDate = startDate;
if (period == 1) { if (period == 1) {
@@ -40,45 +40,43 @@ public class SavingAccountAssembler {
private final CalculateSavingSchedule calculateSavingSchedule; private final CalculateSavingSchedule calculateSavingSchedule;
@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,
this.clientRepository=clientRepository; final CalculateSavingSchedule calculateSavingSchedule) {
this.savingProductRepository=savingProductRepository; this.clientRepository = clientRepository;
this.reccuringDepositInterestCalculator=reccuringDepositInterestCalculator; this.savingProductRepository = savingProductRepository;
this.reccuringDepositInterestCalculator = reccuringDepositInterestCalculator;
this.calculateSavingSchedule = calculateSavingSchedule; this.calculateSavingSchedule = calculateSavingSchedule;
} }
//minimumBalanceForWithdrawal,isPartialDepositAllowed
public SavingAccount assembleFrom(SavingAccountCommand command){ // minimumBalanceForWithdrawal,isPartialDepositAllowed
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) {
currency = new MonetaryCurrency(command.getCurrencyCode(), command.getDigitsAfterDecimal()); currency = new MonetaryCurrency(command.getCurrencyCode(), command.getDigitsAfterDecimal());
} }
Money savingsDeposit = Money.of(currency, command.getSavingsDepositAmount()); Money savingsDeposit = Money.of(currency, command.getSavingsDepositAmount());
Integer tenure = product.getSavingProductRelatedDetail().getTenure(); Integer tenure = product.getSavingProductRelatedDetail().getTenure();
if(command.getTenure() != null){ if (command.getTenure() != null) {
tenure=command.getTenure(); tenure = command.getTenure();
} }
TenureTypeEnum tenureTypeEnum=product.getSavingProductRelatedDetail().getTenureType(); TenureTypeEnum tenureTypeEnum = product.getSavingProductRelatedDetail().getTenureType();
if (command.getTenureType() != null) { if (command.getTenureType() != null) {
tenureTypeEnum = TenureTypeEnum.fromInt(command.getTenureType()); tenureTypeEnum = TenureTypeEnum.fromInt(command.getTenureType());
} }
SavingProductType savingProductType= product.getSavingProductRelatedDetail().getSavingProductType(); SavingProductType savingProductType = product.getSavingProductRelatedDetail().getSavingProductType();
if(command.getSavingProductType() != null){ if (command.getSavingProductType() != null) {
savingProductType = SavingProductType.fromInt(command.getSavingProductType()); savingProductType = SavingProductType.fromInt(command.getSavingProductType());
} }
@@ -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,37 +98,34 @@ 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()) {
isLockinPeriodAllowed = command.isLockinPeriodAllowed(); isLockinPeriodAllowed = command.isLockinPeriodAllowed();
} }
Integer lockinPeriod = product.getSavingProductRelatedDetail().getLockinPeriod(); Integer lockinPeriod = product.getSavingProductRelatedDetail().getLockinPeriod();
if(command.getLockinPeriod() != null){ if (command.getLockinPeriod() != null) {
lockinPeriod = command.getLockinPeriod(); lockinPeriod = command.getLockinPeriod();
} }
PeriodFrequencyType lockinPeriodType = product.getSavingProductRelatedDetail().getLockinPeriodType(); PeriodFrequencyType lockinPeriodType = product.getSavingProductRelatedDetail().getLockinPeriodType();
if(command.getLockinPeriodType() != null){ if (command.getLockinPeriodType() != null) {
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
for(SavingSchedulePeriodData savingSchedulePeriodData : savingScheduleData.getPeriods()){ .toCalculateSavingScheduleCommand());
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);
} }
@@ -138,26 +134,25 @@ public class SavingAccountAssembler {
public void assembleFrom(SavingAccountCommand command, SavingAccount account) { public void assembleFrom(SavingAccountCommand command, SavingAccount account) {
SavingProduct product=account.getProduct(); SavingProduct product = account.getProduct();
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());
} }
} }
String externalId = account.getExternalId(); String externalId = account.getExternalId();
if(command.isExternalIdChanged()){ if (command.isExternalIdChanged()) {
externalId = command.getExternalId(); externalId = command.getExternalId();
} }
Money savingsDeposit = Money.of(product.getCurrency(), account.getSavingsDepositAmountPerPeriod()); Money savingsDeposit = Money.of(product.getCurrency(), account.getSavingsDepositAmountPerPeriod());
if(command.isDepositAmountChanged()){ if (command.isDepositAmountChanged()) {
savingsDeposit = Money.of(product.getCurrency(), command.getSavingsDepositAmount()); savingsDeposit = Money.of(product.getCurrency(), command.getSavingsDepositAmount());
} }
Integer tenure = account.getTenure(); Integer tenure = account.getTenure();
if(command.isTenureInMonthsChanged()){ if (command.isTenureInMonthsChanged()) {
tenure = command.getTenure(); tenure = command.getTenure();
} }
@@ -166,12 +161,12 @@ public class SavingAccountAssembler {
commencementDate = command.getCommencementDate(); commencementDate = command.getCommencementDate();
} }
TenureTypeEnum tenureTypeEnum=account.getTenureType(); TenureTypeEnum tenureTypeEnum = account.getTenureType();
if(command.isTenureTypeEnumChanged()){ if (command.isTenureTypeEnumChanged()) {
tenureTypeEnum = TenureTypeEnum.fromInt(command.getTenureType()); tenureTypeEnum = TenureTypeEnum.fromInt(command.getTenureType());
} }
SavingProductType savingProductType= account.getSavingProductType(); SavingProductType savingProductType = account.getSavingProductType();
if (command.isSavingProductTypeChanged()) { if (command.isSavingProductTypeChanged()) {
savingProductType = SavingProductType.fromInt(command.getSavingProductType()); savingProductType = SavingProductType.fromInt(command.getSavingProductType());
} }
@@ -181,7 +176,7 @@ public class SavingAccountAssembler {
savingFrequencyType = SavingFrequencyType.fromInt(command.getFrequency()); savingFrequencyType = SavingFrequencyType.fromInt(command.getFrequency());
} }
SavingInterestCalculationMethod savingInterestCalculationMethod =account.getInterestCalculationMethod(); SavingInterestCalculationMethod savingInterestCalculationMethod = account.getInterestCalculationMethod();
if (command.isSavingInterestCalculationMethodChanged()) { if (command.isSavingInterestCalculationMethodChanged()) {
savingInterestCalculationMethod = SavingInterestCalculationMethod.fromInt(command.getInterestCalculationMethod()); savingInterestCalculationMethod = SavingInterestCalculationMethod.fromInt(command.getInterestCalculationMethod());
} }
@@ -201,7 +196,7 @@ public class SavingAccountAssembler {
isLockinPeriodAllowed = command.isLockinPeriodAllowed(); isLockinPeriodAllowed = command.isLockinPeriodAllowed();
} }
Integer lockinPeriod =account.getLockinPeriod(); Integer lockinPeriod = account.getLockinPeriod();
if (command.isLockinPeriodChanged()) { if (command.isLockinPeriodChanged()) {
lockinPeriod = command.getLockinPeriod(); lockinPeriod = command.getLockinPeriod();
} }
@@ -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);
} }
@@ -67,39 +67,40 @@ public class SavingProductsApiResource {
private PlatformSecurityContext context; private PlatformSecurityContext context;
@POST @POST
@Consumes({MediaType.APPLICATION_JSON}) @Consumes({ MediaType.APPLICATION_JSON })
@Produces({MediaType.APPLICATION_JSON}) @Produces({ MediaType.APPLICATION_JSON })
public Response createSavingProduct(final String jsonRequestBody){ public Response createSavingProduct(final String jsonRequestBody) {
final SavingProductCommand command=this.apiDataConversionService.convertJsonToSavingProductCommand(null, jsonRequestBody); final SavingProductCommand command = this.apiDataConversionService.convertJsonToSavingProductCommand(null, jsonRequestBody);
EntityIdentifier entityIdentifier=this.savingProductWritePlatformService.createSavingProduct(command); EntityIdentifier entityIdentifier = this.savingProductWritePlatformService.createSavingProduct(command);
return Response.ok().entity(entityIdentifier).build(); return Response.ok().entity(entityIdentifier).build();
} }
@PUT @PUT
@Path("{productId}") @Path("{productId}")
@Consumes({MediaType.APPLICATION_JSON}) @Consumes({ MediaType.APPLICATION_JSON })
@Produces({MediaType.APPLICATION_JSON}) @Produces({ MediaType.APPLICATION_JSON })
public Response updateSavingProduct(@PathParam("productId") final Long productId, final String jsonRequestBody){ public Response updateSavingProduct(@PathParam("productId") final Long productId, final String jsonRequestBody) {
SavingProductCommand command=this.apiDataConversionService.convertJsonToSavingProductCommand(productId, jsonRequestBody); SavingProductCommand command = this.apiDataConversionService.convertJsonToSavingProductCommand(productId, jsonRequestBody);
EntityIdentifier entityIdentifier=this.savingProductWritePlatformService.updateSavingProduct(command); EntityIdentifier entityIdentifier = this.savingProductWritePlatformService.updateSavingProduct(command);
return Response.ok().entity(entityIdentifier).build(); return Response.ok().entity(entityIdentifier).build();
} }
@GET @GET
@Consumes({MediaType.APPLICATION_JSON}) @Consumes({ MediaType.APPLICATION_JSON })
@Produces({MediaType.APPLICATION_JSON}) @Produces({ MediaType.APPLICATION_JSON })
public String retrieveAllSavingProducts(@Context final UriInfo uriInfo) { public String retrieveAllSavingProducts(@Context final UriInfo uriInfo) {
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()) {
@@ -114,16 +115,17 @@ public class SavingProductsApiResource {
@GET @GET
@Path("{productId}") @Path("{productId}")
@Consumes({MediaType.APPLICATION_JSON}) @Consumes({ MediaType.APPLICATION_JSON })
@Produces({MediaType.APPLICATION_JSON}) @Produces({ MediaType.APPLICATION_JSON })
public String retrieveSavingProductDetails(@PathParam("productId") final Long productId, @Context final UriInfo uriInfo) { public String retrieveSavingProductDetails(@PathParam("productId") final Long productId, @Context final UriInfo uriInfo) {
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()) {
@@ -142,17 +144,16 @@ public class SavingProductsApiResource {
@GET @GET
@Path("template") @Path("template")
@Consumes({MediaType.APPLICATION_JSON}) @Consumes({ MediaType.APPLICATION_JSON })
@Produces({MediaType.APPLICATION_JSON}) @Produces({ MediaType.APPLICATION_JSON })
public String retrieveNewSavingProductDetails(@Context final UriInfo uriInfo) { public String retrieveNewSavingProductDetails(@Context final UriInfo uriInfo) {
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()) {
@@ -161,46 +162,48 @@ public class SavingProductsApiResource {
boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters()); boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters());
SavingProductData savingProduct = this.savingProductReadPlatformService.retrieveNewSavingProductDetails(); SavingProductData savingProduct = this.savingProductReadPlatformService.retrieveNewSavingProductDetails();
savingProduct = handleTemplateRelatedData(responseParameters,savingProduct); savingProduct = handleTemplateRelatedData(responseParameters, savingProduct);
return this.apiJsonSerializerService.serializeSavingProductDataToJson(prettyPrint, responseParameters, savingProduct); return this.apiJsonSerializerService.serializeSavingProductDataToJson(prettyPrint, responseParameters, savingProduct);
} }
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);
EnumOptionData regular = SavingProductEnumerations.savingProductType(SavingProductType.REGULAR); EnumOptionData regular = SavingProductEnumerations.savingProductType(SavingProductType.REGULAR);
List<EnumOptionData> savingsProductTypeOptions = Arrays.asList(reccuring,regular); List<EnumOptionData> savingsProductTypeOptions = Arrays.asList(reccuring, regular);
EnumOptionData fixed = SavingProductEnumerations.tenureTypeEnum(TenureTypeEnum.FIXED_PERIOD); EnumOptionData fixed = SavingProductEnumerations.tenureTypeEnum(TenureTypeEnum.FIXED_PERIOD);
EnumOptionData perpetual = SavingProductEnumerations.tenureTypeEnum(TenureTypeEnum.PERPETUAL); EnumOptionData perpetual = SavingProductEnumerations.tenureTypeEnum(TenureTypeEnum.PERPETUAL);
List<EnumOptionData> tenureTypeOptions = Arrays.asList(fixed,perpetual); List<EnumOptionData> tenureTypeOptions = Arrays.asList(fixed, perpetual);
EnumOptionData monthly = SavingProductEnumerations.interestFrequencyType(SavingFrequencyType.MONTHLY); EnumOptionData monthly = SavingProductEnumerations.interestFrequencyType(SavingFrequencyType.MONTHLY);
List<EnumOptionData> savingFrequencyOptions = Arrays.asList(monthly); List<EnumOptionData> savingFrequencyOptions = Arrays.asList(monthly);
EnumOptionData simple = SavingProductEnumerations.savingInterestType(SavingsInterestType.SIMPLE); EnumOptionData simple = SavingProductEnumerations.savingInterestType(SavingsInterestType.SIMPLE);
EnumOptionData compounding = SavingProductEnumerations.savingInterestType(SavingsInterestType.COMPOUNDING); EnumOptionData compounding = SavingProductEnumerations.savingInterestType(SavingsInterestType.COMPOUNDING);
List<EnumOptionData> savingsInterestTypeOptions = Arrays.asList(simple,compounding); List<EnumOptionData> savingsInterestTypeOptions = Arrays.asList(simple, compounding);
EnumOptionData months = SavingProductEnumerations.savingsLockinPeriod(SavingsLockinPeriodEnum.MONTHS); EnumOptionData months = SavingProductEnumerations.savingsLockinPeriod(SavingsLockinPeriodEnum.MONTHS);
List<EnumOptionData> lockinPeriodTypeOptions = Arrays.asList(months); List<EnumOptionData> lockinPeriodTypeOptions = Arrays.asList(months);
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
List<EnumOptionData> interestCalculationOptions= Arrays.asList(averagebal,minbal,monthlyCollection); .savingInterestCalculationMethod(SavingInterestCalculationMethod.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
@Path("{productId}") @Path("{productId}")
@Consumes({MediaType.APPLICATION_JSON}) @Consumes({ MediaType.APPLICATION_JSON })
@Produces({MediaType.APPLICATION_JSON}) @Produces({ MediaType.APPLICATION_JSON })
public Response deleteProduct(@PathParam("productId") final Long productId) { public Response deleteProduct(@PathParam("productId") final Long productId) {
this.savingProductWritePlatformService.deleteSavingProduct(productId); this.savingProductWritePlatformService.deleteSavingProduct(productId);
@@ -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;
@@ -52,18 +46,18 @@ public class SavingProductCommand {
this.minInterestRate = minInterestRate; this.minInterestRate = minInterestRate;
this.maxInterestRate = maxInterestRate; this.maxInterestRate = maxInterestRate;
this.savingsDepositAmount=savingsDepositAmount; this.savingsDepositAmount = savingsDepositAmount;
this.savingProductType=savingProductType; this.savingProductType = savingProductType;
this.tenureType=tenureType; this.tenureType = tenureType;
this.tenure=tenure; this.tenure = tenure;
this.frequency=frequency; this.frequency = frequency;
this.interestType=interestType; this.interestType = interestType;
this.interestCalculationMethod=interestCalculationMethod; this.interestCalculationMethod = interestCalculationMethod;
this.minimumBalanceForWithdrawal=minimumBalanceForWithdrawal; this.minimumBalanceForWithdrawal = minimumBalanceForWithdrawal;
this.isPartialDepositAllowed=isPartialDepositAllowed; this.isPartialDepositAllowed = isPartialDepositAllowed;
this.isLockinPeriodAllowed=isLockinPeriodAllowed; this.isLockinPeriodAllowed = isLockinPeriodAllowed;
this.lockinPeriod=lockinPeriod; this.lockinPeriod = lockinPeriod;
this.lockinPeriodType=lockinPeriodType; this.lockinPeriodType = lockinPeriodType;
this.modifiedParameters = modifiedParameters; this.modifiedParameters = modifiedParameters;
} }
@@ -168,7 +162,7 @@ public class SavingProductCommand {
return this.modifiedParameters.contains("interestRate"); return this.modifiedParameters.contains("interestRate");
} }
public boolean isSavingsDepositAmountChanged(){ public boolean isSavingsDepositAmountChanged() {
return this.modifiedParameters.contains("savingsDepositAmount"); return this.modifiedParameters.contains("savingsDepositAmount");
} }
@@ -44,106 +44,96 @@ public class SavingProductData implements Serializable {
List<EnumOptionData> lockinPeriodTypeOptions = new ArrayList<EnumOptionData>(); List<EnumOptionData> lockinPeriodTypeOptions = new ArrayList<EnumOptionData>();
List<EnumOptionData> interestCalculationOptions = new ArrayList<EnumOptionData>(); List<EnumOptionData> interestCalculationOptions = new ArrayList<EnumOptionData>();
public SavingProductData(){ public SavingProductData() {
this.createdOn=new DateTime(); this.createdOn = new DateTime();
this.lastModifedOn=new DateTime(); this.lastModifedOn = new DateTime();
this.id=null; this.id = null;
this.name=null; this.name = null;
this.description=null; this.description = null;
this.interestRate=BigDecimal.ZERO; this.interestRate = BigDecimal.ZERO;
this.minInterestRate=BigDecimal.ZERO; this.minInterestRate = BigDecimal.ZERO;
this.maxInterestRate=BigDecimal.ZERO; this.maxInterestRate = BigDecimal.ZERO;
this.currency=null; this.currency = null;
this.digitsAfterDecimal=null; this.digitsAfterDecimal = null;
this.savingsDepositAmount=null; this.savingsDepositAmount = null;
this.savingProductType=null; this.savingProductType = null;
this.tenureType = null; this.tenureType = null;
this.tenure = null; this.tenure = null;
this.savingFrequencyType=null; this.savingFrequencyType = null;
this.interestType=null; this.interestType = null;
this.interestCalculationMethod=null; this.interestCalculationMethod = null;
this.minimumBalanceForWithdrawal=null; this.minimumBalanceForWithdrawal = null;
this.isPartialDepositAllowed=true; this.isPartialDepositAllowed = true;
this.isLockinPeriodAllowed=true; this.isLockinPeriodAllowed = true;
this.lockinPeriod=null; this.lockinPeriod = null;
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, this.createdOn = createdOn;
EnumOptionData savingInterestType, this.lastModifedOn = lastModifedOn;
EnumOptionData interestCalculationMethod, this.id = id;
BigDecimal minimumBalanceForWithdrawal, this.name = name;
boolean isPartialDepositAllowed, boolean isLockinPeriodAllowed, this.description = description;
Integer lockinPeriod, EnumOptionData lockinPeriodType) { this.interestRate = interestRate;
this.createdOn=createdOn; this.minInterestRate = minInterestRate;
this.lastModifedOn=lastModifedOn; this.maxInterestRate = maxInterestRate;
this.id=id; this.currency = currency;
this.name=name; this.digitsAfterDecimal = digitsAfterDecimal;
this.description=description; this.savingsDepositAmount = savingsDepositAmount;
this.interestRate=interestRate; this.savingProductType = savingProductType;
this.minInterestRate=minInterestRate;
this.maxInterestRate=maxInterestRate;
this.currency=currency;
this.digitsAfterDecimal=digitsAfterDecimal;
this.savingsDepositAmount=savingsDepositAmount;
this.savingProductType=savingProductType;
this.tenureType = tenureType; this.tenureType = tenureType;
this.tenure = tenure; this.tenure = tenure;
this.savingFrequencyType=savingFrequencyType; this.savingFrequencyType = savingFrequencyType;
this.interestType=savingInterestType; this.interestType = savingInterestType;
this.interestCalculationMethod=interestCalculationMethod; this.interestCalculationMethod = interestCalculationMethod;
this.minimumBalanceForWithdrawal=minimumBalanceForWithdrawal; this.minimumBalanceForWithdrawal = minimumBalanceForWithdrawal;
this.isPartialDepositAllowed=isPartialDepositAllowed; this.isPartialDepositAllowed = isPartialDepositAllowed;
this.isLockinPeriodAllowed=isLockinPeriodAllowed; this.isLockinPeriodAllowed = isLockinPeriodAllowed;
this.lockinPeriod=lockinPeriod; this.lockinPeriod = lockinPeriod;
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();
this.lastModifedOn=product.getLastModifedOn(); this.lastModifedOn = product.getLastModifedOn();
this.id=product.getId(); this.id = product.getId();
this.name=product.getName(); this.name = product.getName();
this.description=product.getDescription(); this.description = product.getDescription();
this.interestRate=product.getInterestRate(); this.interestRate = product.getInterestRate();
this.minInterestRate=product.getMinInterestRate(); this.minInterestRate = product.getMinInterestRate();
this.maxInterestRate=product.getMaxInterestRate(); this.maxInterestRate = product.getMaxInterestRate();
this.currency=product.getCurrency(); this.currency = product.getCurrency();
this.digitsAfterDecimal=product.getDigitsAfterDecimal(); this.digitsAfterDecimal = product.getDigitsAfterDecimal();
this.savingsDepositAmount=product.getSavingsDepositAmount(); this.savingsDepositAmount = product.getSavingsDepositAmount();
this.savingProductType=product.getSavingProductType(); this.savingProductType = product.getSavingProductType();
this.tenureType = product.getTenureType(); this.tenureType = product.getTenureType();
this.tenure = product.getTenure(); this.tenure = product.getTenure();
this.savingFrequencyType=product.getSavingFrequencyType(); this.savingFrequencyType = product.getSavingFrequencyType();
this.interestType=product.getInterestType(); this.interestType = product.getInterestType();
this.interestCalculationMethod=product.getInterestCalculationMethod(); this.interestCalculationMethod = product.getInterestCalculationMethod();
this.minimumBalanceForWithdrawal=product.getMinimumBalanceForWithdrawal(); this.minimumBalanceForWithdrawal = product.getMinimumBalanceForWithdrawal();
this.isPartialDepositAllowed=product.isPartialDepositAllowed(); this.isPartialDepositAllowed = product.isPartialDepositAllowed();
this.isLockinPeriodAllowed=product.isLockinPeriodAllowed(); this.isLockinPeriodAllowed = product.isLockinPeriodAllowed();
this.lockinPeriod=product.getLockinPeriod(); this.lockinPeriod = product.getLockinPeriod();
this.lockinPeriodType=product.getLockinPeriodType(); this.lockinPeriodType = product.getLockinPeriodType();
this.currencyOptions=currencyOptions; this.currencyOptions = currencyOptions;
this.savingsProductTypeOptions=savingsProductTypeOptions; this.savingsProductTypeOptions = savingsProductTypeOptions;
this.tenureTypeOptions=tenureTypeOptions; this.tenureTypeOptions = tenureTypeOptions;
this.savingFrequencyOptions=savingFrequencyOptions; this.savingFrequencyOptions = savingFrequencyOptions;
this.savingsInterestTypeOptions=savingsInterestTypeOptions; this.savingsInterestTypeOptions = savingsInterestTypeOptions;
this.lockinPeriodTypeOptions=lockinPeriodTypeOptions; this.lockinPeriodTypeOptions = lockinPeriodTypeOptions;
this.interestCalculationOptions=interestCalculationOptions; this.interestCalculationOptions = interestCalculationOptions;
} }
@@ -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,26 +1,22 @@
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;
private SavingFrequencyType(final Integer value,final String code) { private SavingFrequencyType(final Integer value, final String code) {
this.value=value; this.value = value;
this.code=code; this.code = code;
} }
public Integer getValue() { public Integer getValue() {
return value; return value;
} }
public String getCode() { public String getCode() {
return code; return code;
} }
@@ -2,17 +2,15 @@ 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;
private SavingInterestCalculationMethod(final Integer value,final String code) { private SavingInterestCalculationMethod(final Integer value, final String code) {
this.value=value; this.value = value;
this.code=code; this.code = code;
} }
public Integer getValue() { public Integer getValue() {
@@ -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;
@@ -25,7 +25,7 @@ public class SavingProduct extends AbstractAuditableCustom<AppUser, Long> {
@Column(name = "description") @Column(name = "description")
private String description; private String description;
@Column(name = "is_deleted", nullable=false) @Column(name = "is_deleted", nullable = false)
private boolean deleted = false; private boolean deleted = false;
@Embedded @Embedded
@@ -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() {
@@ -64,11 +69,11 @@ public class SavingProduct extends AbstractAuditableCustom<AppUser, Long> {
return this.savingProductRelatedDetail.getCurrency(); return this.savingProductRelatedDetail.getCurrency();
} }
public BigDecimal getInterestRate(){ public BigDecimal getInterestRate() {
return this.savingProductRelatedDetail.getInterestRate(); return this.savingProductRelatedDetail.getInterestRate();
} }
public BigDecimal getMinimumBalance(){ public BigDecimal getMinimumBalance() {
return this.savingProductRelatedDetail.getMinimumBalance(); return this.savingProductRelatedDetail.getMinimumBalance();
} }
@@ -31,19 +31,19 @@ public class SavingProductRelatedDetail {
@Column(name = "savings_deposit_amount", scale = 6, precision = 19, nullable = false) @Column(name = "savings_deposit_amount", scale = 6, precision = 19, nullable = false)
private BigDecimal savingsDepositAmount; private BigDecimal savingsDepositAmount;
@Column(name = "savings_product_type", nullable=false) @Column(name = "savings_product_type", nullable = false)
private SavingProductType savingProductType; private SavingProductType savingProductType;
@Column(name = "tenure_type", nullable=false) @Column(name = "tenure_type", nullable = false)
private TenureTypeEnum tenureType; private TenureTypeEnum tenureType;
@Column(name = "tenure", nullable=false) @Column(name = "tenure", nullable = false)
private Integer tenure; private Integer tenure;
@Column(name = "frequency", nullable=false) @Column(name = "frequency", nullable = false)
private SavingFrequencyType frequency; private SavingFrequencyType frequency;
@Column(name = "interest_type", nullable=false) @Column(name = "interest_type", nullable = false)
private SavingsInterestType interestType; private SavingsInterestType interestType;
@Column(name = "interest_calculation_method") @Column(name = "interest_calculation_method")
@@ -52,47 +52,45 @@ public class SavingProductRelatedDetail {
@Column(name = "min_bal_for_withdrawal", scale = 6, precision = 19, nullable = false) @Column(name = "min_bal_for_withdrawal", scale = 6, precision = 19, nullable = false)
private BigDecimal minimumBalanceForWithdrawal; private BigDecimal minimumBalanceForWithdrawal;
@Column(name = "is_partial_deposit_allowed", nullable=false) @Column(name = "is_partial_deposit_allowed", nullable = false)
private boolean isPartialDepositAllowed; private boolean isPartialDepositAllowed;
@Column(name = "is_lock_in_period_allowed", nullable=false) @Column(name = "is_lock_in_period_allowed", nullable = false)
private boolean isLockinPeriodAllowed; private boolean isLockinPeriodAllowed;
@Column(name = "lock_in_period", nullable=false) @Column(name = "lock_in_period", nullable = false)
private Integer lockinPeriod; private Integer lockinPeriod;
@Column(name = "lock_in_period_type", nullable=false) @Column(name = "lock_in_period_type", nullable = false)
private PeriodFrequencyType lockinPeriodType; private PeriodFrequencyType lockinPeriodType;
public SavingProductRelatedDetail() { public SavingProductRelatedDetail() {
this.interestRate=null; this.interestRate = null;
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;
this.minInterestRate = minInterestRate; this.minInterestRate = minInterestRate;
this.maxInterestRate = maxInterestRate; this.maxInterestRate = maxInterestRate;
this.savingsDepositAmount=savingsDepositAmount; this.savingsDepositAmount = savingsDepositAmount;
this.savingProductType=savingProductType; this.savingProductType = savingProductType;
this.tenureType=tenureType; this.tenureType = tenureType;
this.tenure=tenure; this.tenure = tenure;
this.frequency=frequency; this.frequency = frequency;
this.interestType=interestType; this.interestType = interestType;
this.interestCalculationMethod=interestCalculationMethod; this.interestCalculationMethod = interestCalculationMethod;
this.minimumBalanceForWithdrawal=minimumBalanceForWithdrawal; this.minimumBalanceForWithdrawal = minimumBalanceForWithdrawal;
this.isPartialDepositAllowed=isPartialDepositAllowed; this.isPartialDepositAllowed = isPartialDepositAllowed;
this.isLockinPeriodAllowed=isLockinPeriodAllowed; this.isLockinPeriodAllowed = isLockinPeriodAllowed;
this.lockinPeriod=lockinPeriod; this.lockinPeriod = lockinPeriod;
this.lockinPeriodType=lockinPeriodType; this.lockinPeriodType = lockinPeriodType;
} }
public MonetaryCurrency getCurrency() { public MonetaryCurrency getCurrency() {
@@ -103,11 +101,11 @@ public class SavingProductRelatedDetail {
return BigDecimal.valueOf(Double.valueOf(this.interestRate.stripTrailingZeros().toString())); return BigDecimal.valueOf(Double.valueOf(this.interestRate.stripTrailingZeros().toString()));
} }
public BigDecimal getMinimumBalance(){ public BigDecimal getMinimumBalance() {
return BigDecimal.valueOf(Double.valueOf(this.savingsDepositAmount.stripTrailingZeros().toString())); return BigDecimal.valueOf(Double.valueOf(this.savingsDepositAmount.stripTrailingZeros().toString()));
} }
public void update(SavingProductCommand command){ public void update(SavingProductCommand command) {
Integer digitsAfterDecimal = this.currency.getDigitsAfterDecimal(); Integer digitsAfterDecimal = this.currency.getDigitsAfterDecimal();
if (command.isDigitsAfterDecimalChanged()) { if (command.isDigitsAfterDecimalChanged()) {
digitsAfterDecimal = command.getDigitsAfterDecimal(); digitsAfterDecimal = command.getDigitsAfterDecimal();
@@ -126,23 +124,23 @@ public class SavingProductRelatedDetail {
this.interestRate = command.getInterestRate(); this.interestRate = command.getInterestRate();
} }
if(command.isSavingsDepositAmountChanged()){ if (command.isSavingsDepositAmountChanged()) {
this.savingsDepositAmount=command.getSavingsDepositAmount(); this.savingsDepositAmount = command.getSavingsDepositAmount();
} }
if (command.isSavingProductTypeChanged()) { if (command.isSavingProductTypeChanged()) {
this.savingProductType=SavingProductType.fromInt(command.getSavingProductType()); this.savingProductType = SavingProductType.fromInt(command.getSavingProductType());
} }
if(command.isTenureTypeChanged()){ if (command.isTenureTypeChanged()) {
this.tenureType=TenureTypeEnum.fromInt(command.getTenureType()); this.tenureType = TenureTypeEnum.fromInt(command.getTenureType());
} }
if (command.isTenureChanged()) { if (command.isTenureChanged()) {
this.tenure = command.getTenure(); this.tenure = command.getTenure();
} }
if (command.isFrequencyChanged()){ if (command.isFrequencyChanged()) {
this.frequency = SavingFrequencyType.fromInt(command.getFrequency()); this.frequency = SavingFrequencyType.fromInt(command.getFrequency());
} }
@@ -150,7 +148,7 @@ public class SavingProductRelatedDetail {
this.interestType = SavingsInterestType.fromInt(command.getInterestType()); this.interestType = SavingsInterestType.fromInt(command.getInterestType());
} }
if (command.isInterestCalculationMethodChanged()){ if (command.isInterestCalculationMethodChanged()) {
this.interestCalculationMethod = SavingInterestCalculationMethod.fromInt(command.getInterestCalculationMethod()); this.interestCalculationMethod = SavingInterestCalculationMethod.fromInt(command.getInterestCalculationMethod());
} }
@@ -162,16 +160,16 @@ public class SavingProductRelatedDetail {
this.isPartialDepositAllowed = command.isPartialDepositAllowed(); this.isPartialDepositAllowed = command.isPartialDepositAllowed();
} }
if (command.isLockinPeriodAllowedChanged()){ if (command.isLockinPeriodAllowedChanged()) {
this.isLockinPeriodAllowed = command.isLockinPeriodAllowed(); this.isLockinPeriodAllowed = command.isLockinPeriodAllowed();
} }
if (command.isLockinPeriodChanged()){ if (command.isLockinPeriodChanged()) {
this.lockinPeriod = command.getLockinPeriod(); this.lockinPeriod = command.getLockinPeriod();
} }
if (command.isLockinPeriodTypeChanged()){ if (command.isLockinPeriodTypeChanged()) {
this.lockinPeriodType=PeriodFrequencyType.fromInt(command.getLockinPeriodType()); this.lockinPeriodType = PeriodFrequencyType.fromInt(command.getLockinPeriodType());
} }
} }
@@ -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,23 +1,21 @@
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;
private SavingProductType(final Integer value,final String code) { private SavingProductType(final Integer value, final String code) {
this.value=value; this.value = value;
this.code=code; this.code = code;
} }
public Integer getValue() { public Integer getValue() {
return value; return value;
} }
public String getCode() { public String getCode() {
return code; return code;
} }
@@ -39,11 +37,11 @@ public enum SavingProductType {
return savingProductType; return savingProductType;
} }
public boolean isReccuring(){ public boolean isReccuring() {
return this.value.equals(SavingProductType.RECCURING.getValue()); return this.value.equals(SavingProductType.RECCURING.getValue());
} }
public boolean isRegular(){ public boolean isRegular() {
return this.value.equals(SavingProductType.REGULAR.getValue()); return this.value.equals(SavingProductType.REGULAR.getValue());
} }
@@ -1,23 +1,21 @@
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;
private SavingsInterestType(final Integer value,final String code) { private SavingsInterestType(final Integer value, final String code) {
this.value=value; this.value = value;
this.code=code; this.code = code;
} }
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);
} }
} }
@@ -13,7 +13,7 @@ public class SavingProductCommandValidator {
private final SavingProductCommand command; private final SavingProductCommand command;
public SavingProductCommandValidator(final SavingProductCommand command) { public SavingProductCommandValidator(final SavingProductCommand command) {
this.command=command; this.command = command;
} }
public void validateForUpdate() { public void validateForUpdate() {
@@ -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); }
}
} }
} }
@@ -30,7 +30,7 @@ public class SavingProductEnumerations {
return savingInterestCalculationMethod(SavingInterestCalculationMethod.fromInt(id)); return savingInterestCalculationMethod(SavingInterestCalculationMethod.fromInt(id));
} }
public static EnumOptionData savingsLockinPeriod(final int id){ public static EnumOptionData savingsLockinPeriod(final int id) {
return savingsLockinPeriod(SavingsLockinPeriodEnum.fromInt(id)); return savingsLockinPeriod(SavingsLockinPeriodEnum.fromInt(id));
} }
@@ -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,19 +25,19 @@ 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);
this.currencyReadPlatformService=currencyReadPlatformService; this.currencyReadPlatformService = currencyReadPlatformService;
} }
@Override @Override
@@ -45,11 +45,11 @@ public class SavingProductReadPlatformServiceImpl implements
this.context.authenticatedUser(); this.context.authenticatedUser();
SavingProductMapper savingProductMapper=new SavingProductMapper(); SavingProductMapper savingProductMapper = new SavingProductMapper();
String sql = "select " + savingProductMapper.savingProductSchema() + " where sp.is_deleted=0"; String sql = "select " + savingProductMapper.savingProductSchema() + " where sp.is_deleted=0";
return this.jdbcTemplate.query(sql,savingProductMapper, new Object[]{}); return this.jdbcTemplate.query(sql, savingProductMapper, new Object[] {});
} }
@@ -58,22 +58,20 @@ public class SavingProductReadPlatformServiceImpl implements
this.context.authenticatedUser(); this.context.authenticatedUser();
SavingProductLookupMapper savingProductLookupMapper=new SavingProductLookupMapper(); SavingProductLookupMapper savingProductLookupMapper = new SavingProductLookupMapper();
String sql="select"+savingProductLookupMapper.savingProductLookupSchema(); String sql = "select" + savingProductLookupMapper.savingProductLookupSchema();
return this.jdbcTemplate.query(sql, savingProductLookupMapper, new Object[]{}); return this.jdbcTemplate.query(sql, savingProductLookupMapper, new Object[] {});
} }
@Override @Override
public SavingProductData retrieveSavingProduct(Long savingProductId) { public SavingProductData retrieveSavingProduct(Long savingProductId) {
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);
@@ -86,7 +84,7 @@ public class SavingProductReadPlatformServiceImpl implements
@Override @Override
public SavingProductData retrieveNewSavingProductDetails() { public SavingProductData retrieveNewSavingProductDetails() {
SavingProductData productData=new SavingProductData(); SavingProductData productData = new SavingProductData();
populateProductDataWithDropdownOptions(productData); populateProductDataWithDropdownOptions(productData);
@@ -95,7 +93,7 @@ public class SavingProductReadPlatformServiceImpl implements
private static final class SavingProductMapper implements RowMapper<SavingProductData> { private static final class SavingProductMapper implements RowMapper<SavingProductData> {
public String savingProductSchema(){ public String savingProductSchema() {
return "sp.id as id,sp.name as name, sp.description as description,sp.currency_code as currencyCode, sp.currency_digits as currencyDigits,sp.interest_rate as interestRate, " return "sp.id as id,sp.name as name, sp.description as description,sp.currency_code as currencyCode, sp.currency_digits as currencyDigits,sp.interest_rate as interestRate, "
+ "sp.min_interest_rate as minInterestRate, sp.max_interest_rate as maxInterstRate, " + "sp.min_interest_rate as minInterestRate, sp.max_interest_rate as maxInterstRate, "
+ " sp.savings_deposit_amount as savingsDepositAmount, sp.savings_product_type as savingProductType, sp.tenure_type as tenureType, sp.tenure as tenure, sp.frequency as frequency, " + " sp.savings_deposit_amount as savingsDepositAmount, sp.savings_product_type as savingProductType, sp.tenure_type as tenureType, sp.tenure as tenure, sp.frequency as frequency, "
@@ -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");
@@ -118,9 +115,10 @@ public class SavingProductReadPlatformServiceImpl implements
String currencyName = rs.getString("currencyName"); String currencyName = rs.getString("currencyName");
String currencyNameCode = rs.getString("currencyNameCode"); String currencyNameCode = rs.getString("currencyNameCode");
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");
@@ -128,35 +126,37 @@ public class SavingProductReadPlatformServiceImpl implements
DateTime createdOn = JdbcSupport.getDateTime(rs, "createdon"); DateTime createdOn = JdbcSupport.getDateTime(rs, "createdon");
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
BigDecimal minimumBalanceForWithdrawal=rs.getBigDecimal("minimumBalanceForWithdrawal"); .getInteger(rs, "interestCalculationMethod"));
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,9 +25,10 @@ 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,
this.context=context; final SavingProductRepository savingProductRepository) {
this.savingProductRepository=savingProductRepository; this.context = context;
this.savingProductRepository = savingProductRepository;
} }
@Transactional @Transactional
@@ -35,21 +36,23 @@ public class SavingProductWritePlatformServiceJpaRepositoryImpl implements Savin
public EntityIdentifier createSavingProduct(final SavingProductCommand command) { public EntityIdentifier createSavingProduct(final SavingProductCommand command) {
this.context.authenticatedUser(); this.context.authenticatedUser();
SavingProductCommandValidator validator=new SavingProductCommandValidator(command); SavingProductCommandValidator validator = new SavingProductCommandValidator(command);
validator.validateForCreate(); validator.validateForCreate();
SavingProductType savingProductType = SavingProductType.fromInt(command.getSavingProductType()); SavingProductType savingProductType = SavingProductType.fromInt(command.getSavingProductType());
TenureTypeEnum tenureType = TenureTypeEnum.fromInt(command.getTenureType()); TenureTypeEnum tenureType = TenureTypeEnum.fromInt(command.getTenureType());
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());
@@ -60,13 +63,11 @@ public class SavingProductWritePlatformServiceJpaRepositoryImpl implements Savin
public EntityIdentifier updateSavingProduct(final SavingProductCommand command) { public EntityIdentifier updateSavingProduct(final SavingProductCommand command) {
this.context.authenticatedUser(); this.context.authenticatedUser();
SavingProductCommandValidator validator=new SavingProductCommandValidator(command); SavingProductCommandValidator validator = new SavingProductCommandValidator(command);
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()));
@@ -77,14 +78,11 @@ public class SavingProductWritePlatformServiceJpaRepositoryImpl implements Savin
public EntityIdentifier deleteSavingProduct(Long productId) { public EntityIdentifier deleteSavingProduct(Long productId) {
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();
@@ -244,7 +244,7 @@ public class DepositAccountData {
final boolean preClosureAllowed, final BigDecimal preClosureInterestRate, final LocalDate withdrawnonDate, final boolean preClosureAllowed, final BigDecimal preClosureInterestRate, final LocalDate withdrawnonDate,
final LocalDate rejectedonDate, final LocalDate closedonDate, final boolean isInterestWithdrawable, final LocalDate rejectedonDate, final LocalDate closedonDate, final boolean isInterestWithdrawable,
final BigDecimal interestPaid, final boolean interestCompoundingAllowed, final boolean isLockinPeriodAllowed, final BigDecimal interestPaid, final boolean interestCompoundingAllowed, final boolean isLockinPeriodAllowed,
final Integer lockinPeriod, final EnumOptionData lockinPeriodType,final BigDecimal availableInterest, final Integer lockinPeriod, final EnumOptionData lockinPeriodType, final BigDecimal availableInterest,
final BigDecimal interestPostedAmount, final LocalDate lastInterestPostedDate, final LocalDate nextInterestPostedDate) { final BigDecimal interestPostedAmount, final LocalDate lastInterestPostedDate, final LocalDate nextInterestPostedDate) {
this.id = id; this.id = id;
this.externalId = externalId; this.externalId = externalId;
@@ -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()
LocalDate interestWithdrawingDate= new LocalDate().isBefore(getMaturedOn())?new LocalDate():getMaturedOn().plusDays(1); / new Double(account.getTenureInMonths()));
Integer noOfMonthsforInterestCal = Months.monthsBetween(account.getActualCommencementDate(), interestWithdrawingDate).getMonths(); LocalDate interestWithdrawingDate = new LocalDate().isBefore(getMaturedOn()) ? new LocalDate() : getMaturedOn().plusDays(1);
Integer noOfPeriods = noOfMonthsforInterestCal/ account.getInterestCompoundedEvery(); Integer noOfMonthsforInterestCal = Months.monthsBetween(account.getActualCommencementDate(), interestWithdrawingDate)
.getMonths();
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))
}else { .doubleValue() - account.getInterestPaid().doubleValue());
} else {
return BigDecimal.ZERO; return BigDecimal.ZERO;
} }
}else return BigDecimal.ZERO; } else
return BigDecimal.ZERO;
return availableInterestForWithdrawal; return availableInterestForWithdrawal;
} }
@@ -545,30 +550,36 @@ public class DepositAccountData {
private BigDecimal determineAvalableWithdrawalAmount(final DepositAccountData account) { private BigDecimal determineAvalableWithdrawalAmount(final DepositAccountData account) {
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();
} }
} }
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;
BigDecimal interestRateAsFraction = interstRateApplicable.divide(BigDecimal.valueOf(100), mc); BigDecimal interestRateAsFraction = interstRateApplicable.divide(BigDecimal.valueOf(100), mc);
BigDecimal interestRateForOneDay = interestRateAsFraction.divide(BigDecimal.valueOf(daysInYear.doubleValue()), mc); BigDecimal interestRateForOneDay = interestRateAsFraction.divide(BigDecimal.valueOf(daysInYear.doubleValue()), mc);
return BigDecimal.valueOf(depsoitAmount.doubleValue()*days.doubleValue()*interestRateForOneDay.doubleValue()); return BigDecimal.valueOf(depsoitAmount.doubleValue() * days.doubleValue() * interestRateForOneDay.doubleValue());
} }
} }
@@ -18,9 +18,8 @@ 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;
this.transactionType = transactionType; this.transactionType = transactionType;
@@ -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 pendingApproval,final boolean interestWithdrawalAllowed, final boolean renewelAllowed, final boolean isMaturedDepositAccount) { 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() {
@@ -36,7 +36,7 @@ import org.mifosplatform.portfolio.savingsdepositproduct.domain.DepositProduct;
import org.mifosplatform.useradministration.domain.AppUser; import org.mifosplatform.useradministration.domain.AppUser;
@Entity @Entity
@Table(name = "m_deposit_account", uniqueConstraints = @UniqueConstraint(name="deposit_acc_external_id", columnNames = { "external_id" })) @Table(name = "m_deposit_account", uniqueConstraints = @UniqueConstraint(name = "deposit_acc_external_id", columnNames = { "external_id" }))
public class DepositAccount extends AbstractAuditableCustom<AppUser, Long> { public class DepositAccount extends AbstractAuditableCustom<AppUser, Long> {
@ManyToOne @ManyToOne
@@ -59,7 +59,7 @@ public class DepositAccount extends AbstractAuditableCustom<AppUser, Long> {
@Column(name = "maturity_nominal_interest_rate", scale = 6, precision = 19, nullable = false) @Column(name = "maturity_nominal_interest_rate", scale = 6, precision = 19, nullable = false)
private BigDecimal interestRate; private BigDecimal interestRate;
@Column(name = "tenure_months", nullable=false) @Column(name = "tenure_months", nullable = false)
private Integer tenureInMonths; private Integer tenureInMonths;
@Column(name = "interest_compounded_every", nullable = false) @Column(name = "interest_compounded_every", nullable = false)
@@ -101,7 +101,7 @@ public class DepositAccount extends AbstractAuditableCustom<AppUser, Long> {
@Column(name = "is_preclosure_allowed", nullable = false) @Column(name = "is_preclosure_allowed", nullable = false)
private boolean preClosureAllowed = false; private boolean preClosureAllowed = false;
@Column(name = "is_deleted", nullable=false) @Column(name = "is_deleted", nullable = false)
private boolean deleted = false; private boolean deleted = false;
@Column(name = "status_enum", nullable = false) @Column(name = "status_enum", nullable = false)
@@ -139,20 +139,20 @@ public class DepositAccount extends AbstractAuditableCustom<AppUser, Long> {
private final List<DepositAccountTransaction> depositaccountTransactions = new ArrayList<DepositAccountTransaction>(); private final List<DepositAccountTransaction> depositaccountTransactions = new ArrayList<DepositAccountTransaction>();
@SuppressWarnings("unused") @SuppressWarnings("unused")
@OneToOne(optional=true, cascade={CascadeType.PERSIST}) @OneToOne(optional = true, cascade = { CascadeType.PERSIST })
@JoinColumn(name = "renewed_account_id") @JoinColumn(name = "renewed_account_id")
private DepositAccount renewdAccount; private DepositAccount renewdAccount;
@Column(name = "is_lock_in_period_allowed", nullable=false) @Column(name = "is_lock_in_period_allowed", nullable = false)
private boolean isLockinPeriodAllowed = false; private boolean isLockinPeriodAllowed = false;
@Column(name = "lock_in_period", nullable=false) @Column(name = "lock_in_period", nullable = false)
private Integer lockinPeriod; private Integer lockinPeriod;
@Column(name = "lock_in_period_type", nullable=false) @Column(name = "lock_in_period_type", nullable = false)
private PeriodFrequencyType lockinPeriodType; private PeriodFrequencyType lockinPeriodType;
//for interest posting // for interest posting
@Column(name = "available_interest", scale = 6, precision = 19) @Column(name = "available_interest", scale = 6, precision = 19)
private BigDecimal availableInterest; private BigDecimal availableInterest;
@@ -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;
@@ -259,10 +242,10 @@ public class DepositAccount extends AbstractAuditableCustom<AppUser, Long> {
// derived fields // derived fields
this.projectedInterestAccruedOnMaturity = futureValueOnMaturity.minus(deposit).getAmount(); this.projectedInterestAccruedOnMaturity = futureValueOnMaturity.minus(deposit).getAmount();
this.projectedTotalOnMaturity = futureValueOnMaturity.getAmount(); this.projectedTotalOnMaturity = futureValueOnMaturity.getAmount();
this.depositStatus=depositStatus; this.depositStatus = depositStatus;
this.interestAccrued=BigDecimal.ZERO; this.interestAccrued = BigDecimal.ZERO;
this.interstPaid=BigDecimal.ZERO; this.interstPaid = BigDecimal.ZERO;
this.total=BigDecimal.ZERO; this.total = BigDecimal.ZERO;
} }
private void setExternalId(final String externalId) { private void setExternalId(final String externalId) {
@@ -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,20 +271,18 @@ 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) {
this.tenureInMonths = command.getTenureInMonths(); this.tenureInMonths = command.getTenureInMonths();
} }
if(command.getMaturityInterestRate() != null){ if (command.getMaturityInterestRate() != null) {
this.interestRate = command.getMaturityInterestRate(); this.interestRate = command.getMaturityInterestRate();
} }
this.product.validateInterestRateInRange(this.interestRate); this.product.validateInterestRateInRange(this.interestRate);
@@ -319,28 +301,24 @@ public class DepositAccount extends AbstractAuditableCustom<AppUser, Long> {
this.actualCommencementDate = actualCommencementDate.toDate(); this.actualCommencementDate = actualCommencementDate.toDate();
this.maturesOnDate = getActualCommencementDate().plusMonths(this.tenureInMonths).minusDays(1).toDate(); this.maturesOnDate = getActualCommencementDate().plusMonths(this.tenureInMonths).minusDays(1).toDate();
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);
//for interest posting initializing // for interest posting initializing
this.lastInterestPostedDate = this.actualCommencementDate; this.lastInterestPostedDate = this.actualCommencementDate;
this.nextInterestPostingDate = new LocalDate(this.lastInterestPostedDate).plusMonths(this.interestCompoundedEvery).toDate(); this.nextInterestPostingDate = new LocalDate(this.lastInterestPostedDate).plusMonths(this.interestCompoundedEvery).toDate();
this.availableInterest = BigDecimal.ZERO; this.availableInterest = BigDecimal.ZERO;
@@ -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,15 +391,13 @@ 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();
this.maturesOnDate=null; this.maturesOnDate = null;
this.rejectedOnDate = rejectedOn.toDateTimeAtCurrentTime().toDate(); this.rejectedOnDate = rejectedOn.toDateTimeAtCurrentTime().toDate();
this.closedOnDate = rejectedOn.toDateTimeAtCurrentTime().toDate(); this.closedOnDate = rejectedOn.toDateTimeAtCurrentTime().toDate();
@@ -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,32 +432,29 @@ 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();
this.actualCommencementDate = null; this.actualCommencementDate = null;
this.projectedInterestAccruedOnMaturity=this.interestAccrued; this.projectedInterestAccruedOnMaturity = this.interestAccrued;
this.projectedTotalOnMaturity = this.depositAmount.add(this.projectedInterestAccruedOnMaturity); this.projectedTotalOnMaturity = this.depositAmount.add(this.projectedInterestAccruedOnMaturity);
this.maturesOnDate = getProjectedCommencementDate().plusMonths(this.tenureInMonths).minusDays(1).toDate(); this.maturesOnDate = getProjectedCommencementDate().plusMonths(this.tenureInMonths).minusDays(1).toDate();
this.total=null; this.total = null;
this.interestAccrued=null; this.interestAccrued = null;
this.depositaccountTransactions.clear(); this.depositaccountTransactions.clear();
} }
@@ -494,7 +466,7 @@ public class DepositAccount extends AbstractAuditableCustom<AppUser, Long> {
return Money.of(this.currency, this.depositAmount); return Money.of(this.currency, this.depositAmount);
} }
public Money getAccuredInterest(){ public Money getAccuredInterest() {
return Money.of(this.currency, this.interestAccrued); return Money.of(this.currency, this.interestAccrued);
} }
@@ -502,7 +474,7 @@ public class DepositAccount extends AbstractAuditableCustom<AppUser, Long> {
return this.client; return this.client;
} }
public DepositProduct product(){ public DepositProduct product() {
return this.product; return this.product;
} }
@@ -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,46 +571,54 @@ 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")
boolean statustest = isActive(); boolean statustest = isActive();
if(isActive()){ if (isActive()) {
DepositAccountTransaction depositAccountTransaction = DepositAccountTransaction.withdraw(null, new LocalDate(), interest); DepositAccountTransaction depositAccountTransaction = DepositAccountTransaction.withdraw(null, new LocalDate(), interest);
depositAccountTransaction.updateAccount(this); depositAccountTransaction.updateAccount(this);
this.depositaccountTransactions.add(depositAccountTransaction); this.depositaccountTransactions.add(depositAccountTransaction);
@@ -641,40 +628,35 @@ public class DepositAccount extends AbstractAuditableCustom<AppUser, Long> {
} }
} }
public void closeDepositAccount(DepositLifecycleStateMachine depositLifecycleStateMachine){
DepositAccountStatus statusEnumForClose = depositLifecycleStateMachine.transition(DepositAccountEvent.DEPOSIT_CLOSED, DepositAccountStatus.fromInt(this.depositStatus)); public void closeDepositAccount(DepositLifecycleStateMachine depositLifecycleStateMachine) {
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);
@@ -687,25 +669,25 @@ public class DepositAccount extends AbstractAuditableCustom<AppUser, Long> {
this.tenureInMonths = tenureInMonths; this.tenureInMonths = tenureInMonths;
this.interestRate = maturityInterestRate; this.interestRate = maturityInterestRate;
this.product.validateInterestRateInRange(maturityInterestRate); this.product.validateInterestRateInRange(maturityInterestRate);
this.preClosureInterestRate=preClosureInterestRate; this.preClosureInterestRate = preClosureInterestRate;
this.interestCompoundedEvery=interestCompoundedEvery; this.interestCompoundedEvery = interestCompoundedEvery;
this.interestCompoundedFrequencyType=compoundingInterestFrequency.getValue(); this.interestCompoundedFrequencyType = compoundingInterestFrequency.getValue();
this.renewalAllowed=renewalAllowed; this.renewalAllowed = renewalAllowed;
this.preClosureAllowed=preClosureAllowed; this.preClosureAllowed = preClosureAllowed;
this.isInterestWithdrawable=isInterestWithdrawable; this.isInterestWithdrawable = isInterestWithdrawable;
this.interestCompoundingAllowed=isInterestCompoundingAllowed; this.interestCompoundingAllowed = isInterestCompoundingAllowed;
this.projectedInterestAccruedOnMaturity = futureValueOnMaturity.minus(deposit).getAmount(); this.projectedInterestAccruedOnMaturity = futureValueOnMaturity.minus(deposit).getAmount();
this.projectedTotalOnMaturity = futureValueOnMaturity.getAmount(); this.projectedTotalOnMaturity = futureValueOnMaturity.getAmount();
this.isLockinPeriodAllowed = isLockinPeriodAllowed; this.isLockinPeriodAllowed = isLockinPeriodAllowed;
this.lockinPeriod = lockinPeriod; this.lockinPeriod = lockinPeriod;
this.lockinPeriodType = lockinPeriodType; this.lockinPeriodType = lockinPeriodType;
this.interestAccrued=BigDecimal.ZERO; this.interestAccrued = BigDecimal.ZERO;
} }
public void update(final boolean renewalAllowed, final boolean isInterestWithdrawable) { public void update(final boolean renewalAllowed, final boolean isInterestWithdrawable) {
this.renewalAllowed=renewalAllowed; this.renewalAllowed = renewalAllowed;
this.isInterestWithdrawable=isInterestWithdrawable; this.isInterestWithdrawable = isInterestWithdrawable;
} }
public boolean isSubmittedAndPendingApproval() { public boolean isSubmittedAndPendingApproval() {
@@ -721,24 +703,28 @@ public class DepositAccount extends AbstractAuditableCustom<AppUser, Long> {
LocalDate lastInterestPostedDate = getLastInterestPostedDate(); LocalDate lastInterestPostedDate = getLastInterestPostedDate();
LocalDate nextInterestPostingDate = getNextInterestPostedDate(); LocalDate nextInterestPostingDate = getNextInterestPostedDate();
Integer monthsForInterestCalculation = Months.monthsBetween(lastInterestPostedDate, new LocalDate()).getMonths(); Integer monthsForInterestCalculation = Months.monthsBetween(lastInterestPostedDate, new LocalDate()).getMonths();
Integer postInterestItereations = monthsForInterestCalculation/this.interestCompoundedEvery; Integer postInterestItereations = monthsForInterestCalculation / this.interestCompoundedEvery;
Money deposit = Money.of(this.currency, this.depositAmount); Money deposit = Money.of(this.currency, this.depositAmount);
while (postInterestItereations > 0) { while (postInterestItereations > 0) {
lastInterestPostedDate = getLastInterestPostedDate(); lastInterestPostedDate = getLastInterestPostedDate();
nextInterestPostingDate = getNextInterestPostedDate(); nextInterestPostingDate = getNextInterestPostedDate();
if (lastInterestPostedDate.isBefore(getMaturityDate())){ if (lastInterestPostedDate.isBefore(getMaturityDate())) {
if (nextInterestPostingDate.isAfter(getMaturityDate())){ if (nextInterestPostingDate.isAfter(getMaturityDate())) {
Integer noofRemainMonthsAfterMaturity = Months.monthsBetween(getMaturityDate(), nextInterestPostingDate).getMonths(); Integer noofRemainMonthsAfterMaturity = Months.monthsBetween(getMaturityDate(), nextInterestPostingDate).getMonths();
Integer noOfMonthsBeforeMaturity = Months.monthsBetween(lastInterestPostedDate, getMaturityDate()).getMonths(); Integer noOfMonthsBeforeMaturity = Months.monthsBetween(lastInterestPostedDate, getMaturityDate()).getMonths();
Money futureValueOnMaturity =null; Money futureValueOnMaturity = null;
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());
@@ -746,12 +732,16 @@ public class DepositAccount extends AbstractAuditableCustom<AppUser, Long> {
this.nextInterestPostingDate = nextInterestPostingDate.plusMonths(this.interestCompoundedEvery).toDate(); this.nextInterestPostingDate = nextInterestPostingDate.plusMonths(this.interestCompoundedEvery).toDate();
} }
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{
Money futureValueOnMaturity =null;
if (this.interestCompoundingAllowed) {
futureValueOnMaturity = fixedTermDepositInterestCalculator.calculateInterestOnMaturityFor(deposit, this.interestCompoundedEvery, this.preClosureInterestRate, this.interestCompoundedEvery, getInterestCompoundedFrequencyType());
} else { } else {
futureValueOnMaturity = fixedTermDepositInterestCalculator.calculateInterestOnMaturityForSimpleInterest(deposit, this.interestCompoundedEvery, this.preClosureInterestRate, this.interestCompoundedEvery, getInterestCompoundedFrequencyType()); Money futureValueOnMaturity = null;
if (this.interestCompoundingAllowed) {
futureValueOnMaturity = fixedTermDepositInterestCalculator.calculateInterestOnMaturityFor(deposit,
this.interestCompoundedEvery, this.preClosureInterestRate, this.interestCompoundedEvery,
getInterestCompoundedFrequencyType());
} else {
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);
} }
@@ -804,7 +805,7 @@ public class DepositAccount extends AbstractAuditableCustom<AppUser, Long> {
private final LocalDate getLastInterestPostedDate() { private final LocalDate getLastInterestPostedDate() {
LocalDate lastInterestPostedDate; LocalDate lastInterestPostedDate;
if (this.lastInterestPostedDate == null){ if (this.lastInterestPostedDate == null) {
lastInterestPostedDate = new LocalDate(this.actualCommencementDate); lastInterestPostedDate = new LocalDate(this.actualCommencementDate);
} else { } else {
lastInterestPostedDate = new LocalDate(this.lastInterestPostedDate); lastInterestPostedDate = new LocalDate(this.lastInterestPostedDate);
@@ -814,7 +815,7 @@ public class DepositAccount extends AbstractAuditableCustom<AppUser, Long> {
private final LocalDate getNextInterestPostedDate() { private final LocalDate getNextInterestPostedDate() {
LocalDate nextInterestPostingDate; LocalDate nextInterestPostingDate;
if (this.nextInterestPostingDate == null){ if (this.nextInterestPostingDate == null) {
nextInterestPostingDate = new LocalDate(this.nextInterestPostingDate).plusMonths(this.interestCompoundedEvery); nextInterestPostingDate = new LocalDate(this.nextInterestPostingDate).plusMonths(this.interestCompoundedEvery);
} else { } else {
nextInterestPostingDate = new LocalDate(this.nextInterestPostingDate); nextInterestPostingDate = new LocalDate(this.nextInterestPostingDate);
@@ -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> {
} }
@@ -4,13 +4,12 @@ public enum DepositAccountStatus {
INVALID(0, "depositStatusType.invalid"), // INVALID(0, "depositStatusType.invalid"), //
SUBMITED_AND_PENDING_APPROVAL(100, "depositStatusType.submitted.and.pending.approval"), // SUBMITED_AND_PENDING_APPROVAL(100, "depositStatusType.submitted.and.pending.approval"), //
//APPROVED(200, "depositStatusType.approved"), // // APPROVED(200, "depositStatusType.approved"), //
ACTIVE(300, "depositStatusType.active"), // ACTIVE(300, "depositStatusType.active"), //
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());
@@ -56,7 +56,7 @@ public enum DepositAccountStatus {
return this.value.equals(DepositAccountStatus.REJECTED.getValue()); return this.value.equals(DepositAccountStatus.REJECTED.getValue());
} }
public boolean isPreClosed(){ public boolean isPreClosed() {
return this.value.equals(DepositAccountStatus.PRECLOSED.getValue()); return this.value.equals(DepositAccountStatus.PRECLOSED.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;
@@ -21,12 +21,12 @@ import org.mifosplatform.organisation.monetary.domain.Money;
import org.springframework.data.jpa.domain.AbstractPersistable; import org.springframework.data.jpa.domain.AbstractPersistable;
@Entity @Entity
@Table(name="m_deposit_account_transaction") @Table(name = "m_deposit_account_transaction")
public class DepositAccountTransaction extends AbstractPersistable<Long> { public class DepositAccountTransaction extends AbstractPersistable<Long> {
@SuppressWarnings("unused") @SuppressWarnings("unused")
@ManyToOne(optional = false) @ManyToOne(optional = false)
@JoinColumn(name = "deposit_account_id", nullable=false) @JoinColumn(name = "deposit_account_id", nullable = false)
private DepositAccount depositAccount; private DepositAccount depositAccount;
@Enumerated(EnumType.ORDINAL) @Enumerated(EnumType.ORDINAL)
@@ -34,12 +34,12 @@ public class DepositAccountTransaction extends AbstractPersistable<Long> {
private DepositAccountTransactionType typeOf; private DepositAccountTransactionType typeOf;
@SuppressWarnings("unused") @SuppressWarnings("unused")
@OneToOne(optional=true, cascade={CascadeType.PERSIST}) @OneToOne(optional = true, cascade = { CascadeType.PERSIST })
@JoinColumn(name="contra_id") @JoinColumn(name = "contra_id")
private DepositAccountTransaction contra; private DepositAccountTransaction contra;
@Temporal(TemporalType.DATE) @Temporal(TemporalType.DATE)
@Column(name = "transaction_date", nullable=false) @Column(name = "transaction_date", nullable = false)
private final Date dateOf; private final Date dateOf;
@Column(name = "amount", scale = 6, precision = 19, nullable = false) @Column(name = "amount", scale = 6, precision = 19, nullable = false)
@@ -53,21 +53,22 @@ public class DepositAccountTransaction extends AbstractPersistable<Long> {
@Column(name = "total", scale = 6, precision = 19, nullable = false) @Column(name = "total", scale = 6, precision = 19, nullable = false)
private final BigDecimal total; private final BigDecimal total;
protected DepositAccountTransaction(){ protected DepositAccountTransaction() {
this.depositAccount=null; this.depositAccount = null;
this.typeOf=null; this.typeOf = null;
this.amount=null; this.amount = null;
this.dateOf=null; this.dateOf = null;
this.interest=null; this.interest = null;
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();
this.interest = interest; this.interest = interest;
this.total = amount.doubleValue()==0?new BigDecimal(0):amount.add(interest); this.total = amount.doubleValue() == 0 ? new BigDecimal(0) : amount.add(interest);
} }
public Date getDateOf() { public Date getDateOf() {
@@ -90,23 +91,27 @@ public class DepositAccountTransaction extends AbstractPersistable<Long> {
return new LocalDate(this.dateOf); return new LocalDate(this.dateOf);
} }
public boolean isDeposit(){ public boolean isDeposit() {
return DepositAccountTransactionType.DEPOSIT.equals(typeOf); return DepositAccountTransactionType.DEPOSIT.equals(typeOf);
} }
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) {
this.depositAccount=depositAccount; this.depositAccount = depositAccount;
} }
} }
@@ -5,15 +5,14 @@ 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;
private DepositAccountTransactionType(final Integer value, final String code) { private DepositAccountTransactionType(final Integer value, final String code) {
this.value=value; this.value = value;
this.code=code; this.code = code;
} }
public Integer getValue() { public Integer getValue() {
@@ -24,32 +23,30 @@ public enum DepositAccountTransactionType {
return code; return code;
} }
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) {
case 1: case 1:
depositTransactionType=DepositAccountTransactionType.DEPOSIT; depositTransactionType = DepositAccountTransactionType.DEPOSIT;
break; break;
case 2: case 2:
depositTransactionType=DepositAccountTransactionType.WITHDRAW; depositTransactionType = DepositAccountTransactionType.WITHDRAW;
break; break;
case 3: case 3:
depositTransactionType=DepositAccountTransactionType.REVERSAL; depositTransactionType = DepositAccountTransactionType.REVERSAL;
break; break;
case 4: case 4:
depositTransactionType=DepositAccountTransactionType.INTEREST_POSTING; depositTransactionType = DepositAccountTransactionType.INTEREST_POSTING;
break; break;
default : default:
depositTransactionType=DepositAccountTransactionType.INVALID; depositTransactionType = DepositAccountTransactionType.INVALID;
break; break;
} }
@@ -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,13 +4,12 @@ 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;
public DepositLifecycleStateMachineImpl(List<DepositAccountStatus> allowedDepositStatuses) { public DepositLifecycleStateMachineImpl(List<DepositAccountStatus> allowedDepositStatuses) {
this.allowedDepositStatuses=allowedDepositStatuses; this.allowedDepositStatuses = allowedDepositStatuses;
} }
@Override @Override
@@ -27,64 +26,57 @@ 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);
} }
break; break;
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);
} }
break; break;
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);
} }
break; break;
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);
} }
break; break;
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);
} }
break; break;
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);
} }
break; break;
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);
} }
break; break;
default: default:
@@ -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,45 +54,47 @@ 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 totalAmount =deposit.getAmount().add(interest); BigDecimal.valueOf(new Double(numberOfPeriods)));
BigDecimal totalAmount = deposit.getAmount().add(interest);
return Money.of(deposit.getCurrency(), totalAmount); return Money.of(deposit.getCurrency(), totalAmount);
} }
public Money calculateRemainInterest(Money deposit, Integer days, BigDecimal interestRate){ public Money calculateRemainInterest(Money deposit, Integer days, BigDecimal interestRate) {
MathContext mc = new MathContext(8, RoundingMode.HALF_EVEN); MathContext mc = new MathContext(8, RoundingMode.HALF_EVEN);
Integer daysInYear = 365; Integer daysInYear = 365;
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);
} }
} }
@@ -3,10 +3,9 @@ package org.mifosplatform.portfolio.savingsdepositaccount.exception;
import org.joda.time.LocalDate; import org.joda.time.LocalDate;
import org.mifosplatform.infrastructure.core.exception.AbstractPlatformDomainRuleException; import org.mifosplatform.infrastructure.core.exception.AbstractPlatformDomainRuleException;
public class DepositAccountReopenException extends AbstractPlatformDomainRuleException{ public class DepositAccountReopenException extends AbstractPlatformDomainRuleException {
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();
@@ -69,13 +67,12 @@ public class DepositAccountAssembler {
} }
BigDecimal preClosureInterestRate = product.getPreClosureInterestRate(); BigDecimal preClosureInterestRate = product.getPreClosureInterestRate();
if(command.getPreClosureInterestRate()!=null){ if (command.getPreClosureInterestRate() != null) {
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) {
@@ -97,35 +94,32 @@ public class DepositAccountAssembler {
preClosureAllowed = command.isPreClosureAllowed(); preClosureAllowed = command.isPreClosureAllowed();
} }
boolean interestCompoundingAllowed= product.isInterestCompoundingAllowed(); boolean interestCompoundingAllowed = product.isInterestCompoundingAllowed();
if(command.isInterestCompoundingAllowedChanged()){ if (command.isInterestCompoundingAllowedChanged()) {
interestCompoundingAllowed = command.isInterestCompoundingAllowed(); interestCompoundingAllowed = command.isInterestCompoundingAllowed();
} }
boolean isLockinPeriodAllowed = product.isLockinPeriodAllowed(); boolean isLockinPeriodAllowed = product.isLockinPeriodAllowed();
if(command.isLockinPeriodChanged()){ if (command.isLockinPeriodChanged()) {
isLockinPeriodAllowed = command.isLockinPeriodAllowed(); isLockinPeriodAllowed = command.isLockinPeriodAllowed();
} }
Integer lockinPeriod = product.getLockinPeriod(); Integer lockinPeriod = product.getLockinPeriod();
if(command.getLockinPeriod() != null){ if (command.getLockinPeriod() != null) {
lockinPeriod = command.getLockinPeriod(); lockinPeriod = command.getLockinPeriod();
} }
PeriodFrequencyType lockinPeriodType = product.getLockinPeriodType(); PeriodFrequencyType lockinPeriodType = product.getLockinPeriodType();
if(command.getLockinPeriodType() != null){ if (command.getLockinPeriodType() != null) {
lockinPeriodType = PeriodFrequencyType.fromInt(command.getLockinPeriodType()); lockinPeriodType = PeriodFrequencyType.fromInt(command.getLockinPeriodType());
} }
// 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;
} }
@@ -140,208 +134,204 @@ public class DepositAccountAssembler {
Client client = account.client(); Client client = account.client();
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();
if(command.getDepositAmount() != null){ if (command.getDepositAmount() != null) {
deposit = Money.of(account.getDeposit().getCurrency(), command.getDepositAmount()); deposit = Money.of(account.getDeposit().getCurrency(), command.getDepositAmount());
} }
Integer tenureInMonths = account.getTenureInMonths(); Integer tenureInMonths = account.getTenureInMonths();
if(command.getTenureInMonths() != null){ if (command.getTenureInMonths() != null) {
tenureInMonths =command.getTenureInMonths(); tenureInMonths = command.getTenureInMonths();
} }
BigDecimal maturityInterestRate = account.getInterestRate(); BigDecimal maturityInterestRate = account.getInterestRate();
if(command.getMaturityInterestRate() != null){ if (command.getMaturityInterestRate() != null) {
maturityInterestRate = command.getMaturityInterestRate(); maturityInterestRate = command.getMaturityInterestRate();
} }
BigDecimal preClosureInterestRate = account.getPreClosureInterestRate(); BigDecimal preClosureInterestRate = account.getPreClosureInterestRate();
if(command.getPreClosureInterestRate() != null){ if (command.getPreClosureInterestRate() != null) {
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) {
compoundingInterestEvery = command.getInterestCompoundedEvery(); compoundingInterestEvery = command.getInterestCompoundedEvery();
} }
PeriodFrequencyType compoundingInterestFrequency = account.getInterestCompoundedFrequencyType(); PeriodFrequencyType compoundingInterestFrequency = account.getInterestCompoundedFrequencyType();
if(command.getInterestCompoundedEveryPeriodType() !=null){ if (command.getInterestCompoundedEveryPeriodType() != null) {
compoundingInterestFrequency = PeriodFrequencyType.fromInt(command.getInterestCompoundedEveryPeriodType()); compoundingInterestFrequency = PeriodFrequencyType.fromInt(command.getInterestCompoundedEveryPeriodType());
} }
boolean renewalAllowed = account.isRenewalAllowed(); boolean renewalAllowed = account.isRenewalAllowed();
if(command.isRenewalAllowedChanged()){ if (command.isRenewalAllowedChanged()) {
renewalAllowed = command.isRenewalAllowed(); renewalAllowed = command.isRenewalAllowed();
} }
boolean preClosureAllowed = account.isPreClosureAllowed(); boolean preClosureAllowed = account.isPreClosureAllowed();
if(command.isPreClosureAllowedChanged()){ if (command.isPreClosureAllowedChanged()) {
preClosureAllowed = command.isPreClosureAllowed(); preClosureAllowed = command.isPreClosureAllowed();
} }
boolean isInterestWithdrawable = account.isInterestWithdrawable(); boolean isInterestWithdrawable = account.isInterestWithdrawable();
if(command.isInterestWithdrawableChanged()){ if (command.isInterestWithdrawableChanged()) {
isInterestWithdrawable = command.isInterestWithdrawable(); isInterestWithdrawable = command.isInterestWithdrawable();
} }
boolean isInterestCompoundingAllowed = account.isInterestCompoundingAllowed(); boolean isInterestCompoundingAllowed = account.isInterestCompoundingAllowed();
if(command.isInterestCompoundingAllowedChanged()){ if (command.isInterestCompoundingAllowedChanged()) {
isInterestCompoundingAllowed = command.isInterestCompoundingAllowed(); isInterestCompoundingAllowed = command.isInterestCompoundingAllowed();
} }
boolean isLockinPeriodAllowed = account.isLockinPeriodAllowed(); boolean isLockinPeriodAllowed = account.isLockinPeriodAllowed();
if(command.isLockinPeriodChanged()){ if (command.isLockinPeriodChanged()) {
isLockinPeriodAllowed = command.isLockinPeriodAllowed(); isLockinPeriodAllowed = command.isLockinPeriodAllowed();
} }
Integer lockinPeriod = account.getLockinPeriod(); Integer lockinPeriod = account.getLockinPeriod();
if(command.getLockinPeriod() != null){ if (command.getLockinPeriod() != null) {
lockinPeriod = command.getLockinPeriod(); lockinPeriod = command.getLockinPeriod();
} }
PeriodFrequencyType lockinPeriodType = account.getLockinPeriodType(); PeriodFrequencyType lockinPeriodType = account.getLockinPeriodType();
if(command.getLockinPeriodType() != null){ if (command.getLockinPeriodType() != null) {
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();
if(command.isExternalIdChanged()){ if (command.isExternalIdChanged()) {
externalId = command.getExternalId(); externalId = command.getExternalId();
} }
LocalDate commencementDate = account.getProjectedCommencementDate(); LocalDate commencementDate = account.getProjectedCommencementDate();
if(command.isCommencementDateChanged()){ if (command.isCommencementDateChanged()) {
commencementDate = new LocalDate(command.getCommencementDate()); commencementDate = new LocalDate(command.getCommencementDate());
} }
Money deposit = account.getDeposit(); Money deposit = account.getDeposit();
if(command.isDepositAmountChanged()){ if (command.isDepositAmountChanged()) {
deposit = Money.of(product.getCurrency(), command.getDepositAmount()); deposit = Money.of(product.getCurrency(), command.getDepositAmount());
} }
Integer tenureInMonths = account.getTenureInMonths(); Integer tenureInMonths = account.getTenureInMonths();
if(command.isTenureInMonthsChanged()){ if (command.isTenureInMonthsChanged()) {
tenureInMonths =command.getTenureInMonths(); tenureInMonths = command.getTenureInMonths();
} }
BigDecimal maturityInterestRate = account.getInterestRate(); BigDecimal maturityInterestRate = account.getInterestRate();
if(command.isMaturityActualInterestRateChanged()){ if (command.isMaturityActualInterestRateChanged()) {
maturityInterestRate = command.getMaturityInterestRate(); maturityInterestRate = command.getMaturityInterestRate();
} }
BigDecimal preClosureInterestRate = account.getPreClosureInterestRate(); BigDecimal preClosureInterestRate = account.getPreClosureInterestRate();
if(command.isPreClosureInterestRateChanged()){ if (command.isPreClosureInterestRateChanged()) {
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()) {
compoundingInterestEvery = command.getInterestCompoundedEvery(); compoundingInterestEvery = command.getInterestCompoundedEvery();
} }
PeriodFrequencyType compoundingInterestFrequency = account.getInterestCompoundedFrequencyType(); PeriodFrequencyType compoundingInterestFrequency = account.getInterestCompoundedFrequencyType();
if(command.getInterestCompoundedEveryPeriodType() !=null){ if (command.getInterestCompoundedEveryPeriodType() != null) {
compoundingInterestFrequency = PeriodFrequencyType.fromInt(command.getInterestCompoundedEveryPeriodType()); compoundingInterestFrequency = PeriodFrequencyType.fromInt(command.getInterestCompoundedEveryPeriodType());
} }
boolean renewalAllowed = account.isRenewalAllowed(); boolean renewalAllowed = account.isRenewalAllowed();
if(command.isRenewalAllowedChanged()){ if (command.isRenewalAllowedChanged()) {
renewalAllowed = command.isRenewalAllowed(); renewalAllowed = command.isRenewalAllowed();
} }
boolean preClosureAllowed = account.isPreClosureAllowed(); boolean preClosureAllowed = account.isPreClosureAllowed();
if(command.isPreClosureAllowedChanged()){ if (command.isPreClosureAllowedChanged()) {
preClosureAllowed = command.isPreClosureAllowed(); preClosureAllowed = command.isPreClosureAllowed();
} }
boolean isInterestWithdrawable = account.isInterestWithdrawable(); boolean isInterestWithdrawable = account.isInterestWithdrawable();
if(command.isInterestWithdrawableChanged()){ if (command.isInterestWithdrawableChanged()) {
isInterestWithdrawable = command.isInterestWithdrawable(); isInterestWithdrawable = command.isInterestWithdrawable();
} }
boolean isInterestCompoundingAllowed = account.isInterestCompoundingAllowed(); boolean isInterestCompoundingAllowed = account.isInterestCompoundingAllowed();
if(command.isInterestCompoundingAllowedChanged()){ if (command.isInterestCompoundingAllowedChanged()) {
isInterestCompoundingAllowed = command.isInterestCompoundingAllowed(); isInterestCompoundingAllowed = command.isInterestCompoundingAllowed();
} }
boolean isLockinPeriodAllowed = account.isLockinPeriodAllowed(); boolean isLockinPeriodAllowed = account.isLockinPeriodAllowed();
if(command.isLockinPeriodChanged()){ if (command.isLockinPeriodChanged()) {
isLockinPeriodAllowed = command.isLockinPeriodAllowed(); isLockinPeriodAllowed = command.isLockinPeriodAllowed();
} }
Integer lockinPeriod = account.getLockinPeriod(); Integer lockinPeriod = account.getLockinPeriod();
if(command.getLockinPeriod() != null){ if (command.getLockinPeriod() != null) {
lockinPeriod = command.getLockinPeriod(); lockinPeriod = command.getLockinPeriod();
} }
PeriodFrequencyType lockinPeriodType = account.getLockinPeriodType(); PeriodFrequencyType lockinPeriodType = account.getLockinPeriodType();
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) {
boolean renewalAllowed = account.isRenewalAllowed(); boolean renewalAllowed = account.isRenewalAllowed();
if(command.isRenewalAllowedChanged()){ if (command.isRenewalAllowedChanged()) {
renewalAllowed = command.isRenewalAllowed(); renewalAllowed = command.isRenewalAllowed();
} }
boolean isInterestWithdrawable = account.isInterestWithdrawable(); boolean isInterestWithdrawable = account.isInterestWithdrawable();
if(command.isInterestWithdrawableChanged()){ if (command.isInterestWithdrawableChanged()) {
isInterestWithdrawable = command.isInterestWithdrawable(); isInterestWithdrawable = command.isInterestWithdrawable();
} }
account.update(renewalAllowed,isInterestWithdrawable); account.update(renewalAllowed, isInterestWithdrawable);
} }
public void postInterest(DepositAccount account) { public void postInterest(DepositAccount account) {
account.postInterestForDepositAccount(account,this.fixedTermDepositInterestCalculator); account.postInterestForDepositAccount(account, this.fixedTermDepositInterestCalculator);
} }
} }
@@ -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();
} }
} }
@@ -282,19 +294,19 @@ public class DepositAccountReadPlatformServiceImpl implements DepositAccountRead
this.context.authenticatedUser(); this.context.authenticatedUser();
DepositAccountLookupMapper mapper = new DepositAccountLookupMapper(); DepositAccountLookupMapper mapper = new DepositAccountLookupMapper();
String sql = "select "+mapper.depositAccountLookupSchema(); String sql = "select " + mapper.depositAccountLookupSchema();
return this.jdbcTemplate.query(sql, mapper, new Object[]{}); return this.jdbcTemplate.query(sql, mapper, new Object[] {});
} }
private static final class DepositAccountLookupMapper implements RowMapper<DepositAccountsForLookup> { private static final class DepositAccountLookupMapper implements RowMapper<DepositAccountsForLookup> {
public String depositAccountLookupSchema(){ public String depositAccountLookupSchema() {
return " da.id as id from m_deposit_account da where da.status_enum=300 and da.is_deleted=0"; return " da.id as id from m_deposit_account da where da.status_enum=300 and da.is_deleted=0";
} }
@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);
} }
@@ -11,21 +11,25 @@ public class DepositAccountTransactionEnumerations {
private static EnumOptionData depositType(DepositAccountTransactionType transactionType) { private static EnumOptionData depositType(DepositAccountTransactionType transactionType) {
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);
} }
@@ -13,10 +13,10 @@ public class DepositStateTransitionCommandValidator {
private final DepositStateTransitionCommand command; private final DepositStateTransitionCommand command;
public DepositStateTransitionCommandValidator(final DepositStateTransitionCommand command) { public DepositStateTransitionCommandValidator(final DepositStateTransitionCommand command) {
this.command=command; this.command = command;
} }
public void validate(){ public void validate() {
List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>(); List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("deposit.transition"); DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("deposit.transition");
@@ -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); }
} }
}
} }
@@ -13,7 +13,7 @@ public class RenewDepositAccountCommandValidator {
private final DepositAccountCommand command; private final DepositAccountCommand command;
public RenewDepositAccountCommandValidator(final DepositAccountCommand command) { public RenewDepositAccountCommandValidator(final DepositAccountCommand command) {
this.command=command; this.command = command;
} }
public void validateForCreate() { public void validateForCreate() {
@@ -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); }
}
} }
} }