Skip to content

Commit edc734c

Browse files
logoutdhavalDhaval Maniyar
authored andcommitted
FINERACT-1668: Adding Configuration for reversal transaction (#2454)
Co-authored-by: Dhaval Maniyar <dhavalmaniyar@Dhavals-MacBook-Pro.local>
1 parent 251b125 commit edc734c

12 files changed

Lines changed: 162 additions & 44 deletions

File tree

fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/domain/ConfigurationDomainService.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,4 +116,6 @@ public interface ConfigurationDomainService {
116116
boolean isBusinessDateEnabled();
117117

118118
boolean isCOBDateAdjustmentEnabled();
119+
120+
boolean isReversalTransactionAllowed();
119121
}

fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/domain/ConfigurationDomainServiceJpa.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -444,4 +444,11 @@ public boolean isBusinessDateEnabled() {
444444
public boolean isCOBDateAdjustmentEnabled() {
445445
return getGlobalConfigurationPropertyData(ENABLE_AUTOMATIC_COB_DATE_ADJUSTMENT).isEnabled();
446446
}
447+
448+
@Override
449+
public boolean isReversalTransactionAllowed() {
450+
final String propertyName = "enable-post-reversal-txns-for-reverse-transactions";
451+
final GlobalConfigurationPropertyData property = getGlobalConfigurationPropertyData(propertyName);
452+
return property.isEnabled();
453+
}
447454
}

fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/DepositAccountDomainServiceJpa.java

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,6 @@ public SavingsAccountTransaction handleRDDeposit(final RecurringDepositAccount a
140140
final boolean isSavingsInterestPostingAtCurrentPeriodEnd = this.configurationDomainService
141141
.isSavingsInterestPostingAtCurrentPeriodEnd();
142142
final Integer financialYearBeginningMonth = this.configurationDomainService.retrieveFinancialYearBeginningMonth();
143-
144143
boolean isAccountTransfer = false;
145144
final boolean isPreMatureClosure = false;
146145
final MathContext mc = MathContext.DECIMAL64;
@@ -348,7 +347,7 @@ public Long handleRDAccountClosure(final RecurringDepositAccount account, final
348347
final boolean isSavingsInterestPostingAtCurrentPeriodEnd = this.configurationDomainService
349348
.isSavingsInterestPostingAtCurrentPeriodEnd();
350349
final Integer financialYearBeginningMonth = this.configurationDomainService.retrieveFinancialYearBeginningMonth();
351-
350+
final boolean postReversals = false;
352351
boolean isRegularTransaction = false;
353352
boolean isAccountTransfer = false;
354353
final boolean isPreMatureClosure = false;
@@ -364,7 +363,7 @@ public Long handleRDAccountClosure(final RecurringDepositAccount account, final
364363
final DateTimeFormatter fmt = DateTimeFormatter.ofPattern(command.dateFormat()).withLocale(locale);
365364
final LocalDate closedDate = command.localDateValueOfParameterNamed(SavingsApiConstants.closedOnDateParamName);
366365
Long savingsTransactionId = null;
367-
account.postMaturityInterest(isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth, closedDate);
366+
account.postMaturityInterest(isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth, closedDate, postReversals);
368367
final BigDecimal transactionAmount = account.getAccountBalance();
369368
final Integer onAccountClosureId = command.integerValueOfParameterNamed(onAccountClosureIdParamName);
370369
final DepositAccountOnClosureType onClosureType = DepositAccountOnClosureType.fromInt(onAccountClosureId);
@@ -385,7 +384,7 @@ public Long handleRDAccountClosure(final RecurringDepositAccount account, final
385384
Integer frequency = CalendarUtils.getInterval(calendar.getRecurrence());
386385
frequency = frequency == -1 ? 1 : frequency;
387386
reinvestedDeposit.generateSchedule(frequencyType, frequency, calendar);
388-
reinvestedDeposit.processAccountUponActivation(fmt, user);
387+
reinvestedDeposit.processAccountUponActivation(fmt, user, postReversals);
389388
reinvestedDeposit.updateMaturityDateAndAmount(mc, isPreMatureClosure, isSavingsInterestPostingAtCurrentPeriodEnd,
390389
financialYearBeginningMonth);
391390
this.savingsAccountRepository.save(reinvestedDeposit);
@@ -520,7 +519,7 @@ public Long handleRDAccountPreMatureClosure(final RecurringDepositAccount accoun
520519
final boolean isSavingsInterestPostingAtCurrentPeriodEnd = this.configurationDomainService
521520
.isSavingsInterestPostingAtCurrentPeriodEnd();
522521
final Integer financialYearBeginningMonth = this.configurationDomainService.retrieveFinancialYearBeginningMonth();
523-
522+
final boolean postReversals = false;
524523
boolean isAccountTransfer = false;
525524
final boolean isPreMatureClosure = true;
526525
boolean isRegularTransaction = false;
@@ -537,7 +536,7 @@ public Long handleRDAccountPreMatureClosure(final RecurringDepositAccount accoun
537536
Long savingsTransactionId = null;
538537
// post interest
539538
account.postPreMaturityInterest(closedDate, isPreMatureClosure, isSavingsInterestPostingAtCurrentPeriodEnd,
540-
financialYearBeginningMonth);
539+
financialYearBeginningMonth, postReversals);
541540

542541
final Integer closureTypeValue = command.integerValueOfParameterNamed(DepositsApiConstants.onAccountClosureIdParamName);
543542
DepositAccountOnClosureType closureType = DepositAccountOnClosureType.fromInt(closureTypeValue);

fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/FixedDepositAccount.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
import javax.persistence.FetchType;
4040
import javax.persistence.OneToOne;
4141
import javax.persistence.Transient;
42+
import org.apache.fineract.infrastructure.configuration.domain.ConfigurationDomainService;
4243
import org.apache.fineract.infrastructure.core.api.JsonCommand;
4344
import org.apache.fineract.infrastructure.core.data.ApiParameterError;
4445
import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder;
@@ -77,6 +78,8 @@ public class FixedDepositAccount extends SavingsAccount {
7778

7879
@Transient
7980
protected InterestRateChartAssembler chartAssembler;
81+
@Transient
82+
private ConfigurationDomainService configurationDomainService;
8083

8184
protected FixedDepositAccount() {
8285
//

fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/RecurringDepositAccount.java

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -270,11 +270,11 @@ public void updateMaturityDateAndAmount(final MathContext mc, final boolean isPr
270270
}
271271
}
272272

273-
public void updateMaturityStatus(final boolean isSavingsInterestPostingAtCurrentPeriodEnd, final Integer financialYearBeginningMonth) {
273+
public void updateMaturityStatus(final boolean isSavingsInterestPostingAtCurrentPeriodEnd, final Integer financialYearBeginningMonth,
274+
final boolean postReversals) {
274275
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
275276
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
276277
.resource(RECURRING_DEPOSIT_ACCOUNT_RESOURCE_NAME + SavingsApiConstants.updateMaturityDetailsAction);
277-
278278
final SavingsAccountStatusType currentStatus = SavingsAccountStatusType.fromInt(this.status);
279279
if (!SavingsAccountStatusType.ACTIVE.hasStateOf(currentStatus)) {
280280
baseDataValidator.reset().failWithCodeNoParameterAddedToErrorCode("not.in.active.state");
@@ -287,7 +287,7 @@ public void updateMaturityStatus(final boolean isSavingsInterestPostingAtCurrent
287287
if (!this.maturityDate().isAfter(todayDate)) {
288288
// update account status
289289
this.status = SavingsAccountStatusType.MATURED.getValue();
290-
postMaturityInterest(isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth, todayDate);
290+
postMaturityInterest(isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth, todayDate, postReversals);
291291
}
292292
}
293293

@@ -537,7 +537,7 @@ public Money activateWithBalance() {
537537
return Money.of(this.currency, this.minRequiredOpeningBalance);
538538
}
539539

540-
protected void processAccountUponActivation(final DateTimeFormatter fmt, final AppUser user) {
540+
protected void processAccountUponActivation(final DateTimeFormatter fmt, final AppUser user, final boolean postReversals) {
541541
final Money minRequiredOpeningBalance = Money.of(this.currency, this.minRequiredOpeningBalance);
542542
final boolean backdatedTxnsAllowedTill = false;
543543
String refNo = null;
@@ -549,7 +549,6 @@ protected void processAccountUponActivation(final DateTimeFormatter fmt, final A
549549

550550
// update existing transactions so derived balance fields are
551551
// correct.
552-
boolean postReversals = false;
553552
recalculateDailyBalances(Money.zero(this.currency), DateUtils.getBusinessLocalDate(), backdatedTxnsAllowedTill, postReversals);
554553
}
555554
}
@@ -635,7 +634,7 @@ public void close(final AppUser currentUser, final JsonCommand command, final Lo
635634
}
636635

637636
public void postMaturityInterest(final boolean isSavingsInterestPostingAtCurrentPeriodEnd, final Integer financialYearBeginningMonth,
638-
final LocalDate closeDate) {
637+
final LocalDate closeDate, final boolean postReversals) {
639638
LocalDate interestPostingUpToDate = maturityDate();
640639
if (interestPostingUpToDate == null) {
641640
interestPostingUpToDate = closeDate;
@@ -645,7 +644,6 @@ public void postMaturityInterest(final boolean isSavingsInterestPostingAtCurrent
645644
boolean isInterestTransfer = false;
646645
LocalDate postInterestOnDate = null;
647646
final boolean backdatedTxnsAllowedTill = false;
648-
boolean postReversals = false;
649647
final List<PostingPeriod> postingPeriods = calculateInterestUsing(mc, interestPostingUpToDate.minusDays(1), isInterestTransfer,
650648
isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth, postInterestOnDate, backdatedTxnsAllowedTill,
651649
postReversals);
@@ -690,7 +688,7 @@ public void postMaturityInterest(final boolean isSavingsInterestPostingAtCurrent
690688
}
691689

692690
public void postPreMaturityInterest(final LocalDate accountCloseDate, final boolean isPreMatureClosure,
693-
final boolean isSavingsInterestPostingAtCurrentPeriodEnd, final Integer financialYearBeginningMonth) {
691+
final boolean isSavingsInterestPostingAtCurrentPeriodEnd, final Integer financialYearBeginningMonth, boolean postReversals) {
694692

695693
final Money interestPostedToDate = totalInterestPosted();
696694
// calculate interest before one day of closure date
@@ -713,7 +711,6 @@ public void postPreMaturityInterest(final LocalDate accountCloseDate, final bool
713711
}
714712

715713
applyWithholdTaxForDepositAccounts(accountCloseDate, recalucateDailyBalance, backdatedTxnsAllowedTill);
716-
boolean postReversals = false;
717714
if (recalucateDailyBalance) {
718715
// update existing transactions so derived balance fields are
719716
// correct.
@@ -755,11 +752,11 @@ private Money calculatePreMatureInterest(final LocalDate preMatureDate, final Li
755752
return interestOnMaturity;
756753
}
757754

755+
@Override
758756
public void postInterest(final MathContext mc, final LocalDate postingDate, final boolean isInterestTransfer,
759757
final boolean isSavingsInterestPostingAtCurrentPeriodEnd, final Integer financialYearBeginningMonth,
760-
final LocalDate postInterestAson, final boolean backdatedTxnsAllowedTill) {
758+
final LocalDate postInterestAson, final boolean backdatedTxnsAllowedTill, final boolean postReversals) {
761759
final LocalDate interestPostingUpToDate = interestPostingUpToDate(postingDate);
762-
boolean postReversals = false;
763760
super.postInterest(mc, interestPostingUpToDate, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
764761
financialYearBeginningMonth, postInterestAson, backdatedTxnsAllowedTill, postReversals);
765762
}

fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccount.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -977,7 +977,6 @@ protected List<SavingsAccountTransaction> retreiveListOfTransactions() {
977977

978978
protected void recalculateDailyBalances(final Money openingAccountBalance, final LocalDate interestPostingUpToDate,
979979
final boolean backdatedTxnsAllowedTill, boolean postReversals) {
980-
981980
Money runningBalance = openingAccountBalance.copy();
982981

983982
List<SavingsAccountTransaction> accountTransactionsSorted = null;
@@ -2775,6 +2774,7 @@ public void approveAndActivateApplication(final LocalDate appliedonDate, final A
27752774
private void payActivationCharges(final boolean isSavingsInterestPostingAtCurrentPeriodEnd, final Integer financialYearBeginningMonth,
27762775
final AppUser user, final boolean backdatedTxnsAllowedTill) {
27772776
boolean isSavingsChargeApplied = false;
2777+
boolean postReversals = false;
27782778
UUID refNo = UUID.randomUUID();
27792779
for (SavingsAccountCharge savingsAccountCharge : this.charges()) {
27802780
if (savingsAccountCharge.isSavingsActivation()) {
@@ -2788,7 +2788,6 @@ private void payActivationCharges(final boolean isSavingsInterestPostingAtCurren
27882788
final MathContext mc = MathContext.DECIMAL64;
27892789
boolean isInterestTransfer = false;
27902790
LocalDate postInterestAsOnDate = null;
2791-
boolean postReversals = false;
27922791
if (this.isBeforeLastPostingPeriod(getActivationLocalDate(), backdatedTxnsAllowedTill)) {
27932792
final LocalDate today = DateUtils.getBusinessLocalDate();
27942793
this.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth,
@@ -3551,12 +3550,12 @@ public void escheat(AppUser appUser) {
35513550
this.closedOnDate = DateUtils.getBusinessLocalDate();
35523551
this.closedBy = appUser;
35533552
boolean postInterestAsOnDate = false;
3553+
boolean postReversals = false;
35543554
LocalDate transactionDate = DateUtils.getBusinessLocalDate();
35553555
if (this.getSummary().getAccountBalance(this.getCurrency()).isGreaterThanZero()) {
35563556
SavingsAccountTransaction transaction = SavingsAccountTransaction.escheat(this, transactionDate, appUser, postInterestAsOnDate);
35573557
this.transactions.add(transaction);
35583558
}
3559-
boolean postReversals = false;
35603559
recalculateDailyBalances(Money.zero(this.currency), transactionDate, false, postReversals);
35613560
this.summary.updateSummary(this.currency, this.savingsAccountTransactionSummaryWrapper, this.transactions);
35623561
}

fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccountDomainServiceJpa.java

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ public SavingsAccountTransaction handleWithdrawal(final SavingsAccount account,
9292
final boolean isSavingsInterestPostingAtCurrentPeriodEnd = this.configurationDomainService
9393
.isSavingsInterestPostingAtCurrentPeriodEnd();
9494
final Long relaxingDaysConfigForPivotDate = this.configurationDomainService.retrieveRelaxingDaysConfigForPivotDate();
95+
final boolean postReversals = this.configurationDomainService.isReversalTransactionAllowed();
9596
final Integer financialYearBeginningMonth = this.configurationDomainService.retrieveFinancialYearBeginningMonth();
9697
if (transactionBooleanValues.isRegularTransaction() && !account.allowWithdrawal()) {
9798
throw new DepositAccountTransactionNotAllowedException(account.getId(), "withdraw", account.depositAccountType());
@@ -115,7 +116,7 @@ public SavingsAccountTransaction handleWithdrawal(final SavingsAccount account,
115116
final MathContext mc = MathContext.DECIMAL64;
116117

117118
final LocalDate today = DateUtils.getBusinessLocalDate();
118-
boolean postReversals = false;
119+
119120
if (account.isBeforeLastPostingPeriod(transactionDate, backdatedTxnsAllowedTill)) {
120121
account.postInterest(mc, today, transactionBooleanValues.isInterestTransfer(), isSavingsInterestPostingAtCurrentPeriodEnd,
121122
financialYearBeginningMonth, postInterestOnDate, backdatedTxnsAllowedTill, postReversals);
@@ -202,7 +203,7 @@ private SavingsAccountTransaction handleDeposit(final SavingsAccount account, fi
202203
final MathContext mc = MathContext.DECIMAL64;
203204

204205
final LocalDate today = DateUtils.getBusinessLocalDate();
205-
boolean postReversals = false;
206+
boolean postReversals = this.configurationDomainService.isReversalTransactionAllowed();
206207
if (account.isBeforeLastPostingPeriod(transactionDate, backdatedTxnsAllowedTill)) {
207208
account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth,
208209
postInterestOnDate, backdatedTxnsAllowedTill, postReversals);
@@ -297,6 +298,7 @@ public SavingsAccountTransaction handleReversal(SavingsAccount account, List<Sav
297298
.isSavingsInterestPostingAtCurrentPeriodEnd();
298299
final Integer financialYearBeginningMonth = this.configurationDomainService.retrieveFinancialYearBeginningMonth();
299300
final Long relaxingDaysConfigForPivotDate = this.configurationDomainService.retrieveRelaxingDaysConfigForPivotDate();
301+
final boolean postReversals = true;
300302
final Set<Long> existingTransactionIds = new HashSet<>();
301303
final Set<Long> existingReversedTransactionIds = new HashSet<>();
302304

@@ -314,15 +316,16 @@ public SavingsAccountTransaction handleReversal(SavingsAccount account, List<Sav
314316
chargePaidBySet = savingsAccountTransaction.getSavingsAccountChargesPaid();
315317
reversal.getSavingsAccountChargesPaid().addAll(chargePaidBySet);
316318
account.undoTransaction(savingsAccountTransaction);
317-
newTransactions.add(reversal);
319+
if (postReversals) {
320+
newTransactions.add(reversal);
321+
}
318322
}
319323

320324
boolean isInterestTransfer = false;
321325
LocalDate postInterestOnDate = null;
322326
final LocalDate today = DateUtils.getBusinessLocalDate();
323327
final MathContext mc = new MathContext(15, MoneyHelper.getRoundingMode());
324328
for (SavingsAccountTransaction savingsAccountTransaction : savingsAccountTransactions) {
325-
boolean postReversals = true;
326329
if (savingsAccountTransaction.isPostInterestCalculationRequired()
327330
&& account.isBeforeLastPostingPeriod(savingsAccountTransaction.transactionLocalDate(), backdatedTxnsAllowedTill)) {
328331

0 commit comments

Comments
 (0)