FINERACT-1668: Adding Configuration for reversal transaction (#2454)
Co-authored-by: Dhaval Maniyar <dhavalmaniyar@Dhavals-MacBook-Pro.local>
This commit is contained in:
co-authored by
Dhaval Maniyar
parent
e15459c659
commit
4685e96c81
+2
@@ -116,4 +116,6 @@ public interface ConfigurationDomainService {
|
||||
boolean isBusinessDateEnabled();
|
||||
|
||||
boolean isCOBDateAdjustmentEnabled();
|
||||
|
||||
boolean isReversalTransactionAllowed();
|
||||
}
|
||||
|
||||
+7
@@ -444,4 +444,11 @@ public class ConfigurationDomainServiceJpa implements ConfigurationDomainService
|
||||
public boolean isCOBDateAdjustmentEnabled() {
|
||||
return getGlobalConfigurationPropertyData(ENABLE_AUTOMATIC_COB_DATE_ADJUSTMENT).isEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReversalTransactionAllowed() {
|
||||
final String propertyName = "enable-post-reversal-txns-for-reverse-transactions";
|
||||
final GlobalConfigurationPropertyData property = getGlobalConfigurationPropertyData(propertyName);
|
||||
return property.isEnabled();
|
||||
}
|
||||
}
|
||||
|
||||
+5
-6
@@ -140,7 +140,6 @@ public class DepositAccountDomainServiceJpa implements DepositAccountDomainServi
|
||||
final boolean isSavingsInterestPostingAtCurrentPeriodEnd = this.configurationDomainService
|
||||
.isSavingsInterestPostingAtCurrentPeriodEnd();
|
||||
final Integer financialYearBeginningMonth = this.configurationDomainService.retrieveFinancialYearBeginningMonth();
|
||||
|
||||
boolean isAccountTransfer = false;
|
||||
final boolean isPreMatureClosure = false;
|
||||
final MathContext mc = MathContext.DECIMAL64;
|
||||
@@ -348,7 +347,7 @@ public class DepositAccountDomainServiceJpa implements DepositAccountDomainServi
|
||||
final boolean isSavingsInterestPostingAtCurrentPeriodEnd = this.configurationDomainService
|
||||
.isSavingsInterestPostingAtCurrentPeriodEnd();
|
||||
final Integer financialYearBeginningMonth = this.configurationDomainService.retrieveFinancialYearBeginningMonth();
|
||||
|
||||
final boolean postReversals = false;
|
||||
boolean isRegularTransaction = false;
|
||||
boolean isAccountTransfer = false;
|
||||
final boolean isPreMatureClosure = false;
|
||||
@@ -364,7 +363,7 @@ public class DepositAccountDomainServiceJpa implements DepositAccountDomainServi
|
||||
final DateTimeFormatter fmt = DateTimeFormatter.ofPattern(command.dateFormat()).withLocale(locale);
|
||||
final LocalDate closedDate = command.localDateValueOfParameterNamed(SavingsApiConstants.closedOnDateParamName);
|
||||
Long savingsTransactionId = null;
|
||||
account.postMaturityInterest(isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth, closedDate);
|
||||
account.postMaturityInterest(isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth, closedDate, postReversals);
|
||||
final BigDecimal transactionAmount = account.getAccountBalance();
|
||||
final Integer onAccountClosureId = command.integerValueOfParameterNamed(onAccountClosureIdParamName);
|
||||
final DepositAccountOnClosureType onClosureType = DepositAccountOnClosureType.fromInt(onAccountClosureId);
|
||||
@@ -385,7 +384,7 @@ public class DepositAccountDomainServiceJpa implements DepositAccountDomainServi
|
||||
Integer frequency = CalendarUtils.getInterval(calendar.getRecurrence());
|
||||
frequency = frequency == -1 ? 1 : frequency;
|
||||
reinvestedDeposit.generateSchedule(frequencyType, frequency, calendar);
|
||||
reinvestedDeposit.processAccountUponActivation(fmt, user);
|
||||
reinvestedDeposit.processAccountUponActivation(fmt, user, postReversals);
|
||||
reinvestedDeposit.updateMaturityDateAndAmount(mc, isPreMatureClosure, isSavingsInterestPostingAtCurrentPeriodEnd,
|
||||
financialYearBeginningMonth);
|
||||
this.savingsAccountRepository.save(reinvestedDeposit);
|
||||
@@ -520,7 +519,7 @@ public class DepositAccountDomainServiceJpa implements DepositAccountDomainServi
|
||||
final boolean isSavingsInterestPostingAtCurrentPeriodEnd = this.configurationDomainService
|
||||
.isSavingsInterestPostingAtCurrentPeriodEnd();
|
||||
final Integer financialYearBeginningMonth = this.configurationDomainService.retrieveFinancialYearBeginningMonth();
|
||||
|
||||
final boolean postReversals = false;
|
||||
boolean isAccountTransfer = false;
|
||||
final boolean isPreMatureClosure = true;
|
||||
boolean isRegularTransaction = false;
|
||||
@@ -537,7 +536,7 @@ public class DepositAccountDomainServiceJpa implements DepositAccountDomainServi
|
||||
Long savingsTransactionId = null;
|
||||
// post interest
|
||||
account.postPreMaturityInterest(closedDate, isPreMatureClosure, isSavingsInterestPostingAtCurrentPeriodEnd,
|
||||
financialYearBeginningMonth);
|
||||
financialYearBeginningMonth, postReversals);
|
||||
|
||||
final Integer closureTypeValue = command.integerValueOfParameterNamed(DepositsApiConstants.onAccountClosureIdParamName);
|
||||
DepositAccountOnClosureType closureType = DepositAccountOnClosureType.fromInt(closureTypeValue);
|
||||
|
||||
+3
@@ -39,6 +39,7 @@ import javax.persistence.Entity;
|
||||
import javax.persistence.FetchType;
|
||||
import javax.persistence.OneToOne;
|
||||
import javax.persistence.Transient;
|
||||
import org.apache.fineract.infrastructure.configuration.domain.ConfigurationDomainService;
|
||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||
import org.apache.fineract.infrastructure.core.data.ApiParameterError;
|
||||
import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder;
|
||||
@@ -77,6 +78,8 @@ public class FixedDepositAccount extends SavingsAccount {
|
||||
|
||||
@Transient
|
||||
protected InterestRateChartAssembler chartAssembler;
|
||||
@Transient
|
||||
private ConfigurationDomainService configurationDomainService;
|
||||
|
||||
protected FixedDepositAccount() {
|
||||
//
|
||||
|
||||
+8
-11
@@ -270,11 +270,11 @@ public class RecurringDepositAccount extends SavingsAccount {
|
||||
}
|
||||
}
|
||||
|
||||
public void updateMaturityStatus(final boolean isSavingsInterestPostingAtCurrentPeriodEnd, final Integer financialYearBeginningMonth) {
|
||||
public void updateMaturityStatus(final boolean isSavingsInterestPostingAtCurrentPeriodEnd, final Integer financialYearBeginningMonth,
|
||||
final boolean postReversals) {
|
||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
|
||||
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
|
||||
.resource(RECURRING_DEPOSIT_ACCOUNT_RESOURCE_NAME + SavingsApiConstants.updateMaturityDetailsAction);
|
||||
|
||||
final SavingsAccountStatusType currentStatus = SavingsAccountStatusType.fromInt(this.status);
|
||||
if (!SavingsAccountStatusType.ACTIVE.hasStateOf(currentStatus)) {
|
||||
baseDataValidator.reset().failWithCodeNoParameterAddedToErrorCode("not.in.active.state");
|
||||
@@ -287,7 +287,7 @@ public class RecurringDepositAccount extends SavingsAccount {
|
||||
if (!this.maturityDate().isAfter(todayDate)) {
|
||||
// update account status
|
||||
this.status = SavingsAccountStatusType.MATURED.getValue();
|
||||
postMaturityInterest(isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth, todayDate);
|
||||
postMaturityInterest(isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth, todayDate, postReversals);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -537,7 +537,7 @@ public class RecurringDepositAccount extends SavingsAccount {
|
||||
return Money.of(this.currency, this.minRequiredOpeningBalance);
|
||||
}
|
||||
|
||||
protected void processAccountUponActivation(final DateTimeFormatter fmt, final AppUser user) {
|
||||
protected void processAccountUponActivation(final DateTimeFormatter fmt, final AppUser user, final boolean postReversals) {
|
||||
final Money minRequiredOpeningBalance = Money.of(this.currency, this.minRequiredOpeningBalance);
|
||||
final boolean backdatedTxnsAllowedTill = false;
|
||||
String refNo = null;
|
||||
@@ -549,7 +549,6 @@ public class RecurringDepositAccount extends SavingsAccount {
|
||||
|
||||
// update existing transactions so derived balance fields are
|
||||
// correct.
|
||||
boolean postReversals = false;
|
||||
recalculateDailyBalances(Money.zero(this.currency), DateUtils.getBusinessLocalDate(), backdatedTxnsAllowedTill, postReversals);
|
||||
}
|
||||
}
|
||||
@@ -635,7 +634,7 @@ public class RecurringDepositAccount extends SavingsAccount {
|
||||
}
|
||||
|
||||
public void postMaturityInterest(final boolean isSavingsInterestPostingAtCurrentPeriodEnd, final Integer financialYearBeginningMonth,
|
||||
final LocalDate closeDate) {
|
||||
final LocalDate closeDate, final boolean postReversals) {
|
||||
LocalDate interestPostingUpToDate = maturityDate();
|
||||
if (interestPostingUpToDate == null) {
|
||||
interestPostingUpToDate = closeDate;
|
||||
@@ -645,7 +644,6 @@ public class RecurringDepositAccount extends SavingsAccount {
|
||||
boolean isInterestTransfer = false;
|
||||
LocalDate postInterestOnDate = null;
|
||||
final boolean backdatedTxnsAllowedTill = false;
|
||||
boolean postReversals = false;
|
||||
final List<PostingPeriod> postingPeriods = calculateInterestUsing(mc, interestPostingUpToDate.minusDays(1), isInterestTransfer,
|
||||
isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth, postInterestOnDate, backdatedTxnsAllowedTill,
|
||||
postReversals);
|
||||
@@ -690,7 +688,7 @@ public class RecurringDepositAccount extends SavingsAccount {
|
||||
}
|
||||
|
||||
public void postPreMaturityInterest(final LocalDate accountCloseDate, final boolean isPreMatureClosure,
|
||||
final boolean isSavingsInterestPostingAtCurrentPeriodEnd, final Integer financialYearBeginningMonth) {
|
||||
final boolean isSavingsInterestPostingAtCurrentPeriodEnd, final Integer financialYearBeginningMonth, boolean postReversals) {
|
||||
|
||||
final Money interestPostedToDate = totalInterestPosted();
|
||||
// calculate interest before one day of closure date
|
||||
@@ -713,7 +711,6 @@ public class RecurringDepositAccount extends SavingsAccount {
|
||||
}
|
||||
|
||||
applyWithholdTaxForDepositAccounts(accountCloseDate, recalucateDailyBalance, backdatedTxnsAllowedTill);
|
||||
boolean postReversals = false;
|
||||
if (recalucateDailyBalance) {
|
||||
// update existing transactions so derived balance fields are
|
||||
// correct.
|
||||
@@ -755,11 +752,11 @@ public class RecurringDepositAccount extends SavingsAccount {
|
||||
return interestOnMaturity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postInterest(final MathContext mc, final LocalDate postingDate, final boolean isInterestTransfer,
|
||||
final boolean isSavingsInterestPostingAtCurrentPeriodEnd, final Integer financialYearBeginningMonth,
|
||||
final LocalDate postInterestAson, final boolean backdatedTxnsAllowedTill) {
|
||||
final LocalDate postInterestAson, final boolean backdatedTxnsAllowedTill, final boolean postReversals) {
|
||||
final LocalDate interestPostingUpToDate = interestPostingUpToDate(postingDate);
|
||||
boolean postReversals = false;
|
||||
super.postInterest(mc, interestPostingUpToDate, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
|
||||
financialYearBeginningMonth, postInterestAson, backdatedTxnsAllowedTill, postReversals);
|
||||
}
|
||||
|
||||
+2
-3
@@ -977,7 +977,6 @@ public class SavingsAccount extends AbstractPersistableCustom {
|
||||
|
||||
protected void recalculateDailyBalances(final Money openingAccountBalance, final LocalDate interestPostingUpToDate,
|
||||
final boolean backdatedTxnsAllowedTill, boolean postReversals) {
|
||||
|
||||
Money runningBalance = openingAccountBalance.copy();
|
||||
|
||||
List<SavingsAccountTransaction> accountTransactionsSorted = null;
|
||||
@@ -2775,6 +2774,7 @@ public class SavingsAccount extends AbstractPersistableCustom {
|
||||
private void payActivationCharges(final boolean isSavingsInterestPostingAtCurrentPeriodEnd, final Integer financialYearBeginningMonth,
|
||||
final AppUser user, final boolean backdatedTxnsAllowedTill) {
|
||||
boolean isSavingsChargeApplied = false;
|
||||
boolean postReversals = false;
|
||||
UUID refNo = UUID.randomUUID();
|
||||
for (SavingsAccountCharge savingsAccountCharge : this.charges()) {
|
||||
if (savingsAccountCharge.isSavingsActivation()) {
|
||||
@@ -2788,7 +2788,6 @@ public class SavingsAccount extends AbstractPersistableCustom {
|
||||
final MathContext mc = MathContext.DECIMAL64;
|
||||
boolean isInterestTransfer = false;
|
||||
LocalDate postInterestAsOnDate = null;
|
||||
boolean postReversals = false;
|
||||
if (this.isBeforeLastPostingPeriod(getActivationLocalDate(), backdatedTxnsAllowedTill)) {
|
||||
final LocalDate today = DateUtils.getBusinessLocalDate();
|
||||
this.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth,
|
||||
@@ -3551,12 +3550,12 @@ public class SavingsAccount extends AbstractPersistableCustom {
|
||||
this.closedOnDate = DateUtils.getBusinessLocalDate();
|
||||
this.closedBy = appUser;
|
||||
boolean postInterestAsOnDate = false;
|
||||
boolean postReversals = false;
|
||||
LocalDate transactionDate = DateUtils.getBusinessLocalDate();
|
||||
if (this.getSummary().getAccountBalance(this.getCurrency()).isGreaterThanZero()) {
|
||||
SavingsAccountTransaction transaction = SavingsAccountTransaction.escheat(this, transactionDate, appUser, postInterestAsOnDate);
|
||||
this.transactions.add(transaction);
|
||||
}
|
||||
boolean postReversals = false;
|
||||
recalculateDailyBalances(Money.zero(this.currency), transactionDate, false, postReversals);
|
||||
this.summary.updateSummary(this.currency, this.savingsAccountTransactionSummaryWrapper, this.transactions);
|
||||
}
|
||||
|
||||
+7
-4
@@ -92,6 +92,7 @@ public class SavingsAccountDomainServiceJpa implements SavingsAccountDomainServi
|
||||
final boolean isSavingsInterestPostingAtCurrentPeriodEnd = this.configurationDomainService
|
||||
.isSavingsInterestPostingAtCurrentPeriodEnd();
|
||||
final Long relaxingDaysConfigForPivotDate = this.configurationDomainService.retrieveRelaxingDaysConfigForPivotDate();
|
||||
final boolean postReversals = this.configurationDomainService.isReversalTransactionAllowed();
|
||||
final Integer financialYearBeginningMonth = this.configurationDomainService.retrieveFinancialYearBeginningMonth();
|
||||
if (transactionBooleanValues.isRegularTransaction() && !account.allowWithdrawal()) {
|
||||
throw new DepositAccountTransactionNotAllowedException(account.getId(), "withdraw", account.depositAccountType());
|
||||
@@ -115,7 +116,7 @@ public class SavingsAccountDomainServiceJpa implements SavingsAccountDomainServi
|
||||
final MathContext mc = MathContext.DECIMAL64;
|
||||
|
||||
final LocalDate today = DateUtils.getBusinessLocalDate();
|
||||
boolean postReversals = false;
|
||||
|
||||
if (account.isBeforeLastPostingPeriod(transactionDate, backdatedTxnsAllowedTill)) {
|
||||
account.postInterest(mc, today, transactionBooleanValues.isInterestTransfer(), isSavingsInterestPostingAtCurrentPeriodEnd,
|
||||
financialYearBeginningMonth, postInterestOnDate, backdatedTxnsAllowedTill, postReversals);
|
||||
@@ -202,7 +203,7 @@ public class SavingsAccountDomainServiceJpa implements SavingsAccountDomainServi
|
||||
final MathContext mc = MathContext.DECIMAL64;
|
||||
|
||||
final LocalDate today = DateUtils.getBusinessLocalDate();
|
||||
boolean postReversals = false;
|
||||
boolean postReversals = this.configurationDomainService.isReversalTransactionAllowed();
|
||||
if (account.isBeforeLastPostingPeriod(transactionDate, backdatedTxnsAllowedTill)) {
|
||||
account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth,
|
||||
postInterestOnDate, backdatedTxnsAllowedTill, postReversals);
|
||||
@@ -297,6 +298,7 @@ public class SavingsAccountDomainServiceJpa implements SavingsAccountDomainServi
|
||||
.isSavingsInterestPostingAtCurrentPeriodEnd();
|
||||
final Integer financialYearBeginningMonth = this.configurationDomainService.retrieveFinancialYearBeginningMonth();
|
||||
final Long relaxingDaysConfigForPivotDate = this.configurationDomainService.retrieveRelaxingDaysConfigForPivotDate();
|
||||
final boolean postReversals = true;
|
||||
final Set<Long> existingTransactionIds = new HashSet<>();
|
||||
final Set<Long> existingReversedTransactionIds = new HashSet<>();
|
||||
|
||||
@@ -314,7 +316,9 @@ public class SavingsAccountDomainServiceJpa implements SavingsAccountDomainServi
|
||||
chargePaidBySet = savingsAccountTransaction.getSavingsAccountChargesPaid();
|
||||
reversal.getSavingsAccountChargesPaid().addAll(chargePaidBySet);
|
||||
account.undoTransaction(savingsAccountTransaction);
|
||||
newTransactions.add(reversal);
|
||||
if (postReversals) {
|
||||
newTransactions.add(reversal);
|
||||
}
|
||||
}
|
||||
|
||||
boolean isInterestTransfer = false;
|
||||
@@ -322,7 +326,6 @@ public class SavingsAccountDomainServiceJpa implements SavingsAccountDomainServi
|
||||
final LocalDate today = DateUtils.getBusinessLocalDate();
|
||||
final MathContext mc = new MathContext(15, MoneyHelper.getRoundingMode());
|
||||
for (SavingsAccountTransaction savingsAccountTransaction : savingsAccountTransactions) {
|
||||
boolean postReversals = true;
|
||||
if (savingsAccountTransaction.isPostInterestCalculationRequired()
|
||||
&& account.isBeforeLastPostingPeriod(savingsAccountTransaction.transactionLocalDate(), backdatedTxnsAllowedTill)) {
|
||||
|
||||
|
||||
+16
-18
@@ -151,7 +151,7 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
final boolean isSavingsInterestPostingAtCurrentPeriodEnd = this.configurationDomainService
|
||||
.isSavingsInterestPostingAtCurrentPeriodEnd();
|
||||
final Integer financialYearBeginningMonth = this.configurationDomainService.retrieveFinancialYearBeginningMonth();
|
||||
|
||||
final boolean postReversals = false;
|
||||
this.depositAccountTransactionDataValidator.validateActivation(command);
|
||||
final MathContext mc = MathContext.DECIMAL64;
|
||||
final FixedDepositAccount account = (FixedDepositAccount) this.depositAccountAssembler.assembleFrom(savingsId,
|
||||
@@ -189,7 +189,6 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
}
|
||||
final boolean isInterestTransfer = false;
|
||||
final LocalDate postInterestOnDate = null;
|
||||
final boolean postReversals = false;
|
||||
if (activationChargeAmount.isGreaterThanZero()) {
|
||||
payActivationCharge(account, user);
|
||||
}
|
||||
@@ -259,7 +258,7 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
final boolean isSavingsInterestPostingAtCurrentPeriodEnd = this.configurationDomainService
|
||||
.isSavingsInterestPostingAtCurrentPeriodEnd();
|
||||
final Integer financialYearBeginningMonth = this.configurationDomainService.retrieveFinancialYearBeginningMonth();
|
||||
|
||||
final boolean postReversals = false;
|
||||
this.depositAccountTransactionDataValidator.validateActivation(command);
|
||||
|
||||
final RecurringDepositAccount account = (RecurringDepositAccount) this.depositAccountAssembler.assembleFrom(savingsId,
|
||||
@@ -317,11 +316,10 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
account.updateOverduePayments(overdueUptoDate);
|
||||
final boolean isInterestTransfer = false;
|
||||
final LocalDate postInterestOnDate = null;
|
||||
boolean postReversals = false;
|
||||
if (account.isBeforeLastPostingPeriod(account.getActivationLocalDate(), false)) {
|
||||
final LocalDate today = DateUtils.getBusinessLocalDate();
|
||||
account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth,
|
||||
postInterestOnDate, false);
|
||||
postInterestOnDate, false, postReversals);
|
||||
} else {
|
||||
final LocalDate today = DateUtils.getBusinessLocalDate();
|
||||
account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
|
||||
@@ -473,7 +471,7 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
checkClientOrGroupActive(account);
|
||||
|
||||
final LocalDate today = DateUtils.getBusinessLocalDate();
|
||||
boolean postReversals = false;
|
||||
final boolean postReversals = false;
|
||||
final MathContext mc = new MathContext(15, MoneyHelper.getRoundingMode());
|
||||
boolean isInterestTransfer = false;
|
||||
LocalDate postInterestOnDate = null;
|
||||
@@ -521,7 +519,7 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
final MathContext mc = new MathContext(10, MoneyHelper.getRoundingMode());
|
||||
boolean isInterestTransfer = false;
|
||||
LocalDate postInterestOnDate = null;
|
||||
boolean postReversals = false;
|
||||
final boolean postReversals = false;
|
||||
account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth,
|
||||
postInterestOnDate, false, postReversals);
|
||||
this.savingAccountRepositoryWrapper.saveAndFlush(account);
|
||||
@@ -573,11 +571,11 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
boolean isInterestTransfer = false;
|
||||
LocalDate postInterestOnDate = null;
|
||||
checkClientOrGroupActive(account);
|
||||
boolean postReversals = false;
|
||||
final boolean postReversals = false;
|
||||
if (savingsAccountTransaction.isPostInterestCalculationRequired()
|
||||
&& account.isBeforeLastPostingPeriod(savingsAccountTransaction.transactionLocalDate(), false)) {
|
||||
account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth,
|
||||
postInterestOnDate, false);
|
||||
postInterestOnDate, false, postReversals);
|
||||
} else {
|
||||
account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
|
||||
financialYearBeginningMonth, postInterestOnDate, false, postReversals);
|
||||
@@ -686,11 +684,11 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
final Long newtransactionId = saveTransactionToGenerateTransactionId(transaction);
|
||||
boolean isInterestTransfer = false;
|
||||
final LocalDate postInterestOnDate = null;
|
||||
boolean postReversals = false;
|
||||
final boolean postReversals = false;
|
||||
if (account.isBeforeLastPostingPeriod(transactionDate, false)
|
||||
|| account.isBeforeLastPostingPeriod(savingsAccountTransaction.transactionLocalDate(), false)) {
|
||||
account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth,
|
||||
postInterestOnDate, false);
|
||||
postInterestOnDate, false, postReversals);
|
||||
} else {
|
||||
account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
|
||||
financialYearBeginningMonth, postInterestOnDate, false, postReversals);
|
||||
@@ -915,7 +913,7 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
savingsAccount.setStatus(SavingsAccountStatusType.TRANSFER_IN_PROGRESS.getValue());
|
||||
final MathContext mc = MathContext.DECIMAL64;
|
||||
boolean isInterestTransfer = false;
|
||||
boolean postReversals = false;
|
||||
final boolean postReversals = false;
|
||||
savingsAccount.calculateInterestUsing(mc, transferDate, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
|
||||
financialYearBeginningMonth, postInterestOnDate, false, postReversals);
|
||||
|
||||
@@ -947,7 +945,7 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
savingsAccount.office(), transferDate, user);
|
||||
savingsAccount.addTransaction(withdrawtransferTransaction);
|
||||
savingsAccount.setStatus(SavingsAccountStatusType.ACTIVE.getValue());
|
||||
boolean postReversals = false;
|
||||
final boolean postReversals = false;
|
||||
final MathContext mc = MathContext.DECIMAL64;
|
||||
boolean isInterestTransfer = false;
|
||||
LocalDate postInterestOnDate = null;
|
||||
@@ -993,7 +991,7 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
savingsAccount.reassignSavingsOfficer(fieldOfficer, transferDate);
|
||||
}
|
||||
boolean isInterestTransfer = false;
|
||||
boolean postReversals = false;
|
||||
final boolean postReversals = false;
|
||||
LocalDate postInterestOnDate = null;
|
||||
final MathContext mc = MathContext.DECIMAL64;
|
||||
savingsAccount.calculateInterestUsing(mc, transferDate, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
|
||||
@@ -1150,7 +1148,7 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
boolean isInterestTransfer = false;
|
||||
LocalDate postInterestOnDate = null;
|
||||
final MathContext mc = MathContext.DECIMAL64;
|
||||
boolean postReversals = false;
|
||||
final boolean postReversals = false;
|
||||
if (account.isBeforeLastPostingPeriod(savingsAccountCharge.getDueLocalDate(), false)) {
|
||||
final LocalDate today = DateUtils.getBusinessLocalDate();
|
||||
account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth,
|
||||
@@ -1290,7 +1288,7 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
boolean isInterestTransfer = false;
|
||||
LocalDate postInterestOnDate = null;
|
||||
final MathContext mc = MathContext.DECIMAL64;
|
||||
boolean postReversals = false;
|
||||
final boolean postReversals = false;
|
||||
if (account.isBeforeLastPostingPeriod(transactionDate, false)) {
|
||||
final LocalDate today = DateUtils.getBusinessLocalDate();
|
||||
account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth,
|
||||
@@ -1321,7 +1319,7 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
final boolean isSavingsInterestPostingAtCurrentPeriodEnd = this.configurationDomainService
|
||||
.isSavingsInterestPostingAtCurrentPeriodEnd();
|
||||
final Integer financialYearBeginningMonth = this.configurationDomainService.retrieveFinancialYearBeginningMonth();
|
||||
|
||||
final boolean postReversals = false;
|
||||
final SavingsAccount account = this.depositAccountAssembler.assembleFrom(depositAccountId, depositAccountType);
|
||||
final Set<Long> existingTransactionIds = new HashSet<>();
|
||||
final Set<Long> existingReversedTransactionIds = new HashSet<>();
|
||||
@@ -1356,7 +1354,7 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
}
|
||||
} else if (depositAccountType.isRecurringDeposit()) {
|
||||
((RecurringDepositAccount) account).updateMaturityStatus(isSavingsInterestPostingAtCurrentPeriodEnd,
|
||||
financialYearBeginningMonth);
|
||||
financialYearBeginningMonth, postReversals);
|
||||
}
|
||||
this.savingAccountRepositoryWrapper.saveAndFlush(account);
|
||||
postJournalEntries(account, existingTransactionIds, existingReversedTransactionIds);
|
||||
|
||||
@@ -45,4 +45,5 @@
|
||||
<include file="parts/0023_use_the_proper_date_or_datetime_type.xml" relativeToChangelogFile="true"/>
|
||||
<include file="parts/0024_add_audit_entries.xml" relativeToChangelogFile="true"/>
|
||||
<include file="parts/0025_add_audit_entries_to_journal_entry.xml" relativeToChangelogFile="true"/>
|
||||
<include file="parts/0026_reversals_for_reversed_transactions.xml" relativeToChangelogFile="true"/>
|
||||
</databaseChangeLog>
|
||||
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
|
||||
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.
|
||||
|
||||
-->
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.1.xsd">
|
||||
<changeSet author="fineract" id="1">
|
||||
<insert tableName="c_configuration">
|
||||
<column name="id" valueNumeric="46"/>
|
||||
<column name="name" value="enable-post-reversal-txns-for-reverse-transactions"/>
|
||||
<column name="value"/>
|
||||
<column name="date_value"/>
|
||||
<column name="string_value"/>
|
||||
<column name="enabled" valueBoolean="false"/>
|
||||
<column name="is_trap_door" valueBoolean="false"/>
|
||||
<column name="description"/>
|
||||
</insert>
|
||||
</changeSet>
|
||||
</databaseChangeLog>
|
||||
+64
@@ -2990,6 +2990,70 @@ public class ClientSavingsIntegrationTest {
|
||||
assertEquals("error.msg.savings.transaction.is.not.allowed", error.get(0).get(CommonConstants.RESPONSE_ERROR_MESSAGE_CODE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReversalEntriesAfterSystemReversingTransactionWithReversalConfigOn() {
|
||||
this.savingsAccountHelper = new SavingsAccountHelper(this.requestSpec, this.responseSpec);
|
||||
this.savingsProductHelper = new SavingsProductHelper();
|
||||
this.scheduleJobHelper = new SchedulerJobHelper(requestSpec);
|
||||
GlobalConfigurationHelper.updateEnabledFlagForGlobalConfiguration(this.requestSpec, this.responseSpec, "46", true);
|
||||
LocalDate transactionDate = LocalDate.now(Utils.getZoneIdOfTenant()).minusDays(5);
|
||||
LocalDate nextTransactionDate = transactionDate.plusDays(2);
|
||||
final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd MMMM yyyy");
|
||||
String startDate = formatter.format(transactionDate);
|
||||
String nxtTransaction = formatter.format(nextTransactionDate);
|
||||
final String jobName = "Post Interest For Savings";
|
||||
final Integer clientID = ClientHelper.createClient(this.requestSpec, this.responseSpec, startDate);
|
||||
Assertions.assertNotNull(clientID);
|
||||
|
||||
final Integer savingsId = createSavingsAccountDailyPostingOverdraft(clientID, startDate);
|
||||
this.savingsAccountHelper.withdrawalFromSavingsAccount(savingsId, "100", startDate, CommonConstants.RESPONSE_RESOURCE_ID);
|
||||
this.scheduleJobHelper.executeAndAwaitJob(jobName);
|
||||
this.savingsAccountHelper.withdrawalFromSavingsAccount(savingsId, "100", nxtTransaction, CommonConstants.RESPONSE_RESOURCE_ID);
|
||||
|
||||
List<HashMap> transactions = this.savingsAccountHelper.getSavingsTransactions(savingsId);
|
||||
boolean reversalFlag = false;
|
||||
for (int i = 0; i < transactions.size(); i++) {
|
||||
boolean isReversal = (boolean) transactions.get(i).get("isReversal");
|
||||
if (isReversal) {
|
||||
reversalFlag = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
Assertions.assertTrue(reversalFlag);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReversalEntriesAfterSystemReversingTransactionWithReversalConfigOff() {
|
||||
this.savingsAccountHelper = new SavingsAccountHelper(this.requestSpec, this.responseSpec);
|
||||
this.savingsProductHelper = new SavingsProductHelper();
|
||||
this.scheduleJobHelper = new SchedulerJobHelper(requestSpec);
|
||||
GlobalConfigurationHelper.updateEnabledFlagForGlobalConfiguration(this.requestSpec, this.responseSpec, "46", false);
|
||||
LocalDate transactionDate = LocalDate.now(Utils.getZoneIdOfTenant()).minusDays(5);
|
||||
LocalDate nextTransactionDate = transactionDate.plusDays(2);
|
||||
final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd MMMM yyyy");
|
||||
String startDate = formatter.format(transactionDate);
|
||||
String nxtTransaction = formatter.format(nextTransactionDate);
|
||||
final String jobName = "Post Interest For Savings";
|
||||
final Integer clientID = ClientHelper.createClient(this.requestSpec, this.responseSpec, startDate);
|
||||
Assertions.assertNotNull(clientID);
|
||||
|
||||
final Integer savingsId = createSavingsAccountDailyPostingOverdraft(clientID, startDate);
|
||||
this.savingsAccountHelper.withdrawalFromSavingsAccount(savingsId, "100", startDate, CommonConstants.RESPONSE_RESOURCE_ID);
|
||||
this.scheduleJobHelper.executeAndAwaitJob(jobName);
|
||||
this.savingsAccountHelper.withdrawalFromSavingsAccount(savingsId, "100", nxtTransaction, CommonConstants.RESPONSE_RESOURCE_ID);
|
||||
|
||||
List<HashMap> transactions = this.savingsAccountHelper.getSavingsTransactions(savingsId);
|
||||
boolean reversalFlag = false;
|
||||
for (int i = 0; i < transactions.size(); i++) {
|
||||
boolean isReversal = (boolean) transactions.get(i).get("isReversal");
|
||||
if (isReversal) {
|
||||
reversalFlag = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
Assertions.assertFalse(reversalFlag);
|
||||
}
|
||||
|
||||
private Integer createSavingsAccountDailyPostingOverdraft(final Integer clientID, final String startDate) {
|
||||
final Integer savingsProductID = createSavingsProductDailyPostingOverdraft();
|
||||
Assertions.assertNotNull(savingsProductID);
|
||||
|
||||
+10
-2
@@ -99,8 +99,8 @@ public class GlobalConfigurationHelper {
|
||||
ArrayList<HashMap> actualGlobalConfigurations = getAllGlobalConfigurations(requestSpec, responseSpec);
|
||||
|
||||
// There are currently 37 global configurations.
|
||||
Assertions.assertEquals(40, expectedGlobalConfigurations.size());
|
||||
Assertions.assertEquals(40, actualGlobalConfigurations.size());
|
||||
Assertions.assertEquals(41, expectedGlobalConfigurations.size());
|
||||
Assertions.assertEquals(41, actualGlobalConfigurations.size());
|
||||
|
||||
for (int i = 0; i < expectedGlobalConfigurations.size(); i++) {
|
||||
|
||||
@@ -456,6 +456,14 @@ public class GlobalConfigurationHelper {
|
||||
isAutomaticCOBDateAdjustmentEnabled.put("trapDoor", false);
|
||||
defaults.add(isAutomaticCOBDateAdjustmentEnabled);
|
||||
|
||||
HashMap<String, Object> isReversalTransactionAllowed = new HashMap<>();
|
||||
isReversalTransactionAllowed.put("id", 46);
|
||||
isReversalTransactionAllowed.put("name", "enable-post-reversal-txns-for-reverse-transactions");
|
||||
isReversalTransactionAllowed.put("value", 0);
|
||||
isReversalTransactionAllowed.put("enabled", false);
|
||||
isReversalTransactionAllowed.put("trapDoor", false);
|
||||
defaults.add(isReversalTransactionAllowed);
|
||||
|
||||
return defaults;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user