Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ private DepositsApiConstants() {
public static final String localeParamName = "locale";
public static final String dateFormatParamName = "dateFormat";
public static final String monthDayFormatParamName = "monthDayFormat";
public static final String startDateParamName = "startDate";
public static final String closeDateParamName = "closeDate";

// deposit product and account parameters
public static final String idParamName = "id";
Expand Down Expand Up @@ -217,10 +219,11 @@ private DepositsApiConstants() {
* Deposit Product Parameters
*/
private static final Set<String> DEPOSIT_PRODUCT_REQUEST_DATA_PARAMETERS = new HashSet<>(Arrays.asList(localeParamName,
monthDayFormatParamName, nameParamName, shortNameParamName, descriptionParamName, currencyCodeParamName,
digitsAfterDecimalParamName, inMultiplesOfParamName, nominalAnnualInterestRateParamName, interestCompoundingPeriodTypeParamName,
interestPostingPeriodTypeParamName, interestCalculationTypeParamName, interestCalculationDaysInYearTypeParamName,
lockinPeriodFrequencyParamName, lockinPeriodFrequencyTypeParamName, accountingRuleParamName, chargesParamName,
monthDayFormatParamName, dateFormatParamName, startDateParamName, closeDateParamName, nameParamName, shortNameParamName,
descriptionParamName, currencyCodeParamName, digitsAfterDecimalParamName, inMultiplesOfParamName,
nominalAnnualInterestRateParamName, interestCompoundingPeriodTypeParamName, interestPostingPeriodTypeParamName,
interestCalculationTypeParamName, interestCalculationDaysInYearTypeParamName, lockinPeriodFrequencyParamName,
lockinPeriodFrequencyTypeParamName, accountingRuleParamName, chargesParamName,
SavingProductAccountingParams.INCOME_FROM_FEES.getValue(), SavingProductAccountingParams.INCOME_FROM_PENALTIES.getValue(),
SavingProductAccountingParams.INTEREST_ON_SAVINGS.getValue(),
SavingProductAccountingParams.PAYMENT_CHANNEL_FUND_SOURCE_MAPPING.getValue(),
Expand Down Expand Up @@ -277,6 +280,7 @@ private static Set<String> fixedDepositProductResponseData() {
fixedDepositRequestData.addAll(DEPOSIT_PRODUCT_REQUEST_DATA_PARAMETERS);
fixedDepositRequestData.addAll(PRECLOSURE_RESPONSE_DATA_PARAMETERS);
fixedDepositRequestData.addAll(DEPOSIT_TERM_RESPONSE_DATA_PARAMETERS);
fixedDepositRequestData.add(statusParamName);
return fixedDepositRequestData;
}

Expand All @@ -296,6 +300,7 @@ private static Set<String> recurringDepositProductResponseData() {
recurringDepositRequestData.addAll(PRECLOSURE_RESPONSE_DATA_PARAMETERS);
recurringDepositRequestData.addAll(DEPOSIT_TERM_RESPONSE_DATA_PARAMETERS);
recurringDepositRequestData.addAll(RECURRING_DETAILS_RESPONSE_DATA_PARAMETERS);
recurringDepositRequestData.add(statusParamName);
recurringDepositRequestData.add(SavingsApiConstants.minBalanceForInterestCalculationParamName);
return recurringDepositRequestData;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ public String retrieveAll(@Context final UriInfo uriInfo, @QueryParam("paged") @
@POST
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
@Operation(summary = "Submit new fixed deposit application", description = """
@Operation(summary = "Submit new fixed deposit application", operationId = "submitApplicationFixedDepositAccount", description = """
Submits a new fixed deposit application
Mandatory Fields: clientId or groupId, productId, submittedOnDate, depositAmount, depositPeriod, depositPeriodFrequencyId

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ public class FixedDepositProductsApiResource {

Mandatory Fields: name, shortName, description, currencyCode, digitsAfterDecimal,inMultiplesOf, interestCompoundingPeriodType, interestCalculationType, interestCalculationDaysInYearType, minDepositTerm, minDepositTermTypeId, accountingRule

Optional Fields: lockinPeriodFrequency, lockinPeriodFrequencyType, maxDepositTerm, maxDepositTermTypeId, inMultiplesOfDepositTerm, inMultiplesOfDepositTermTypeId, preClosurePenalApplicable, preClosurePenalInterest, preClosurePenalInterestOnTypeId, feeToIncomeAccountMappings, penaltyToIncomeAccountMappings, charges, charts, , withHoldTax, taxGroupId
Optional Fields: startDate, closeDate, lockinPeriodFrequency, lockinPeriodFrequencyType, maxDepositTerm, maxDepositTermTypeId, inMultiplesOfDepositTerm, inMultiplesOfDepositTermTypeId, preClosurePenalApplicable, preClosurePenalInterest, preClosurePenalInterestOnTypeId, feeToIncomeAccountMappings, penaltyToIncomeAccountMappings, charges, charts, , withHoldTax, taxGroupId


Mandatory Fields for Cash based accounting (accountingRule = 2): savingsReferenceAccountId, savingsControlAccountId, interestOnSavingsAccountId, incomeFromFeeAccountId, transfersInSuspenseAccountId, incomeFromPenaltyAccountId""")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@ private PostFixedDepositProductsChartSlabs() {}
public String shortName;
@Schema(example = "Daily compounding using Daily Balance, 5% per year, 365 days in year")
public String description;
@Schema(example = "10 July 2022")
public String startDate;
@Schema(example = "10 July 2022")
public String closeDate;
@Schema(example = "USD")
public String currencyCode;
@Schema(example = "2")
Expand All @@ -77,6 +81,8 @@ private PostFixedDepositProductsChartSlabs() {}
public Integer inMultiplesOf;
@Schema(example = "en")
public String locale;
@Schema(example = "dd MMMM yyyy")
public String dateFormat;
@Schema(example = "1")
public Integer interestCompoundingPeriodType;
@Schema(example = "4")
Expand Down Expand Up @@ -120,8 +126,14 @@ private PutFixedDepositProductsProductIdRequest() {}

@Schema(example = "Fixed deposit product new offerings")
public String description;
@Schema(example = "10 July 2022")
public String startDate;
@Schema(example = "10 July 2022")
public String closeDate;
@Schema(example = "en")
public String locale;
@Schema(example = "dd MMMM yyyy")
public String dateFormat;
@Schema(example = "5")
public Integer minDepositTerm;
@Schema(example = "1")
Expand All @@ -139,6 +151,10 @@ private PutFixedDepositProductsChanges() {}

@Schema(example = "Fixed deposit product new offerings")
public String description;
@Schema(example = "10 July 2022")
public String startDate;
@Schema(example = "10 July 2022")
public String closeDate;
@Schema(example = "5")
public Integer minDepositTerm;
}
Expand Down Expand Up @@ -265,6 +281,12 @@ private GetFixedDepositProductsAccountingRule() {}
public String shortName;
@Schema(example = "FD01")
public String description;
@Schema(example = "[2013, 9, 2]")
public LocalDate startDate;
@Schema(example = "[2014, 2, 7]")
public LocalDate closeDate;
@Schema(example = "loanProduct.active")
public String status;
public GetFixedDepositProductsCurrency currency;
@Schema(example = "false")
public Boolean preClosurePenalApplicable;
Expand Down Expand Up @@ -491,6 +513,12 @@ private GetFixedDepositProductsProductIdPeriodType() {}
public String shortName;
@Schema(example = "Daily compounding using Daily Balance, 5% per year, 365 days in year")
public String description;
@Schema(example = "[2013, 9, 2]")
public LocalDate startDate;
@Schema(example = "[2014, 2, 7]")
public LocalDate closeDate;
@Schema(example = "loanProduct.active")
public String status;
public GetFixedDepositProductsProductIdCurrency currency;
public GetFixedDepositProductsProductIdInterestCompoundingPeriodType interestCompoundingPeriodType;
public GetFixedDepositProductsResponse.GetFixedDepositProductsInterestPostingPeriodType interestPostingPeriodType;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ public class RecurringDepositProductsApiResource {
@Operation(summary = "Create a Recurring Deposit Product", operationId = "createRecurringDepositProduct", description = "Creates a Recurring Deposit Product\n\n"
+ "Mandatory Fields: name, shortName, description, currencyCode, digitsAfterDecimal,inMultiplesOf, interestCompoundingPeriodType, interestPostingPeriodType, interestCalculationType, interestCalculationDaysInYearType, minDepositTerm, minDepositTermTypeId, accountingRule, depositAmount, charts\n\n"
+ "Mandatory Fields for Cash based accounting (accountingRule = 2): savingsReferenceAccountId, savingsControlAccountId, interestOnSavingsAccountId, incomeFromFeeAccountId, transfersInSuspenseAccountId, incomeFromPenaltyAccountId\n\n"
+ "Optional Fields: lockinPeriodFrequency, lockinPeriodFrequencyType, maxDepositTerm, maxDepositTermTypeId, inMultiplesOfDepositTerm, inMultiplesOfDepositTermTypeId, preClosurePenalApplicable, preClosurePenalInterest, preClosurePenalInterestOnTypeId, feeToIncomeAccountMappings, penaltyToIncomeAccountMappings, charges, minDepositAmount, maxDepositAmount, withHoldTax, taxGroupId")
+ "Optional Fields: startDate, closeDate, lockinPeriodFrequency, lockinPeriodFrequencyType, maxDepositTerm, maxDepositTermTypeId, inMultiplesOfDepositTerm, inMultiplesOfDepositTermTypeId, preClosurePenalApplicable, preClosurePenalInterest, preClosurePenalInterestOnTypeId, feeToIncomeAccountMappings, penaltyToIncomeAccountMappings, charges, minDepositAmount, maxDepositAmount, withHoldTax, taxGroupId")
@RequestBody(required = true, content = @Content(schema = @Schema(implementation = RecurringDepositProductsApiResourceSwagger.PostRecurringDepositProductsRequest.class)))
@ApiResponses({
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = RecurringDepositProductsApiResourceSwagger.PostRecurringDepositProductsResponse.class))) })
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@ private PostRecurringDepositProductsChartSlabs() {}
public String shortName;
@Schema(example = "Daily compounding using Daily Balance, 5% per year, 365 days in year")
public String description;
@Schema(example = "10 July 2022")
public String startDate;
@Schema(example = "10 July 2022")
public String closeDate;
@Schema(example = "USD")
public String currencyCode;
@Schema(example = "2")
Expand All @@ -77,6 +81,8 @@ private PostRecurringDepositProductsChartSlabs() {}
public Integer inMultiplesOf;
@Schema(example = "en")
public String locale;
@Schema(example = "dd MMMM yyyy")
public String dateFormat;
@Schema(example = "1")
public Integer interestCompoundingPeriodType;
@Schema(example = "4")
Expand Down Expand Up @@ -126,8 +132,14 @@ private PutRecurringDepositProductsRequest() {}

@Schema(example = "Recurring deposit product new offerings")
public String description;
@Schema(example = "10 July 2022")
public String startDate;
@Schema(example = "10 July 2022")
public String closeDate;
@Schema(example = "en")
public String locale;
@Schema(example = "dd MMMM yyyy")
public String dateFormat;
@Schema(example = "5")
public Integer minDepositTerm;
@Schema(example = "1")
Expand All @@ -145,6 +157,10 @@ private PutRecurringDepositProductsChanges() {}

@Schema(example = "Recurring deposit product new offerings")
public String description;
@Schema(example = "10 July 2022")
public String startDate;
@Schema(example = "10 July 2022")
public String closeDate;
@Schema(example = "5")
public Integer minDepositTerm;
}
Expand Down Expand Up @@ -283,6 +299,12 @@ private GetRecurringDepositProductsRecurringDepositFrequencyType() {}
public String shortName;
@Schema(example = "RD01")
public String description;
@Schema(example = "[2013, 9, 2]")
public LocalDate startDate;
@Schema(example = "[2014, 2, 7]")
public LocalDate closeDate;
@Schema(example = "loanProduct.active")
public String status;
public GetRecurringDepositProductsCurrency currency;
@Schema(example = "1")
public Integer recurringDepositFrequency;
Expand Down Expand Up @@ -511,6 +533,12 @@ private GetRecurringDepositProductsProductIdPeriodType() {}
public String shortName;
@Schema(example = "Daily compounding using Daily Balance, 5% per year, 365 days in year")
public String description;
@Schema(example = "[2013, 9, 2]")
public LocalDate startDate;
@Schema(example = "[2014, 2, 7]")
public LocalDate closeDate;
@Schema(example = "loanProduct.active")
public String status;
public GetRecurringDepositProductsProductIdCurrency currency;
public GetRecurringDepositProductsProductIdInterestCompoundingPeriodType interestCompoundingPeriodType;
public GetRecurringDepositProductsResponse.GetRecurringDepositProductsInterestPostingPeriodType interestPostingPeriodType;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
import org.apache.fineract.infrastructure.core.exception.InvalidJsonException;
import org.apache.fineract.infrastructure.core.exception.UnsupportedParameterException;
import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
import org.apache.fineract.infrastructure.core.service.DateUtils;
import org.apache.fineract.infrastructure.core.service.ExternalIdFactory;
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
import org.apache.fineract.organisation.staff.domain.Staff;
Expand All @@ -96,6 +97,7 @@
import org.apache.fineract.portfolio.savings.SavingsPeriodFrequencyType;
import org.apache.fineract.portfolio.savings.SavingsPostingInterestPeriodType;
import org.apache.fineract.portfolio.savings.data.SavingsAccountTransactionDTO;
import org.apache.fineract.portfolio.savings.exception.DepositAccountApplicationDateException;
import org.apache.fineract.portfolio.savings.exception.FixedDepositProductNotFoundException;
import org.apache.fineract.portfolio.savings.exception.RecurringDepositProductNotFoundException;
import org.apache.fineract.portfolio.savings.exception.SavingsProductNotFoundException;
Expand Down Expand Up @@ -223,6 +225,7 @@ public SavingsAccount assembleFrom(final JsonCommand command, final AppUser subm
}

final LocalDate submittedOnDate = this.fromApiJsonHelper.extractLocalDateNamed(submittedOnDateParamName, element);
validateProductApplicationDate(submittedOnDate, product);

BigDecimal interestRate = null;
if (command.parameterExists(nominalAnnualInterestRateParamName)) {
Expand Down Expand Up @@ -367,6 +370,22 @@ public SavingsAccount assembleFrom(final JsonCommand command, final AppUser subm
return account;
}

public void validateProductApplicationDate(final LocalDate submittedOnDate, final SavingsProduct savingsProduct) {
final FixedDepositProduct product = (FixedDepositProduct) savingsProduct;
final LocalDate startDate = product.getStartDate();
final LocalDate closeDate = product.getCloseDate();

if (startDate != null && DateUtils.isBefore(submittedOnDate, startDate)) {
throw new DepositAccountApplicationDateException("submitted.on.date.cannot.be.before.the.deposit.product.start.date",
"submittedOnDate cannot be before the deposit product startDate.", submittedOnDate.toString(), startDate.toString());
}

if (closeDate != null && DateUtils.isAfter(submittedOnDate, closeDate)) {
throw new DepositAccountApplicationDateException("submitted.on.date.cannot.be.after.the.deposit.product.close.date",
"submittedOnDate cannot be after the deposit product closeDate.", submittedOnDate.toString(), closeDate.toString());
}
}

public SavingsAccount assembleFrom(final Long savingsId, DepositAccountType depositAccountType) {
final SavingsAccount account = this.savingsAccountRepository.findOneWithNotFoundDetection(savingsId, depositAccountType);
account.setHelpers(this.savingsAccountTransactionSummaryWrapper, this.savingsHelper, this.configurationDomainService);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ public Long handleFDAccountClosure(final FixedDepositAccount account, final Paym
if (onClosureType == DepositAccountOnClosureType.REINVEST_PRINCIPAL_AND_INTEREST
|| onClosureType == DepositAccountOnClosureType.REINVEST_PRINCIPAL_ONLY) {
ExternalId externalId = this.externalIdFactory.create();
this.depositAccountAssembler.validateProductApplicationDate(closedDate, account.savingsProduct());
FixedDepositAccount reinvestedDeposit = account.reInvest(account.getAccountBalance(), externalId);
this.depositAccountAssembler.assignSavingAccountHelpers(reinvestedDeposit);
reinvestedDeposit.updateMaturityDateAndAmountBeforeAccountActivation(mc, isPreMatureClosure,
Expand Down Expand Up @@ -271,6 +272,7 @@ public Long handleFDAccountMaturityClosure(final FixedDepositAccount account, fi
}
ExternalId externalId = this.externalIdFactory.create();

this.depositAccountAssembler.validateProductApplicationDate(closedDate, account.savingsProduct());
FixedDepositAccount reinvestedDeposit = account.reInvest(reInvestAmount, externalId);
this.depositAccountAssembler.assignSavingAccountHelpers(reinvestedDeposit);
reinvestedDeposit.updateMaturityDateAndAmountBeforeAccountActivation(mc, isPreMatureClosure,
Expand Down Expand Up @@ -352,6 +354,7 @@ public Long handleRDAccountClosure(final RecurringDepositAccount account, final
} else {
reInvestAmount = account.getAccountBalance();
}
this.depositAccountAssembler.validateProductApplicationDate(closedDate, account.savingsProduct());
RecurringDepositAccount reinvestedDeposit = account.reInvest(reInvestAmount);
depositAccountAssembler.assignSavingAccountHelpers(reinvestedDeposit);
this.savingsAccountRepository.save(reinvestedDeposit);
Expand Down
Loading