interest posting on specified date
This commit is contained in:
+1020
-3
File diff suppressed because it is too large
Load Diff
+42
@@ -47,6 +47,7 @@ public class SavingsAccountHelper {
|
||||
private static final String WITHDRAWN_BY_CLIENT_SAVINGS_COMMAND = "withdrawnByApplicant";
|
||||
private static final String CALCULATE_INTEREST_SAVINGS_COMMAND = "calculateInterest";
|
||||
private static final String POST_INTEREST_SAVINGS_COMMAND = "postInterest";
|
||||
private static final String POST_INTEREST_AS_ON_SAVINGS_COMMAND = "postInterestAsOn";
|
||||
private static final String CLOSE_SAVINGS_COMMAND = "close";
|
||||
private static final String UPDATE_WITHHOLD_TAX_STATUS = "updateWithHoldTax";
|
||||
|
||||
@@ -195,6 +196,12 @@ public class SavingsAccountHelper {
|
||||
performSavingActions(createSavingsCalculateInterestURL(POST_INTEREST_SAVINGS_COMMAND, savingsId),
|
||||
getCalculatedInterestForSavingsApplicationAsJSON(), "");
|
||||
}
|
||||
|
||||
public void postInterestAsOnSavings(final Integer savingsId, final String today) {
|
||||
System.out.println("--------------------------------- POST INTEREST AS ON FOR SAVINGS --------------------------------");
|
||||
performSavingActions(createSavingsPostInterestAsOnURL(POST_INTEREST_AS_ON_SAVINGS_COMMAND, savingsId),
|
||||
getCalculatedInterestForSavingsApplicationAsJSON(today), CommonConstants.RESPONSE_RESOURCE_ID);
|
||||
}
|
||||
|
||||
public Integer addChargesForSavings(final Integer savingsId, final Integer chargeId, boolean addDueDate) {
|
||||
System.out.println("--------------------------------- ADD CHARGES FOR SAVINGS --------------------------------");
|
||||
@@ -286,6 +293,16 @@ public class SavingsAccountHelper {
|
||||
System.out.println(savingsAccountCalculatedInterestJson);
|
||||
return savingsAccountCalculatedInterestJson;
|
||||
}
|
||||
|
||||
private String getCalculatedInterestForSavingsApplicationAsJSON(final String today) {
|
||||
final HashMap<String, String> map = new HashMap<>();
|
||||
map.put("locale", CommonConstants.locale);
|
||||
map.put("dateFormat", CommonConstants.dateFormat);
|
||||
map.put("transactionDate", today);
|
||||
map.put("postInterestManualOrAutomatic", "true");
|
||||
String savingsAccountCalculatedInterestJson = new Gson().toJson(map);
|
||||
return savingsAccountCalculatedInterestJson;
|
||||
}
|
||||
|
||||
private String getSavingsPayChargeJSON(final String amount, final String dueDate) {
|
||||
final HashMap<String, Object> map = new HashMap<>();
|
||||
@@ -321,6 +338,20 @@ public class SavingsAccountHelper {
|
||||
map.put("closedOnDate", closedOnDate);
|
||||
map.put("withdrawBalance", withdrawBalance);
|
||||
map.put("note", "Close Test");
|
||||
|
||||
String josn = new Gson().toJson(map);
|
||||
return josn;
|
||||
}
|
||||
|
||||
private String getCloseAccountPostInterestJSON(String withdrawBalance, String closedOnDate) {
|
||||
final HashMap<String, Object> map = new HashMap<>();
|
||||
map.put("locale", CommonConstants.locale);
|
||||
map.put("dateFormat", CommonConstants.dateFormat);
|
||||
map.put("closedOnDate", closedOnDate);
|
||||
map.put("withdrawBalance", withdrawBalance);
|
||||
map.put("note", "Close Test");
|
||||
map.put("postInterestValidationOnClosure", "true");
|
||||
|
||||
String josn = new Gson().toJson(map);
|
||||
return josn;
|
||||
}
|
||||
@@ -341,6 +372,10 @@ public class SavingsAccountHelper {
|
||||
private String createSavingsCalculateInterestURL(final String command, final Integer savingsID) {
|
||||
return SAVINGS_ACCOUNT_URL + "/" + savingsID + "?command=" + command + "&" + Utils.TENANT_IDENTIFIER;
|
||||
}
|
||||
|
||||
private String createSavingsPostInterestAsOnURL(final String command, final Integer savingsID) {
|
||||
return SAVINGS_ACCOUNT_URL + "/" + savingsID + "/transactions/" + "?command=" + command + "&" + Utils.TENANT_IDENTIFIER;
|
||||
}
|
||||
|
||||
private String createChargesURL(final String command, final Integer savingsID, final Integer chargeId) {
|
||||
return SAVINGS_ACCOUNT_URL + "/" + savingsID + "/charges/" + chargeId + "?command=" + command + "&" + Utils.TENANT_IDENTIFIER;
|
||||
@@ -418,6 +453,13 @@ public class SavingsAccountHelper {
|
||||
return performSavingActions(createSavingsOperationURL(CLOSE_SAVINGS_COMMAND, savingsID),
|
||||
getCloseAccountJSON(withdrawBalance, closedOnDate), jsonAttributeToGetBack);
|
||||
}
|
||||
|
||||
public Object closeSavingsAccountPostInterestAndGetBackRequiredField(final Integer savingsID, String withdrawBalance,
|
||||
final String jsonAttributeToGetBack, final String closedOnDate) {
|
||||
System.out.println("---------------------------------- CLOSE SAVINGS APPLICATION ----------------------------------");
|
||||
return performSavingActions(createSavingsOperationURL(CLOSE_SAVINGS_COMMAND, savingsID),
|
||||
getCloseAccountPostInterestJSON(withdrawBalance, closedOnDate), jsonAttributeToGetBack);
|
||||
}
|
||||
|
||||
private String getPeriodChargeRequestJSON(Integer chargeId, boolean addDueDate) {
|
||||
final HashMap<String, Object> map = new HashMap<>();
|
||||
|
||||
+9
@@ -2248,6 +2248,15 @@ public class CommandWrapperBuilder {
|
||||
this.href = "/savingsaccounts/" + accountId + "?commad=unassignSavingsOfficer";
|
||||
return this;
|
||||
}
|
||||
|
||||
public CommandWrapperBuilder SavingsInterestPostingAsOnDate(final Long accountId) {
|
||||
this.actionName = "POSTINTERESTASONDATE";
|
||||
this.entityName = "SAVINGSACCOUNT";
|
||||
this.savingsId = accountId;
|
||||
this.entityId = null;
|
||||
this.href = "/savingsaccounts/" + accountId + "?command=postInterestAsOn";
|
||||
return this;
|
||||
}
|
||||
|
||||
public CommandWrapperBuilder createLoanRescheduleRequest(final String entityName) {
|
||||
this.actionName = "CREATE";
|
||||
|
||||
+6
-1
@@ -34,6 +34,7 @@ public class SavingsApiConstants {
|
||||
public static final String SAVINGS_ACCOUNT_CHARGE_RESOURCE_NAME = "savingsaccountcharge";
|
||||
|
||||
// actions
|
||||
public static final String postInterestValidationOnClosure = "postInterestValidationOnClosure";
|
||||
public static String summitalAction = ".summital";
|
||||
public static String approvalAction = ".approval";
|
||||
public static String undoApprovalAction = ".undoApproval";
|
||||
@@ -244,13 +245,17 @@ public class SavingsApiConstants {
|
||||
public static final Set<String> SAVINGS_TRANSACTION_RESPONSE_DATA_PARAMETERS = new HashSet<>(
|
||||
Arrays.asList(idParamName, "accountId", accountNoParamName, "currency", "amount", dateParamName, paymentDetailDataParamName,
|
||||
runningBalanceParamName, reversedParamName));
|
||||
|
||||
public static final Set<String> SAVINGS_ACCOUNT_TRANSACTION_RESPONSE_DATA_PARAMETERS = new HashSet<>(Arrays.asList(idParamName,
|
||||
accountNoParamName));
|
||||
|
||||
public static final Set<String> SAVINGS_ACCOUNT_ACTIVATION_REQUEST_DATA_PARAMETERS = new HashSet<>(Arrays.asList(localeParamName,
|
||||
dateFormatParamName, activatedOnDateParamName));
|
||||
|
||||
public static final Set<String> SAVINGS_ACCOUNT_CLOSE_REQUEST_DATA_PARAMETERS = new HashSet<>(Arrays.asList(localeParamName,
|
||||
dateFormatParamName, closedOnDateParamName, noteParamName, paymentTypeIdParamName, withdrawBalanceParamName,
|
||||
transactionAccountNumberParamName, checkNumberParamName, routingCodeParamName, receiptNumberParamName, bankNumberParamName));
|
||||
transactionAccountNumberParamName, checkNumberParamName, routingCodeParamName, receiptNumberParamName, bankNumberParamName,
|
||||
postInterestValidationOnClosure));
|
||||
|
||||
public static final Set<String> SAVINGS_ACCOUNT_CHARGES_RESPONSE_DATA_PARAMETERS = new HashSet<>(Arrays.asList(chargeIdParamName,
|
||||
savingsAccountChargeIdParamName, chargeNameParamName, penaltyParamName, chargeTimeTypeParamName, dueAsOfDateParamName,
|
||||
|
||||
+6
-3
@@ -91,8 +91,8 @@ public class SavingsAccountTransactionsApiResource {
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String retrieveTemplate(@PathParam("savingsId") final Long savingsId,
|
||||
// @QueryParam("command") final String commandParam,
|
||||
@Context final UriInfo uriInfo) {
|
||||
|
||||
@Context final UriInfo uriInfo) {
|
||||
|
||||
this.context.authenticatedUser().validateHasReadPermission(SavingsApiConstants.SAVINGS_ACCOUNT_RESOURCE_NAME);
|
||||
|
||||
// FIXME - KW - for now just send back generic default information for
|
||||
@@ -104,7 +104,7 @@ public class SavingsAccountTransactionsApiResource {
|
||||
|
||||
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
||||
return this.toApiJsonSerializer.serialize(settings, savingsAccount,
|
||||
SavingsApiConstants.SAVINGS_TRANSACTION_RESPONSE_DATA_PARAMETERS);
|
||||
SavingsApiConstants.SAVINGS_TRANSACTION_RESPONSE_DATA_PARAMETERS);
|
||||
}
|
||||
|
||||
@GET
|
||||
@@ -142,6 +142,9 @@ public class SavingsAccountTransactionsApiResource {
|
||||
} else if (is(commandParam, "withdrawal")) {
|
||||
final CommandWrapper commandRequest = builder.savingsAccountWithdrawal(savingsId).build();
|
||||
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
||||
} else if (is(commandParam, "postInterestAsOn")) {
|
||||
final CommandWrapper commandRequest = builder.savingsAccountInterestPosting(savingsId).build();
|
||||
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
||||
}
|
||||
|
||||
if (result == null) {
|
||||
|
||||
+19
-17
@@ -49,6 +49,7 @@ public class SavingsAccountTransactionData {
|
||||
private final boolean reversed;
|
||||
private final AccountTransferData transfer;
|
||||
private final LocalDate submittedOnDate;
|
||||
private final boolean interestedPostedAsOn;
|
||||
|
||||
// templates
|
||||
final Collection<PaymentTypeData> paymentTypeOptions;
|
||||
@@ -56,19 +57,19 @@ public class SavingsAccountTransactionData {
|
||||
public static SavingsAccountTransactionData create(final Long id, final SavingsAccountTransactionEnumData transactionType,
|
||||
final PaymentDetailData paymentDetailData, final Long savingsId, final String savingsAccountNo, final LocalDate date,
|
||||
final CurrencyData currency, final BigDecimal amount, final BigDecimal runningBalance, final boolean reversed,
|
||||
final AccountTransferData transfer) {
|
||||
final AccountTransferData transfer, final boolean interestedPostedAsOn) {
|
||||
final Collection<PaymentTypeData> paymentTypeOptions = null;
|
||||
return new SavingsAccountTransactionData(id, transactionType, paymentDetailData, savingsId, savingsAccountNo, date, currency,
|
||||
amount, runningBalance, reversed, transfer, paymentTypeOptions);
|
||||
amount, runningBalance, reversed, transfer, paymentTypeOptions, interestedPostedAsOn);
|
||||
}
|
||||
|
||||
public static SavingsAccountTransactionData create(final Long id, final SavingsAccountTransactionEnumData transactionType,
|
||||
final PaymentDetailData paymentDetailData, final Long savingsId, final String savingsAccountNo, final LocalDate date,
|
||||
final CurrencyData currency, final BigDecimal amount, final BigDecimal runningBalance, final boolean reversed,
|
||||
final AccountTransferData transfer,final LocalDate submittedOnDate) {
|
||||
final PaymentDetailData paymentDetailData, final Long savingsId, final String savingsAccountNo, final LocalDate date,
|
||||
final CurrencyData currency, final BigDecimal amount, final BigDecimal runningBalance, final boolean reversed,
|
||||
final AccountTransferData transfer, final LocalDate submittedOnDate, final boolean interestedPostedAsOn) {
|
||||
final Collection<PaymentTypeData> paymentTypeOptions = null;
|
||||
return new SavingsAccountTransactionData(id, transactionType, paymentDetailData, savingsId, savingsAccountNo, date, currency,
|
||||
amount, runningBalance, reversed, transfer, paymentTypeOptions,submittedOnDate);
|
||||
amount, runningBalance, reversed, transfer, paymentTypeOptions, submittedOnDate, interestedPostedAsOn);
|
||||
}
|
||||
|
||||
public static SavingsAccountTransactionData template(final Long savingsId, final String savingsAccountNo,
|
||||
@@ -80,8 +81,9 @@ public class SavingsAccountTransactionData {
|
||||
final boolean reversed = false;
|
||||
final PaymentDetailData paymentDetailData = null;
|
||||
final Collection<CodeValueData> paymentTypeOptions = null;
|
||||
final boolean interestedPostedAsOn = false;
|
||||
return new SavingsAccountTransactionData(id, transactionType, paymentDetailData, savingsId, savingsAccountNo, defaultLocalDate,
|
||||
currency, amount, runningBalance, reversed, null, null);
|
||||
currency, amount, runningBalance, reversed, null, null, interestedPostedAsOn);
|
||||
}
|
||||
|
||||
public static SavingsAccountTransactionData templateOnTop(final SavingsAccountTransactionData savingsAccountTransactionData,
|
||||
@@ -90,24 +92,23 @@ public class SavingsAccountTransactionData {
|
||||
savingsAccountTransactionData.paymentDetailData, savingsAccountTransactionData.accountId,
|
||||
savingsAccountTransactionData.accountNo, savingsAccountTransactionData.date, savingsAccountTransactionData.currency,
|
||||
savingsAccountTransactionData.amount, savingsAccountTransactionData.runningBalance, savingsAccountTransactionData.reversed,
|
||||
savingsAccountTransactionData.transfer, paymentTypeOptions);
|
||||
savingsAccountTransactionData.transfer, paymentTypeOptions, savingsAccountTransactionData.interestedPostedAsOn);
|
||||
}
|
||||
|
||||
private SavingsAccountTransactionData(final Long id, final SavingsAccountTransactionEnumData transactionType,
|
||||
final PaymentDetailData paymentDetailData, final Long savingsId, final String savingsAccountNo, final LocalDate date,
|
||||
final CurrencyData currency, final BigDecimal amount, final BigDecimal runningBalance, final boolean reversed,
|
||||
final AccountTransferData transfer, final Collection<PaymentTypeData> paymentTypeOptions) {
|
||||
|
||||
this(id,transactionType,paymentDetailData,savingsId, savingsAccountNo,date,
|
||||
currency,amount,runningBalance, reversed,
|
||||
transfer, paymentTypeOptions,null);
|
||||
final AccountTransferData transfer, final Collection<PaymentTypeData> paymentTypeOptions, final boolean interestedPostedAsOn) {
|
||||
|
||||
this(id, transactionType, paymentDetailData, savingsId, savingsAccountNo, date, currency, amount, runningBalance, reversed,
|
||||
transfer, paymentTypeOptions, null, interestedPostedAsOn);
|
||||
}
|
||||
|
||||
private SavingsAccountTransactionData(final Long id, final SavingsAccountTransactionEnumData transactionType,
|
||||
final PaymentDetailData paymentDetailData, final Long savingsId, final String savingsAccountNo, final LocalDate date,
|
||||
final CurrencyData currency, final BigDecimal amount, final BigDecimal runningBalance, final boolean reversed,
|
||||
final AccountTransferData transfer, final Collection<PaymentTypeData> paymentTypeOptions,final LocalDate submittedOnDate) {
|
||||
final PaymentDetailData paymentDetailData, final Long savingsId, final String savingsAccountNo, final LocalDate date,
|
||||
final CurrencyData currency, final BigDecimal amount, final BigDecimal runningBalance, final boolean reversed,
|
||||
final AccountTransferData transfer, final Collection<PaymentTypeData> paymentTypeOptions, final LocalDate submittedOnDate,
|
||||
final boolean interestedPostedAsOn) {
|
||||
this.id = id;
|
||||
this.transactionType = transactionType;
|
||||
this.paymentDetailData = paymentDetailData;
|
||||
@@ -121,6 +122,7 @@ public class SavingsAccountTransactionData {
|
||||
this.transfer = transfer;
|
||||
this.paymentTypeOptions = paymentTypeOptions;
|
||||
this.submittedOnDate = submittedOnDate;
|
||||
this.interestedPostedAsOn = interestedPostedAsOn;
|
||||
}
|
||||
|
||||
public static SavingsAccountTransactionData withWithDrawalTransactionDetails(
|
||||
@@ -135,6 +137,6 @@ public class SavingsAccountTransactionData {
|
||||
savingsAccountTransactionData.accountNo, currentDate, savingsAccountTransactionData.currency,
|
||||
savingsAccountTransactionData.runningBalance, savingsAccountTransactionData.runningBalance,
|
||||
savingsAccountTransactionData.reversed, savingsAccountTransactionData.transfer,
|
||||
savingsAccountTransactionData.paymentTypeOptions);
|
||||
savingsAccountTransactionData.paymentTypeOptions, savingsAccountTransactionData.interestedPostedAsOn);
|
||||
}
|
||||
}
|
||||
+24
-13
@@ -190,9 +190,10 @@ public class FixedDepositAccount extends SavingsAccount {
|
||||
public void updateMaturityDateAndAmountBeforeAccountActivation(final MathContext mc, final boolean isPreMatureClosure,
|
||||
final boolean isSavingsInterestPostingAtCurrentPeriodEnd, final Integer financialYearBeginningMonth) {
|
||||
List<SavingsAccountTransaction> allTransactions = new ArrayList<>();
|
||||
final boolean postInterestAsOn = false;
|
||||
final Money transactionAmountMoney = Money.of(getCurrency(), this.accountTermAndPreClosure.depositAmount());
|
||||
final SavingsAccountTransaction transaction = SavingsAccountTransaction.deposit(null, office(), null,
|
||||
this.accountSubmittedOrActivationDate(), transactionAmountMoney, new Date(), null); // TODO:
|
||||
this.accountSubmittedOrActivationDate(), transactionAmountMoney, new Date(), null, postInterestAsOn); // TODO:
|
||||
// verify
|
||||
// if
|
||||
// it
|
||||
@@ -297,9 +298,11 @@ public class FixedDepositAccount extends SavingsAccount {
|
||||
|
||||
final SavingsInterestCalculationDaysInYearType daysInYearType = SavingsInterestCalculationDaysInYearType
|
||||
.fromInt(this.interestCalculationDaysInYearType);
|
||||
|
||||
List<LocalDate> postedAsOnTransactionDates= getManualPostingDates();
|
||||
|
||||
final List<LocalDateInterval> postingPeriodIntervals = this.savingsHelper.determineInterestPostingPeriods(
|
||||
accountSubmittedOrActivationDate(), maturityDate, postingPeriodType, financialYearBeginningMonth);
|
||||
accountSubmittedOrActivationDate(), maturityDate, postingPeriodType, financialYearBeginningMonth,
|
||||
postedAsOnTransactionDates);
|
||||
|
||||
final List<PostingPeriod> allPostingPeriods = new ArrayList<>();
|
||||
|
||||
@@ -311,11 +314,14 @@ public class FixedDepositAccount extends SavingsAccount {
|
||||
boolean isInterestTransfer = false;
|
||||
final Money minBalanceForInterestCalculation = Money.of(getCurrency(), minBalanceForInterestCalculation());
|
||||
for (final LocalDateInterval periodInterval : postingPeriodIntervals) {
|
||||
|
||||
boolean isUserPosting = false;
|
||||
if (postedAsOnTransactionDates.contains(periodInterval.endDate())) {
|
||||
isUserPosting = true;
|
||||
}
|
||||
final PostingPeriod postingPeriod = PostingPeriod.createFrom(periodInterval, periodStartingBalance, transactions,
|
||||
this.currency, compoundingPeriodType, interestCalculationType, interestRateAsFraction, daysInYearType.getValue(),
|
||||
maturityDate, interestPostTransactions, isInterestTransfer, minBalanceForInterestCalculation,
|
||||
isSavingsInterestPostingAtCurrentPeriodEnd);
|
||||
isSavingsInterestPostingAtCurrentPeriodEnd, isUserPosting);
|
||||
|
||||
periodStartingBalance = postingPeriod.closingBalance();
|
||||
|
||||
@@ -490,8 +496,9 @@ public class FixedDepositAccount extends SavingsAccount {
|
||||
final LocalDate interestPostingUpToDate = maturityDate();
|
||||
final MathContext mc = MathContext.DECIMAL64;
|
||||
final boolean isInterestTransfer = false;
|
||||
final boolean postInterestAsOn = false;
|
||||
final List<PostingPeriod> postingPeriods = calculateInterestUsing(mc, interestPostingUpToDate, isInterestTransfer,
|
||||
isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth);
|
||||
isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth, postInterestAsOn);
|
||||
|
||||
Money interestPostedToDate = Money.zero(this.currency);
|
||||
|
||||
@@ -511,7 +518,7 @@ public class FixedDepositAccount extends SavingsAccount {
|
||||
final SavingsAccountTransaction postingTransaction = findInterestPostingTransactionFor(interestPostingTransactionDate);
|
||||
if (postingTransaction == null) {
|
||||
final SavingsAccountTransaction newPostingTransaction = SavingsAccountTransaction.interestPosting(this, office(),
|
||||
interestPostingTransactionDate, interestEarnedToBePostedForPeriod);
|
||||
interestPostingTransactionDate, interestEarnedToBePostedForPeriod, postInterestAsOn);
|
||||
this.transactions.add(newPostingTransaction);
|
||||
recalucateDailyBalanceDetails = true;
|
||||
} else {
|
||||
@@ -519,7 +526,7 @@ public class FixedDepositAccount extends SavingsAccount {
|
||||
if (correctionRequired) {
|
||||
postingTransaction.reverse();
|
||||
final SavingsAccountTransaction newPostingTransaction = SavingsAccountTransaction.interestPosting(this, office(),
|
||||
interestPostingTransactionDate, interestEarnedToBePostedForPeriod);
|
||||
interestPostingTransactionDate, interestEarnedToBePostedForPeriod, postInterestAsOn);
|
||||
this.transactions.add(newPostingTransaction);
|
||||
recalucateDailyBalanceDetails = true;
|
||||
}
|
||||
@@ -549,8 +556,9 @@ public class FixedDepositAccount extends SavingsAccount {
|
||||
// post remaining interest
|
||||
final Money remainigInterestToBePosted = interestOnMaturity.minus(interestPostedToDate);
|
||||
if (!remainigInterestToBePosted.isZero()) {
|
||||
final boolean postInterestAsOn = false;
|
||||
final SavingsAccountTransaction newPostingTransaction = SavingsAccountTransaction.interestPosting(this, office(),
|
||||
accountCloseDate, remainigInterestToBePosted);
|
||||
accountCloseDate, remainigInterestToBePosted, postInterestAsOn);
|
||||
this.transactions.add(newPostingTransaction);
|
||||
recalucateDailyBalance = true;
|
||||
}
|
||||
@@ -600,18 +608,21 @@ public class FixedDepositAccount extends SavingsAccount {
|
||||
|
||||
@Override
|
||||
public void postInterest(final MathContext mc, final LocalDate postingDate, boolean isInterestTransfer,
|
||||
final boolean isSavingsInterestPostingAtCurrentPeriodEnd, final Integer financialYearBeginningMonth) {
|
||||
final boolean isSavingsInterestPostingAtCurrentPeriodEnd, final Integer financialYearBeginningMonth,
|
||||
final boolean postAsInterestOn) {
|
||||
final boolean postInterestAsOn=false;
|
||||
final LocalDate interestPostingUpToDate = interestPostingUpToDate(postingDate);
|
||||
super.postInterest(mc, interestPostingUpToDate, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
|
||||
financialYearBeginningMonth);
|
||||
financialYearBeginningMonth, postInterestAsOn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<PostingPeriod> calculateInterestUsing(final MathContext mc, final LocalDate postingDate, boolean isInterestTransfer,
|
||||
final boolean isSavingsInterestPostingAtCurrentPeriodEnd, final Integer financialYearBeginningMonth) {
|
||||
final boolean isSavingsInterestPostingAtCurrentPeriodEnd, final Integer financialYearBeginningMonth,
|
||||
final boolean postAsInterestOn) {
|
||||
final LocalDate interestPostingUpToDate = interestPostingUpToDate(postingDate);
|
||||
return super.calculateInterestUsing(mc, interestPostingUpToDate, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
|
||||
financialYearBeginningMonth);
|
||||
financialYearBeginningMonth, postAsInterestOn);
|
||||
}
|
||||
|
||||
private LocalDate interestPostingUpToDate(final LocalDate interestPostingDate) {
|
||||
|
||||
+19
-12
@@ -331,9 +331,9 @@ public class RecurringDepositAccount extends SavingsAccount {
|
||||
|
||||
final SavingsInterestCalculationDaysInYearType daysInYearType = SavingsInterestCalculationDaysInYearType
|
||||
.fromInt(this.interestCalculationDaysInYearType);
|
||||
|
||||
List<LocalDate> PostedAsOnDates = getManualPostingDates();
|
||||
final List<LocalDateInterval> postingPeriodIntervals = this.savingsHelper.determineInterestPostingPeriods(depositStartDate(),
|
||||
maturityDate, postingPeriodType, financialYearBeginningMonth);
|
||||
maturityDate, postingPeriodType, financialYearBeginningMonth, PostedAsOnDates);
|
||||
|
||||
final List<PostingPeriod> allPostingPeriods = new ArrayList<>();
|
||||
|
||||
@@ -345,10 +345,14 @@ public class RecurringDepositAccount extends SavingsAccount {
|
||||
boolean isInterestTransfer = false;
|
||||
final Money minBalanceForInterestCalculation = Money.of(getCurrency(), minBalanceForInterestCalculation());
|
||||
for (final LocalDateInterval periodInterval : postingPeriodIntervals) {
|
||||
boolean isUserPosting = false;
|
||||
if (PostedAsOnDates.contains(periodInterval.endDate())) {
|
||||
isUserPosting = true;
|
||||
}
|
||||
final PostingPeriod postingPeriod = PostingPeriod.createFrom(periodInterval, periodStartingBalance, transactions,
|
||||
this.currency, compoundingPeriodType, interestCalculationType, interestRateAsFraction, daysInYearType.getValue(),
|
||||
maturityDate, interestPostTransactions, isInterestTransfer, minBalanceForInterestCalculation,
|
||||
isSavingsInterestPostingAtCurrentPeriodEnd);
|
||||
isSavingsInterestPostingAtCurrentPeriodEnd, isUserPosting);
|
||||
|
||||
periodStartingBalance = postingPeriod.closingBalance();
|
||||
|
||||
@@ -369,9 +373,10 @@ public class RecurringDepositAccount extends SavingsAccount {
|
||||
if (generateFutureTransactions) {
|
||||
for (RecurringDepositScheduleInstallment installment : depositScheduleInstallments()) {
|
||||
if (installment.isPrincipalNotCompleted(getCurrency())) {
|
||||
boolean postInterestAsOn = false;
|
||||
final SavingsAccountTransaction transaction = SavingsAccountTransaction.deposit(null, office(), null,
|
||||
installment.dueDate(), installment.getDepositAmountOutstanding(getCurrency()), installment.dueDate().toDate(),
|
||||
null);
|
||||
null, postInterestAsOn);
|
||||
allTransactions.add(transaction);
|
||||
}
|
||||
}
|
||||
@@ -598,8 +603,9 @@ public class RecurringDepositAccount extends SavingsAccount {
|
||||
}
|
||||
final MathContext mc = MathContext.DECIMAL64;
|
||||
boolean isInterestTransfer = false;
|
||||
boolean postInterestAsOn =false;
|
||||
final List<PostingPeriod> postingPeriods = calculateInterestUsing(mc, interestPostingUpToDate.minusDays(1), isInterestTransfer,
|
||||
isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth);
|
||||
isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth, postInterestAsOn);
|
||||
|
||||
Money interestPostedToDate = Money.zero(this.currency);
|
||||
|
||||
@@ -617,7 +623,7 @@ public class RecurringDepositAccount extends SavingsAccount {
|
||||
final SavingsAccountTransaction postingTransaction = findInterestPostingTransactionFor(interestPostingTransactionDate);
|
||||
if (postingTransaction == null) {
|
||||
final SavingsAccountTransaction newPostingTransaction = SavingsAccountTransaction.interestPosting(this, office(),
|
||||
interestPostingTransactionDate, interestEarnedToBePostedForPeriod);
|
||||
interestPostingTransactionDate, interestEarnedToBePostedForPeriod, postInterestAsOn);
|
||||
addTransaction(newPostingTransaction);
|
||||
recalucateDailyBalanceDetails = true;
|
||||
} else {
|
||||
@@ -625,7 +631,7 @@ public class RecurringDepositAccount extends SavingsAccount {
|
||||
if (correctionRequired) {
|
||||
postingTransaction.reverse();
|
||||
final SavingsAccountTransaction newPostingTransaction = SavingsAccountTransaction.interestPosting(this, office(),
|
||||
interestPostingTransactionDate, interestEarnedToBePostedForPeriod);
|
||||
interestPostingTransactionDate, interestEarnedToBePostedForPeriod, postInterestAsOn);
|
||||
addTransaction(newPostingTransaction);
|
||||
recalucateDailyBalanceDetails = true;
|
||||
}
|
||||
@@ -656,8 +662,9 @@ public class RecurringDepositAccount extends SavingsAccount {
|
||||
// post remaining interest
|
||||
final Money remainigInterestToBePosted = interestOnMaturity.minus(interestPostedToDate);
|
||||
if (!remainigInterestToBePosted.isZero()) {
|
||||
final boolean postInterestAsOn = false;
|
||||
final SavingsAccountTransaction newPostingTransaction = SavingsAccountTransaction.interestPosting(this, office(),
|
||||
accountCloseDate, remainigInterestToBePosted);
|
||||
accountCloseDate, remainigInterestToBePosted, postInterestAsOn);
|
||||
addTransaction(newPostingTransaction);
|
||||
recalucateDailyBalance = true;
|
||||
}
|
||||
@@ -707,18 +714,18 @@ public class RecurringDepositAccount extends SavingsAccount {
|
||||
|
||||
@Override
|
||||
public void postInterest(final MathContext mc, final LocalDate postingDate, final boolean isInterestTransfer,
|
||||
final boolean isSavingsInterestPostingAtCurrentPeriodEnd, final Integer financialYearBeginningMonth) {
|
||||
final boolean isSavingsInterestPostingAtCurrentPeriodEnd, final Integer financialYearBeginningMonth,final boolean postInterestAson) {
|
||||
final LocalDate interestPostingUpToDate = interestPostingUpToDate(postingDate);
|
||||
super.postInterest(mc, interestPostingUpToDate, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
|
||||
financialYearBeginningMonth);
|
||||
financialYearBeginningMonth, postInterestAson);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<PostingPeriod> calculateInterestUsing(final MathContext mc, final LocalDate postingDate, boolean isInterestTransfer,
|
||||
final boolean isSavingsInterestPostingAtCurrentPeriodEnd, final Integer financialYearBeginningMonth) {
|
||||
final boolean isSavingsInterestPostingAtCurrentPeriodEnd, final Integer financialYearBeginningMonth,final boolean postAsInterestOn) {
|
||||
final LocalDate interestPostingUpToDate = interestPostingUpToDate(postingDate);
|
||||
return super.calculateInterestUsing(mc, interestPostingUpToDate, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
|
||||
financialYearBeginningMonth);
|
||||
financialYearBeginningMonth, postAsInterestOn);
|
||||
}
|
||||
|
||||
private LocalDate interestPostingUpToDate(final LocalDate interestPostingDate) {
|
||||
|
||||
+44
-22
@@ -235,6 +235,7 @@ public class SavingsAccount extends AbstractPersistableCustom<Long> {
|
||||
@Column(name = "interest_calculation_type_enum", nullable = false)
|
||||
protected Integer interestCalculationType;
|
||||
|
||||
|
||||
/**
|
||||
* A value from the {@link SavingsInterestCalculationDaysInYearType}
|
||||
* enumeration.
|
||||
@@ -462,13 +463,10 @@ public class SavingsAccount extends AbstractPersistableCustom<Long> {
|
||||
public boolean isClosed() {
|
||||
return SavingsAccountStatusType.fromInt(this.status).isClosed();
|
||||
}
|
||||
|
||||
public void postInterest(final MathContext mc, final LocalDate interestPostingUpToDate, final boolean isInterestTransfer,
|
||||
final boolean isSavingsInterestPostingAtCurrentPeriodEnd, final Integer financialYearBeginningMonth) {
|
||||
|
||||
final boolean isSavingsInterestPostingAtCurrentPeriodEnd, final Integer financialYearBeginningMonth,final boolean postInterestAsOn) {
|
||||
final List<PostingPeriod> postingPeriods = calculateInterestUsing(mc, interestPostingUpToDate, isInterestTransfer,
|
||||
isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth);
|
||||
|
||||
isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth, postInterestAsOn);
|
||||
Money interestPostedToDate = Money.zero(this.currency);
|
||||
|
||||
boolean recalucateDailyBalanceDetails = false;
|
||||
@@ -477,23 +475,23 @@ public class SavingsAccount extends AbstractPersistableCustom<Long> {
|
||||
withholdTransactions.addAll(findWithHoldTransactions());
|
||||
|
||||
for (final PostingPeriod interestPostingPeriod : postingPeriods) {
|
||||
|
||||
|
||||
final LocalDate interestPostingTransactionDate = interestPostingPeriod.dateOfPostingTransaction();
|
||||
final Money interestEarnedToBePostedForPeriod = interestPostingPeriod.getInterestEarned();
|
||||
|
||||
|
||||
if (!interestPostingTransactionDate.isAfter(interestPostingUpToDate)) {
|
||||
|
||||
interestPostedToDate = interestPostedToDate.plus(interestEarnedToBePostedForPeriod);
|
||||
|
||||
final SavingsAccountTransaction postingTransaction = findInterestPostingTransactionFor(interestPostingTransactionDate);
|
||||
if (postingTransaction == null) {
|
||||
SavingsAccountTransaction newPostingTransaction;
|
||||
if (interestEarnedToBePostedForPeriod.isGreaterThanOrEqualTo(Money.zero(currency))) {
|
||||
|
||||
newPostingTransaction = SavingsAccountTransaction.interestPosting(this, office(), interestPostingTransactionDate,
|
||||
interestEarnedToBePostedForPeriod);
|
||||
interestEarnedToBePostedForPeriod, interestPostingPeriod.isUserPosting());
|
||||
} else {
|
||||
newPostingTransaction = SavingsAccountTransaction.overdraftInterest(this, office(), interestPostingTransactionDate,
|
||||
interestEarnedToBePostedForPeriod.negated());
|
||||
interestEarnedToBePostedForPeriod.negated(), interestPostingPeriod.isUserPosting());
|
||||
}
|
||||
addTransaction(newPostingTransaction);
|
||||
if (applyWithHoldTax) {
|
||||
@@ -519,10 +517,12 @@ public class SavingsAccount extends AbstractPersistableCustom<Long> {
|
||||
SavingsAccountTransaction newPostingTransaction;
|
||||
if (interestEarnedToBePostedForPeriod.isGreaterThanOrEqualTo(Money.zero(currency))) {
|
||||
newPostingTransaction = SavingsAccountTransaction.interestPosting(this, office(),
|
||||
interestPostingTransactionDate, interestEarnedToBePostedForPeriod);
|
||||
interestPostingTransactionDate, interestEarnedToBePostedForPeriod,
|
||||
interestPostingPeriod.isUserPosting());
|
||||
} else {
|
||||
newPostingTransaction = SavingsAccountTransaction.overdraftInterest(this, office(),
|
||||
interestPostingTransactionDate, interestEarnedToBePostedForPeriod.negated());
|
||||
interestPostingTransactionDate, interestEarnedToBePostedForPeriod.negated(),
|
||||
interestPostingPeriod.isUserPosting());
|
||||
}
|
||||
addTransaction(newPostingTransaction);
|
||||
if (applyWithHoldTaxForOldTransaction) {
|
||||
@@ -641,6 +641,16 @@ public class SavingsAccount extends AbstractPersistableCustom<Long> {
|
||||
return savingsTransaction;
|
||||
}
|
||||
|
||||
public List<LocalDate> getManualPostingDates() {
|
||||
List<LocalDate> transactions = new ArrayList<>();
|
||||
for (SavingsAccountTransaction trans : this.transactions) {
|
||||
if (trans.isManualTransaction()) {
|
||||
transactions.add(trans.getTransactionLocalDate());
|
||||
}
|
||||
}
|
||||
return transactions;
|
||||
}
|
||||
|
||||
/**
|
||||
* All interest calculation based on END-OF-DAY-BALANCE.
|
||||
*
|
||||
@@ -657,9 +667,10 @@ public class SavingsAccount extends AbstractPersistableCustom<Long> {
|
||||
*
|
||||
* @param isInterestTransfer
|
||||
* TODO
|
||||
*/
|
||||
*/
|
||||
|
||||
public List<PostingPeriod> calculateInterestUsing(final MathContext mc, final LocalDate upToInterestCalculationDate,
|
||||
boolean isInterestTransfer, final boolean isSavingsInterestPostingAtCurrentPeriodEnd, final Integer financialYearBeginningMonth) {
|
||||
boolean isInterestTransfer, final boolean isSavingsInterestPostingAtCurrentPeriodEnd, final Integer financialYearBeginningMonth,final boolean postInterestAsOn) {
|
||||
|
||||
// no openingBalance concept supported yet but probably will to allow
|
||||
// for migrations.
|
||||
@@ -680,10 +691,14 @@ public class SavingsAccount extends AbstractPersistableCustom<Long> {
|
||||
.fromInt(this.interestCompoundingPeriodType);
|
||||
|
||||
final SavingsInterestCalculationDaysInYearType daysInYearType = SavingsInterestCalculationDaysInYearType
|
||||
.fromInt(this.interestCalculationDaysInYearType);
|
||||
|
||||
.fromInt(this.interestCalculationDaysInYearType);
|
||||
List<LocalDate> postedAsOnDates= getManualPostingDates();
|
||||
if(postInterestAsOn){
|
||||
postedAsOnDates.add(upToInterestCalculationDate);
|
||||
}
|
||||
final List<LocalDateInterval> postingPeriodIntervals = this.savingsHelper.determineInterestPostingPeriods(
|
||||
getStartInterestCalculationDate(), upToInterestCalculationDate, postingPeriodType, financialYearBeginningMonth);
|
||||
getStartInterestCalculationDate(), upToInterestCalculationDate, postingPeriodType, financialYearBeginningMonth,
|
||||
postedAsOnDates);
|
||||
|
||||
final List<PostingPeriod> allPostingPeriods = new ArrayList<>();
|
||||
|
||||
@@ -719,12 +734,17 @@ public class SavingsAccount extends AbstractPersistableCustom<Long> {
|
||||
final Money minOverdraftForInterestCalculation = Money.of(getCurrency(), this.minOverdraftForInterestCalculation);
|
||||
|
||||
for (final LocalDateInterval periodInterval : postingPeriodIntervals) {
|
||||
|
||||
boolean isUserPosting = false;
|
||||
if(postedAsOnDates.contains(periodInterval.endDate().plusDays(1))){
|
||||
isUserPosting = true;
|
||||
}
|
||||
|
||||
final PostingPeriod postingPeriod = PostingPeriod.createFrom(periodInterval, periodStartingBalance,
|
||||
retreiveOrderedNonInterestPostingTransactions(), this.currency, compoundingPeriodType, interestCalculationType,
|
||||
interestRateAsFraction, daysInYearType.getValue(), upToInterestCalculationDate, interestPostTransactions,
|
||||
isInterestTransfer, minBalanceForInterestCalculation, isSavingsInterestPostingAtCurrentPeriodEnd,
|
||||
overdraftInterestRateAsFraction, minOverdraftForInterestCalculation);
|
||||
overdraftInterestRateAsFraction, minOverdraftForInterestCalculation, isUserPosting);
|
||||
|
||||
periodStartingBalance = postingPeriod.closingBalance();
|
||||
|
||||
@@ -2133,13 +2153,15 @@ public class SavingsAccount extends AbstractPersistableCustom<Long> {
|
||||
if (isSavingsChargeApplied) {
|
||||
final MathContext mc = MathContext.DECIMAL64;
|
||||
boolean isInterestTransfer = false;
|
||||
boolean postInterestAsOnDate = false;
|
||||
if (this.isBeforeLastPostingPeriod(getActivationLocalDate())) {
|
||||
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
||||
this.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth);
|
||||
this.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth,
|
||||
postInterestAsOnDate);
|
||||
} else {
|
||||
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
||||
this.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
|
||||
financialYearBeginningMonth);
|
||||
financialYearBeginningMonth, postInterestAsOnDate);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2781,10 +2803,10 @@ public class SavingsAccount extends AbstractPersistableCustom<Long> {
|
||||
this.sub_status = SavingsAccountSubStatusEnum.ESCHEAT.getValue();
|
||||
this.closedOnDate = DateUtils.getDateOfTenant();
|
||||
this.closedBy = appUser;
|
||||
|
||||
boolean postInterestAsOnDate = false;
|
||||
LocalDate transactionDate = DateUtils.getLocalDateOfTenant();
|
||||
if(this.getSummary().getAccountBalance(this.getCurrency()).isGreaterThanZero()){
|
||||
SavingsAccountTransaction transaction = SavingsAccountTransaction.escheat(this, transactionDate, appUser);
|
||||
SavingsAccountTransaction transaction = SavingsAccountTransaction.escheat(this, transactionDate, appUser, postInterestAsOnDate);
|
||||
this.transactions.add(transaction);
|
||||
}
|
||||
recalculateDailyBalances(Money.zero(this.currency), transactionDate);
|
||||
|
||||
+7
-5
@@ -86,6 +86,7 @@ public class SavingsAccountDomainServiceJpa implements SavingsAccountDomainServi
|
||||
if (transactionBooleanValues.isRegularTransaction() && !account.allowWithdrawal()) { throw new DepositAccountTransactionNotAllowedException(
|
||||
account.getId(), "withdraw", account.depositAccountType()); }
|
||||
final Set<Long> existingTransactionIds = new HashSet<>();
|
||||
final boolean interestPostAsOn = false;
|
||||
final Set<Long> existingReversedTransactionIds = new HashSet<>();
|
||||
updateExistingTransactionsDetails(account, existingTransactionIds, existingReversedTransactionIds);
|
||||
final SavingsAccountTransactionDTO transactionDTO = new SavingsAccountTransactionDTO(fmt, transactionDate, transactionAmount,
|
||||
@@ -96,11 +97,11 @@ public class SavingsAccountDomainServiceJpa implements SavingsAccountDomainServi
|
||||
if (account.isBeforeLastPostingPeriod(transactionDate)) {
|
||||
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
||||
account.postInterest(mc, today, transactionBooleanValues.isInterestTransfer(), isSavingsInterestPostingAtCurrentPeriodEnd,
|
||||
financialYearBeginningMonth);
|
||||
financialYearBeginningMonth, interestPostAsOn);
|
||||
} else {
|
||||
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
||||
account.calculateInterestUsing(mc, today, transactionBooleanValues.isInterestTransfer(),
|
||||
isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth);
|
||||
isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth, interestPostAsOn);
|
||||
}
|
||||
List<DepositAccountOnHoldTransaction> depositAccountOnHoldTransactions = null;
|
||||
if (account.getOnHoldFunds().compareTo(BigDecimal.ZERO) == 1) {
|
||||
@@ -154,15 +155,16 @@ public class SavingsAccountDomainServiceJpa implements SavingsAccountDomainServi
|
||||
final SavingsAccountTransactionDTO transactionDTO = new SavingsAccountTransactionDTO(fmt, transactionDate, transactionAmount,
|
||||
paymentDetail, new Date(), user);
|
||||
final SavingsAccountTransaction deposit = account.deposit(transactionDTO, savingsAccountTransactionType);
|
||||
|
||||
final boolean interestPostAsOn = false;
|
||||
final MathContext mc = MathContext.DECIMAL64;
|
||||
if (account.isBeforeLastPostingPeriod(transactionDate)) {
|
||||
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
||||
account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth);
|
||||
account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth,
|
||||
interestPostAsOn);
|
||||
} else {
|
||||
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
||||
account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
|
||||
financialYearBeginningMonth);
|
||||
financialYearBeginningMonth, interestPostAsOn);
|
||||
}
|
||||
|
||||
saveTransactionToGenerateTransactionId(deposit);
|
||||
|
||||
+67
-25
@@ -114,6 +114,9 @@ public final class SavingsAccountTransaction extends AbstractPersistableCustom<L
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "appuser_id", nullable = true)
|
||||
private AppUser appUser;
|
||||
|
||||
@Column(name = "is_manual", length = 1, nullable = true)
|
||||
private boolean isManualTransaction;
|
||||
|
||||
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch=FetchType.EAGER)
|
||||
@JoinColumn(name = "savings_transaction_id", referencedColumnName = "id", nullable = false)
|
||||
@@ -126,112 +129,123 @@ public final class SavingsAccountTransaction extends AbstractPersistableCustom<L
|
||||
}
|
||||
|
||||
public static SavingsAccountTransaction deposit(final SavingsAccount savingsAccount, final Office office,
|
||||
final PaymentDetail paymentDetail, final LocalDate date, final Money amount, Date createdDate, final AppUser appUser) {
|
||||
final PaymentDetail paymentDetail, final LocalDate date, final Money amount, Date createdDate, final AppUser appUser,
|
||||
final boolean isManualTransaction) {
|
||||
final boolean isReversed = false;
|
||||
return new SavingsAccountTransaction(savingsAccount, office, paymentDetail, SavingsAccountTransactionType.DEPOSIT.getValue(), date,
|
||||
createdDate, amount, isReversed, appUser);
|
||||
createdDate, amount, isReversed, appUser, isManualTransaction);
|
||||
}
|
||||
|
||||
public static SavingsAccountTransaction deposit(final SavingsAccount savingsAccount, final Office office,
|
||||
final PaymentDetail paymentDetail, final LocalDate date, final Money amount, Date createdDate, final AppUser appUser,
|
||||
final SavingsAccountTransactionType savingsAccountTransactionType) {
|
||||
final boolean isReversed = false;
|
||||
final boolean isManualTransaction = false;
|
||||
return new SavingsAccountTransaction(savingsAccount, office, paymentDetail, savingsAccountTransactionType.getValue(), date,
|
||||
createdDate, amount, isReversed, appUser);
|
||||
createdDate, amount, isReversed, appUser,isManualTransaction);
|
||||
}
|
||||
|
||||
public static SavingsAccountTransaction withdrawal(final SavingsAccount savingsAccount, final Office office,
|
||||
final PaymentDetail paymentDetail, final LocalDate date, final Money amount, Date createdDate, final AppUser appUser) {
|
||||
final boolean isReversed = false;
|
||||
final boolean isManualTransaction = false;
|
||||
return new SavingsAccountTransaction(savingsAccount, office, paymentDetail, SavingsAccountTransactionType.WITHDRAWAL.getValue(),
|
||||
date, createdDate, amount, isReversed, appUser);
|
||||
date, createdDate, amount, isReversed, appUser, isManualTransaction);
|
||||
}
|
||||
|
||||
public static SavingsAccountTransaction interestPosting(final SavingsAccount savingsAccount, final Office office, final LocalDate date,
|
||||
final Money amount) {
|
||||
final Money amount,final boolean isManualTransaction) {
|
||||
final boolean isReversed = false;
|
||||
return new SavingsAccountTransaction(savingsAccount, office, SavingsAccountTransactionType.INTEREST_POSTING.getValue(), date,
|
||||
amount, isReversed, null);
|
||||
amount, isReversed, null, isManualTransaction);
|
||||
}
|
||||
|
||||
public static SavingsAccountTransaction overdraftInterest(final SavingsAccount savingsAccount, final Office office,
|
||||
final LocalDate date, final Money amount) {
|
||||
final LocalDate date, final Money amount,final boolean isManualTransaction) {
|
||||
final boolean isReversed = false;
|
||||
return new SavingsAccountTransaction(savingsAccount, office, SavingsAccountTransactionType.OVERDRAFT_INTEREST.getValue(), date,
|
||||
amount, isReversed, null);
|
||||
amount, isReversed, null, isManualTransaction);
|
||||
}
|
||||
|
||||
public static SavingsAccountTransaction withdrawalFee(final SavingsAccount savingsAccount, final Office office, final LocalDate date,
|
||||
final Money amount, final AppUser appUser) {
|
||||
final boolean isReversed = false;
|
||||
final boolean isManualTransaction = false;
|
||||
return new SavingsAccountTransaction(savingsAccount, office, SavingsAccountTransactionType.WITHDRAWAL_FEE.getValue(), date, amount,
|
||||
isReversed, appUser);
|
||||
isReversed, appUser, isManualTransaction);
|
||||
}
|
||||
|
||||
public static SavingsAccountTransaction annualFee(final SavingsAccount savingsAccount, final Office office, final LocalDate date,
|
||||
final Money amount, final AppUser appUser) {
|
||||
final boolean isReversed = false;
|
||||
final boolean isManualTransaction = false;
|
||||
return new SavingsAccountTransaction(savingsAccount, office, SavingsAccountTransactionType.ANNUAL_FEE.getValue(), date, amount,
|
||||
isReversed, appUser);
|
||||
isReversed, appUser, isManualTransaction);
|
||||
}
|
||||
|
||||
public static SavingsAccountTransaction charge(final SavingsAccount savingsAccount, final Office office, final LocalDate date,
|
||||
final Money amount, final AppUser appUser) {
|
||||
final boolean isReversed = false;
|
||||
final boolean isManualTransaction = false;
|
||||
return new SavingsAccountTransaction(savingsAccount, office, SavingsAccountTransactionType.PAY_CHARGE.getValue(), date, amount,
|
||||
isReversed, appUser);
|
||||
isReversed, appUser, isManualTransaction);
|
||||
}
|
||||
|
||||
public static SavingsAccountTransaction waiver(final SavingsAccount savingsAccount, final Office office, final LocalDate date,
|
||||
final Money amount, final AppUser appUser) {
|
||||
final boolean isReversed = false;
|
||||
final boolean isManualTransaction = false;
|
||||
return new SavingsAccountTransaction(savingsAccount, office, SavingsAccountTransactionType.WAIVE_CHARGES.getValue(), date, amount,
|
||||
isReversed, appUser);
|
||||
isReversed, appUser, isManualTransaction);
|
||||
}
|
||||
|
||||
public static SavingsAccountTransaction initiateTransfer(final SavingsAccount savingsAccount, final Office office,
|
||||
final LocalDate date, final AppUser appUser) {
|
||||
final boolean isReversed = false;
|
||||
final boolean isManualTransaction = false;
|
||||
final PaymentDetail paymentDetail = null;
|
||||
return new SavingsAccountTransaction(savingsAccount, office, paymentDetail,
|
||||
SavingsAccountTransactionType.INITIATE_TRANSFER.getValue(), date, new Date(), savingsAccount.getSummary()
|
||||
.getAccountBalance(), isReversed, appUser);
|
||||
.getAccountBalance(), isReversed, appUser, isManualTransaction);
|
||||
}
|
||||
|
||||
public static SavingsAccountTransaction approveTransfer(final SavingsAccount savingsAccount, final Office office, final LocalDate date,
|
||||
final AppUser appUser) {
|
||||
final boolean isReversed = false;
|
||||
final boolean isManualTransaction = false;
|
||||
final PaymentDetail paymentDetail = null;
|
||||
return new SavingsAccountTransaction(savingsAccount, office, paymentDetail,
|
||||
SavingsAccountTransactionType.APPROVE_TRANSFER.getValue(), date, new Date(), savingsAccount.getSummary()
|
||||
.getAccountBalance(), isReversed, appUser);
|
||||
.getAccountBalance(), isReversed, appUser, isManualTransaction);
|
||||
}
|
||||
|
||||
public static SavingsAccountTransaction withdrawTransfer(final SavingsAccount savingsAccount, final Office office,
|
||||
final LocalDate date, final AppUser appUser) {
|
||||
final boolean isReversed = false;
|
||||
final boolean isManualTransaction = false;
|
||||
final PaymentDetail paymentDetail = null;
|
||||
return new SavingsAccountTransaction(savingsAccount, office, paymentDetail,
|
||||
SavingsAccountTransactionType.WITHDRAW_TRANSFER.getValue(), date, new Date(), savingsAccount.getSummary()
|
||||
.getAccountBalance(), isReversed, appUser);
|
||||
.getAccountBalance(), isReversed, appUser, isManualTransaction);
|
||||
}
|
||||
|
||||
public static SavingsAccountTransaction withHoldTax(final SavingsAccount savingsAccount, final Office office, final LocalDate date,
|
||||
final Money amount, final Map<TaxComponent, BigDecimal> taxDetails) {
|
||||
final boolean isReversed = false;
|
||||
final boolean isManualTransaction = false;
|
||||
SavingsAccountTransaction accountTransaction = new SavingsAccountTransaction(savingsAccount, office,
|
||||
SavingsAccountTransactionType.WITHHOLD_TAX.getValue(), date, amount, isReversed, null);
|
||||
SavingsAccountTransactionType.WITHHOLD_TAX.getValue(), date, amount, isReversed, null, isManualTransaction);
|
||||
updateTaxDetails(taxDetails, accountTransaction);
|
||||
return accountTransaction;
|
||||
}
|
||||
|
||||
public static SavingsAccountTransaction escheat(final SavingsAccount savingsAccount, final LocalDate date,
|
||||
final AppUser appUser) {
|
||||
final AppUser appUser,final boolean accountTransaction) {
|
||||
final boolean isReversed = false;
|
||||
final PaymentDetail paymentDetail = null;
|
||||
return new SavingsAccountTransaction(savingsAccount, savingsAccount.office(), paymentDetail,
|
||||
SavingsAccountTransactionType.ESCHEAT.getValue(), date, new Date(), savingsAccount.getSummary()
|
||||
.getAccountBalance(), isReversed, appUser);
|
||||
.getAccountBalance(), isReversed, appUser,accountTransaction);
|
||||
}
|
||||
|
||||
public static void updateTaxDetails(final Map<TaxComponent, BigDecimal> taxDetails, final SavingsAccountTransaction accountTransaction) {
|
||||
@@ -245,23 +259,25 @@ public final class SavingsAccountTransaction extends AbstractPersistableCustom<L
|
||||
public static SavingsAccountTransaction copyTransaction(SavingsAccountTransaction accountTransaction) {
|
||||
return new SavingsAccountTransaction(accountTransaction.savingsAccount, accountTransaction.office,
|
||||
accountTransaction.paymentDetail, accountTransaction.typeOf, accountTransaction.transactionLocalDate(),
|
||||
accountTransaction.createdDate, accountTransaction.amount, accountTransaction.reversed, accountTransaction.appUser);
|
||||
accountTransaction.createdDate, accountTransaction.amount, accountTransaction.reversed, accountTransaction.appUser,
|
||||
accountTransaction.isManualTransaction);
|
||||
}
|
||||
|
||||
private SavingsAccountTransaction(final SavingsAccount savingsAccount, final Office office, final Integer typeOf,
|
||||
final LocalDate transactionLocalDate, final Money amount, final boolean isReversed, final AppUser appUser) {
|
||||
this(savingsAccount, office, null, typeOf, transactionLocalDate, new Date(), amount, isReversed, appUser);
|
||||
final LocalDate transactionLocalDate, final Money amount, final boolean isReversed, final AppUser appUser,final boolean isManualTransaction) {
|
||||
this(savingsAccount, office, null, typeOf, transactionLocalDate, new Date(), amount, isReversed, appUser, isManualTransaction);
|
||||
}
|
||||
|
||||
private SavingsAccountTransaction(final SavingsAccount savingsAccount, final Office office, final PaymentDetail paymentDetail,
|
||||
final Integer typeOf, final LocalDate transactionLocalDate, final Date createdDate, final Money amount,
|
||||
final boolean isReversed, final AppUser appUser) {
|
||||
this(savingsAccount, office, paymentDetail, typeOf, transactionLocalDate, createdDate, amount.getAmount(), isReversed, appUser);
|
||||
final boolean isReversed, final AppUser appUser, final boolean isManualTransaction) {
|
||||
this(savingsAccount, office, paymentDetail, typeOf, transactionLocalDate, createdDate, amount.getAmount(), isReversed, appUser,
|
||||
isManualTransaction);
|
||||
}
|
||||
|
||||
private SavingsAccountTransaction(final SavingsAccount savingsAccount, final Office office, final PaymentDetail paymentDetail,
|
||||
final Integer typeOf, final LocalDate transactionLocalDate, final Date createdDate, final BigDecimal amount,
|
||||
final boolean isReversed, final AppUser appUser) {
|
||||
final boolean isReversed, final AppUser appUser, final boolean isManualTransaction) {
|
||||
this.savingsAccount = savingsAccount;
|
||||
this.office = office;
|
||||
this.typeOf = typeOf;
|
||||
@@ -271,6 +287,7 @@ public final class SavingsAccountTransaction extends AbstractPersistableCustom<L
|
||||
this.paymentDetail = paymentDetail;
|
||||
this.createdDate = createdDate;
|
||||
this.appUser = appUser;
|
||||
this.isManualTransaction = isManualTransaction;
|
||||
}
|
||||
|
||||
public LocalDate transactionLocalDate() {
|
||||
@@ -389,7 +406,7 @@ public final class SavingsAccountTransaction extends AbstractPersistableCustom<L
|
||||
this.cumulativeBalance = Money.of(currency, this.runningBalance).multipliedBy(this.balanceNumberOfDays).getAmount();
|
||||
}
|
||||
|
||||
private LocalDate getTransactionLocalDate() {
|
||||
public LocalDate getTransactionLocalDate() {
|
||||
return new LocalDate(this.dateOf);
|
||||
}
|
||||
|
||||
@@ -470,6 +487,14 @@ public final class SavingsAccountTransaction extends AbstractPersistableCustom<L
|
||||
public boolean isAfter(final LocalDate transactionDate) {
|
||||
return getTransactionLocalDate().isAfter(transactionDate);
|
||||
}
|
||||
|
||||
public boolean isManualTransaction() {
|
||||
return this.isManualTransaction;
|
||||
}
|
||||
|
||||
public void setPostInterestAsOn(boolean isManualTransaction) {
|
||||
this.isManualTransaction = isManualTransaction;
|
||||
}
|
||||
|
||||
public EndOfDayBalance toEndOfDayBalance(final LocalDateInterval periodInterval, final MonetaryCurrency currency) {
|
||||
|
||||
@@ -704,5 +729,22 @@ public final class SavingsAccountTransaction extends AbstractPersistableCustom<L
|
||||
public void updateAmount(final Money amount) {
|
||||
this.amount = amount.getAmount();
|
||||
}
|
||||
|
||||
public Integer getTypeOf() {
|
||||
return this.typeOf;
|
||||
}
|
||||
|
||||
public SavingsAccount getSavingsAccount() {
|
||||
return this.savingsAccount;
|
||||
}
|
||||
|
||||
|
||||
public void setSavingsAccount(SavingsAccount savingsAccount) {
|
||||
this.savingsAccount = savingsAccount;
|
||||
}
|
||||
|
||||
public Date getDateOf() {
|
||||
return this.dateOf;
|
||||
}
|
||||
|
||||
}
|
||||
+31
-15
@@ -33,9 +33,9 @@ import org.apache.fineract.portfolio.savings.domain.interest.PostingPeriod;
|
||||
import org.joda.time.LocalDate;
|
||||
|
||||
public final class SavingsHelper {
|
||||
|
||||
|
||||
AccountTransfersReadPlatformService accountTransfersReadPlatformService = null;
|
||||
|
||||
|
||||
public SavingsHelper(AccountTransfersReadPlatformService accountTransfersReadPlatformService) {
|
||||
this.accountTransfersReadPlatformService = accountTransfersReadPlatformService;
|
||||
}
|
||||
@@ -44,30 +44,49 @@ public final class SavingsHelper {
|
||||
|
||||
public List<LocalDateInterval> determineInterestPostingPeriods(final LocalDate startInterestCalculationLocalDate,
|
||||
final LocalDate interestPostingUpToDate, final SavingsPostingInterestPeriodType postingPeriodType,
|
||||
final Integer financialYearBeginningMonth) {
|
||||
final Integer financialYearBeginningMonth,List<LocalDate> postInterestAsOn) {
|
||||
|
||||
final List<LocalDateInterval> postingPeriods = new ArrayList<>();
|
||||
|
||||
LocalDate periodStartDate = startInterestCalculationLocalDate;
|
||||
LocalDate periodEndDate = periodStartDate;
|
||||
|
||||
LocalDate actualPeriodStartDate = periodStartDate;
|
||||
|
||||
while (!periodStartDate.isAfter(interestPostingUpToDate) && !periodEndDate.isAfter(interestPostingUpToDate)) {
|
||||
|
||||
final LocalDate interestPostingLocalDate = determineInterestPostingPeriodEndDateFrom(periodStartDate, postingPeriodType,
|
||||
|
||||
final LocalDate interestPostingLocalDate = determineInterestPostingPeriodEndDateFrom(periodStartDate, postingPeriodType,
|
||||
interestPostingUpToDate, financialYearBeginningMonth);
|
||||
|
||||
periodEndDate = interestPostingLocalDate.minusDays(1);
|
||||
|
||||
|
||||
if (!postInterestAsOn.isEmpty()) {
|
||||
for (LocalDate transactiondate : postInterestAsOn) {
|
||||
if (periodStartDate.isBefore(transactiondate)
|
||||
&& (periodEndDate.isAfter(transactiondate) || periodEndDate
|
||||
.isEqual(transactiondate))) {
|
||||
periodEndDate = transactiondate.minusDays(1);
|
||||
actualPeriodStartDate = periodEndDate;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
postingPeriods.add(LocalDateInterval.create(periodStartDate, periodEndDate));
|
||||
|
||||
|
||||
if (actualPeriodStartDate.isEqual(periodEndDate))
|
||||
{
|
||||
periodEndDate = actualPeriodStartDate.plusDays(1);
|
||||
periodStartDate = actualPeriodStartDate.plusDays(1);
|
||||
}else{
|
||||
periodEndDate = interestPostingLocalDate;
|
||||
periodStartDate = interestPostingLocalDate;
|
||||
}
|
||||
}
|
||||
|
||||
return postingPeriods;
|
||||
}
|
||||
|
||||
private LocalDate determineInterestPostingPeriodEndDateFrom(final LocalDate periodStartDate,
|
||||
final SavingsPostingInterestPeriodType interestPostingPeriodType, final LocalDate interestPostingUpToDate,
|
||||
final SavingsPostingInterestPeriodType interestPostingPeriodType, final LocalDate interestPostingUpToDate,
|
||||
Integer financialYearBeginningMonth) {
|
||||
|
||||
LocalDate periodEndDate = interestPostingUpToDate;
|
||||
@@ -90,7 +109,6 @@ public final class SavingsHelper {
|
||||
biannualDates.add(periodStartDate.withMonthOfYear(financialYearBeginningMonth).plusMonths(6).withYear(periodStartDate.getYear())
|
||||
.dayOfMonth().withMaximumValue());
|
||||
Collections.sort(biannualDates);
|
||||
|
||||
boolean isEndDateSet = false;
|
||||
|
||||
switch (interestPostingPeriodType) {
|
||||
@@ -131,11 +149,9 @@ public final class SavingsHelper {
|
||||
}
|
||||
periodEndDate = periodEndDate.dayOfMonth().withMaximumValue();
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
// interest posting always occurs on next day after the period end date.
|
||||
periodEndDate = periodEndDate.plusDays(1);
|
||||
|
||||
periodEndDate = periodEndDate.plusDays(1);
|
||||
return periodEndDate;
|
||||
}
|
||||
|
||||
|
||||
+15
-5
@@ -54,6 +54,7 @@ public class PostingPeriod {
|
||||
|
||||
// include in compounding interest
|
||||
private boolean interestTransfered = false;
|
||||
private boolean isUserPosting = false;
|
||||
|
||||
// minimum balance for interest calculation
|
||||
private final Money minBalanceForInterestCalculation;
|
||||
@@ -65,7 +66,7 @@ public class PostingPeriod {
|
||||
final SavingsCompoundingInterestPeriodType interestCompoundingPeriodType,
|
||||
final SavingsInterestCalculationType interestCalculationType, final BigDecimal interestRateAsFraction, final long daysInYear,
|
||||
final LocalDate upToInterestCalculationDate, Collection<Long> interestPostTransactions, boolean isInterestTransfer,
|
||||
final Money minBalanceForInterestCalculation, final boolean isSavingsInterestPostingAtCurrentPeriodEnd) {
|
||||
final Money minBalanceForInterestCalculation, final boolean isSavingsInterestPostingAtCurrentPeriodEnd,final boolean isUserPosting) {
|
||||
|
||||
final BigDecimal overdraftInterestRateAsFraction = BigDecimal.ZERO;
|
||||
final Money minOverdraftForInterestCalculation = Money.zero(currency);
|
||||
@@ -74,7 +75,7 @@ public class PostingPeriod {
|
||||
interestCompoundingPeriodType, interestCalculationType, interestRateAsFraction, daysInYear,
|
||||
upToInterestCalculationDate, interestPostTransactions, isInterestTransfer,
|
||||
minBalanceForInterestCalculation, isSavingsInterestPostingAtCurrentPeriodEnd,
|
||||
overdraftInterestRateAsFraction, minOverdraftForInterestCalculation);
|
||||
overdraftInterestRateAsFraction, minOverdraftForInterestCalculation, isUserPosting);
|
||||
}
|
||||
|
||||
// isInterestTransfer boolean is to identify newly created transaction is
|
||||
@@ -85,7 +86,7 @@ public class PostingPeriod {
|
||||
final SavingsInterestCalculationType interestCalculationType, final BigDecimal interestRateAsFraction, final long daysInYear,
|
||||
final LocalDate upToInterestCalculationDate, Collection<Long> interestPostTransactions, boolean isInterestTransfer,
|
||||
final Money minBalanceForInterestCalculation, final boolean isSavingsInterestPostingAtCurrentPeriodEnd,
|
||||
final BigDecimal overdraftInterestRateAsFraction, final Money minOverdraftForInterestCalculation) {
|
||||
final BigDecimal overdraftInterestRateAsFraction, final Money minOverdraftForInterestCalculation, boolean isUserPosting) {
|
||||
|
||||
final List<EndOfDayBalance> accountEndOfDayBalances = new ArrayList<>();
|
||||
boolean interestTransfered = false;
|
||||
@@ -147,7 +148,7 @@ public class PostingPeriod {
|
||||
return new PostingPeriod(periodInterval, currency, periodStartingBalance, openingDayBalance, interestCompoundingPeriodType,
|
||||
interestCalculationType, interestRateAsFraction, daysInYear, compoundingPeriods, interestTransfered,
|
||||
minBalanceForInterestCalculation, isSavingsInterestPostingAtCurrentPeriodEnd,
|
||||
overdraftInterestRateAsFraction, minOverdraftForInterestCalculation);
|
||||
overdraftInterestRateAsFraction, minOverdraftForInterestCalculation, isUserPosting);
|
||||
}
|
||||
|
||||
private PostingPeriod(final LocalDateInterval periodInterval, final MonetaryCurrency currency, final Money openingBalance,
|
||||
@@ -155,7 +156,7 @@ public class PostingPeriod {
|
||||
final SavingsInterestCalculationType interestCalculationType, final BigDecimal interestRateAsFraction, final long daysInYear,
|
||||
final List<CompoundingPeriod> compoundingPeriods, boolean interestTransfered, final Money minBalanceForInterestCalculation,
|
||||
final boolean isSavingsInterestPostingAtCurrentPeriodEnd, final BigDecimal overdraftInterestRateAsFraction,
|
||||
final Money minOverdraftForInterestCalculation) {
|
||||
final Money minOverdraftForInterestCalculation, boolean isUserPosting) {
|
||||
this.periodInterval = periodInterval;
|
||||
this.currency = currency;
|
||||
this.openingBalance = openingBalance;
|
||||
@@ -174,6 +175,7 @@ public class PostingPeriod {
|
||||
this.minBalanceForInterestCalculation = minBalanceForInterestCalculation;
|
||||
this.overdraftInterestRateAsFraction = overdraftInterestRateAsFraction;
|
||||
this.minOverdraftForInterestCalculation = minOverdraftForInterestCalculation;
|
||||
this.isUserPosting = isUserPosting;
|
||||
}
|
||||
|
||||
public Money interest() {
|
||||
@@ -410,4 +412,12 @@ public class PostingPeriod {
|
||||
public boolean isInterestTransfered() {
|
||||
return this.interestTransfered;
|
||||
}
|
||||
|
||||
public LocalDateInterval getPeriodInterval() {
|
||||
return this.periodInterval;
|
||||
}
|
||||
|
||||
public boolean isUserPosting() {
|
||||
return this.isUserPosting;
|
||||
}
|
||||
}
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.portfolio.savings.exception;
|
||||
|
||||
|
||||
import org.apache.fineract.infrastructure.core.exception.AbstractPlatformDomainRuleException;
|
||||
|
||||
|
||||
public class PostInterestAsOnDateException extends AbstractPlatformDomainRuleException{
|
||||
public static enum PostInterestAsOnException_TYPE {
|
||||
FUTURE_DATE, VALID_DATE, ACTIVATION_DATE, LAST_TRANSACTION_DATE;
|
||||
public String errorMessage() {
|
||||
if (name().toString().equalsIgnoreCase("FUTURE_DATE")) {
|
||||
return "Cannot Post Interest in future Dates";
|
||||
} else if (name().toString().equalsIgnoreCase("VALID_DATE")) {
|
||||
return "Please Pass a valid date";
|
||||
} else if (name().toString().equalsIgnoreCase("ACTIVATION_DATE")) {
|
||||
return "Post Interest Date must be after the Activation date";
|
||||
} else if (name().toString().equalsIgnoreCase("LAST_TRANSACTION_DATE")) {
|
||||
return "Cannot Post Interest before last transaction date";
|
||||
}
|
||||
return name().toString();
|
||||
}
|
||||
|
||||
public String errorCode() {
|
||||
if (name().toString().equalsIgnoreCase("FUTURE_DATE")) {
|
||||
return "error.msg.futureDate";
|
||||
} else if (name().toString().equalsIgnoreCase("VALID_DATE")) {
|
||||
return "error.msg.nullDatePassed";
|
||||
} else if (name().toString().equalsIgnoreCase("ACTIVATION_DATE")) {
|
||||
return "error.msg.before activation date";
|
||||
} else if (name().toString().equalsIgnoreCase("LAST_TRANSACTION_DATE")) {
|
||||
return "error.msg.countInterest";
|
||||
}
|
||||
return name().toString();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public PostInterestAsOnDateException(final PostInterestAsOnException_TYPE reason) {
|
||||
super(reason.errorCode(), reason.errorMessage());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.portfolio.savings.exception;
|
||||
|
||||
import org.apache.fineract.infrastructure.core.exception.AbstractPlatformDomainRuleException;
|
||||
|
||||
public class PostInterestClosingDateException extends AbstractPlatformDomainRuleException {
|
||||
|
||||
public PostInterestClosingDateException() {
|
||||
super("error.msg.postInterest.notDone", "Please do a post interest on the closing date");
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -41,6 +41,6 @@ public class PostInterestSavingsAccountCommandHandler implements NewCommandSourc
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult processCommand(final JsonCommand command) {
|
||||
return this.writePlatformService.postInterest(command.getSavingsId());
|
||||
return this.writePlatformService.postInterest(command);
|
||||
}
|
||||
}
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.portfolio.savings.handler;
|
||||
|
||||
import org.apache.fineract.commands.annotation.CommandType;
|
||||
import org.apache.fineract.commands.handler.NewCommandSourceHandler;
|
||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.apache.fineract.portfolio.savings.service.SavingsAccountWritePlatformService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Service
|
||||
@CommandType(entity = "SAVINGSACCOUNT", action = "POSTINTERESTASONDATE")
|
||||
public class PostSavingsAccountInterestAsOnDateCommandHandler implements NewCommandSourceHandler {
|
||||
|
||||
private final SavingsAccountWritePlatformService writePlatformService;
|
||||
|
||||
@Autowired
|
||||
public PostSavingsAccountInterestAsOnDateCommandHandler(final SavingsAccountWritePlatformService writePlatformService) {
|
||||
this.writePlatformService = writePlatformService;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult processCommand(final JsonCommand command) {
|
||||
return this.writePlatformService.postInterest(command);
|
||||
}
|
||||
|
||||
}
|
||||
+4
-4
@@ -1049,9 +1049,9 @@ public class DepositAccountReadPlatformServiceImpl implements DepositAccountRead
|
||||
transfer = AccountTransferData.transferBasicDetails(toTransferId, currency, toTransferAmount, toTransferDate,
|
||||
toTransferDescription, toTransferReversed);
|
||||
}
|
||||
|
||||
final boolean postInterestAsOn = false;
|
||||
return SavingsAccountTransactionData.create(id, transactionType, paymentDetailData, savingsId, accountNo, date, currency,
|
||||
amount, runningBalance, reversed, transfer);
|
||||
amount, runningBalance, reversed, transfer, postInterestAsOn);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1437,9 +1437,9 @@ public class DepositAccountReadPlatformServiceImpl implements DepositAccountRead
|
||||
final PaymentDetailData paymentDetailData = null;
|
||||
final AccountTransferData transfer = null;
|
||||
final BigDecimal runningBalance = JdbcSupport.getBigDecimalDefaultToNullIfZero(rs, "runningBalance");
|
||||
;
|
||||
final boolean postInterestAsOn = false;
|
||||
return SavingsAccountTransactionData.create(savingsId, transactionType, paymentDetailData, savingsId, accountNo, duedate,
|
||||
currency, dueamount, runningBalance, false, transfer);
|
||||
currency, dueamount, runningBalance, false, transfer, postInterestAsOn);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+85
-67
@@ -143,7 +143,6 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
private final WorkingDaysRepositoryWrapper workingDaysRepository;
|
||||
private final DepositAccountOnHoldTransactionRepository depositAccountOnHoldTransactionRepository;
|
||||
|
||||
|
||||
@Autowired
|
||||
public DepositAccountWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context,
|
||||
final SavingsAccountRepositoryWrapper savingAccountRepositoryWrapper,
|
||||
@@ -185,7 +184,7 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
this.depositAccountReadPlatformService = depositAccountReadPlatformService;
|
||||
this.calendarInstanceRepository = calendarInstanceRepository;
|
||||
this.configurationDomainService = configurationDomainService;
|
||||
this.depositAccountOnHoldTransactionRepository =depositAccountOnHoldTransactionRepository;
|
||||
this.depositAccountOnHoldTransactionRepository = depositAccountOnHoldTransactionRepository;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@@ -235,14 +234,15 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
this.accountTransfersWritePlatformService.transferFunds(accountTransferDTO);
|
||||
}
|
||||
final boolean isInterestTransfer = false;
|
||||
final boolean postInterestAsOn = false;
|
||||
if (account.isBeforeLastPostingPeriod(account.getActivationLocalDate())) {
|
||||
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
||||
account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
|
||||
financialYearBeginningMonth);
|
||||
financialYearBeginningMonth, postInterestAsOn);
|
||||
} else {
|
||||
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
||||
account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
|
||||
financialYearBeginningMonth);
|
||||
financialYearBeginningMonth, postInterestAsOn);
|
||||
}
|
||||
|
||||
updateExistingTransactionsDetails(account, existingTransactionIds, existingReversedTransactionIds);
|
||||
@@ -252,10 +252,12 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
account.updateMaturityDateAndAmount(mc, isPreMatureClosure, isSavingsInterestPostingAtCurrentPeriodEnd,
|
||||
financialYearBeginningMonth);
|
||||
List<DepositAccountOnHoldTransaction> depositAccountOnHoldTransactions = null;
|
||||
if(account.getOnHoldFunds().compareTo(BigDecimal.ZERO) == 1){
|
||||
depositAccountOnHoldTransactions = this.depositAccountOnHoldTransactionRepository.findBySavingsAccountAndReversedFalseOrderByCreatedDateAsc(account);
|
||||
if (account.getOnHoldFunds().compareTo(BigDecimal.ZERO) == 1) {
|
||||
depositAccountOnHoldTransactions = this.depositAccountOnHoldTransactionRepository
|
||||
.findBySavingsAccountAndReversedFalseOrderByCreatedDateAsc(account);
|
||||
}
|
||||
account.validateAccountBalanceDoesNotBecomeNegative(SavingsAccountTransactionType.PAY_CHARGE.name(),depositAccountOnHoldTransactions);
|
||||
account.validateAccountBalanceDoesNotBecomeNegative(SavingsAccountTransactionType.PAY_CHARGE.name(),
|
||||
depositAccountOnHoldTransactions);
|
||||
this.savingAccountRepositoryWrapper.saveAndFlush(account);
|
||||
}
|
||||
|
||||
@@ -338,21 +340,24 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
final LocalDate overdueUptoDate = DateUtils.getLocalDateOfTenant();
|
||||
account.updateOverduePayments(overdueUptoDate);
|
||||
final boolean isInterestTransfer = false;
|
||||
final boolean postInterestAsOn = false;
|
||||
if (account.isBeforeLastPostingPeriod(account.getActivationLocalDate())) {
|
||||
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
||||
account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
|
||||
financialYearBeginningMonth);
|
||||
financialYearBeginningMonth, postInterestAsOn);
|
||||
} else {
|
||||
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
||||
account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
|
||||
financialYearBeginningMonth);
|
||||
financialYearBeginningMonth, postInterestAsOn);
|
||||
}
|
||||
List<DepositAccountOnHoldTransaction> depositAccountOnHoldTransactions = null;
|
||||
if(account.getOnHoldFunds().compareTo(BigDecimal.ZERO) == 1){
|
||||
depositAccountOnHoldTransactions = this.depositAccountOnHoldTransactionRepository.findBySavingsAccountAndReversedFalseOrderByCreatedDateAsc(account);
|
||||
if (account.getOnHoldFunds().compareTo(BigDecimal.ZERO) == 1) {
|
||||
depositAccountOnHoldTransactions = this.depositAccountOnHoldTransactionRepository
|
||||
.findBySavingsAccountAndReversedFalseOrderByCreatedDateAsc(account);
|
||||
}
|
||||
|
||||
account.validateAccountBalanceDoesNotBecomeNegative(SavingsAccountTransactionType.PAY_CHARGE.name(),depositAccountOnHoldTransactions);
|
||||
account.validateAccountBalanceDoesNotBecomeNegative(SavingsAccountTransactionType.PAY_CHARGE.name(),
|
||||
depositAccountOnHoldTransactions);
|
||||
|
||||
this.savingAccountRepositoryWrapper.saveAndFlush(account);
|
||||
}
|
||||
@@ -391,8 +396,8 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
final LocalDate depositAmountUpdateEffectiveFromDate = command
|
||||
.localDateValueOfParameterNamed(DepositsApiConstants.effectiveDateParamName);
|
||||
|
||||
final RecurringDepositAccount recurringDepositAccount = (RecurringDepositAccount) this.depositAccountAssembler
|
||||
.assembleFrom(savingsId, DepositAccountType.RECURRING_DEPOSIT);
|
||||
final RecurringDepositAccount recurringDepositAccount = (RecurringDepositAccount) this.depositAccountAssembler.assembleFrom(
|
||||
savingsId, DepositAccountType.RECURRING_DEPOSIT);
|
||||
DepositAccountRecurringDetail recurringDetail = recurringDepositAccount.getRecurringDetail();
|
||||
Map<String, Object> changes = recurringDetail.updateMandatoryRecommendedDepositAmount(mandatoryRecommendedDepositAmount,
|
||||
depositAmountUpdateEffectiveFromDate, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth);
|
||||
@@ -446,8 +451,7 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult withdrawal(final Long savingsId, final JsonCommand command,
|
||||
final DepositAccountType depositAccountType) {
|
||||
public CommandProcessingResult withdrawal(final Long savingsId, final JsonCommand command, final DepositAccountType depositAccountType) {
|
||||
|
||||
boolean isRegularTransaction = true;
|
||||
|
||||
@@ -493,9 +497,9 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
||||
final MathContext mc = new MathContext(15, MoneyHelper.getRoundingMode());
|
||||
boolean isInterestTransfer = false;
|
||||
|
||||
boolean postInterestAsOn = false;
|
||||
account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
|
||||
financialYearBeginningMonth);
|
||||
financialYearBeginningMonth, postInterestAsOn);
|
||||
|
||||
this.savingAccountRepositoryWrapper.save(account);
|
||||
|
||||
@@ -537,7 +541,9 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
||||
final MathContext mc = new MathContext(10, MoneyHelper.getRoundingMode());
|
||||
boolean isInterestTransfer = false;
|
||||
account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth);
|
||||
boolean postInterestAsOn = false;
|
||||
account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth,
|
||||
postInterestAsOn);
|
||||
this.savingAccountRepositoryWrapper.saveAndFlush(account);
|
||||
|
||||
postJournalEntries(account, existingTransactionIds, existingReversedTransactionIds);
|
||||
@@ -588,11 +594,10 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
.findOneByIdAndSavingsAccountId(transactionId, savingsId);
|
||||
if (savingsAccountTransaction == null) { throw new SavingsAccountTransactionNotFoundException(savingsId, transactionId); }
|
||||
|
||||
if (!allowAccountTransferModification && this.accountTransfersReadPlatformService.isAccountTransfer(transactionId,
|
||||
PortfolioAccountType.SAVINGS)) { throw new PlatformServiceUnavailableException(
|
||||
"error.msg.recurring.deposit.account.transfer.transaction.update.not.allowed",
|
||||
"Recurring deposit account transaction:" + transactionId + " update not allowed as it involves in account transfer",
|
||||
transactionId); }
|
||||
if (!allowAccountTransferModification
|
||||
&& this.accountTransfersReadPlatformService.isAccountTransfer(transactionId, PortfolioAccountType.SAVINGS)) { throw new PlatformServiceUnavailableException(
|
||||
"error.msg.recurring.deposit.account.transfer.transaction.update.not.allowed", "Recurring deposit account transaction:"
|
||||
+ transactionId + " update not allowed as it involves in account transfer", transactionId); }
|
||||
|
||||
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
||||
final MathContext mc = MathContext.DECIMAL64;
|
||||
@@ -602,24 +607,26 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
}
|
||||
account.undoTransaction(transactionId);
|
||||
boolean isInterestTransfer = false;
|
||||
boolean postInterestAsOn = false;
|
||||
checkClientOrGroupActive(account);
|
||||
if (savingsAccountTransaction.isPostInterestCalculationRequired()
|
||||
&& account.isBeforeLastPostingPeriod(savingsAccountTransaction.transactionLocalDate())) {
|
||||
account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth);
|
||||
account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth,
|
||||
postInterestAsOn);
|
||||
} else {
|
||||
account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
|
||||
financialYearBeginningMonth);
|
||||
financialYearBeginningMonth, postInterestAsOn);
|
||||
}
|
||||
List<DepositAccountOnHoldTransaction> depositAccountOnHoldTransactions = null;
|
||||
if(account.getOnHoldFunds().compareTo(BigDecimal.ZERO) == 1){
|
||||
depositAccountOnHoldTransactions = this.depositAccountOnHoldTransactionRepository.findBySavingsAccountAndReversedFalseOrderByCreatedDateAsc(account);
|
||||
if (account.getOnHoldFunds().compareTo(BigDecimal.ZERO) == 1) {
|
||||
depositAccountOnHoldTransactions = this.depositAccountOnHoldTransactionRepository
|
||||
.findBySavingsAccountAndReversedFalseOrderByCreatedDateAsc(account);
|
||||
}
|
||||
|
||||
account.validateAccountBalanceDoesNotBecomeNegative(SavingsApiConstants.undoTransactionAction,depositAccountOnHoldTransactions);
|
||||
account.validateAccountBalanceDoesNotBecomeNegative(SavingsApiConstants.undoTransactionAction, depositAccountOnHoldTransactions);
|
||||
// account.activateAccountBasedOnBalance();
|
||||
final boolean isPreMatureClosure = false;
|
||||
account.updateMaturityDateAndAmount(mc, isPreMatureClosure, isSavingsInterestPostingAtCurrentPeriodEnd,
|
||||
financialYearBeginningMonth);
|
||||
account.updateMaturityDateAndAmount(mc, isPreMatureClosure, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth);
|
||||
|
||||
final LocalDate overdueUptoDate = DateUtils.getLocalDateOfTenant();
|
||||
|
||||
@@ -663,14 +670,12 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
.findOneByIdAndSavingsAccountId(transactionId, savingsId);
|
||||
if (savingsAccountTransaction == null) { throw new SavingsAccountTransactionNotFoundException(savingsId, transactionId); }
|
||||
|
||||
if (!(savingsAccountTransaction.isDeposit() || savingsAccountTransaction.isWithdrawal())
|
||||
|| savingsAccountTransaction.isReversed()) { throw new TransactionUpdateNotAllowedException(savingsId, transactionId); }
|
||||
if (!(savingsAccountTransaction.isDeposit() || savingsAccountTransaction.isWithdrawal()) || savingsAccountTransaction.isReversed()) { throw new TransactionUpdateNotAllowedException(
|
||||
savingsId, transactionId); }
|
||||
|
||||
if (this.accountTransfersReadPlatformService.isAccountTransfer(transactionId,
|
||||
PortfolioAccountType.SAVINGS)) { throw new PlatformServiceUnavailableException(
|
||||
"error.msg.saving.account.transfer.transaction.update.not.allowed",
|
||||
"Deposit account transaction:" + transactionId + " update not allowed as it involves in account transfer",
|
||||
transactionId); }
|
||||
if (this.accountTransfersReadPlatformService.isAccountTransfer(transactionId, PortfolioAccountType.SAVINGS)) { throw new PlatformServiceUnavailableException(
|
||||
"error.msg.saving.account.transfer.transaction.update.not.allowed", "Deposit account transaction:" + transactionId
|
||||
+ " update not allowed as it involves in account transfer", transactionId); }
|
||||
|
||||
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
||||
|
||||
@@ -705,19 +710,22 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
}
|
||||
final Long newtransactionId = saveTransactionToGenerateTransactionId(transaction);
|
||||
boolean isInterestTransfer = false;
|
||||
final boolean postInterestAsOn = false;
|
||||
if (account.isBeforeLastPostingPeriod(transactionDate)
|
||||
|| account.isBeforeLastPostingPeriod(savingsAccountTransaction.transactionLocalDate())) {
|
||||
account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth);
|
||||
account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth,
|
||||
postInterestAsOn);
|
||||
} else {
|
||||
account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
|
||||
financialYearBeginningMonth);
|
||||
financialYearBeginningMonth, postInterestAsOn);
|
||||
}
|
||||
List<DepositAccountOnHoldTransaction> depositAccountOnHoldTransactions = null;
|
||||
if(account.getOnHoldFunds().compareTo(BigDecimal.ZERO) == 1){
|
||||
depositAccountOnHoldTransactions = this.depositAccountOnHoldTransactionRepository.findBySavingsAccountAndReversedFalseOrderByCreatedDateAsc(account);
|
||||
if (account.getOnHoldFunds().compareTo(BigDecimal.ZERO) == 1) {
|
||||
depositAccountOnHoldTransactions = this.depositAccountOnHoldTransactionRepository
|
||||
.findBySavingsAccountAndReversedFalseOrderByCreatedDateAsc(account);
|
||||
}
|
||||
|
||||
account.validateAccountBalanceDoesNotBecomeNegative(SavingsApiConstants.adjustTransactionAction,depositAccountOnHoldTransactions);
|
||||
account.validateAccountBalanceDoesNotBecomeNegative(SavingsApiConstants.adjustTransactionAction, depositAccountOnHoldTransactions);
|
||||
account.activateAccountBasedOnBalance();
|
||||
|
||||
if (savingsAccountTransaction.isDeposit()) {
|
||||
@@ -913,7 +921,7 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
final Integer financialYearBeginningMonth = this.configurationDomainService.retrieveFinancialYearBeginningMonth();
|
||||
|
||||
final SavingsAccount savingsAccount = this.depositAccountAssembler.assembleFrom(accountId, depositAccountType);
|
||||
|
||||
final boolean postInterestAsOn = false;
|
||||
final Set<Long> existingTransactionIds = new HashSet<>();
|
||||
final Set<Long> existingReversedTransactionIds = new HashSet<>();
|
||||
updateExistingTransactionsDetails(savingsAccount, existingTransactionIds, existingReversedTransactionIds);
|
||||
@@ -925,7 +933,7 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
final MathContext mc = MathContext.DECIMAL64;
|
||||
boolean isInterestTransfer = false;
|
||||
savingsAccount.calculateInterestUsing(mc, transferDate, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
|
||||
financialYearBeginningMonth);
|
||||
financialYearBeginningMonth, postInterestAsOn);
|
||||
|
||||
this.savingsAccountTransactionRepository.save(newTransferTransaction);
|
||||
this.savingAccountRepositoryWrapper.saveAndFlush(savingsAccount);
|
||||
@@ -957,8 +965,9 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
savingsAccount.setStatus(SavingsAccountStatusType.ACTIVE.getValue());
|
||||
final MathContext mc = MathContext.DECIMAL64;
|
||||
boolean isInterestTransfer = false;
|
||||
boolean postInterestAsOn = false;
|
||||
savingsAccount.calculateInterestUsing(mc, transferDate, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
|
||||
financialYearBeginningMonth);
|
||||
financialYearBeginningMonth, postInterestAsOn);
|
||||
|
||||
this.savingsAccountTransactionRepository.save(withdrawtransferTransaction);
|
||||
this.savingAccountRepositoryWrapper.saveAndFlush(savingsAccount);
|
||||
@@ -999,9 +1008,10 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
savingsAccount.reassignSavingsOfficer(fieldOfficer, transferDate);
|
||||
}
|
||||
boolean isInterestTransfer = false;
|
||||
boolean postInterestAsOn = false;
|
||||
final MathContext mc = MathContext.DECIMAL64;
|
||||
savingsAccount.calculateInterestUsing(mc, transferDate, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
|
||||
financialYearBeginningMonth);
|
||||
financialYearBeginningMonth, postInterestAsOn);
|
||||
|
||||
this.savingsAccountTransactionRepository.save(acceptTransferTransaction);
|
||||
this.savingAccountRepositoryWrapper.saveAndFlush(savingsAccount);
|
||||
@@ -1131,8 +1141,8 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
.isSavingsInterestPostingAtCurrentPeriodEnd();
|
||||
final Integer financialYearBeginningMonth = this.configurationDomainService.retrieveFinancialYearBeginningMonth();
|
||||
|
||||
final SavingsAccountCharge savingsAccountCharge = this.savingsAccountChargeRepository
|
||||
.findOneWithNotFoundDetection(savingsAccountChargeId, savingsAccountId);
|
||||
final SavingsAccountCharge savingsAccountCharge = this.savingsAccountChargeRepository.findOneWithNotFoundDetection(
|
||||
savingsAccountChargeId, savingsAccountId);
|
||||
|
||||
// Get Savings account from savings charge
|
||||
final SavingsAccount account = savingsAccountCharge.savingsAccount();
|
||||
@@ -1144,21 +1154,25 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
|
||||
account.waiveCharge(savingsAccountChargeId, user);
|
||||
boolean isInterestTransfer = false;
|
||||
boolean postInterestAsOn = false;
|
||||
final MathContext mc = MathContext.DECIMAL64;
|
||||
if (account.isBeforeLastPostingPeriod(savingsAccountCharge.getDueLocalDate())) {
|
||||
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
||||
account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth);
|
||||
account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth,
|
||||
postInterestAsOn);
|
||||
} else {
|
||||
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
||||
account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
|
||||
financialYearBeginningMonth);
|
||||
financialYearBeginningMonth, postInterestAsOn);
|
||||
}
|
||||
List<DepositAccountOnHoldTransaction> depositAccountOnHoldTransactions = null;
|
||||
if(account.getOnHoldFunds().compareTo(BigDecimal.ZERO) == 1){
|
||||
depositAccountOnHoldTransactions = this.depositAccountOnHoldTransactionRepository.findBySavingsAccountAndReversedFalseOrderByCreatedDateAsc(account);
|
||||
if (account.getOnHoldFunds().compareTo(BigDecimal.ZERO) == 1) {
|
||||
depositAccountOnHoldTransactions = this.depositAccountOnHoldTransactionRepository
|
||||
.findBySavingsAccountAndReversedFalseOrderByCreatedDateAsc(account);
|
||||
}
|
||||
|
||||
account.validateAccountBalanceDoesNotBecomeNegative(SavingsApiConstants.waiveChargeTransactionAction,depositAccountOnHoldTransactions);
|
||||
account.validateAccountBalanceDoesNotBecomeNegative(SavingsApiConstants.waiveChargeTransactionAction,
|
||||
depositAccountOnHoldTransactions);
|
||||
|
||||
this.savingAccountRepositoryWrapper.saveAndFlush(account);
|
||||
|
||||
@@ -1181,8 +1195,8 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
|
||||
final SavingsAccount savingsAccount = this.depositAccountAssembler.assembleFrom(savingsAccountId, depositAccountType);
|
||||
checkClientOrGroupActive(savingsAccount);
|
||||
final SavingsAccountCharge savingsAccountCharge = this.savingsAccountChargeRepository
|
||||
.findOneWithNotFoundDetection(savingsAccountChargeId, savingsAccountId);
|
||||
final SavingsAccountCharge savingsAccountCharge = this.savingsAccountChargeRepository.findOneWithNotFoundDetection(
|
||||
savingsAccountChargeId, savingsAccountId);
|
||||
|
||||
savingsAccount.removeCharge(savingsAccountCharge);
|
||||
this.savingAccountRepositoryWrapper.saveAndFlush(savingsAccount);
|
||||
@@ -1208,8 +1222,8 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
final BigDecimal amountPaid = command.bigDecimalValueOfParameterNamed(amountParamName);
|
||||
final LocalDate transactionDate = command.localDateValueOfParameterNamed(dueAsOfDateParamName);
|
||||
|
||||
final SavingsAccountCharge savingsAccountCharge = this.savingsAccountChargeRepository
|
||||
.findOneWithNotFoundDetection(savingsAccountChargeId, savingsAccountId);
|
||||
final SavingsAccountCharge savingsAccountCharge = this.savingsAccountChargeRepository.findOneWithNotFoundDetection(
|
||||
savingsAccountChargeId, savingsAccountId);
|
||||
|
||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
|
||||
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
|
||||
@@ -1247,8 +1261,8 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
@SuppressWarnings("unused") final DepositAccountType depositAccountType) {
|
||||
// always use current date as transaction date for batch job
|
||||
final LocalDate transactionDate = DateUtils.getLocalDateOfTenant();
|
||||
final SavingsAccountCharge savingsAccountCharge = this.savingsAccountChargeRepository
|
||||
.findOneWithNotFoundDetection(savingsAccountChargeId, accountId);
|
||||
final SavingsAccountCharge savingsAccountCharge = this.savingsAccountChargeRepository.findOneWithNotFoundDetection(
|
||||
savingsAccountChargeId, accountId);
|
||||
|
||||
final DateTimeFormatter fmt = DateTimeFormat.forPattern("dd MM yyyy");
|
||||
|
||||
@@ -1275,21 +1289,25 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
updateExistingTransactionsDetails(account, existingTransactionIds, existingReversedTransactionIds);
|
||||
account.payCharge(savingsAccountCharge, amountPaid, transactionDate, formatter, user);
|
||||
boolean isInterestTransfer = false;
|
||||
boolean postInterestAsOn = false;
|
||||
final MathContext mc = MathContext.DECIMAL64;
|
||||
if (account.isBeforeLastPostingPeriod(transactionDate)) {
|
||||
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
||||
account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth);
|
||||
account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth,
|
||||
postInterestAsOn);
|
||||
} else {
|
||||
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
||||
account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
|
||||
financialYearBeginningMonth);
|
||||
financialYearBeginningMonth, postInterestAsOn);
|
||||
}
|
||||
List<DepositAccountOnHoldTransaction> depositAccountOnHoldTransactions = null;
|
||||
if(account.getOnHoldFunds().compareTo(BigDecimal.ZERO) == 1){
|
||||
depositAccountOnHoldTransactions = this.depositAccountOnHoldTransactionRepository.findBySavingsAccountAndReversedFalseOrderByCreatedDateAsc(account);
|
||||
if (account.getOnHoldFunds().compareTo(BigDecimal.ZERO) == 1) {
|
||||
depositAccountOnHoldTransactions = this.depositAccountOnHoldTransactionRepository
|
||||
.findBySavingsAccountAndReversedFalseOrderByCreatedDateAsc(account);
|
||||
}
|
||||
|
||||
account.validateAccountBalanceDoesNotBecomeNegative("." + SavingsAccountTransactionType.PAY_CHARGE.getCode(),depositAccountOnHoldTransactions);
|
||||
account.validateAccountBalanceDoesNotBecomeNegative("." + SavingsAccountTransactionType.PAY_CHARGE.getCode(),
|
||||
depositAccountOnHoldTransactions);
|
||||
|
||||
this.savingAccountRepositoryWrapper.saveAndFlush(account);
|
||||
|
||||
@@ -1340,8 +1358,8 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
@Override
|
||||
public SavingsAccountTransaction mandatorySavingsAccountDeposit(final SavingsAccountTransactionDTO accountTransactionDTO) {
|
||||
boolean isRegularTransaction = false;
|
||||
final RecurringDepositAccount account = (RecurringDepositAccount) this.depositAccountAssembler
|
||||
.assembleFrom(accountTransactionDTO.getSavingsAccountId(), DepositAccountType.RECURRING_DEPOSIT);
|
||||
final RecurringDepositAccount account = (RecurringDepositAccount) this.depositAccountAssembler.assembleFrom(
|
||||
accountTransactionDTO.getSavingsAccountId(), DepositAccountType.RECURRING_DEPOSIT);
|
||||
final PaymentDetail paymentDetail = accountTransactionDTO.getPaymentDetail();
|
||||
if (paymentDetail != null && paymentDetail.getId() == null) {
|
||||
this.paymentDetailWritePlatformService.persistPaymentDetail(paymentDetail);
|
||||
|
||||
+6
-2
@@ -767,7 +767,8 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
|
||||
.append("sa.currency_code as currencyCode, sa.currency_digits as currencyDigits, sa.currency_multiplesof as inMultiplesOf, ");
|
||||
sqlBuilder.append("curr.name as currencyName, curr.internationalized_name_code as currencyNameCode, ");
|
||||
sqlBuilder.append("curr.display_symbol as currencyDisplaySymbol, ");
|
||||
sqlBuilder.append("pt.value as paymentTypeName ");
|
||||
sqlBuilder.append("pt.value as paymentTypeName, ");
|
||||
sqlBuilder.append("tr.is_manual as postInterestAsOn ");
|
||||
sqlBuilder.append("from m_savings_account sa ");
|
||||
sqlBuilder.append("join m_savings_account_transaction tr on tr.savings_account_id = sa.id ");
|
||||
sqlBuilder.append("join m_currency curr on curr.code = sa.currency_code ");
|
||||
@@ -797,6 +798,7 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
|
||||
|
||||
final Long savingsId = rs.getLong("savingsId");
|
||||
final String accountNo = rs.getString("accountNo");
|
||||
final boolean postInterestAsOn = rs.getBoolean("postInterestAsOn");
|
||||
|
||||
PaymentDetailData paymentDetailData = null;
|
||||
if (transactionType.isDepositOrWithdrawal()) {
|
||||
@@ -840,12 +842,14 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
|
||||
final boolean toTransferReversed = rs.getBoolean("toTransferReversed");
|
||||
final String toTransferDescription = rs.getString("toTransferDescription");
|
||||
|
||||
|
||||
|
||||
transfer = AccountTransferData.transferBasicDetails(toTransferId, currency, toTransferAmount, toTransferDate,
|
||||
toTransferDescription, toTransferReversed);
|
||||
}
|
||||
|
||||
return SavingsAccountTransactionData.create(id, transactionType, paymentDetailData, savingsId, accountNo, date, currency,
|
||||
amount, runningBalance, reversed, transfer, submittedOnDate);
|
||||
amount, runningBalance, reversed, transfer, submittedOnDate, postInterestAsOn);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+4
-3
@@ -41,8 +41,6 @@ public interface SavingsAccountWritePlatformService {
|
||||
|
||||
CommandProcessingResult calculateInterest(Long savingsId);
|
||||
|
||||
CommandProcessingResult postInterest(Long savingsId);
|
||||
|
||||
CommandProcessingResult undoTransaction(Long savingsId, Long transactionId, boolean allowAccountTransferModification);
|
||||
|
||||
CommandProcessingResult adjustSavingsTransaction(Long savingsId, Long transactionId, JsonCommand command);
|
||||
@@ -78,7 +76,6 @@ public interface SavingsAccountWritePlatformService {
|
||||
void processPostActiveActions(SavingsAccount account, DateTimeFormatter fmt, Set<Long> existingTransactionIds,
|
||||
Set<Long> existingReversedTransactionIds);
|
||||
|
||||
void postInterest(SavingsAccount account);
|
||||
|
||||
CommandProcessingResult modifyWithHoldTax(Long savingsAccountId, JsonCommand command);
|
||||
|
||||
@@ -87,4 +84,8 @@ public interface SavingsAccountWritePlatformService {
|
||||
void setSubStatusDormant(Long savingsId);
|
||||
|
||||
void escheat(Long savingsId);
|
||||
|
||||
CommandProcessingResult postInterest(JsonCommand command);
|
||||
|
||||
void postInterest(SavingsAccount account, boolean postInterestAs, LocalDate transactionDate);
|
||||
}
|
||||
+79
-27
@@ -39,6 +39,8 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.fineract.accounting.journalentry.exception.JournalEntryInvalidException;
|
||||
import org.apache.fineract.accounting.journalentry.exception.JournalEntryInvalidException.GL_JOURNAL_ENTRY_INVALID_REASON;
|
||||
import org.apache.fineract.accounting.journalentry.service.JournalEntryWritePlatformService;
|
||||
import org.apache.fineract.infrastructure.configuration.domain.ConfigurationDomainService;
|
||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||
@@ -95,11 +97,14 @@ import org.apache.fineract.portfolio.savings.domain.SavingsAccountRepositoryWrap
|
||||
import org.apache.fineract.portfolio.savings.domain.SavingsAccountStatusType;
|
||||
import org.apache.fineract.portfolio.savings.domain.SavingsAccountTransaction;
|
||||
import org.apache.fineract.portfolio.savings.domain.SavingsAccountTransactionRepository;
|
||||
import org.apache.fineract.portfolio.savings.exception.PostInterestAsOnDateException;
|
||||
import org.apache.fineract.portfolio.savings.exception.PostInterestClosingDateException;
|
||||
import org.apache.fineract.portfolio.savings.exception.SavingsAccountClosingNotAllowedException;
|
||||
import org.apache.fineract.portfolio.savings.exception.SavingsAccountTransactionNotFoundException;
|
||||
import org.apache.fineract.portfolio.savings.exception.SavingsOfficerAssignmentException;
|
||||
import org.apache.fineract.portfolio.savings.exception.SavingsOfficerUnassignmentException;
|
||||
import org.apache.fineract.portfolio.savings.exception.TransactionUpdateNotAllowedException;
|
||||
import org.apache.fineract.portfolio.savings.exception.PostInterestAsOnDateException.PostInterestAsOnException_TYPE;
|
||||
import org.apache.fineract.useradministration.domain.AppUser;
|
||||
import org.apache.fineract.useradministration.domain.AppUserRepositoryWrapper;
|
||||
import org.joda.time.LocalDate;
|
||||
@@ -255,7 +260,6 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
|
||||
final SavingsAccount account = this.savingAccountAssembler.assembleFrom(savingsId);
|
||||
checkClientOrGroupActive(account);
|
||||
|
||||
final Locale locale = command.extractLocale();
|
||||
final DateTimeFormatter fmt = DateTimeFormat.forPattern(command.dateFormat()).withLocale(locale);
|
||||
|
||||
@@ -268,7 +272,6 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
boolean isRegularTransaction = true;
|
||||
final SavingsAccountTransaction deposit = this.savingsAccountDomainService.handleDeposit(account, fmt, transactionDate,
|
||||
transactionAmount, paymentDetail, isAccountTransfer, isRegularTransaction);
|
||||
|
||||
return new CommandProcessingResultBuilder() //
|
||||
.withEntityId(deposit.getId()) //
|
||||
.withOfficeId(account.officeId()) //
|
||||
@@ -277,6 +280,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
.withSavingsId(savingsId) //
|
||||
.with(changes) //
|
||||
.build();
|
||||
|
||||
}
|
||||
|
||||
private Long saveTransactionToGenerateTransactionId(final SavingsAccountTransaction transaction) {
|
||||
@@ -300,8 +304,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
final PaymentDetail paymentDetail = this.paymentDetailWritePlatformService.createAndPersistPaymentDetail(command, changes);
|
||||
|
||||
final SavingsAccount account = this.savingAccountAssembler.assembleFrom(savingsId);
|
||||
checkClientOrGroupActive(account);
|
||||
|
||||
checkClientOrGroupActive(account);
|
||||
final boolean isAccountTransfer = false;
|
||||
final boolean isRegularTransaction = true;
|
||||
final boolean isApplyWithdrawFee = true;
|
||||
@@ -359,7 +362,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
final MathContext mc = new MathContext(15, MoneyHelper.getRoundingMode());
|
||||
boolean isInterestTransfer = false;
|
||||
account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
|
||||
financialYearBeginningMonth);
|
||||
financialYearBeginningMonth,false);
|
||||
|
||||
this.savingAccountRepositoryWrapper.save(account);
|
||||
|
||||
@@ -371,13 +374,32 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
.withSavingsId(savingsId) //
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandProcessingResult postInterest(final Long savingsId) {
|
||||
|
||||
public CommandProcessingResult postInterest(final JsonCommand command) {
|
||||
|
||||
Long savingsId=command.getSavingsId();
|
||||
final boolean postInterestAs =command.booleanPrimitiveValueOfParameterNamed("isPostInterestAsOn");
|
||||
final LocalDate transactionDate = command.localDateValueOfParameterNamed("transactionDate");
|
||||
final SavingsAccount account = this.savingAccountAssembler.assembleFrom(savingsId);
|
||||
checkClientOrGroupActive(account);
|
||||
postInterest(account);
|
||||
if (postInterestAs == true) {
|
||||
|
||||
if (transactionDate == null) {
|
||||
|
||||
throw new PostInterestAsOnDateException(PostInterestAsOnException_TYPE.VALID_DATE); }
|
||||
if (transactionDate.isBefore(account.accountSubmittedOrActivationDate())) { throw new PostInterestAsOnDateException(
|
||||
PostInterestAsOnException_TYPE.ACTIVATION_DATE); }
|
||||
List<SavingsAccountTransaction> savingTransactions = account.getTransactions();
|
||||
for (SavingsAccountTransaction savingTransaction : savingTransactions) {
|
||||
if (transactionDate.toDate().before(savingTransaction.getDateOf())) { throw new PostInterestAsOnDateException(
|
||||
PostInterestAsOnException_TYPE.LAST_TRANSACTION_DATE); }
|
||||
}
|
||||
|
||||
LocalDate today = DateUtils.getLocalDateOfTenant();
|
||||
if (transactionDate.isAfter(today)) { throw new PostInterestAsOnDateException(PostInterestAsOnException_TYPE.FUTURE_DATE); }
|
||||
|
||||
}
|
||||
postInterest(account,postInterestAs,transactionDate);
|
||||
return new CommandProcessingResultBuilder() //
|
||||
.withEntityId(savingsId) //
|
||||
.withOfficeId(account.officeId()) //
|
||||
@@ -389,7 +411,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public void postInterest(final SavingsAccount account) {
|
||||
public void postInterest(final SavingsAccount account,final boolean postInterestAs,final LocalDate transactionDate) {
|
||||
|
||||
final boolean isSavingsInterestPostingAtCurrentPeriodEnd = this.configurationDomainService
|
||||
.isSavingsInterestPostingAtCurrentPeriodEnd();
|
||||
@@ -403,14 +425,18 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
||||
final MathContext mc = new MathContext(10, MoneyHelper.getRoundingMode());
|
||||
boolean isInterestTransfer = false;
|
||||
account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth);
|
||||
|
||||
if(postInterestAs==false){
|
||||
account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth,postInterestAs);
|
||||
}
|
||||
else{
|
||||
account.postInterest(mc, transactionDate, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth,postInterestAs);
|
||||
}
|
||||
// for generating transaction id's
|
||||
List<SavingsAccountTransaction> transactions = account.getTransactions();
|
||||
for (SavingsAccountTransaction accountTransaction : transactions) {
|
||||
if (accountTransaction.getId() == null) {
|
||||
this.savingsAccountTransactionRepository.save(accountTransaction);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.savingAccountRepositoryWrapper.saveAndFlush(account);
|
||||
@@ -418,7 +444,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
postJournalEntries(account, existingTransactionIds, existingReversedTransactionIds);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public CommandProcessingResult undoTransaction(final Long savingsId, final Long transactionId,
|
||||
final boolean allowAccountTransferModification) {
|
||||
@@ -466,10 +492,10 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
checkClientOrGroupActive(account);
|
||||
if (savingsAccountTransaction.isPostInterestCalculationRequired()
|
||||
&& account.isBeforeLastPostingPeriod(savingsAccountTransaction.transactionLocalDate())) {
|
||||
account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth);
|
||||
account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth,false);
|
||||
} else {
|
||||
account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
|
||||
financialYearBeginningMonth);
|
||||
financialYearBeginningMonth,false);
|
||||
}
|
||||
List<DepositAccountOnHoldTransaction> depositAccountOnHoldTransactions = null;
|
||||
if (account.getOnHoldFunds().compareTo(BigDecimal.ZERO) == 1) {
|
||||
@@ -555,10 +581,10 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
|
||||
if (account.isBeforeLastPostingPeriod(transactionDate)
|
||||
|| account.isBeforeLastPostingPeriod(savingsAccountTransaction.transactionLocalDate())) {
|
||||
account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth);
|
||||
account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth,false);
|
||||
} else {
|
||||
account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
|
||||
financialYearBeginningMonth);
|
||||
financialYearBeginningMonth,false);
|
||||
}
|
||||
List<DepositAccountOnHoldTransaction> depositAccountOnHoldTransactions = null;
|
||||
if (account.getOnHoldFunds().compareTo(BigDecimal.ZERO) == 1) {
|
||||
@@ -604,9 +630,10 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
@Override
|
||||
public CommandProcessingResult close(final Long savingsId, final JsonCommand command) {
|
||||
final AppUser user = this.context.authenticatedUser();
|
||||
|
||||
|
||||
this.savingsAccountTransactionDataValidator.validateClosing(command);
|
||||
final SavingsAccount account = this.savingAccountAssembler.assembleFrom(savingsId);
|
||||
|
||||
final boolean isLinkedWithAnyActiveLoan = this.accountAssociationsReadPlatformService.isLinkedWithAnyActiveAccount(savingsId);
|
||||
|
||||
if (isLinkedWithAnyActiveLoan) {
|
||||
@@ -614,18 +641,36 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
+ " is not allowed, since it is linked with one of the active accounts";
|
||||
throw new SavingsAccountClosingNotAllowedException("linked", defaultUserMessage, savingsId);
|
||||
}
|
||||
|
||||
|
||||
|
||||
final boolean isWithdrawBalance = command.booleanPrimitiveValueOfParameterNamed(withdrawBalanceParamName);
|
||||
|
||||
final Locale locale = command.extractLocale();
|
||||
final DateTimeFormatter fmt = DateTimeFormat.forPattern(command.dateFormat()).withLocale(locale);
|
||||
final LocalDate closedDate = command.localDateValueOfParameterNamed(SavingsApiConstants.closedOnDateParamName);
|
||||
|
||||
final boolean isPostInterest = command.booleanPrimitiveValueOfParameterNamed(SavingsApiConstants.postInterestValidationOnClosure);
|
||||
// postInterest(account,closedDate,flag);
|
||||
if (isPostInterest) {
|
||||
boolean postInterestOnClosingDate = false;
|
||||
List<SavingsAccountTransaction> savingTransactions = account.getTransactions();
|
||||
for (SavingsAccountTransaction savingTransaction : savingTransactions) {
|
||||
if (closedDate.toDate().equals(savingTransaction.getDateOf())) if (savingTransaction.getTypeOf() == SavingsAccountTransactionType.OVERDRAFT_INTEREST.getValue()) {
|
||||
postInterestOnClosingDate = true;
|
||||
}
|
||||
}
|
||||
if (postInterestOnClosingDate == false) { throw new PostInterestClosingDateException(); }
|
||||
}
|
||||
|
||||
final Map<String, Object> changes = new LinkedHashMap<>();
|
||||
|
||||
if (isWithdrawBalance && account.getSummary().getAccountBalance(account.getCurrency()).isGreaterThanZero()) {
|
||||
|
||||
|
||||
|
||||
|
||||
final BigDecimal transactionAmount = account.getSummary().getAccountBalance();
|
||||
|
||||
final PaymentDetail paymentDetail = this.paymentDetailWritePlatformService.createAndPersistPaymentDetail(command, changes);
|
||||
|
||||
final boolean isAccountTransfer = false;
|
||||
@@ -685,8 +730,9 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
savingsAccount.setStatus(SavingsAccountStatusType.TRANSFER_IN_PROGRESS.getValue());
|
||||
final MathContext mc = MathContext.DECIMAL64;
|
||||
boolean isInterestTransfer = false;
|
||||
boolean postInterestAsOn = false;
|
||||
savingsAccount.calculateInterestUsing(mc, transferDate, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
|
||||
financialYearBeginningMonth);
|
||||
financialYearBeginningMonth, postInterestAsOn);
|
||||
|
||||
this.savingsAccountTransactionRepository.save(newTransferTransaction);
|
||||
this.savingAccountRepositoryWrapper.saveAndFlush(savingsAccount);
|
||||
@@ -715,8 +761,9 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
savingsAccount.setStatus(SavingsAccountStatusType.ACTIVE.getValue());
|
||||
final MathContext mc = MathContext.DECIMAL64;
|
||||
boolean isInterestTransfer = false;
|
||||
boolean postInterestAsOn =false;
|
||||
savingsAccount.calculateInterestUsing(mc, transferDate, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
|
||||
financialYearBeginningMonth);
|
||||
financialYearBeginningMonth, postInterestAsOn);
|
||||
|
||||
this.savingsAccountTransactionRepository.save(withdrawtransferTransaction);
|
||||
this.savingAccountRepositoryWrapper.saveAndFlush(savingsAccount);
|
||||
@@ -756,8 +803,9 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
}
|
||||
boolean isInterestTransfer = false;
|
||||
final MathContext mc = MathContext.DECIMAL64;
|
||||
boolean postInterestAsOn = false;
|
||||
savingsAccount.calculateInterestUsing(mc, transferDate, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
|
||||
financialYearBeginningMonth);
|
||||
financialYearBeginningMonth, postInterestAsOn);
|
||||
|
||||
this.savingsAccountTransactionRepository.save(acceptTransferTransaction);
|
||||
this.savingAccountRepositoryWrapper.saveAndFlush(savingsAccount);
|
||||
@@ -906,14 +954,16 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
|
||||
account.waiveCharge(savingsAccountChargeId, user);
|
||||
boolean isInterestTransfer = false;
|
||||
boolean postInterestAsOn = false;
|
||||
final MathContext mc = MathContext.DECIMAL64;
|
||||
if (account.isBeforeLastPostingPeriod(savingsAccountCharge.getDueLocalDate())) {
|
||||
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
||||
account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth);
|
||||
account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth,
|
||||
postInterestAsOn);
|
||||
} else {
|
||||
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
||||
account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
|
||||
financialYearBeginningMonth);
|
||||
financialYearBeginningMonth, postInterestAsOn);
|
||||
}
|
||||
List<DepositAccountOnHoldTransaction> depositAccountOnHoldTransactions = null;
|
||||
if (account.getOnHoldFunds().compareTo(BigDecimal.ZERO) == 1) {
|
||||
@@ -1038,14 +1088,16 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
updateExistingTransactionsDetails(account, existingTransactionIds, existingReversedTransactionIds);
|
||||
account.payCharge(savingsAccountCharge, amountPaid, transactionDate, formatter, user);
|
||||
boolean isInterestTransfer = false;
|
||||
boolean postInterestAsOn = false;
|
||||
final MathContext mc = MathContext.DECIMAL64;
|
||||
if (account.isBeforeLastPostingPeriod(transactionDate)) {
|
||||
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
||||
account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth);
|
||||
account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth,
|
||||
postInterestAsOn);
|
||||
} else {
|
||||
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
||||
account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
|
||||
financialYearBeginningMonth);
|
||||
financialYearBeginningMonth, postInterestAsOn);
|
||||
}
|
||||
List<DepositAccountOnHoldTransaction> depositAccountOnHoldTransactions = null;
|
||||
if (account.getOnHoldFunds().compareTo(BigDecimal.ZERO) == 1) {
|
||||
|
||||
+3
-1
@@ -60,7 +60,9 @@ public class SavingsSchedularServiceImpl implements SavingsSchedularService {
|
||||
for (final SavingsAccount savingsAccount : savingsAccounts) {
|
||||
try {
|
||||
this.savingAccountAssembler.assignSavingAccountHelpers(savingsAccount);
|
||||
this.savingsAccountWritePlatformService.postInterest(savingsAccount);
|
||||
boolean postInterestAsOn = false;
|
||||
LocalDate transactionDate = null;
|
||||
this.savingsAccountWritePlatformService.postInterest(savingsAccount, postInterestAsOn, transactionDate);
|
||||
} catch (Exception e) {
|
||||
Throwable realCause = e;
|
||||
if (e.getCause() != null) {
|
||||
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
--
|
||||
-- Licensed to the Apache Software Foundation (ASF) under one
|
||||
-- or more contributor license agreements. See the NOTICE file
|
||||
-- distributed with this work for additional information
|
||||
-- regarding copyright ownership. The ASF licenses this file
|
||||
-- to you under the Apache License, Version 2.0 (the
|
||||
-- "License"); you may not use this file except in compliance
|
||||
-- with the License. You may obtain a copy of the License at
|
||||
--
|
||||
-- http://www.apache.org/licenses/LICENSE-2.0
|
||||
--
|
||||
-- Unless required by applicable law or agreed to in writing,
|
||||
-- software distributed under the License is distributed on an
|
||||
-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
-- KIND, either express or implied. See the License for the
|
||||
-- specific language governing permissions and limitations
|
||||
-- under the License.
|
||||
--
|
||||
|
||||
ALTER TABLE m_savings_account_transaction
|
||||
ADD is_manual boolean default 0
|
||||
Reference in New Issue
Block a user