/** * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mifosplatform.portfolio.savings.domain; import static org.mifosplatform.portfolio.savings.DepositsApiConstants.mandatoryRecommendedDepositAmountParamName; import java.math.BigDecimal; import java.math.MathContext; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import javax.persistence.Column; import javax.persistence.Embedded; import javax.persistence.Entity; import javax.persistence.JoinColumn; import javax.persistence.OneToOne; import javax.persistence.Table; import org.joda.time.LocalDate; import org.mifosplatform.infrastructure.core.api.JsonCommand; import org.mifosplatform.infrastructure.core.data.ApiParameterError; import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException; import org.mifosplatform.infrastructure.core.service.DateUtils; import org.mifosplatform.organisation.monetary.domain.Money; import org.mifosplatform.portfolio.savings.DepositsApiConstants; import org.springframework.data.jpa.domain.AbstractPersistable; @Entity @Table(name = "m_deposit_account_recurring_detail") public class DepositAccountRecurringDetail extends AbstractPersistable<Long> { @Column(name = "mandatory_recommended_deposit_amount", scale = 6, precision = 19, nullable = true) private BigDecimal mandatoryRecommendedDepositAmount; @Column(name = "total_overdue_amount", scale = 6, precision = 19, nullable = true) private BigDecimal totalOverdueAmount; @Column(name = "is_calendar_inherited", nullable = false) private final boolean isCalendarInherited; @Column(name = "no_of_overdue_installments", nullable = false) private Integer noOfOverdueInstallments; @Embedded private DepositRecurringDetail recurringDetail; @OneToOne @JoinColumn(name = "savings_account_id", nullable = false) private SavingsAccount account; /** * */ public DepositAccountRecurringDetail() { this.noOfOverdueInstallments = 0; this.isCalendarInherited = false; } public static DepositAccountRecurringDetail createNew(final BigDecimal mandatoryRecommendedDepositAmount, final DepositRecurringDetail recurringDetail, final SavingsAccount account, final boolean isCalendarInherited) { final BigDecimal totalOverdueAmount = null; final Integer noOfOverdueInstallments = null; return new DepositAccountRecurringDetail(mandatoryRecommendedDepositAmount, totalOverdueAmount, noOfOverdueInstallments, recurringDetail, account, isCalendarInherited); } /** * @param mandatoryRecommendedDepositAmount * @param totalOverdueAmount * @param noOfOverdueInstallments * @param recurringDetail * @param account */ protected DepositAccountRecurringDetail(final BigDecimal mandatoryRecommendedDepositAmount, final BigDecimal totalOverdueAmount, final Integer noOfOverdueInstallments, final DepositRecurringDetail recurringDetail, final SavingsAccount account, final boolean isCalendarInherited) { this.mandatoryRecommendedDepositAmount = mandatoryRecommendedDepositAmount; this.totalOverdueAmount = totalOverdueAmount; this.noOfOverdueInstallments = noOfOverdueInstallments; this.recurringDetail = recurringDetail; this.account = account; this.isCalendarInherited = isCalendarInherited; } public Map<String, Object> update(final JsonCommand command) { final Map<String, Object> actualChanges = new LinkedHashMap<>(10); if (command.isChangeInBigDecimalParameterNamed(mandatoryRecommendedDepositAmountParamName, this.mandatoryRecommendedDepositAmount)) { final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(mandatoryRecommendedDepositAmountParamName); actualChanges.put(mandatoryRecommendedDepositAmountParamName, newValue); this.mandatoryRecommendedDepositAmount = newValue; } if (this.recurringDetail != null) { actualChanges.putAll(this.recurringDetail.update(command)); } return actualChanges; } public Map<String, Object> updateMandatoryRecommendedDepositAmount(BigDecimal newMandatoryRecommendedDepositAmount, LocalDate effectiveDate, Boolean isSavingsInterestPostingAtCurrentPeriodEnd, Integer financialYearBeginningMonth) { final Map<String, Object> actualChanges = new LinkedHashMap<>(10); actualChanges.put(mandatoryRecommendedDepositAmountParamName, newMandatoryRecommendedDepositAmount); this.mandatoryRecommendedDepositAmount = newMandatoryRecommendedDepositAmount; RecurringDepositAccount depositAccount = (RecurringDepositAccount) this.account; if (depositAccount.isNotActive()) { final String defaultUserMessage = "Updates to the recommended deposit amount are allowed only when the underlying account is active."; final ApiParameterError error = ApiParameterError.generalError("error.msg." + DepositsApiConstants.RECURRING_DEPOSIT_ACCOUNT_RESOURCE_NAME + ".is.not.active", defaultUserMessage); final List<ApiParameterError> dataValidationErrors = new ArrayList<>(); dataValidationErrors.add(error); throw new PlatformApiDataValidationException(dataValidationErrors); } depositAccount.updateScheduleInstallmentsWithNewRecommendedDepositAmount(newMandatoryRecommendedDepositAmount, effectiveDate); depositAccount.updateOverduePayments(DateUtils.getLocalDateOfTenant()); MathContext mc = MathContext.DECIMAL64; Boolean isPreMatureClosure = false; depositAccount.updateMaturityDateAndAmount(mc, isPreMatureClosure, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth); return actualChanges; } public DepositRecurringDetail recurringDetail() { return this.recurringDetail; } public void updateAccountReference(final SavingsAccount account) { this.account = account; } public boolean isMandatoryDeposit() { return this.recurringDetail.isMandatoryDeposit(); } public boolean allowWithdrawal() { return this.recurringDetail.allowWithdrawal(); } public boolean adjustAdvanceTowardsFuturePayments() { return this.recurringDetail.adjustAdvanceTowardsFuturePayments(); } public BigDecimal mandatoryRecommendedDepositAmount() { return this.mandatoryRecommendedDepositAmount; } public boolean isCalendarInherited() { return this.isCalendarInherited; } public DepositAccountRecurringDetail copy() { final BigDecimal mandatoryRecommendedDepositAmount = this.mandatoryRecommendedDepositAmount; final DepositRecurringDetail recurringDetail = this.recurringDetail.copy(); final boolean isCalendarInherited = this.isCalendarInherited; return DepositAccountRecurringDetail.createNew(mandatoryRecommendedDepositAmount, recurringDetail, null, isCalendarInherited); } public void updateOverdueDetails(final int noOfOverdueInstallments, final Money totalOverdueAmount) { this.noOfOverdueInstallments = noOfOverdueInstallments; this.totalOverdueAmount = totalOverdueAmount.getAmount(); } }