From 9e5e7329adfedb68dadd5cadabaef2ba43e22c88 Mon Sep 17 00:00:00 2001 From: Nazeer Hussain Shaik Date: Tue, 28 Jun 2016 11:09:42 +0530 Subject: [PATCH] Removing Hibernate annotations --- .../ClientLoanIntegrationTest.java | 1 + .../domain/ProvisioningEntry.java | 11 +- ...WritePlatformServiceJpaRepositoryImpl.java | 7 +- .../rule/domain/AccountingRule.java | 6 +- .../dataqueries/domain/Report.java | 6 +- .../infrastructure/hooks/domain/Hook.java | 10 +- .../hooks/domain/HookTemplate.java | 6 +- .../domain/ProvisioningCriteria.java | 9 +- .../domain/AccountTransferDetails.java | 5 +- .../portfolio/client/domain/Client.java | 5 +- .../client/domain/ClientTransaction.java | 6 +- .../floatingrates/domain/FloatingRate.java | 6 +- .../loanaccount/data/LoanAccountData.java | 1 - .../portfolio/loanaccount/domain/Loan.java | 357 ++++++++++-------- .../domain/LoanAccountDomainServiceJpa.java | 10 +- .../loanaccount/domain/LoanCharge.java | 5 +- .../LoanRepaymentScheduleInstallment.java | 16 +- .../loanaccount/domain/LoanTransaction.java | 11 +- .../guarantor/domain/Guarantor.java | 6 +- .../domain/GuarantorFundingDetails.java | 6 +- .../domain/AbstractLoanScheduleGenerator.java | 4 +- .../LoanScheduleModelDisbursementPeriod.java | 4 +- .../domain/LoanScheduleModelPeriod.java | 4 +- .../LoanScheduleModelRepaymentPeriod.java | 8 +- .../service/LoanScheduleAssembler.java | 13 +- ...cheduleCalculationPlatformServiceImpl.java | 7 +- .../LoanScheduleWritePlatformServiceImpl.java | 5 +- ...heduleRequestWritePlatformServiceImpl.java | 9 +- ...anApplicationCommandFromApiJsonHelper.java | 2 +- ...WritePlatformServiceJpaRepositoryImpl.java | 2 +- ...WritePlatformServiceJpaRepositoryImpl.java | 31 +- .../loanproduct/domain/LoanProduct.java | 17 +- .../DepositAccountDomainServiceJpa.java | 2 +- .../DepositAccountInterestRateChart.java | 6 +- .../DepositAccountInterestRateChartSlabs.java | 6 +- .../domain/RecurringDepositAccount.java | 49 ++- .../RecurringDepositScheduleInstallment.java | 4 + .../savings/domain/SavingsAccount.java | 90 +++-- .../savings/domain/SavingsAccountCharge.java | 3 +- .../savings/domain/SavingsAccountSummary.java | 3 +- .../domain/SavingsAccountTransaction.java | 9 +- ...vingsAccountTransactionSummaryWrapper.java | 24 +- ...WritePlatformServiceJpaRepositoryImpl.java | 6 +- ...WritePlatformServiceJpaRepositoryImpl.java | 44 +-- .../shareaccounts/domain/ShareAccount.java | 9 +- .../domain/ShareAccountTransaction.java | 6 +- .../shareproducts/domain/ShareProduct.java | 5 +- .../ShareProductDividendPayOutDetails.java | 6 +- .../portfolio/tax/domain/TaxComponent.java | 19 +- .../portfolio/tax/domain/TaxGroup.java | 18 +- .../tax/serialization/TaxValidator.java | 8 +- .../portfolio/tax/service/TaxAssembler.java | 8 +- .../portfolio/tax/service/TaxUtils.java | 5 +- .../service/TaxWritePlatformServiceImpl.java | 4 +- .../useradministration/domain/AppUser.java | 5 +- ...anRepaymentScheduleInstallmentBuilder.java | 4 +- 56 files changed, 475 insertions(+), 464 deletions(-) diff --git a/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/ClientLoanIntegrationTest.java b/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/ClientLoanIntegrationTest.java index b2a737c75..66740c8d7 100644 --- a/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/ClientLoanIntegrationTest.java +++ b/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/ClientLoanIntegrationTest.java @@ -3805,6 +3805,7 @@ public class ClientLoanIntegrationTest { final Integer loanID = applyForLoanApplicationForInterestRecalculation(clientID, loanProductID, LOAN_DISBURSEMENT_DATE, REST_START_DATE, LoanApplicationTestBuilder.DEFAULT_STRATEGY, null); + Assert.assertNotNull(loanID); HashMap loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(this.requestSpec, this.responseSpec, loanID); LoanStatusChecker.verifyLoanIsPending(loanStatusHashMap); diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/provisioning/domain/ProvisioningEntry.java b/fineract-provider/src/main/java/org/apache/fineract/accounting/provisioning/domain/ProvisioningEntry.java index 7d75c5c98..5b565079c 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/accounting/provisioning/domain/ProvisioningEntry.java +++ b/fineract-provider/src/main/java/org/apache/fineract/accounting/provisioning/domain/ProvisioningEntry.java @@ -21,10 +21,12 @@ package org.apache.fineract.accounting.provisioning.domain; import java.util.Collection; import java.util.Date; import java.util.HashSet; +import java.util.Set; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; +import javax.persistence.FetchType; import javax.persistence.JoinColumn; import javax.persistence.OneToMany; import javax.persistence.OneToOne; @@ -33,8 +35,6 @@ import javax.persistence.Temporal; import javax.persistence.TemporalType; import org.apache.fineract.useradministration.domain.AppUser; -import org.hibernate.annotations.LazyCollection; -import org.hibernate.annotations.LazyCollectionOption; import org.springframework.data.jpa.domain.AbstractPersistable; @Entity @@ -44,9 +44,8 @@ public class ProvisioningEntry extends AbstractPersistable { @Column(name = "journal_entry_created") private Boolean isJournalEntryCreated; - @LazyCollection(LazyCollectionOption.FALSE) - @OneToMany(cascade = CascadeType.ALL, mappedBy = "entry", orphanRemoval = true) - Collection provisioningEntries = new HashSet<>(); + @OneToMany(cascade = CascadeType.ALL, mappedBy = "entry", orphanRemoval = true, fetch=FetchType.EAGER) + Set provisioningEntries = new HashSet<>(); @OneToOne @JoinColumn(name = "createdby_id") @@ -68,7 +67,7 @@ public class ProvisioningEntry extends AbstractPersistable { } - public ProvisioningEntry(AppUser createdBy, Date createdDate, AppUser lastModifiedBy, Date lastModifiedDate, Collection provisioningEntries ) { + public ProvisioningEntry(AppUser createdBy, Date createdDate, AppUser lastModifiedBy, Date lastModifiedDate, Set provisioningEntries ) { this.provisioningEntries = provisioningEntries ; this.createdBy = createdBy ; this.createdDate = createdDate ; diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/provisioning/service/ProvisioningEntriesWritePlatformServiceJpaRepositoryImpl.java b/fineract-provider/src/main/java/org/apache/fineract/accounting/provisioning/service/ProvisioningEntriesWritePlatformServiceJpaRepositoryImpl.java index 2eb191e8a..517f20cff 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/accounting/provisioning/service/ProvisioningEntriesWritePlatformServiceJpaRepositoryImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/accounting/provisioning/service/ProvisioningEntriesWritePlatformServiceJpaRepositoryImpl.java @@ -22,6 +22,7 @@ import java.util.Collection; import java.util.Date; import java.util.HashMap; import java.util.Map; +import java.util.Set; import org.apache.fineract.accounting.glaccount.domain.GLAccount; import org.apache.fineract.accounting.glaccount.domain.GLAccountRepository; @@ -58,8 +59,6 @@ import org.apache.fineract.portfolio.loanproduct.domain.LoanProduct; import org.apache.fineract.portfolio.loanproduct.domain.LoanProductRepository; import org.apache.fineract.useradministration.domain.AppUser; import org.joda.time.LocalDate; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.dao.DataIntegrityViolationException; import org.springframework.stereotype.Service; @@ -69,8 +68,6 @@ import com.google.gson.JsonObject; @Service public class ProvisioningEntriesWritePlatformServiceJpaRepositoryImpl implements ProvisioningEntriesWritePlatformService { - private final static Logger logger = LoggerFactory.getLogger(ProvisioningEntriesWritePlatformServiceJpaRepositoryImpl.class); - private final ProvisioningEntriesReadPlatformService provisioningEntriesReadPlatformService; private final ProvisioningCriteriaReadPlatformService provisioningCriteriaReadPlatformService ; private final LoanProductRepository loanProductRepository; @@ -192,7 +189,7 @@ public class ProvisioningEntriesWritePlatformServiceJpaRepositoryImpl implements AppUser currentUser = this.platformSecurityContext.authenticatedUser(); AppUser lastModifiedBy = null; Date lastModifiedDate = null; - Collection nullEntries = null; + Set nullEntries = null; ProvisioningEntry requestedEntry = new ProvisioningEntry(currentUser, date, lastModifiedBy, lastModifiedDate, nullEntries); Collection entries = generateLoanProvisioningEntry(requestedEntry, date); requestedEntry.setProvisioningEntries(entries); diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/rule/domain/AccountingRule.java b/fineract-provider/src/main/java/org/apache/fineract/accounting/rule/domain/AccountingRule.java index c0027b4e9..a60372267 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/accounting/rule/domain/AccountingRule.java +++ b/fineract-provider/src/main/java/org/apache/fineract/accounting/rule/domain/AccountingRule.java @@ -28,6 +28,7 @@ import java.util.Set; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; +import javax.persistence.FetchType; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.OneToMany; @@ -40,8 +41,6 @@ import org.apache.fineract.accounting.journalentry.domain.JournalEntryType; import org.apache.fineract.accounting.rule.api.AccountingRuleJsonInputParams; import org.apache.fineract.infrastructure.core.api.JsonCommand; import org.apache.fineract.organisation.office.domain.Office; -import org.hibernate.annotations.LazyCollection; -import org.hibernate.annotations.LazyCollectionOption; import org.springframework.data.jpa.domain.AbstractPersistable; @Entity @@ -69,8 +68,7 @@ public class AccountingRule extends AbstractPersistable { @Column(name = "system_defined", nullable = false) private Boolean systemDefined; - @LazyCollection(LazyCollectionOption.FALSE) - @OneToMany(cascade = CascadeType.ALL, mappedBy = "accountingRule", orphanRemoval = true) + @OneToMany(cascade = CascadeType.ALL, mappedBy = "accountingRule", orphanRemoval = true, fetch=FetchType.EAGER) private final List accountingTagRules = new ArrayList<>(); @Column(name = "allow_multiple_credits", nullable = false) diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/dataqueries/domain/Report.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/dataqueries/domain/Report.java index 799f003dd..4d8fe0257 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/dataqueries/domain/Report.java +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/dataqueries/domain/Report.java @@ -29,6 +29,7 @@ import java.util.Set; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; +import javax.persistence.FetchType; import javax.persistence.OneToMany; import javax.persistence.Table; import javax.persistence.UniqueConstraint; @@ -39,8 +40,6 @@ import org.apache.fineract.infrastructure.core.data.ApiParameterError; import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder; import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException; import org.apache.fineract.infrastructure.core.exception.PlatformDataIntegrityException; -import org.hibernate.annotations.LazyCollection; -import org.hibernate.annotations.LazyCollectionOption; import org.springframework.data.jpa.domain.AbstractPersistable; import com.google.gson.JsonArray; @@ -74,8 +73,7 @@ public final class Report extends AbstractPersistable { @Column(name = "report_sql") private String reportSql; - @LazyCollection(LazyCollectionOption.FALSE) - @OneToMany(cascade = CascadeType.ALL, mappedBy = "report", orphanRemoval = true) + @OneToMany(cascade = CascadeType.ALL, mappedBy = "report", orphanRemoval = true, fetch=FetchType.EAGER) private final Set reportParameterUsages = new HashSet<>(); public static Report fromJson(final JsonCommand command, final Collection reportTypes) { diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/hooks/domain/Hook.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/hooks/domain/Hook.java index 986e69091..7f7ea7427 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/hooks/domain/Hook.java +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/hooks/domain/Hook.java @@ -20,16 +20,16 @@ package org.apache.fineract.infrastructure.hooks.domain; import com.google.gson.JsonArray; import com.google.gson.JsonElement; + import org.apache.commons.lang.StringUtils; import org.apache.fineract.infrastructure.core.api.JsonCommand; import org.apache.fineract.infrastructure.core.domain.AbstractAuditableCustom; import org.apache.fineract.template.domain.Template; import org.apache.fineract.useradministration.domain.AppUser; -import org.hibernate.annotations.LazyCollection; -import org.hibernate.annotations.LazyCollectionOption; import org.springframework.util.CollectionUtils; import javax.persistence.*; + import java.util.HashSet; import java.util.LinkedHashMap; import java.util.Map; @@ -47,12 +47,10 @@ public class Hook extends AbstractAuditableCustom { @Column(name = "is_active", nullable = false) private Boolean isActive; - @LazyCollection(LazyCollectionOption.FALSE) - @OneToMany(cascade = CascadeType.ALL, mappedBy = "hook", orphanRemoval = true) + @OneToMany(cascade = CascadeType.ALL, mappedBy = "hook", orphanRemoval = true, fetch=FetchType.EAGER) private Set events = new HashSet<>(); - @LazyCollection(LazyCollectionOption.FALSE) - @OneToMany(cascade = CascadeType.ALL, mappedBy = "hook", orphanRemoval = true) + @OneToMany(cascade = CascadeType.ALL, mappedBy = "hook", orphanRemoval = true, fetch=FetchType.EAGER) private Set config = new HashSet<>(); @ManyToOne(optional = true) diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/hooks/domain/HookTemplate.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/hooks/domain/HookTemplate.java index 0da4af84b..904db7aa3 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/hooks/domain/HookTemplate.java +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/hooks/domain/HookTemplate.java @@ -26,13 +26,12 @@ import java.util.Set; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; +import javax.persistence.FetchType; import javax.persistence.OneToMany; import javax.persistence.Table; import org.apache.commons.lang.StringUtils; import org.apache.fineract.infrastructure.core.api.JsonCommand; -import org.hibernate.annotations.LazyCollection; -import org.hibernate.annotations.LazyCollectionOption; import org.springframework.data.jpa.domain.AbstractPersistable; @Entity @@ -42,8 +41,7 @@ public class HookTemplate extends AbstractPersistable { @Column(name = "name", nullable = false, length = 100) private String name; - @LazyCollection(LazyCollectionOption.FALSE) - @OneToMany(cascade = CascadeType.ALL, mappedBy = "template", orphanRemoval = true) + @OneToMany(cascade = CascadeType.ALL, mappedBy = "template", orphanRemoval = true, fetch=FetchType.EAGER) private final Set fields = new HashSet<>(); private HookTemplate(final String name) { diff --git a/fineract-provider/src/main/java/org/apache/fineract/organisation/provisioning/domain/ProvisioningCriteria.java b/fineract-provider/src/main/java/org/apache/fineract/organisation/provisioning/domain/ProvisioningCriteria.java index 90aeb4756..320b3ccdd 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/organisation/provisioning/domain/ProvisioningCriteria.java +++ b/fineract-provider/src/main/java/org/apache/fineract/organisation/provisioning/domain/ProvisioningCriteria.java @@ -27,6 +27,7 @@ import java.util.Set; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; +import javax.persistence.FetchType; import javax.persistence.OneToMany; import javax.persistence.Table; import javax.persistence.UniqueConstraint; @@ -38,8 +39,6 @@ import org.apache.fineract.organisation.provisioning.constants.ProvisioningCrite import org.apache.fineract.organisation.provisioning.data.ProvisioningCriteriaDefinitionData; import org.apache.fineract.portfolio.loanproduct.domain.LoanProduct; import org.apache.fineract.useradministration.domain.AppUser; -import org.hibernate.annotations.LazyCollection; -import org.hibernate.annotations.LazyCollectionOption; import org.joda.time.DateTime; @Entity @@ -49,12 +48,10 @@ public class ProvisioningCriteria extends AbstractAuditableCustom @Column(name = "criteria_name", nullable = false) private String criteriaName; - @LazyCollection(LazyCollectionOption.FALSE) - @OneToMany(cascade = CascadeType.ALL, mappedBy = "criteria", orphanRemoval = true) + @OneToMany(cascade = CascadeType.ALL, mappedBy = "criteria", orphanRemoval = true, fetch=FetchType.EAGER) Set provisioningCriteriaDefinition = new HashSet<>(); - @LazyCollection(LazyCollectionOption.FALSE) - @OneToMany(cascade = CascadeType.ALL, mappedBy = "criteria", orphanRemoval = true) + @OneToMany(cascade = CascadeType.ALL, mappedBy = "criteria", orphanRemoval = true, fetch=FetchType.EAGER) Set loanProductMapping = new HashSet<>(); public String getCriteriaName() { diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/domain/AccountTransferDetails.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/domain/AccountTransferDetails.java index 710660234..d8cd05757 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/domain/AccountTransferDetails.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/domain/AccountTransferDetails.java @@ -35,8 +35,6 @@ import org.apache.fineract.organisation.office.domain.Office; import org.apache.fineract.portfolio.client.domain.Client; import org.apache.fineract.portfolio.loanaccount.domain.Loan; import org.apache.fineract.portfolio.savings.domain.SavingsAccount; -import org.hibernate.annotations.LazyCollection; -import org.hibernate.annotations.LazyCollectionOption; import org.springframework.data.jpa.domain.AbstractPersistable; @Entity @@ -78,8 +76,7 @@ public class AccountTransferDetails extends AbstractPersistable { @Column(name = "transfer_type") private Integer transferType; - @LazyCollection(LazyCollectionOption.FALSE) - @OneToMany(cascade = CascadeType.ALL, mappedBy = "accountTransferDetails", orphanRemoval = true) + @OneToMany(cascade = CascadeType.ALL, mappedBy = "accountTransferDetails", orphanRemoval = true, fetch=FetchType.EAGER) private final List accountTransferTransactions = new ArrayList<>(); @OneToOne(mappedBy = "accountTransferDetails", cascade = CascadeType.ALL, optional = true, orphanRemoval = true, fetch = FetchType.LAZY) diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/domain/Client.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/domain/Client.java index 5ed9ad445..70f205a0b 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/domain/Client.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/domain/Client.java @@ -57,8 +57,6 @@ import org.apache.fineract.portfolio.group.domain.Group; import org.apache.fineract.portfolio.savings.domain.SavingsAccount; import org.apache.fineract.portfolio.savings.domain.SavingsProduct; import org.apache.fineract.useradministration.domain.AppUser; -import org.hibernate.annotations.LazyCollection; -import org.hibernate.annotations.LazyCollectionOption; import org.joda.time.LocalDate; import org.joda.time.format.DateTimeFormatter; import org.springframework.data.jpa.domain.AbstractPersistable; @@ -134,8 +132,7 @@ public final class Client extends AbstractPersistable { @JoinColumn(name = "staff_id") private Staff staff; - @LazyCollection(LazyCollectionOption.FALSE) - @ManyToMany + @ManyToMany(fetch=FetchType.EAGER) @JoinTable(name = "m_group_client", joinColumns = @JoinColumn(name = "client_id"), inverseJoinColumns = @JoinColumn(name = "group_id")) private Set groups; diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/domain/ClientTransaction.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/domain/ClientTransaction.java index e3f56f6e9..65a0e36e8 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/domain/ClientTransaction.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/domain/ClientTransaction.java @@ -30,6 +30,7 @@ import java.util.Set; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; +import javax.persistence.FetchType; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.OneToMany; @@ -48,8 +49,6 @@ import org.apache.fineract.organisation.office.domain.Office; import org.apache.fineract.organisation.office.domain.OrganisationCurrency; import org.apache.fineract.portfolio.paymentdetail.domain.PaymentDetail; import org.apache.fineract.useradministration.domain.AppUser; -import org.hibernate.annotations.LazyCollection; -import org.hibernate.annotations.LazyCollectionOption; import org.joda.time.LocalDate; import org.springframework.data.jpa.domain.AbstractPersistable; @@ -96,8 +95,7 @@ public class ClientTransaction extends AbstractPersistable { @JoinColumn(name = "appuser_id", nullable = true) private AppUser appUser; - @LazyCollection(LazyCollectionOption.FALSE) - @OneToMany(cascade = CascadeType.ALL, mappedBy = "clientTransaction", orphanRemoval = true) + @OneToMany(cascade = CascadeType.ALL, mappedBy = "clientTransaction", orphanRemoval = true, fetch=FetchType.EAGER) private Set clientChargePaidByCollection = new HashSet<>(); @Transient diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/floatingrates/domain/FloatingRate.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/floatingrates/domain/FloatingRate.java index b6649a68d..6275074b8 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/floatingrates/domain/FloatingRate.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/floatingrates/domain/FloatingRate.java @@ -30,6 +30,7 @@ import java.util.Set; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; +import javax.persistence.FetchType; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.OneToMany; @@ -43,8 +44,6 @@ import org.apache.fineract.infrastructure.core.service.DateUtils; import org.apache.fineract.portfolio.floatingrates.data.FloatingRateDTO; import org.apache.fineract.portfolio.floatingrates.data.FloatingRatePeriodData; import org.apache.fineract.useradministration.domain.AppUser; -import org.hibernate.annotations.LazyCollection; -import org.hibernate.annotations.LazyCollectionOption; import org.joda.time.LocalDate; import org.springframework.data.jpa.domain.AbstractPersistable; @@ -66,8 +65,7 @@ public class FloatingRate extends AbstractPersistable { private boolean isActive; @OrderBy(value = "fromDate,id") - @LazyCollection(LazyCollectionOption.FALSE) - @OneToMany(cascade = CascadeType.ALL, mappedBy = "floatingRate", orphanRemoval = true) + @OneToMany(cascade = CascadeType.ALL, mappedBy = "floatingRate", orphanRemoval = true, fetch=FetchType.EAGER) private Set floatingRatePeriods; @ManyToOne(optional = true) diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/LoanAccountData.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/LoanAccountData.java index 555ed3bec..fa6881d74 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/LoanAccountData.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/LoanAccountData.java @@ -48,7 +48,6 @@ import org.apache.fineract.portfolio.loanproduct.data.TransactionProcessingStrat import org.apache.fineract.portfolio.loanproduct.domain.LoanProductConfigurableAttributes; import org.apache.fineract.portfolio.loanproduct.domain.LoanProductValueConditionType; import org.apache.fineract.portfolio.note.data.NoteData; -import org.hibernate.dialect.Sybase11Dialect; import org.joda.time.LocalDate; import org.springframework.util.CollectionUtils; diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/Loan.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/Loan.java index 12a2db36e..5bd7a0bf6 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/Loan.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/Loan.java @@ -40,6 +40,7 @@ import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Embedded; import javax.persistence.Entity; +import javax.persistence.FetchType; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.OneToMany; @@ -130,8 +131,6 @@ import org.apache.fineract.portfolio.loanproduct.domain.RecalculationFrequencyTy import org.apache.fineract.portfolio.loanproduct.service.LoanEnumerations; import org.apache.fineract.portfolio.paymentdetail.domain.PaymentDetail; import org.apache.fineract.useradministration.domain.AppUser; -import org.hibernate.annotations.LazyCollection; -import org.hibernate.annotations.LazyCollectionOption; import org.joda.time.Days; import org.joda.time.LocalDate; import org.joda.time.LocalDateTime; @@ -172,23 +171,23 @@ public class Loan extends AbstractPersistable { @Column(name = "loan_type_enum", nullable = false) private Integer loanType; - @ManyToOne + @ManyToOne(fetch=FetchType.EAGER) @JoinColumn(name = "product_id", nullable = false) private LoanProduct loanProduct; - @ManyToOne(optional = true) + @ManyToOne(optional = true, fetch=FetchType.EAGER) @JoinColumn(name = "fund_id", nullable = true) private Fund fund; - @ManyToOne + @ManyToOne(fetch=FetchType.EAGER) @JoinColumn(name = "loan_officer_id", nullable = true) private Staff loanOfficer; - @ManyToOne + @ManyToOne(fetch=FetchType.LAZY) @JoinColumn(name = "loanpurpose_cv_id", nullable = true) private CodeValue loanPurpose; - @ManyToOne + @ManyToOne(fetch=FetchType.EAGER) @JoinColumn(name = "loan_transaction_strategy_id", nullable = true) private LoanTransactionProcessingStrategy transactionProcessingStrategy; @@ -212,7 +211,7 @@ public class Loan extends AbstractPersistable { @Column(name = "submittedon_date") private Date submittedOnDate; - @ManyToOne(optional = true) + @ManyToOne(optional = true, fetch=FetchType.LAZY) @JoinColumn(name = "submittedon_userid", nullable = true) private AppUser submittedBy; @@ -220,7 +219,7 @@ public class Loan extends AbstractPersistable { @Column(name = "rejectedon_date") private Date rejectedOnDate; - @ManyToOne(optional = true) + @ManyToOne(optional = true, fetch=FetchType.LAZY) @JoinColumn(name = "rejectedon_userid", nullable = true) private AppUser rejectedBy; @@ -228,7 +227,7 @@ public class Loan extends AbstractPersistable { @Column(name = "withdrawnon_date") private Date withdrawnOnDate; - @ManyToOne(optional = true) + @ManyToOne(optional = true, fetch=FetchType.LAZY) @JoinColumn(name = "withdrawnon_userid", nullable = true) private AppUser withdrawnBy; @@ -236,7 +235,7 @@ public class Loan extends AbstractPersistable { @Column(name = "approvedon_date") private Date approvedOnDate; - @ManyToOne(optional = true) + @ManyToOne(optional = true, fetch=FetchType.LAZY) @JoinColumn(name = "approvedon_userid", nullable = true) private AppUser approvedBy; @@ -248,7 +247,7 @@ public class Loan extends AbstractPersistable { @Column(name = "disbursedon_date") private Date actualDisbursementDate; - @ManyToOne(optional = true) + @ManyToOne(optional = true, fetch=FetchType.LAZY) @JoinColumn(name = "disbursedon_userid", nullable = true) private AppUser disbursedBy; @@ -256,7 +255,7 @@ public class Loan extends AbstractPersistable { @Column(name = "closedon_date") private Date closedOnDate; - @ManyToOne(optional = true) + @ManyToOne(optional = true, fetch=FetchType.LAZY) @JoinColumn(name = "closedon_userid", nullable = true) private AppUser closedBy; @@ -268,7 +267,7 @@ public class Loan extends AbstractPersistable { @Column(name = "rescheduledon_date") private Date rescheduledOnDate; - @ManyToOne(optional = true) + @ManyToOne(optional = true, fetch=FetchType.LAZY) @JoinColumn(name = "rescheduledon_userid", nullable = true) private AppUser rescheduledByUser; @@ -297,36 +296,38 @@ public class Loan extends AbstractPersistable { @Column(name = "loan_product_counter") private Integer loanProductCounter; - @LazyCollection(LazyCollectionOption.FALSE) - @OneToMany(cascade = CascadeType.ALL, mappedBy = "loan", orphanRemoval = true) + @OneToMany(cascade = CascadeType.ALL, mappedBy = "loan", orphanRemoval = true, fetch=FetchType.EAGER) private Set charges = new HashSet<>(); - @LazyCollection(LazyCollectionOption.FALSE) - @OneToMany(cascade = CascadeType.ALL, mappedBy = "loan", orphanRemoval = true) + @OneToMany(cascade = CascadeType.ALL, mappedBy = "loan", orphanRemoval = true, fetch=FetchType.EAGER) private Set trancheCharges = new HashSet<>(); - @LazyCollection(LazyCollectionOption.FALSE) - @OneToMany(cascade = CascadeType.ALL, mappedBy = "loan", orphanRemoval = true) + @OneToMany(cascade = CascadeType.ALL, mappedBy = "loan", orphanRemoval = true, fetch=FetchType.LAZY) private Set collateral = null; - @LazyCollection(LazyCollectionOption.FALSE) - @OneToMany(cascade = CascadeType.ALL, mappedBy = "loan", orphanRemoval = true) + @OneToMany(cascade = CascadeType.ALL, mappedBy = "loan", orphanRemoval = true, fetch=FetchType.LAZY) private Set loanOfficerHistory; // see // http://stackoverflow.com/questions/4334970/hibernate-cannot-simultaneously-fetch-multiple-bags - @LazyCollection(LazyCollectionOption.FALSE) @OrderBy(value = "installmentNumber") - @OneToMany(cascade = CascadeType.ALL, mappedBy = "loan", orphanRemoval = true) - private final List repaymentScheduleInstallments = new ArrayList<>(); + @OneToMany(cascade = CascadeType.ALL, mappedBy = "loan", orphanRemoval = true, fetch=FetchType.EAGER) + private final Set repaymentScheduleInstallments = new HashSet<>(); // see // http://stackoverflow.com/questions/4334970/hibernate-cannot-simultaneously-fetch-multiple-bags @OrderBy(value = "dateOf, id") - @LazyCollection(LazyCollectionOption.FALSE) - @OneToMany(cascade = CascadeType.ALL, mappedBy = "loan", orphanRemoval = true) - private final List loanTransactions = new ArrayList<>(); + @OneToMany(cascade = CascadeType.ALL, mappedBy = "loan", orphanRemoval = true, fetch=FetchType.EAGER) + private final Set loanTransactions = new HashSet<>(); + private transient List sortedTransactions = null ; + + private transient boolean isTransactionsListDirty = false ; + + private transient List sortedrepaymentScheduleInstallments = null ; + + private transient boolean isrepaymentScheduleInstallmentsListDirty = false ; + @Embedded private LoanSummary summary; @@ -352,21 +353,18 @@ public class Loan extends AbstractPersistable { @Column(name = "max_outstanding_loan_balance", scale = 6, precision = 19, nullable = false) private BigDecimal maxOutstandingLoanBalance; - @LazyCollection(LazyCollectionOption.FALSE) - @OneToMany(cascade = CascadeType.ALL, mappedBy = "loan", orphanRemoval = true) + @OneToMany(cascade = CascadeType.ALL, mappedBy = "loan", orphanRemoval = true, fetch=FetchType.EAGER) @OrderBy(value = "expectedDisbursementDate, id") private Set disbursementDetails = new HashSet<>(); @OrderBy(value = "termApplicableFrom, id") - @LazyCollection(LazyCollectionOption.FALSE) - @OneToMany(cascade = CascadeType.ALL, mappedBy = "loan", orphanRemoval = true) - private final List loanTermVariations = new ArrayList<>(); + @OneToMany(cascade = CascadeType.ALL, mappedBy = "loan", orphanRemoval = true, fetch=FetchType.EAGER) + private final Set loanTermVariations = new HashSet<>(); @Column(name = "total_recovered_derived", scale = 6, precision = 19) private BigDecimal totalRecovered; - @LazyCollection(LazyCollectionOption.FALSE) - @OneToOne(cascade = CascadeType.ALL, mappedBy = "loan", optional = true, orphanRemoval = true) + @OneToOne(cascade = CascadeType.ALL, mappedBy = "loan", optional = true, orphanRemoval = true, fetch=FetchType.EAGER) private LoanInterestRecalculationDetails loanInterestRecalculationDetails; @Column(name = "is_npa", nullable = false) @@ -392,7 +390,7 @@ public class Loan extends AbstractPersistable { @Column(name = "interest_rate_differential", scale = 6, precision = 19, nullable = true) private BigDecimal interestRateDifferential; - @ManyToOne + @ManyToOne(fetch=FetchType.LAZY) @JoinColumn(name = "writeoff_reason_cv_id", nullable = true) private CodeValue writeOffReason; @@ -616,7 +614,7 @@ public class Loan extends AbstractPersistable { // store Id's of existing loan transactions and existing reversed loan // transactions final LoanRepaymentScheduleProcessingWrapper wrapper = new LoanRepaymentScheduleProcessingWrapper(); - wrapper.reprocess(getCurrency(), getDisbursementDate(), this.repaymentScheduleInstallments, charges()); + wrapper.reprocess(getCurrency(), getDisbursementDate(), getRepaymentScheduleInstallments(), charges()); updateLoanSummaryDerivedFields(); } @@ -627,11 +625,12 @@ public class Loan extends AbstractPersistable { .determineProcessor(this.transactionProcessingStrategy); final List allNonContraTransactionsPostDisbursement = retreiveListOfTransactionsPostDisbursement(); changedTransactionDetail = loanRepaymentScheduleTransactionProcessor.handleTransaction(getDisbursementDate(), - allNonContraTransactionsPostDisbursement, getCurrency(), this.repaymentScheduleInstallments, charges()); + allNonContraTransactionsPostDisbursement, getCurrency(), getRepaymentScheduleInstallments(), charges()); for (final Map.Entry mapEntry : changedTransactionDetail.getNewTransactionMappings().entrySet()) { mapEntry.getValue().updateLoan(this); } this.loanTransactions.addAll(changedTransactionDetail.getNewTransactionMappings().values()); + this.isTransactionsListDirty = true ; updateLoanSummaryDerivedFields(); this.loanTransactions.removeAll(changedTransactionDetail.getNewTransactionMappings().values()); return changedTransactionDetail; @@ -681,7 +680,7 @@ public class Loan extends AbstractPersistable { final LoanChargePaidBy loanChargePaidBy = new LoanChargePaidBy(applyLoanChargeTransaction, loanCharge, loanCharge.getAmount( getCurrency()).getAmount(), installmentNumber); applyLoanChargeTransaction.getLoanChargesPaid().add(loanChargePaidBy); - this.loanTransactions.add(applyLoanChargeTransaction); + addLoanTransaction(applyLoanChargeTransaction); return applyLoanChargeTransaction; } @@ -691,7 +690,7 @@ public class Loan extends AbstractPersistable { final LoanChargePaidBy loanChargePaidBy = new LoanChargePaidBy(chargesPayment, charge, chargesPayment.getAmount(getCurrency()) .getAmount(), installmentNumber); chargesPayment.getLoanChargesPaid().add(loanChargePaidBy); - this.loanTransactions.add(chargesPayment); + addLoanTransaction(chargesPayment); final LoanStatus statusEnum = loanLifecycleStateMachine.transition(LoanEvent.LOAN_CHARGE_PAYMENT, LoanStatus.fromInt(this.loanStatus)); this.loanStatus = statusEnum.getValue(); @@ -700,7 +699,8 @@ public class Loan extends AbstractPersistable { .determineProcessor(this.transactionProcessingStrategy); final List chargePaymentInstallments = new ArrayList<>(); LocalDate startDate = getDisbursementDate(); - for (final LoanRepaymentScheduleInstallment installment : this.repaymentScheduleInstallments) { + List installments = getRepaymentScheduleInstallments() ; + for (final LoanRepaymentScheduleInstallment installment : installments) { if (installmentNumber == null && charge.isDueForCollectionFromAndUpToAndIncluding(startDate, installment.getDueDate())) { chargePaymentInstallments.add(installment); break; @@ -743,7 +743,8 @@ public class Loan extends AbstractPersistable { private LocalDate getLastRepaymentPeriodDueDate(final boolean includeRecalculatedInterestComponent) { LocalDate lastRepaymentDate = getDisbursementDate(); - for (LoanRepaymentScheduleInstallment installment : this.repaymentScheduleInstallments) { + List installments = getRepaymentScheduleInstallments() ; + for (LoanRepaymentScheduleInstallment installment : installments) { if ((includeRecalculatedInterestComponent || !installment.isRecalculatedInterestComponent()) && installment.getDueDate().isAfter(lastRepaymentDate)) { lastRepaymentDate = installment.getDueDate(); @@ -765,7 +766,7 @@ public class Loan extends AbstractPersistable { if (removed) { loanCharge.setActive(false); final LoanRepaymentScheduleProcessingWrapper wrapper = new LoanRepaymentScheduleProcessingWrapper(); - wrapper.reprocess(getCurrency(), getDisbursementDate(), this.repaymentScheduleInstallments, charges()); + wrapper.reprocess(getCurrency(), getDisbursementDate(), getRepaymentScheduleInstallments(), charges()); updateSummaryWithTotalFeeChargesDueAtDisbursement(deriveSumTotalOfChargesDueAtDisbursement()); } @@ -784,7 +785,7 @@ public class Loan extends AbstractPersistable { ***/ final List allNonContraTransactionsPostDisbursement = retreiveListOfTransactionsPostDisbursement(); loanRepaymentScheduleTransactionProcessor.handleTransaction(getDisbursementDate(), allNonContraTransactionsPostDisbursement, - getCurrency(), this.repaymentScheduleInstallments, charges()); + getCurrency(), getRepaymentScheduleInstallments(), charges()); } this.charges.remove(loanCharge); updateLoanSummaryDerivedFields(); @@ -793,7 +794,8 @@ public class Loan extends AbstractPersistable { private void removeOrModifyTransactionAssociatedWithLoanChargeIfDueAtDisbursement(final LoanCharge loanCharge) { if (loanCharge.isDueAtDisbursement()) { LoanTransaction transactionToRemove = null; - for (final LoanTransaction transaction : this.loanTransactions) { + List transactions = getLoanTransactions() ; + for (final LoanTransaction transaction : transactions) { if (transaction.isRepaymentAtDisbursement() && transaction.getLoanChargesPaid().contains(loanCharge)) { final MonetaryCurrency currency = loanCurrency(); @@ -842,11 +844,11 @@ public class Loan extends AbstractPersistable { ***/ final List allNonContraTransactionsPostDisbursement = retreiveListOfTransactionsPostDisbursement(); loanRepaymentScheduleTransactionProcessor.handleTransaction(getDisbursementDate(), allNonContraTransactionsPostDisbursement, - getCurrency(), this.repaymentScheduleInstallments, charges()); + getCurrency(), getRepaymentScheduleInstallments(), charges()); } else { // reprocess loan schedule based on charge been waived. final LoanRepaymentScheduleProcessingWrapper wrapper = new LoanRepaymentScheduleProcessingWrapper(); - wrapper.reprocess(getCurrency(), getDisbursementDate(), this.repaymentScheduleInstallments, charges()); + wrapper.reprocess(getCurrency(), getDisbursementDate(), getRepaymentScheduleInstallments(), charges()); } updateLoanSummaryDerivedFields(); @@ -889,7 +891,7 @@ public class Loan extends AbstractPersistable { * @return */ public BigDecimal getTotalInterest() { - return this.loanSummaryWrapper.calculateTotalInterestCharged(this.repaymentScheduleInstallments, getCurrency()).getAmount(); + return this.loanSummaryWrapper.calculateTotalInterestCharged(getRepaymentScheduleInstallments(), getCurrency()).getAmount(); } private BigDecimal calculatePerInstallmentChargeAmount(final LoanCharge loanCharge) { @@ -898,7 +900,8 @@ public class Loan extends AbstractPersistable { public BigDecimal calculatePerInstallmentChargeAmount(final ChargeCalculationType calculationType, final BigDecimal percentage) { Money amount = Money.zero(getCurrency()); - for (final LoanRepaymentScheduleInstallment installment : this.repaymentScheduleInstallments) { + List installments = getRepaymentScheduleInstallments() ; + for (final LoanRepaymentScheduleInstallment installment : installments) { amount = amount.plus(calculateInstallmentChargeAmount(calculationType, percentage, installment)); } return amount.getAmount(); @@ -995,8 +998,7 @@ public class Loan extends AbstractPersistable { final LoanChargePaidBy loanChargePaidBy = new LoanChargePaidBy(waiveLoanChargeTransaction, loanCharge, waiveLoanChargeTransaction .getAmount(getCurrency()).getAmount(), loanInstallmentNumber); waiveLoanChargeTransaction.getLoanChargesPaid().add(loanChargePaidBy); - this.loanTransactions.add(waiveLoanChargeTransaction); - + addLoanTransaction(waiveLoanChargeTransaction) ; if (this.repaymentScheduleDetail().isInterestRecalculationEnabled() && (loanCharge.getDueLocalDate() == null || LocalDate.now().isAfter(loanCharge.getDueLocalDate()))) { regenerateRepaymentScheduleWithInterestRecalculation(scheduleGeneratorDTO, currentUser); @@ -1016,11 +1018,11 @@ public class Loan extends AbstractPersistable { ***/ final List allNonContraTransactionsPostDisbursement = retreiveListOfTransactionsPostDisbursement(); loanRepaymentScheduleTransactionProcessor.handleTransaction(getDisbursementDate(), allNonContraTransactionsPostDisbursement, - getCurrency(), this.repaymentScheduleInstallments, charges()); + getCurrency(), getRepaymentScheduleInstallments(), charges()); } else { // reprocess loan schedule based on charge been waived. final LoanRepaymentScheduleProcessingWrapper wrapper = new LoanRepaymentScheduleProcessingWrapper(); - wrapper.reprocess(getCurrency(), getDisbursementDate(), this.repaymentScheduleInstallments, charges()); + wrapper.reprocess(getCurrency(), getDisbursementDate(), getRepaymentScheduleInstallments(), charges()); } updateLoanSummaryDerivedFields(); @@ -1139,7 +1141,7 @@ public class Loan extends AbstractPersistable { public void updateLoanSchedule(final LoanScheduleModel modifiedLoanSchedule, AppUser currentUser) { this.repaymentScheduleInstallments.clear(); - + this.isrepaymentScheduleInstallmentsListDirty = true ; for (final LoanScheduleModelPeriod scheduledLoanInstallment : modifiedLoanSchedule.getPeriods()) { if (scheduledLoanInstallment.isRepaymentPeriod()) { @@ -1149,7 +1151,7 @@ public class Loan extends AbstractPersistable { scheduledLoanInstallment.interestDue(), scheduledLoanInstallment.feeChargesDue(), scheduledLoanInstallment.penaltyChargesDue(), scheduledLoanInstallment.isRecalculatedInterestComponent(), scheduledLoanInstallment.getLoanCompoundingDetails()); - addRepaymentScheduleInstallment(installment); + addLoanRepaymentScheduleInstallment(installment); } } @@ -1161,8 +1163,9 @@ public class Loan extends AbstractPersistable { public void updateLoanSchedule(final Collection installments, AppUser currentUser) { this.repaymentScheduleInstallments.clear(); + this.isrepaymentScheduleInstallmentsListDirty = true ; for (final LoanRepaymentScheduleInstallment installment : installments) { - addRepaymentScheduleInstallment(installment); + addLoanRepaymentScheduleInstallment(installment); } updateLoanScheduleDependentDerivedFields(); updateLoanSummaryDerivedFields(); @@ -1184,8 +1187,8 @@ public class Loan extends AbstractPersistable { } private void applyPeriodicAccruals(final Collection accruals) { - - for (LoanRepaymentScheduleInstallment installment : this.repaymentScheduleInstallments) { + List installments = getRepaymentScheduleInstallments() ; + for (LoanRepaymentScheduleInstallment installment : installments) { Money interest = Money.zero(getCurrency()); Money fee = Money.zero(getCurrency()); Money penality = Money.zero(getCurrency()); @@ -1207,8 +1210,8 @@ public class Loan extends AbstractPersistable { } installment.updateAccrualPortion(interest, fee, penality); } - LoanRepaymentScheduleInstallment lastInstallment = this.repaymentScheduleInstallments - .get(this.repaymentScheduleInstallments.size() - 1); + LoanRepaymentScheduleInstallment lastInstallment = getRepaymentScheduleInstallments() + .get(getRepaymentScheduleInstallments().size() - 1); for (LoanTransaction loanTransaction : accruals) { if (loanTransaction.getTransactionDate().isAfter(lastInstallment.getDueDate()) && !loanTransaction.isReversed()) { loanTransaction.reverse(); @@ -1226,7 +1229,7 @@ public class Loan extends AbstractPersistable { final LocalDateTime currentDateTime = DateUtils.getLocalDateTimeOfTenant(); final LoanTransaction interestAppliedTransaction = LoanTransaction.accrueInterest(getOffice(), this, interestApplied, getDisbursementDate(), currentDateTime, currentUser); - this.loanTransactions.add(interestAppliedTransaction); + addLoanTransaction(interestAppliedTransaction) ; } } else { Set chargePaidBies = loanTransaction.getLoanChargesPaid(); @@ -1262,7 +1265,7 @@ public class Loan extends AbstractPersistable { this.totalRecovered = recoveredAmount.getAmountDefaultedToNullIfZero(); final Money principal = this.loanRepaymentScheduleDetail.getPrincipal(); - this.summary.updateSummary(loanCurrency(), principal, this.repaymentScheduleInstallments, this.loanSummaryWrapper, + this.summary.updateSummary(loanCurrency(), principal, getRepaymentScheduleInstallments(), this.loanSummaryWrapper, isDisbursed(), this.charges); updateLoanOutstandingBalaces(); } @@ -1885,9 +1888,11 @@ public class Loan extends AbstractPersistable { } private void removeFirstDisbursementTransaction() { - for (final LoanTransaction loanTransaction : this.loanTransactions) { + List transactions = getLoanTransactions() ; + for (final LoanTransaction loanTransaction : transactions) { if (loanTransaction.isDisbursement()) { this.loanTransactions.remove(loanTransaction); + transactions.remove(loanTransaction) ; break; } } @@ -1970,8 +1975,9 @@ public class Loan extends AbstractPersistable { private LocalDate determineExpectedMaturityDate() { final int numberOfInstallments = this.repaymentScheduleInstallments.size(); - LocalDate maturityDate = this.repaymentScheduleInstallments.get(numberOfInstallments - 1).getDueDate(); - ListIterator iterator = this.repaymentScheduleInstallments.listIterator(numberOfInstallments); + List installments = getRepaymentScheduleInstallments() ; + LocalDate maturityDate = installments.get(numberOfInstallments - 1).getDueDate(); + ListIterator iterator = installments.listIterator(numberOfInstallments); while(iterator.hasPrevious()){ LoanRepaymentScheduleInstallment loanRepaymentScheduleInstallment = iterator.previous(); if(!loanRepaymentScheduleInstallment.isRecalculatedInterestComponent()){ @@ -2240,8 +2246,8 @@ public class Loan extends AbstractPersistable { public Collection findExistingTransactionIds() { final Collection ids = new ArrayList<>(); - - for (final LoanTransaction transaction : this.loanTransactions) { + List transactions = getLoanTransactions() ; + for (final LoanTransaction transaction : transactions) { ids.add(transaction.getId()); } @@ -2251,8 +2257,8 @@ public class Loan extends AbstractPersistable { public Collection findExistingReversedTransactionIds() { final Collection ids = new ArrayList<>(); - - for (final LoanTransaction transaction : this.loanTransactions) { + List transactions = getLoanTransactions() ; + for (final LoanTransaction transaction : transactions) { if (transaction.isReversed()) { ids.add(transaction.getId()); } @@ -2304,10 +2310,10 @@ public class Loan extends AbstractPersistable { **/ if (isNoneOrCashOrUpfrontAccrualAccountingEnabledOnLoanProduct() - && ((isMultiDisburmentLoan() && getDisbursedLoanDisbursementDetails().size() == 1) || !isMultiDisburmentLoan())) { + && ((isMultiDisburmentLoan() && getDisbursedLoanDisbursementDetails().size() == 1) || !isMultiDisburmentLoan())) { final LoanTransaction interestAppliedTransaction = LoanTransaction.accrueInterest(getOffice(), this, interestApplied, actualDisbursementDate, createdDate, currentUser); - this.loanTransactions.add(interestAppliedTransaction); + addLoanTransaction(interestAppliedTransaction) ; } return reprocessTransactionForDisbursement(); @@ -2315,18 +2321,18 @@ public class Loan extends AbstractPersistable { } private List getDisbursedLoanDisbursementDetails() { - List ret = new ArrayList<>(); - if(this.disbursementDetails != null && this.disbursementDetails.size() > 0){ + List ret = new ArrayList<>(); + if(this.disbursementDetails != null && this.disbursementDetails.size() > 0){ for (LoanDisbursementDetails disbursementDetail : this.disbursementDetails) { if (disbursementDetail.actualDisbursementDate() != null) { ret.add(disbursementDetail); } } - } - return ret; - } + } + return ret; + } - public void regenerateScheduleOnDisbursement(final ScheduleGeneratorDTO scheduleGeneratorDTO, final boolean recalculateSchedule, + public void regenerateScheduleOnDisbursement(final ScheduleGeneratorDTO scheduleGeneratorDTO, final boolean recalculateSchedule, final LocalDate actualDisbursementDate, BigDecimal emiAmount, final AppUser currentUser, LocalDate nextPossibleRepaymentDate, Date rescheduledRepaymentDate) { boolean isEmiAmountChanged = false; @@ -2456,7 +2462,7 @@ public class Loan extends AbstractPersistable { final LoanRepaymentScheduleTransactionProcessor loanRepaymentScheduleTransactionProcessor = this.transactionProcessorFactory .determineProcessor(this.transactionProcessingStrategy); changedTransactionDetail = loanRepaymentScheduleTransactionProcessor.handleTransaction(getDisbursementDate(), - allNonContraTransactionsPostDisbursement, getCurrency(), this.repaymentScheduleInstallments, charges()); + allNonContraTransactionsPostDisbursement, getCurrency(), getRepaymentScheduleInstallments(), charges()); for (final Map.Entry mapEntry : changedTransactionDetail.getNewTransactionMappings().entrySet()) { mapEntry.getValue().updateLoan(this); } @@ -2556,8 +2562,8 @@ public class Loan extends AbstractPersistable { } private void updateLoanRepaymentPeriodsDerivedFields(final LocalDate actualDisbursementDate) { - - for (final LoanRepaymentScheduleInstallment repaymentPeriod : this.repaymentScheduleInstallments) { + List installments = getRepaymentScheduleInstallments() ; + for (final LoanRepaymentScheduleInstallment repaymentPeriod : installments) { repaymentPeriod.updateDerivedFields(loanCurrency(), actualDisbursementDate); } } @@ -2667,7 +2673,7 @@ public class Loan extends AbstractPersistable { final Money zero = Money.zero(getCurrency()); chargesPayment.updateComponentsAndTotal(zero, zero, disbursentMoney, zero); chargesPayment.updateLoan(this); - this.loanTransactions.add(chargesPayment); + addLoanTransaction(chargesPayment) ; updateLoanOutstandingBalaces(); } @@ -2713,7 +2719,7 @@ public class Loan extends AbstractPersistable { final Money zero = Money.zero(getCurrency()); chargesPayment.updateComponents(zero, zero, charge.getAmount(getCurrency()), zero); chargesPayment.updateLoan(this); - this.loanTransactions.add(chargesPayment); + addLoanTransaction(chargesPayment) ; updateLoanOutstandingBalaces(); charge.markAsFullyPaid(); return chargesPayment; @@ -2786,8 +2792,8 @@ public class Loan extends AbstractPersistable { charge.resetToOriginal(loanCurrency()); } } - - for (final LoanRepaymentScheduleInstallment currentInstallment : this.repaymentScheduleInstallments) { + List installments = getRepaymentScheduleInstallments() ; + for (final LoanRepaymentScheduleInstallment currentInstallment : installments) { currentInstallment.resetDerivedComponents(); } final List removeTerms = new ArrayList<>(this.loanTermVariations.size()); @@ -2798,7 +2804,7 @@ public class Loan extends AbstractPersistable { } this.loanTermVariations.removeAll(removeTerms); final LoanRepaymentScheduleProcessingWrapper wrapper = new LoanRepaymentScheduleProcessingWrapper(); - wrapper.reprocess(getCurrency(), getDisbursementDate(), this.repaymentScheduleInstallments, charges()); + wrapper.reprocess(getCurrency(), getDisbursementDate(), getRepaymentScheduleInstallments(), charges()); updateLoanSummaryDerivedFields(); } @@ -2899,7 +2905,7 @@ public class Loan extends AbstractPersistable { final String errorMessage = "The refund amount must be less than or equal to overpaid amount "; throw new InvalidLoanStateTransitionException("transaction", "is.exceeding.overpaid.amount", errorMessage, this.totalOverpaid, loanTransaction.getAmount(getCurrency()).getAmount()); - } else if (!isAfterLatRepayment(loanTransaction, this.loanTransactions)) { + } else if (!isAfterLatRepayment(loanTransaction, getLoanTransactions())) { final String errorMessage = "Transfer funds is allowed only after last repayment date"; throw new InvalidLoanStateTransitionException("transaction", "is.not.after.repayment.date", errorMessage); } @@ -2910,7 +2916,7 @@ public class Loan extends AbstractPersistable { loanTransaction.updateLoan(this); if (loanTransaction.isNotZero(loanCurrency())) { - this.loanTransactions.add(loanTransaction); + addLoanTransaction(loanTransaction) ; } updateLoanSummaryDerivedFields(); doPostLoanTransactionChecks(loanTransaction.getTransactionDate(), loanLifecycleStateMachine); @@ -2939,10 +2945,10 @@ public class Loan extends AbstractPersistable { loanTransaction.updateLoan(this); - final boolean isTransactionChronologicallyLatest = isChronologicallyLatestRepaymentOrWaiver(loanTransaction, this.loanTransactions); + final boolean isTransactionChronologicallyLatest = isChronologicallyLatestRepaymentOrWaiver(loanTransaction, getLoanTransactions()); if (loanTransaction.isNotZero(loanCurrency())) { - this.loanTransactions.add(loanTransaction); + addLoanTransaction(loanTransaction) ; } if (loanTransaction.isNotRepayment() && loanTransaction.isNotWaiver() && loanTransaction.isNotRecoveryRepayment()) { @@ -3000,7 +3006,7 @@ public class Loan extends AbstractPersistable { if (isTransactionChronologicallyLatest && adjustedTransaction == null && (!reprocess || !this.repaymentScheduleDetail().isInterestRecalculationEnabled()) && !isForeclosure()) { - loanRepaymentScheduleTransactionProcessor.handleTransaction(loanTransaction, getCurrency(), this.repaymentScheduleInstallments, + loanRepaymentScheduleTransactionProcessor.handleTransaction(loanTransaction, getCurrency(), getRepaymentScheduleInstallments(), charges()); reprocess = false; if (this.repaymentScheduleDetail().isInterestRecalculationEnabled()) { @@ -3021,7 +3027,7 @@ public class Loan extends AbstractPersistable { } final List allNonContraTransactionsPostDisbursement = retreiveListOfTransactionsPostDisbursement(); changedTransactionDetail = loanRepaymentScheduleTransactionProcessor.handleTransaction(getDisbursementDate(), - allNonContraTransactionsPostDisbursement, getCurrency(), this.repaymentScheduleInstallments, charges()); + allNonContraTransactionsPostDisbursement, getCurrency(), getRepaymentScheduleInstallments(), charges()); for (final Map.Entry mapEntry : changedTransactionDetail.getNewTransactionMappings().entrySet()) { mapEntry.getValue().updateLoan(this); } @@ -3031,6 +3037,7 @@ public class Loan extends AbstractPersistable { * transactions first and then new transactions. */ this.loanTransactions.addAll(changedTransactionDetail.getNewTransactionMappings().values()); + this.isTransactionsListDirty = true ; } updateLoanSummaryDerivedFields(); @@ -3061,7 +3068,8 @@ public class Loan extends AbstractPersistable { private LoanRepaymentScheduleInstallment fetchLoanRepaymentScheduleInstallment(LocalDate dueDate) { LoanRepaymentScheduleInstallment installment = null; - for (LoanRepaymentScheduleInstallment loanRepaymentScheduleInstallment : this.repaymentScheduleInstallments) { + List installments = getRepaymentScheduleInstallments() ; + for (LoanRepaymentScheduleInstallment loanRepaymentScheduleInstallment : installments) { if (dueDate.equals(loanRepaymentScheduleInstallment.getDueDate())) { installment = loanRepaymentScheduleInstallment; break; @@ -3072,7 +3080,8 @@ public class Loan extends AbstractPersistable { private List retreiveListOfIncomePostingTransactions() { final List incomePostTransactions = new ArrayList<>(); - for (final LoanTransaction transaction : this.loanTransactions) { + List trans = getLoanTransactions() ; + for (final LoanTransaction transaction : trans) { if (transaction.isNotReversed() && transaction.isIncomePosting()) { incomePostTransactions.add(transaction); } @@ -3084,7 +3093,8 @@ public class Loan extends AbstractPersistable { private List retreiveListOfTransactionsPostDisbursement() { final List repaymentsOrWaivers = new ArrayList<>(); - for (final LoanTransaction transaction : this.loanTransactions) { + List trans = getLoanTransactions() ; + for (final LoanTransaction transaction : trans) { if (transaction.isNotReversed() && !(transaction.isDisbursement() || transaction.isNonMonetaryTransaction())) { repaymentsOrWaivers.add(transaction); } @@ -3185,7 +3195,7 @@ public class Loan extends AbstractPersistable { BigDecimal amountToPost = interestToPost.add(feeToPost).add(penaltyToPost); LoanTransaction finalIncomeTransaction = LoanTransaction.incomePosting(this, this.getOffice(), closedDate, amountToPost, interestToPost, feeToPost, penaltyToPost, null); - this.loanTransactions.add(finalIncomeTransaction); + addLoanTransaction(finalIncomeTransaction) ; if (isPeriodicAccrualAccountingEnabledOnLoanProduct()) { List updatedAccrualTransactions = retreiveListOfAccrualTransactions(); LocalDate lastAccruedDate = this.getDisbursementDate(); @@ -3197,7 +3207,7 @@ public class Loan extends AbstractPersistable { LoanTransaction finalAccrual = LoanTransaction.accrueTransaction(this, this.getOffice(), closedLocalDate, amountToPost, interestToPost, feeToPost, penaltyToPost, null); updateLoanChargesPaidBy(finalAccrual, feeDetails, null); - this.loanTransactions.add(finalAccrual); + addLoanTransaction(finalAccrual) ; } } updateLoanOutstandingBalaces(); @@ -3207,7 +3217,8 @@ public class Loan extends AbstractPersistable { BigDecimal interest = BigDecimal.ZERO; BigDecimal fee = BigDecimal.ZERO; BigDecimal penalty = BigDecimal.ZERO; - for (LoanRepaymentScheduleInstallment installment : this.repaymentScheduleInstallments) { + List installments = getRepaymentScheduleInstallments() ; + for (LoanRepaymentScheduleInstallment installment : installments) { interest = interest.add(installment.getInterestCharged(getCurrency()).getAmount()); fee = fee.add(installment.getFeeChargesCharged(getCurrency()).getAmount()); penalty = penalty.add(installment.getPenaltyChargesCharged(getCurrency()).getAmount()); @@ -3295,7 +3306,8 @@ public class Loan extends AbstractPersistable { public LocalDate possibleNextRepaymentDate() { LocalDate earliestUnpaidInstallmentDate = new LocalDate(); - for (final LoanRepaymentScheduleInstallment installment : this.repaymentScheduleInstallments) { + List installments = getRepaymentScheduleInstallments() ; + for (final LoanRepaymentScheduleInstallment installment : installments) { if (installment.isNotFullyPaidOff()) { earliestUnpaidInstallmentDate = installment.getDueDate(); break; @@ -3319,8 +3331,8 @@ public class Loan extends AbstractPersistable { public LoanRepaymentScheduleInstallment possibleNextRepaymentInstallment() { LoanRepaymentScheduleInstallment loanRepaymentScheduleInstallment = null; - - for (final LoanRepaymentScheduleInstallment installment : this.repaymentScheduleInstallments) { + List installments = getRepaymentScheduleInstallments() ; + for (final LoanRepaymentScheduleInstallment installment : installments) { if (installment.isNotFullyPaidOff()) { loanRepaymentScheduleInstallment = installment; break; @@ -3339,7 +3351,8 @@ public class Loan extends AbstractPersistable { if (totalInterestOutstanding.isGreaterThanZero()) { // find earliest known instance of overdue interest and default to // that - for (final LoanRepaymentScheduleInstallment scheduledRepayment : this.repaymentScheduleInstallments) { + List installments = getRepaymentScheduleInstallments() ; + for (final LoanRepaymentScheduleInstallment scheduledRepayment : installments) { final Money outstandingForPeriod = scheduledRepayment.getInterestOutstanding(loanCurrency()); if (scheduledRepayment.isOverdueOn(new LocalDate()) && scheduledRepayment.isNotFullyPaidOff() @@ -3418,7 +3431,7 @@ public class Loan extends AbstractPersistable { regenerateRepaymentScheduleWithInterestRecalculation(scheduleGeneratorDTO, currentUser); } ChangedTransactionDetail changedTransactionDetail = loanRepaymentScheduleTransactionProcessor.handleTransaction( - getDisbursementDate(), allNonContraTransactionsPostDisbursement, getCurrency(), this.repaymentScheduleInstallments, + getDisbursementDate(), allNonContraTransactionsPostDisbursement, getCurrency(), getRepaymentScheduleInstallments(), charges()); updateLoanSummaryDerivedFields(); return changedTransactionDetail; @@ -3447,8 +3460,8 @@ public class Loan extends AbstractPersistable { final MonetaryCurrency currency = loanCurrency(); Money cumulativeTotalPaidOnInstallments = Money.zero(currency); Money cumulativeTotalWaivedOnInstallments = Money.zero(currency); - - for (final LoanRepaymentScheduleInstallment scheduledRepayment : this.repaymentScheduleInstallments) { + List installments = getRepaymentScheduleInstallments() ; + for (final LoanRepaymentScheduleInstallment scheduledRepayment : installments) { cumulativeTotalPaidOnInstallments = cumulativeTotalPaidOnInstallments .plus(scheduledRepayment.getPrincipalCompleted(currency).plus(scheduledRepayment.getInterestPaid(currency))) @@ -3533,9 +3546,8 @@ public class Loan extends AbstractPersistable { writtenOffOnLocalDate); } - this.loanTransactions.add(loanTransaction); - - loanRepaymentScheduleTransactionProcessor.handleWriteOff(loanTransaction, loanCurrency(), this.repaymentScheduleInstallments); + addLoanTransaction(loanTransaction) ; + loanRepaymentScheduleTransactionProcessor.handleWriteOff(loanTransaction, loanCurrency(), getRepaymentScheduleInstallments()); updateLoanSummaryDerivedFields(); } @@ -3558,10 +3570,10 @@ public class Loan extends AbstractPersistable { } final List allNonContraTransactionsPostDisbursement = retreiveListOfTransactionsPostDisbursement(); changedTransactionDetail = loanRepaymentScheduleTransactionProcessor.handleTransaction(getDisbursementDate(), - allNonContraTransactionsPostDisbursement, getCurrency(), this.repaymentScheduleInstallments, charges()); + allNonContraTransactionsPostDisbursement, getCurrency(), getRepaymentScheduleInstallments(), charges()); for (final Map.Entry mapEntry : changedTransactionDetail.getNewTransactionMappings().entrySet()) { mapEntry.getValue().updateLoan(this); - this.loanTransactions.add(mapEntry.getValue()); + addLoanTransaction(mapEntry.getValue()) ; } updateLoanSummaryDerivedFields(); LoanTransaction loanTransaction = findlatestTransaction(); @@ -3627,17 +3639,16 @@ public class Loan extends AbstractPersistable { this.closedOnDate = closureDate.toDate(); loanTransaction = LoanTransaction.writeoff(this, getOffice(), closureDate, txnExternalId, DateUtils.getLocalDateTimeOfTenant(), currentUser); - final boolean isLastTransaction = isChronologicallyLatestTransaction(loanTransaction, this.loanTransactions); + final boolean isLastTransaction = isChronologicallyLatestTransaction(loanTransaction, getLoanTransactions()); if (!isLastTransaction) { final String errorMessage = "The closing date of the loan must be on or after latest transaction date."; throw new InvalidLoanStateTransitionException("close.loan", "must.occur.on.or.after.latest.transaction.date", errorMessage, closureDate); } - this.loanTransactions.add(loanTransaction); - + addLoanTransaction(loanTransaction) ; loanRepaymentScheduleTransactionProcessor.handleWriteOff(loanTransaction, loanCurrency(), - this.repaymentScheduleInstallments); + getRepaymentScheduleInstallments()); updateLoanSummaryDerivedFields(); } else if (totalOutstanding.isGreaterThanZero()) { @@ -3871,11 +3882,6 @@ public class Loan extends AbstractPersistable { return firstRepaymentDate; } - private void addRepaymentScheduleInstallment(final LoanRepaymentScheduleInstallment installment) { - installment.updateLoan(this); - this.repaymentScheduleInstallments.add(installment); - } - private boolean isActualDisbursedOnDateEarlierOrLaterThanExpected(final LocalDate actualDisbursedOnDate) { boolean isRegenerationRequired = false; if (this.loanProduct.isMultiDisburseLoan()) { @@ -3917,7 +3923,8 @@ public class Loan extends AbstractPersistable { private Money getTotalInterestOutstandingOnLoan() { Money cumulativeInterest = Money.zero(loanCurrency()); - for (final LoanRepaymentScheduleInstallment scheduledRepayment : this.repaymentScheduleInstallments) { + List installments = getRepaymentScheduleInstallments() ; + for (final LoanRepaymentScheduleInstallment scheduledRepayment : installments) { cumulativeInterest = cumulativeInterest.plus(scheduledRepayment.getInterestOutstanding(loanCurrency())); } @@ -3927,8 +3934,8 @@ public class Loan extends AbstractPersistable { @SuppressWarnings("unused") private Money getTotalInterestOverdueOnLoan() { Money cumulativeInterestOverdue = Money.zero(this.loanRepaymentScheduleDetail.getPrincipal().getCurrency()); - - for (final LoanRepaymentScheduleInstallment scheduledRepayment : this.repaymentScheduleInstallments) { + List installments = getRepaymentScheduleInstallments() ; + for (final LoanRepaymentScheduleInstallment scheduledRepayment : installments) { final Money interestOutstandingForPeriod = scheduledRepayment.getInterestOutstanding(loanCurrency()); if (scheduledRepayment.isOverdueOn(new LocalDate())) { @@ -4263,7 +4270,8 @@ public class Loan extends AbstractPersistable { LocalDate newRepaymentDate = null; Boolean isFirstTime = true; LocalDate latestRepaymentDate = null; - for (final LoanRepaymentScheduleInstallment loanRepaymentScheduleInstallment : this.repaymentScheduleInstallments) { + List installments = getRepaymentScheduleInstallments() ; + for (final LoanRepaymentScheduleInstallment loanRepaymentScheduleInstallment : installments) { LocalDate oldDueDate = loanRepaymentScheduleInstallment.getDueDate(); @@ -4319,7 +4327,8 @@ public class Loan extends AbstractPersistable { LocalDate newRepaymentDate = null; LocalDate seedDate = meetingStartDate; LocalDate latestRepaymentDate = null; - for (final LoanRepaymentScheduleInstallment loanRepaymentScheduleInstallment : this.repaymentScheduleInstallments) { + List installments = getRepaymentScheduleInstallments() ; + for (final LoanRepaymentScheduleInstallment loanRepaymentScheduleInstallment : installments) { LocalDate oldDueDate = loanRepaymentScheduleInstallment.getDueDate(); @@ -4387,7 +4396,8 @@ public class Loan extends AbstractPersistable { // first repayment's from date is same as disbursement date. LocalDate tmpFromDate = getDisbursementDate(); // Loop through all loanRepayments - for (final LoanRepaymentScheduleInstallment loanRepaymentScheduleInstallment : this.repaymentScheduleInstallments) { + List installments = getRepaymentScheduleInstallments() ; + for (final LoanRepaymentScheduleInstallment loanRepaymentScheduleInstallment : installments) { final LocalDate oldDueDate = loanRepaymentScheduleInstallment.getDueDate(); // update from date if it's not same as previous installament's due @@ -4495,10 +4505,21 @@ public class Loan extends AbstractPersistable { return this.termPeriodFrequencyType; } + //This method returns copy of all transactions public List getLoanTransactions() { - return this.loanTransactions; + if(this.sortedTransactions == null || isTransactionsListDirty) { + this.sortedTransactions = new ArrayList<>(this.loanTransactions) ; + this.sortedTransactions.sort(new LoanTransactionComparator()); + this.isTransactionsListDirty = false ; + } + return sortedTransactions; } + public void addLoanTransaction(final LoanTransaction loanTransaction) { + this.loanTransactions.add(loanTransaction) ; + this.isTransactionsListDirty = true ; + } + public void setLoanStatus(final Integer loanStatus) { this.loanStatus = loanStatus; } @@ -4680,7 +4701,8 @@ public class Loan extends AbstractPersistable { public Set generateInstallmentLoanCharges(final LoanCharge loanCharge) { final Set loanChargePerInstallments = new HashSet<>(); if (loanCharge.isInstalmentFee()) { - for (final LoanRepaymentScheduleInstallment installment : this.repaymentScheduleInstallments) { + List installments = getRepaymentScheduleInstallments() ; + for (final LoanRepaymentScheduleInstallment installment : installments) { BigDecimal amount = BigDecimal.ZERO; if (loanCharge.getChargeCalculation().isFlat()) { amount = loanCharge.amountOrPercentage(); @@ -4900,11 +4922,11 @@ public class Loan extends AbstractPersistable { .determineProcessor(this.transactionProcessingStrategy); final List allNonContraTransactionsPostDisbursement = retreiveListOfTransactionsPostDisbursement(); ChangedTransactionDetail changedTransactionDetail = loanRepaymentScheduleTransactionProcessor.handleTransaction( - getDisbursementDate(), allNonContraTransactionsPostDisbursement, getCurrency(), this.repaymentScheduleInstallments, + getDisbursementDate(), allNonContraTransactionsPostDisbursement, getCurrency(), getRepaymentScheduleInstallments(), charges()); for (final Map.Entry mapEntry : changedTransactionDetail.getNewTransactionMappings().entrySet()) { mapEntry.getValue().updateLoan(this); - this.loanTransactions.add(mapEntry.getValue()); + addLoanTransaction(mapEntry.getValue()); } return changedTransactionDetail; @@ -4925,7 +4947,8 @@ public class Loan extends AbstractPersistable { public LoanRepaymentScheduleInstallment fetchRepaymentScheduleInstallment(final Integer installmentNumber) { LoanRepaymentScheduleInstallment installment = null; if (installmentNumber == null) { return installment; } - for (final LoanRepaymentScheduleInstallment scheduleInstallment : this.repaymentScheduleInstallments) { + List installments = getRepaymentScheduleInstallments() ; + for (final LoanRepaymentScheduleInstallment scheduleInstallment : installments) { if (scheduleInstallment.getInstallmentNumber().equals(installmentNumber)) { installment = scheduleInstallment; break; @@ -5006,7 +5029,7 @@ public class Loan extends AbstractPersistable { .determineProcessor(this.transactionProcessingStrategy); final List allNonContraTransactionsPostDisbursement = retreiveListOfTransactionsPostDisbursement(); ChangedTransactionDetail changedTransactionDetail = loanRepaymentScheduleTransactionProcessor.handleTransaction( - getDisbursementDate(), allNonContraTransactionsPostDisbursement, getCurrency(), this.repaymentScheduleInstallments, + getDisbursementDate(), allNonContraTransactionsPostDisbursement, getCurrency(), getRepaymentScheduleInstallments(), charges()); for (final Map.Entry mapEntry : changedTransactionDetail.getNewTransactionMappings().entrySet()) { mapEntry.getValue().updateLoan(this); @@ -5017,7 +5040,7 @@ public class Loan extends AbstractPersistable { * first and then new transactions. */ this.loanTransactions.addAll(changedTransactionDetail.getNewTransactionMappings().values()); - + this.isTransactionsListDirty = true ; updateLoanSummaryDerivedFields(); this.loanTransactions.removeAll(changedTransactionDetail.getNewTransactionMappings().values()); @@ -5094,8 +5117,8 @@ public class Loan extends AbstractPersistable { accrualTransaction); lastCompoundingDate = compoundingDetail.getEffectiveDate(); } - LoanRepaymentScheduleInstallment lastInstallment = this.repaymentScheduleInstallments.get(this.repaymentScheduleInstallments - .size() - 1); + List installments = getRepaymentScheduleInstallments() ; + LoanRepaymentScheduleInstallment lastInstallment = installments.get(installments.size() - 1); reverseTransactionsPostEffectiveDate(incomeTransactions, lastInstallment.getDueDate()); reverseTransactionsPostEffectiveDate(accrualTransactions, lastInstallment.getDueDate()); } @@ -5137,12 +5160,12 @@ public class Loan extends AbstractPersistable { if (existingIncomeTransaction == null) { LoanTransaction transaction = LoanTransaction.incomePosting(this, this.getOffice(), compoundingDetail.getEffectiveDate() .toDate(), compoundingDetail.getAmount(), interest, fee, penalties, currentUser); - this.loanTransactions.add(transaction); + addLoanTransaction(transaction); } else if (existingIncomeTransaction.getAmount(getCurrency()).getAmount().compareTo(compoundingDetail.getAmount()) != 0) { existingIncomeTransaction.reverse(); LoanTransaction transaction = LoanTransaction.incomePosting(this, this.getOffice(), compoundingDetail.getEffectiveDate() .toDate(), compoundingDetail.getAmount(), interest, fee, penalties, currentUser); - this.loanTransactions.add(transaction); + addLoanTransaction(transaction); } if (isPeriodicAccrualAccountingEnabledOnLoanProduct()) { @@ -5150,13 +5173,13 @@ public class Loan extends AbstractPersistable { LoanTransaction accrual = LoanTransaction.accrueTransaction(this, this.getOffice(), compoundingDetail.getEffectiveDate(), compoundingDetail.getAmount(), interest, fee, penalties, currentUser); updateLoanChargesPaidBy(accrual, feeDetails, null); - this.loanTransactions.add(accrual); + addLoanTransaction(accrual); } else if (existingAccrualTransaction.getAmount(getCurrency()).getAmount().compareTo(compoundingDetail.getAmount()) != 0) { existingAccrualTransaction.reverse(); LoanTransaction accrual = LoanTransaction.accrueTransaction(this, this.getOffice(), compoundingDetail.getEffectiveDate(), compoundingDetail.getAmount(), interest, fee, penalties, currentUser); updateLoanChargesPaidBy(accrual, feeDetails, null); - this.loanTransactions.add(accrual); + addLoanTransaction(accrual); } } updateLoanOutstandingBalaces(); @@ -5167,7 +5190,8 @@ public class Loan extends AbstractPersistable { BigDecimal penalties = BigDecimal.ZERO; List installments = new ArrayList<>(); - for (LoanRepaymentScheduleInstallment loanRepaymentScheduleInstallment : this.repaymentScheduleInstallments) { + List repaymentSchedule = getRepaymentScheduleInstallments() ; + for (LoanRepaymentScheduleInstallment loanRepaymentScheduleInstallment : repaymentSchedule) { if (loanRepaymentScheduleInstallment.getDueDate().isAfter(fromDate) && !loanRepaymentScheduleInstallment.getDueDate().isAfter(toDate)) { installments.add(loanRepaymentScheduleInstallment.getInstallmentNumber()); @@ -5218,8 +5242,9 @@ public class Loan extends AbstractPersistable { private List extractInterestRecalculationAdditionalDetails() { List retDetails = new ArrayList<>(); + List repaymentSchedule = getRepaymentScheduleInstallments() ; if (null != this.repaymentScheduleInstallments && this.repaymentScheduleInstallments.size() > 0) { - Iterator installmentsItr = this.repaymentScheduleInstallments.iterator(); + Iterator installmentsItr = repaymentSchedule.iterator(); while (installmentsItr.hasNext()) { LoanRepaymentScheduleInstallment installment = installmentsItr.next(); if (null != installment.getLoanCompoundingDetails()) { @@ -5247,7 +5272,7 @@ public class Loan extends AbstractPersistable { copyTransactions.add(LoanTransaction.copyTransactionProperties(loanTransaction)); } loanRepaymentScheduleTransactionProcessor.handleTransaction(getDisbursementDate(), copyTransactions, getCurrency(), - this.repaymentScheduleInstallments, charges()); + getRepaymentScheduleInstallments(), charges()); updateLoanSummaryDerivedFields(); } @@ -5269,7 +5294,7 @@ public class Loan extends AbstractPersistable { return loanScheduleGenerator.rescheduleNextInstallments(mc, loanApplicationTerms, charges(), generatorDTO.getHolidayDetailDTO(), retreiveListOfTransactionsPostDisbursementExcludeAccruals(), loanRepaymentScheduleTransactionProcessor, - repaymentScheduleInstallments, generatorDTO.getRecalculateFrom()); + getRepaymentScheduleInstallments(), generatorDTO.getRecalculateFrom()); } public LoanRepaymentScheduleInstallment fetchPrepaymentDetail(final ScheduleGeneratorDTO scheduleGeneratorDTO, final LocalDate onDate) { @@ -5287,7 +5312,7 @@ public class Loan extends AbstractPersistable { .determineProcessor(this.transactionProcessingStrategy); installment = loanScheduleGenerator.calculatePrepaymentAmount(getCurrency(), onDate, loanApplicationTerms, mc, charges(), scheduleGeneratorDTO.getHolidayDetailDTO(), retreiveListOfTransactionsPostDisbursementExcludeAccruals(), - loanRepaymentScheduleTransactionProcessor, this.fetchRepaymentScheduleInstallments()); + loanRepaymentScheduleTransactionProcessor, getRepaymentScheduleInstallments()); } else { installment = this.getTotalOutstandingOnLoan(); } @@ -5348,7 +5373,7 @@ public class Loan extends AbstractPersistable { this.loanProduct.getInstallmentAmountInMultiplesOf(), recalculationFrequencyType, restCalendarInstance, compoundingMethod, compoundingCalendarInstance, compoundingFrequencyType, this.loanProduct.preCloseInterestCalculationStrategy(), rescheduleStrategyMethod, calendar, getApprovedPrincipal(), annualNominalInterestRate, loanTermVariations, calendarHistoryDataWrapper, - scheduleGeneratorDTO.getNumberOfdays(), scheduleGeneratorDTO.isSkipRepaymentOnFirstDayofMonth(), holidayDetailDTO, allowCompoundingOnEod); + scheduleGeneratorDTO.getNumberOfdays(), scheduleGeneratorDTO.isSkipRepaymentOnFirstDayofMonth(), holidayDetailDTO, allowCompoundingOnEod); return loanApplicationTerms; } @@ -5366,8 +5391,9 @@ public class Loan extends AbstractPersistable { Money penaltyCharges = Money.zero(loanCurrency()); Money totalPrincipal = Money.zero(loanCurrency()); Money totalInterest = Money.zero(loanCurrency()); - final List compoundingDetails = null; - for (final LoanRepaymentScheduleInstallment scheduledRepayment : this.repaymentScheduleInstallments) { + final Set compoundingDetails = null; + List repaymentSchedule = getRepaymentScheduleInstallments() ; + for (final LoanRepaymentScheduleInstallment scheduledRepayment : repaymentSchedule) { totalPrincipal = totalPrincipal.plus(scheduledRepayment.getPrincipalOutstanding(loanCurrency())); totalInterest = totalInterest.plus(scheduledRepayment.getInterestOutstanding(loanCurrency())); feeCharges = feeCharges.plus(scheduledRepayment.getFeeChargesOutstanding(loanCurrency())); @@ -5377,10 +5403,6 @@ public class Loan extends AbstractPersistable { totalInterest.getAmount(), feeCharges.getAmount(), penaltyCharges.getAmount(), false, compoundingDetails); } - public List fetchRepaymentScheduleInstallments() { - return this.repaymentScheduleInstallments; - } - public LocalDate getAccruedTill() { LocalDate accruedTill = null; if (this.accruedTill != null) { @@ -5431,9 +5453,21 @@ public class Loan extends AbstractPersistable { * @return List of loan repayments schedule objects **/ public List getRepaymentScheduleInstallments() { - return this.repaymentScheduleInstallments; + if (this.sortedrepaymentScheduleInstallments == null || this.isrepaymentScheduleInstallmentsListDirty) { + this.sortedrepaymentScheduleInstallments = new ArrayList<>(this.repaymentScheduleInstallments); + this.sortedrepaymentScheduleInstallments.sort(LoanRepaymentScheduleInstallment.installmentNumberComparator); + } + return sortedrepaymentScheduleInstallments; } + public Integer getLoanRepaymentScheduleInstallmentsSize() { + return this.repaymentScheduleInstallments.size() ; + } + public void addLoanRepaymentScheduleInstallment(final LoanRepaymentScheduleInstallment installment) { + installment.updateLoan(this); + this.repaymentScheduleInstallments.add(installment); + this.isrepaymentScheduleInstallmentsListDirty = true ; + } /** * @return Loan product minimum repayments schedule related detail **/ @@ -5464,7 +5498,8 @@ public class Loan extends AbstractPersistable { LoanRepaymentScheduleInstallment installment = null; if (dueDate != null) { - for (LoanRepaymentScheduleInstallment repaymentScheduleInstallment : this.repaymentScheduleInstallments) { + List installments = getRepaymentScheduleInstallments() ; + for (LoanRepaymentScheduleInstallment repaymentScheduleInstallment : installments) { if (repaymentScheduleInstallment.getDueDate().isEqual(dueDate)) { installment = repaymentScheduleInstallment; @@ -5747,7 +5782,7 @@ public class Loan extends AbstractPersistable { } if (loanTransaction.isNotZero(loanCurrency())) { - this.loanTransactions.add(loanTransaction); + addLoanTransaction(loanTransaction); } if (loanTransaction.isNotRefundForActiveLoan()) { @@ -5782,12 +5817,12 @@ public class Loan extends AbstractPersistable { // If is a refund if (adjustedTransaction == null) { - loanRepaymentScheduleTransactionProcessor.handleRefund(loanTransaction, getCurrency(), this.repaymentScheduleInstallments, + loanRepaymentScheduleTransactionProcessor.handleRefund(loanTransaction, getCurrency(), getRepaymentScheduleInstallments(), charges()); } else { final List allNonContraTransactionsPostDisbursement = retreiveListOfTransactionsPostDisbursement(); changedTransactionDetail = loanRepaymentScheduleTransactionProcessor.handleTransaction(getDisbursementDate(), - allNonContraTransactionsPostDisbursement, getCurrency(), this.repaymentScheduleInstallments, charges()); + allNonContraTransactionsPostDisbursement, getCurrency(), getRepaymentScheduleInstallments(), charges()); for (final Map.Entry mapEntry : changedTransactionDetail.getNewTransactionMappings().entrySet()) { mapEntry.getValue().updateLoan(this); } @@ -5932,7 +5967,7 @@ public class Loan extends AbstractPersistable { this.interestRateDifferential = interestRateDifferential; } - public List getLoanTermVariations() { + public Set getLoanTermVariations() { return this.loanTermVariations; } @@ -5950,8 +5985,9 @@ public class Loan extends AbstractPersistable { public int fetchNumberOfInstallmensAfterExceptions() { if (this.repaymentScheduleInstallments.size() > 0) { + List installments = getRepaymentScheduleInstallments() ; int numberOfInstallments = 0; - for (final LoanRepaymentScheduleInstallment installment : this.repaymentScheduleInstallments) { + for (final LoanRepaymentScheduleInstallment installment : installments) { if (!installment.isRecalculatedInterestComponent()) { numberOfInstallments++; } @@ -5973,7 +6009,8 @@ public class Loan extends AbstractPersistable { LocalDate nextRepaymentDate = new LocalDate(); for (LoanDisbursementDetails loanDisbursementDetail : loanDisbursementDetails) { if (loanDisbursementDetail.actualDisbursementDate() == null) { - for (final LoanRepaymentScheduleInstallment installment : this.repaymentScheduleInstallments) { + List installments = getRepaymentScheduleInstallments() ; + for (final LoanRepaymentScheduleInstallment installment : installments) { if (installment.getDueDate().isEqual(loanDisbursementDetail.expectedDisbursementDateAsLocalDate()) || installment.getDueDate().isAfter(loanDisbursementDetail.expectedDisbursementDateAsLocalDate()) && installment.isNotFullyPaidOff()) { @@ -6009,12 +6046,12 @@ public class Loan extends AbstractPersistable { public LoanProduct getLoanProduct() { return loanProduct; } - + public LoanRepaymentScheduleInstallment fetchLoanForeclosureDetail(final LocalDate closureDate) { Money[] receivables = retriveIncomeOutstandingTillDate(closureDate); Money totalPrincipal = (Money.of(getCurrency(), this.getSummary().getTotalPrincipalOutstanding())); totalPrincipal = totalPrincipal.minus(receivables[3]); - final List compoundingDetails = null; + final Set compoundingDetails = null; final LocalDate currentDate = DateUtils.getLocalDateOfTenant(); return new LoanRepaymentScheduleInstallment(null, 0, currentDate, currentDate, totalPrincipal.getAmount(), receivables[0].getAmount(), receivables[1].getAmount(), receivables[2].getAmount(), false, compoundingDetails); @@ -6278,7 +6315,7 @@ public class Loan extends AbstractPersistable { public void updateLoanScheduleOnForeclosure(final Collection installments) { this.repaymentScheduleInstallments.clear(); for (final LoanRepaymentScheduleInstallment installment : installments) { - addRepaymentScheduleInstallment(installment); + addLoanRepaymentScheduleInstallment(installment); } } diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanAccountDomainServiceJpa.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanAccountDomainServiceJpa.java index aa204e75f..1f7e0fd48 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanAccountDomainServiceJpa.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanAccountDomainServiceJpa.java @@ -192,7 +192,7 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService { for (Map.Entry mapEntry : changedTransactionDetail.getNewTransactionMappings().entrySet()) { saveLoanTransactionWithDataIntegrityViolationChecks(mapEntry.getValue()); // update loan with references to the newly created transactions - loan.getLoanTransactions().add(mapEntry.getValue()); + loan.addLoanTransaction(mapEntry.getValue()); updateLoanTransaction(mapEntry.getKey(), mapEntry.getValue()); } } @@ -235,7 +235,7 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService { private void saveAndFlushLoanWithDataIntegrityViolationChecks(final Loan loan) { try { - List installments = loan.fetchRepaymentScheduleInstallments(); + List installments = loan.getRepaymentScheduleInstallments(); for (LoanRepaymentScheduleInstallment installment : installments) { if (installment.getId() == null) { this.repaymentScheduleInstallmentRepository.save(installment); @@ -257,7 +257,7 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService { @Override public void saveLoanWithDataIntegrityViolationChecks(final Loan loan) { try { - List installments = loan.fetchRepaymentScheduleInstallments(); + List installments = loan.getRepaymentScheduleInstallments(); for (LoanRepaymentScheduleInstallment installment : installments) { if (installment.getId() == null) { this.repaymentScheduleInstallmentRepository.save(installment); @@ -410,7 +410,7 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService { LoanTransaction disbursementTransaction = LoanTransaction.disbursement(loan.getOffice(), amount, paymentDetail, transactionDate, txnExternalId, DateUtils.getLocalDateTimeOfTenant(), currentUser); disbursementTransaction.updateLoan(loan); - loan.getLoanTransactions().add(disbursementTransaction); + loan.addLoanTransaction(disbursementTransaction); saveLoanTransactionWithDataIntegrityViolationChecks(disbursementTransaction); saveAndFlushLoanWithDataIntegrityViolationChecks(loan); @@ -448,7 +448,7 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService { if (!loan.isPeriodicAccrualAccountingEnabledOnLoanProduct() || !loan.repaymentScheduleDetail().isInterestRecalculationEnabled() || accruedTill == null || loan.isNpa() || !loan.status().isActive()) { return; } Collection loanScheduleAccrualDatas = new ArrayList<>(); - List installments = loan.fetchRepaymentScheduleInstallments(); + List installments = loan.getRepaymentScheduleInstallments(); Long loanId = loan.getId(); Long officeId = loan.getOfficeId(); LocalDate accrualStartDate = null; diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanCharge.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanCharge.java index 0c0bcbfc8..0189ee4df 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanCharge.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanCharge.java @@ -53,8 +53,6 @@ import org.apache.fineract.portfolio.charge.domain.ChargeTimeType; import org.apache.fineract.portfolio.charge.exception.LoanChargeWithoutMandatoryFieldException; import org.apache.fineract.portfolio.loanaccount.command.LoanChargeCommand; import org.apache.fineract.portfolio.loanaccount.data.LoanChargePaidDetail; -import org.hibernate.annotations.LazyCollection; -import org.hibernate.annotations.LazyCollectionOption; import org.joda.time.LocalDate; import org.springframework.data.jpa.domain.AbstractPersistable; @@ -122,8 +120,7 @@ public class LoanCharge extends AbstractPersistable { @Column(name = "max_cap", scale = 6, precision = 19, nullable = true) private BigDecimal maxCap; - @LazyCollection(LazyCollectionOption.FALSE) - @OneToMany(cascade = CascadeType.ALL, mappedBy = "loancharge", orphanRemoval = true) + @OneToMany(cascade = CascadeType.ALL, mappedBy = "loancharge", orphanRemoval = true, fetch=FetchType.EAGER) private final Set loanInstallmentCharge = new HashSet<>(); @Column(name = "is_active", nullable = false) diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanRepaymentScheduleInstallment.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanRepaymentScheduleInstallment.java index 0e5ce0909..d95d7412a 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanRepaymentScheduleInstallment.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanRepaymentScheduleInstallment.java @@ -19,14 +19,15 @@ package org.apache.fineract.portfolio.loanaccount.domain; import java.math.BigDecimal; -import java.util.ArrayList; import java.util.Comparator; import java.util.Date; -import java.util.List; +import java.util.HashSet; +import java.util.Set; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; +import javax.persistence.FetchType; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.OneToMany; @@ -38,8 +39,6 @@ import org.apache.fineract.infrastructure.core.domain.AbstractAuditableCustom; import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency; import org.apache.fineract.organisation.monetary.domain.Money; import org.apache.fineract.useradministration.domain.AppUser; -import org.hibernate.annotations.LazyCollection; -import org.hibernate.annotations.LazyCollectionOption; import org.joda.time.LocalDate; @Entity @@ -131,10 +130,9 @@ public final class LoanRepaymentScheduleInstallment extends AbstractAuditableCus @Column(name = "recalculated_interest_component", nullable = false) private boolean recalculatedInterestComponent; - @LazyCollection(LazyCollectionOption.FALSE) - @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true) + @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch=FetchType.EAGER) @JoinColumn(name = "loan_repayment_schedule_id", referencedColumnName = "id", nullable = false) - private List loanCompoundingDetails = new ArrayList<>(); + private Set loanCompoundingDetails = new HashSet<>(); protected LoanRepaymentScheduleInstallment() { this.installmentNumber = null; this.fromDate = null; @@ -145,7 +143,7 @@ public final class LoanRepaymentScheduleInstallment extends AbstractAuditableCus public LoanRepaymentScheduleInstallment(final Loan loan, final Integer installmentNumber, final LocalDate fromDate, final LocalDate dueDate, final BigDecimal principal, final BigDecimal interest, final BigDecimal feeCharges, final BigDecimal penaltyCharges, final boolean recalculatedInterestComponent, - final List compoundingDetails) { + final Set compoundingDetails) { this.loan = loan; this.installmentNumber = installmentNumber; this.fromDate = fromDate.toDateTimeAtStartOfDay().toDate(); @@ -782,7 +780,7 @@ public final class LoanRepaymentScheduleInstallment extends AbstractAuditableCus public Money getDue(MonetaryCurrency currency) { return getPrincipal(currency).plus(getInterestCharged(currency)).plus(getFeeChargesCharged(currency)).plus(getPenaltyChargesCharged(currency)); } - public List getLoanCompoundingDetails() { + public Set getLoanCompoundingDetails() { return this.loanCompoundingDetails; } diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanTransaction.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanTransaction.java index 70a2238b6..414ca14e4 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanTransaction.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanTransaction.java @@ -31,6 +31,7 @@ import java.util.Set; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; +import javax.persistence.FetchType; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.OneToMany; @@ -51,8 +52,6 @@ import org.apache.fineract.portfolio.loanproduct.service.LoanEnumerations; import org.apache.fineract.portfolio.paymentdetail.data.PaymentDetailData; import org.apache.fineract.portfolio.paymentdetail.domain.PaymentDetail; import org.apache.fineract.useradministration.domain.AppUser; -import org.hibernate.annotations.LazyCollection; -import org.hibernate.annotations.LazyCollectionOption; import org.joda.time.LocalDate; import org.joda.time.LocalDateTime; import org.springframework.data.jpa.domain.AbstractPersistable; @@ -123,8 +122,7 @@ public final class LoanTransaction extends AbstractPersistable { @JoinColumn(name = "appuser_id", nullable = true) private final AppUser appUser; - @LazyCollection(LazyCollectionOption.FALSE) - @OneToMany(cascade = CascadeType.ALL, mappedBy = "loanTransaction", orphanRemoval = true) + @OneToMany(cascade = CascadeType.ALL, mappedBy = "loanTransaction", orphanRemoval = true, fetch=FetchType.EAGER) private Set loanChargesPaid = new HashSet<>(); @Column(name = "outstanding_loan_balance_derived", scale = 6, precision = 19, nullable = true) @@ -133,9 +131,8 @@ public final class LoanTransaction extends AbstractPersistable { @Column(name = "manually_adjusted_or_reversed", nullable = false) private boolean manuallyAdjustedOrReversed; - @LazyCollection(LazyCollectionOption.FALSE) - @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true) - @JoinColumn(name = "loan_transaction_id", referencedColumnName = "id", nullable = false) + @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch=FetchType.EAGER) + @JoinColumn(name = "loan_transaction_id", referencedColumnName= "id" , nullable = false) private Set loanTransactionToRepaymentScheduleMappings = new HashSet<>(); protected LoanTransaction() { diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/guarantor/domain/Guarantor.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/guarantor/domain/Guarantor.java index 2aa240526..b52e4e793 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/guarantor/domain/Guarantor.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/guarantor/domain/Guarantor.java @@ -27,6 +27,7 @@ import java.util.Map; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; +import javax.persistence.FetchType; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.OneToMany; @@ -39,8 +40,6 @@ import org.apache.fineract.infrastructure.codes.domain.CodeValue; import org.apache.fineract.infrastructure.core.api.JsonCommand; import org.apache.fineract.portfolio.loanaccount.domain.Loan; import org.apache.fineract.portfolio.loanaccount.guarantor.GuarantorConstants.GUARANTOR_JSON_INPUT_PARAMS; -import org.hibernate.annotations.LazyCollection; -import org.hibernate.annotations.LazyCollectionOption; import org.springframework.data.jpa.domain.AbstractPersistable; @Entity @@ -101,8 +100,7 @@ public class Guarantor extends AbstractPersistable { @Column(name = "is_active", nullable = false) private boolean active; - @LazyCollection(LazyCollectionOption.FALSE) - @OneToMany(cascade = CascadeType.ALL, mappedBy = "guarantor", orphanRemoval = true) + @OneToMany(cascade = CascadeType.ALL, mappedBy = "guarantor", orphanRemoval = true, fetch=FetchType.EAGER) private final List guarantorFundDetails = new ArrayList<>(); protected Guarantor() { diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/guarantor/domain/GuarantorFundingDetails.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/guarantor/domain/GuarantorFundingDetails.java index fe7ce850f..0179cb217 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/guarantor/domain/GuarantorFundingDetails.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/guarantor/domain/GuarantorFundingDetails.java @@ -25,6 +25,7 @@ import java.util.List; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; +import javax.persistence.FetchType; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.OneToMany; @@ -33,8 +34,6 @@ import javax.persistence.Table; import org.apache.fineract.portfolio.account.domain.AccountAssociations; import org.apache.fineract.portfolio.loanaccount.domain.Loan; import org.apache.fineract.portfolio.savings.domain.SavingsAccount; -import org.hibernate.annotations.LazyCollection; -import org.hibernate.annotations.LazyCollectionOption; import org.springframework.data.jpa.domain.AbstractPersistable; @Entity @@ -64,8 +63,7 @@ public class GuarantorFundingDetails extends AbstractPersistable { @Column(name = "amount_transfered_derived", scale = 6, precision = 19, nullable = true) private BigDecimal amountTransfered; - @LazyCollection(LazyCollectionOption.FALSE) - @OneToMany(cascade = CascadeType.ALL, mappedBy = "guarantorFundingDetails", orphanRemoval = true) + @OneToMany(cascade = CascadeType.ALL, mappedBy = "guarantorFundingDetails", orphanRemoval = true, fetch=FetchType.EAGER) private final List guarantorFundingTransactions = new ArrayList<>(); protected GuarantorFundingDetails() {} diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/AbstractLoanScheduleGenerator.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/AbstractLoanScheduleGenerator.java index 3581558ca..d9e57a008 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/AbstractLoanScheduleGenerator.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/AbstractLoanScheduleGenerator.java @@ -2575,7 +2575,7 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener currency); } Money amountCharged = getIncomeForCompounding(loanApplicationTerms, currency, installment); - final List details = installment.getLoanCompoundingDetails(); + final Set details = installment.getLoanCompoundingDetails(); Money totalCompounded = Money.zero(currency); Map compoundingMap = new TreeMap<>(); for (LoanInterestRecalcualtionAdditionalDetails additionalDetails : details) { @@ -2754,7 +2754,7 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener penaltyCharges = penaltyCharges.plus(currentInstallment.getPenaltyChargesOutstanding(currency)); } } - final List compoundingDetails = null; + final Set compoundingDetails = null; return new LoanRepaymentScheduleInstallment(null, 0, onDate, onDate, totalPrincipal.getAmount(), totalInterest.getAmount(), feeCharges.getAmount(), penaltyCharges.getAmount(), false, compoundingDetails); } diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/LoanScheduleModelDisbursementPeriod.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/LoanScheduleModelDisbursementPeriod.java index 87d2332ae..999473038 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/LoanScheduleModelDisbursementPeriod.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/LoanScheduleModelDisbursementPeriod.java @@ -19,7 +19,7 @@ package org.apache.fineract.portfolio.loanaccount.loanschedule.domain; import java.math.BigDecimal; -import java.util.List; +import java.util.Set; import org.apache.fineract.organisation.monetary.domain.Money; import org.apache.fineract.portfolio.loanaccount.domain.LoanInterestRecalcualtionAdditionalDetails; @@ -125,7 +125,7 @@ public final class LoanScheduleModelDisbursementPeriod implements LoanScheduleMo return; } @Override - public List getLoanCompoundingDetails() { + public Set getLoanCompoundingDetails() { return null; } } \ No newline at end of file diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/LoanScheduleModelPeriod.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/LoanScheduleModelPeriod.java index db676777c..99095e49a 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/LoanScheduleModelPeriod.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/LoanScheduleModelPeriod.java @@ -19,7 +19,7 @@ package org.apache.fineract.portfolio.loanaccount.loanschedule.domain; import java.math.BigDecimal; -import java.util.List; +import java.util.Set; import org.apache.fineract.organisation.monetary.domain.Money; import org.apache.fineract.portfolio.loanaccount.domain.LoanInterestRecalcualtionAdditionalDetails; @@ -53,5 +53,5 @@ public interface LoanScheduleModelPeriod { void addPrincipalAmount(Money principalDue); void addInterestAmount(Money interestDue); - List getLoanCompoundingDetails(); + Set getLoanCompoundingDetails(); } diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/LoanScheduleModelRepaymentPeriod.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/LoanScheduleModelRepaymentPeriod.java index 201e7ca8b..75c6796d8 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/LoanScheduleModelRepaymentPeriod.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/LoanScheduleModelRepaymentPeriod.java @@ -19,8 +19,8 @@ package org.apache.fineract.portfolio.loanaccount.loanschedule.domain; import java.math.BigDecimal; -import java.util.ArrayList; -import java.util.List; +import java.util.HashSet; +import java.util.Set; import org.apache.fineract.organisation.monetary.domain.Money; import org.apache.fineract.portfolio.loanaccount.domain.LoanInterestRecalcualtionAdditionalDetails; @@ -43,7 +43,7 @@ public final class LoanScheduleModelRepaymentPeriod implements LoanScheduleModel private Money penaltyChargesDue; private Money totalDue; private final boolean recalculatedInterestComponent; - private final List loanCompoundingDetails = new ArrayList<>(); + private final Set loanCompoundingDetails = new HashSet<>(); public static LoanScheduleModelRepaymentPeriod repayment(final int periodNumber, final LocalDate startDate, final LocalDate scheduledDueDate, final Money principalDue, final Money outstandingLoanBalance, final Money interestDue, @@ -159,7 +159,7 @@ public final class LoanScheduleModelRepaymentPeriod implements LoanScheduleModel this.totalDue = this.totalDue.plus(principalDue); } @Override - public List getLoanCompoundingDetails() { + public Set getLoanCompoundingDetails() { return this.loanCompoundingDetails; } } \ No newline at end of file diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/service/LoanScheduleAssembler.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/service/LoanScheduleAssembler.java index b86f2a719..ac4a368fa 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/service/LoanScheduleAssembler.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/service/LoanScheduleAssembler.java @@ -23,7 +23,6 @@ import java.math.MathContext; import java.math.RoundingMode; import java.util.ArrayList; import java.util.Collection; -import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.List; @@ -87,7 +86,6 @@ import org.apache.fineract.portfolio.loanaccount.domain.LoanDisbursementDetails; import org.apache.fineract.portfolio.loanaccount.domain.LoanRepaymentScheduleInstallment; import org.apache.fineract.portfolio.loanaccount.domain.LoanTermVariationType; import org.apache.fineract.portfolio.loanaccount.domain.LoanTermVariations; -import org.apache.fineract.portfolio.loanaccount.domain.LoanTermVariationsComparator; import org.apache.fineract.portfolio.loanaccount.domain.LoanTransaction; import org.apache.fineract.portfolio.loanaccount.domain.transactionprocessor.LoanRepaymentScheduleTransactionProcessor; import org.apache.fineract.portfolio.loanaccount.exception.LoanApplicationDateException; @@ -663,7 +661,7 @@ public class LoanScheduleAssembler { public void assempleVariableScheduleFrom(final Loan loan, final String json) { this.variableLoanScheduleFromApiJsonValidator.validateSchedule(json, loan); - List variations = loan.getLoanTermVariations(); + Set variations = loan.getLoanTermVariations(); List newVariations = new ArrayList<>(); extractLoanTermVariations(loan, json, newVariations); @@ -674,8 +672,8 @@ public class LoanScheduleAssembler { newVariations = retainVariations; } variations.addAll(newVariations); - Collections.sort(variations, new LoanTermVariationsComparator()); - + //Collections.sort(variations, new LoanTermVariationsComparator()); + /* * List loanTermVariationsDatas = new * ArrayList<>(); @@ -686,7 +684,7 @@ public class LoanScheduleAssembler { */ // date validations - List installments = loan.fetchRepaymentScheduleInstallments(); + List installments = loan.getRepaymentScheduleInstallments(); Set dueDates = new TreeSet<>(); LocalDate graceApplicable = loan.getExpectedDisbursedOnLocalDate(); Integer graceOnPrincipal = loan.getLoanProductRelatedDetail().graceOnPrincipalPayment(); @@ -845,11 +843,12 @@ public class LoanScheduleAssembler { loan.regenerateRepaymentSchedule(scheduleGeneratorDTO, currentUser); } - private List adjustExistingVariations(List variations, List newVariations, + private List adjustExistingVariations(Set variations, List newVariations, final Map adjustDueDateVariations) { Map amountVariations = new HashMap<>(); Map dueDateVariations = new HashMap<>(); Map insertVariations = new HashMap<>(); + for (LoanTermVariations loanTermVariations : variations) { switch (loanTermVariations.getTermType()) { case EMI_AMOUNT: diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/service/LoanScheduleCalculationPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/service/LoanScheduleCalculationPlatformServiceImpl.java index 6d1aecda1..41e8313e6 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/service/LoanScheduleCalculationPlatformServiceImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/service/LoanScheduleCalculationPlatformServiceImpl.java @@ -161,7 +161,8 @@ public class LoanScheduleCalculationPlatformServiceImpl implements LoanScheduleC MonetaryCurrency currency = loan.getCurrency(); Money totalPrincipal = Money.zero(currency); final List futureInstallments = new ArrayList<>(); - for (final LoanRepaymentScheduleInstallment currentInstallment : loan.fetchRepaymentScheduleInstallments()) { + List installments = loan.getRepaymentScheduleInstallments() ; + for (final LoanRepaymentScheduleInstallment currentInstallment : installments) { if (currentInstallment.isNotFullyPaidOff()) { if (!currentInstallment.getDueDate().isAfter(today)) { totalPrincipal = totalPrincipal.plus(currentInstallment.getPrincipalOutstanding(currency)); @@ -172,7 +173,7 @@ public class LoanScheduleCalculationPlatformServiceImpl implements LoanScheduleC LoanRepaymentScheduleInstallment loanRepaymentScheduleInstallment = this.loanScheduleAssembler.calculatePrepaymentAmount(currency, today, loanApplicationTerms, loan.charges(), loan.getOfficeId(), loan.retreiveListOfTransactionsPostDisbursementExcludeAccruals(), loanRepaymentScheduleTransactionProcessor, - loan.fetchRepaymentScheduleInstallments()); + loan.getRepaymentScheduleInstallments()); Money totalAmount = totalPrincipal.plus(loanRepaymentScheduleInstallment.getFeeChargesOutstanding(currency)).plus( loanRepaymentScheduleInstallment.getPenaltyChargesOutstanding(currency)); Money interestDue = Money.zero(currency); @@ -193,7 +194,7 @@ public class LoanScheduleCalculationPlatformServiceImpl implements LoanScheduleC } LoanScheduleModel model = this.loanScheduleAssembler.assembleForInterestRecalculation(loanApplicationTerms, loan.getOfficeId(), - modifiedTransactions, loan.charges(), loanRepaymentScheduleTransactionProcessor, loan.fetchRepaymentScheduleInstallments(), + modifiedTransactions, loan.charges(), loanRepaymentScheduleTransactionProcessor, loan.getRepaymentScheduleInstallments(), loan.fetchInterestRecalculateFromDate()); LoanScheduleData scheduleDate = model.toData(); Collection periodDatas = scheduleDate.getPeriods(); diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/service/LoanScheduleWritePlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/service/LoanScheduleWritePlatformServiceImpl.java index 719167152..0999fe55b 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/service/LoanScheduleWritePlatformServiceImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/service/LoanScheduleWritePlatformServiceImpl.java @@ -22,6 +22,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Set; import org.apache.fineract.infrastructure.core.api.JsonCommand; import org.apache.fineract.infrastructure.core.data.CommandProcessingResult; @@ -71,7 +72,7 @@ public class LoanScheduleWritePlatformServiceImpl implements LoanScheduleWritePl this.loanAccountDomainService.saveLoanWithDataIntegrityViolationChecks(loan); final Map changes = new HashMap<>(); List newVariationsData = new ArrayList<>(); - List modifiedVariations = loan.getLoanTermVariations(); + Set modifiedVariations = loan.getLoanTermVariations(); for (LoanTermVariations termVariations : modifiedVariations) { if (loanTermVariations.containsKey(termVariations.getId())) { loanTermVariations.remove(termVariations.getId()); @@ -93,7 +94,7 @@ public class LoanScheduleWritePlatformServiceImpl implements LoanScheduleWritePl @Override public CommandProcessingResult deleteLoanScheduleVariations(final Long loanId) { final Loan loan = this.loanAssembler.assembleFrom(loanId); - List variations = loan.getLoanTermVariations(); + Set variations = loan.getLoanTermVariations(); List deletedVariations = new ArrayList<>(variations.size()); for (LoanTermVariations loanTermVariations : variations) { deletedVariations.add(loanTermVariations.getId()); diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/rescheduleloan/service/LoanRescheduleRequestWritePlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/rescheduleloan/service/LoanRescheduleRequestWritePlatformServiceImpl.java index 3a008ab8f..74ec62413 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/rescheduleloan/service/LoanRescheduleRequestWritePlatformServiceImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/rescheduleloan/service/LoanRescheduleRequestWritePlatformServiceImpl.java @@ -28,6 +28,7 @@ import java.util.Date; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.Set; import org.apache.fineract.accounting.journalentry.service.JournalEntryWritePlatformService; import org.apache.fineract.infrastructure.codes.domain.CodeValue; @@ -371,7 +372,7 @@ public class LoanRescheduleRequestWritePlatformServiceImpl implements LoanResche final Collection periods = loanRescheduleModel.getPeriods(); List repaymentScheduleInstallments = loan.getRepaymentScheduleInstallments(); Collection waiveLoanCharges = new ArrayList<>(); - final List compoundingDetails = null; + final Set compoundingDetails = null; for (LoanRescheduleModelRepaymentPeriod period : periods) { if (period.isNew()) { @@ -379,7 +380,8 @@ public class LoanRescheduleRequestWritePlatformServiceImpl implements LoanResche period.periodNumber(), period.periodFromDate(), period.periodDueDate(), period.principalDue(), period.interestDue(), BigDecimal.ZERO, BigDecimal.ZERO, false, compoundingDetails); - repaymentScheduleInstallments.add(repaymentScheduleInstallment); + loan.addLoanRepaymentScheduleInstallment(repaymentScheduleInstallment); + repaymentScheduleInstallments.add(repaymentScheduleInstallment) ; } else { @@ -423,8 +425,7 @@ public class LoanRescheduleRequestWritePlatformServiceImpl implements LoanResche waiveLoanCharges(loan, waiveLoanCharges); // update the Loan summary - loanSummary - .updateSummary(currency, loan.getPrincpal(), repaymentScheduleInstallments, new LoanSummaryWrapper(), true, null); + loanSummary.updateSummary(currency, loan.getPrincpal(), repaymentScheduleInstallments, new LoanSummaryWrapper(), true, null); // update the total number of schedule repayments loan.updateNumberOfRepayments(periods.size()); diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/serialization/LoanApplicationCommandFromApiJsonHelper.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/serialization/LoanApplicationCommandFromApiJsonHelper.java index f2dd3d914..7d4a8f4c8 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/serialization/LoanApplicationCommandFromApiJsonHelper.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/serialization/LoanApplicationCommandFromApiJsonHelper.java @@ -959,7 +959,7 @@ public final class LoanApplicationCommandFromApiJsonHelper { if (loan.getFixedEmiAmount() != null) { Integer minimumNoOfRepayments = loan.loanProduct().getMinNumberOfRepayments(); Integer maximumNoOfRepayments = loan.loanProduct().getMaxNumberOfRepayments(); - Integer actualNumberOfRepayments = loan.getRepaymentScheduleInstallments().size(); + Integer actualNumberOfRepayments = loan.getLoanRepaymentScheduleInstallmentsSize(); // validate actual number of repayments is > minimum number of // repayments if (minimumNoOfRepayments != null && minimumNoOfRepayments != 0 && actualNumberOfRepayments < minimumNoOfRepayments) { diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanApplicationWritePlatformServiceJpaRepositoryImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanApplicationWritePlatformServiceJpaRepositoryImpl.java index 0d494143d..84322730f 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanApplicationWritePlatformServiceJpaRepositoryImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanApplicationWritePlatformServiceJpaRepositoryImpl.java @@ -1164,7 +1164,7 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa private void saveAndFlushLoanWithDataIntegrityViolationChecks(final Loan loan) { try { - List installments = loan.fetchRepaymentScheduleInstallments(); + List installments = loan.getRepaymentScheduleInstallments(); for (LoanRepaymentScheduleInstallment installment : installments) { if (installment.getId() == null) { this.repaymentScheduleInstallmentRepository.save(installment); diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java index db45fceac..a5cb52b0f 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java @@ -365,7 +365,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf LoanTransaction disbursementTransaction = LoanTransaction.disbursement(loan.getOffice(), disburseAmount, paymentDetail, actualDisbursementDate, txnExternalId, DateUtils.getLocalDateTimeOfTenant(), currentUser); disbursementTransaction.updateLoan(loan); - loan.getLoanTransactions().add(disbursementTransaction); + loan.addLoanTransaction(disbursementTransaction); } regenerateScheduleOnDisbursement(command, loan, recalculateSchedule, scheduleGeneratorDTO, nextPossibleRepaymentDate, rescheduledRepaymentDate); @@ -508,7 +508,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf private void saveAndFlushLoanWithDataIntegrityViolationChecks(final Loan loan) { try { - List installments = loan.fetchRepaymentScheduleInstallments(); + List installments = loan.getRepaymentScheduleInstallments(); for (LoanRepaymentScheduleInstallment installment : installments) { if (installment.getId() == null) { this.repaymentScheduleInstallmentRepository.save(installment); @@ -529,7 +529,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf private void saveLoanWithDataIntegrityViolationChecks(final Loan loan) { try { - List installments = loan.fetchRepaymentScheduleInstallments(); + List installments = loan.getRepaymentScheduleInstallments(); for (LoanRepaymentScheduleInstallment installment : installments) { if (installment.getId() == null) { this.repaymentScheduleInstallmentRepository.save(installment); @@ -607,7 +607,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf LoanTransaction disbursementTransaction = LoanTransaction.disbursement(loan.getOffice(), disburseAmount, paymentDetail, actualDisbursementDate, txnExternalId, DateUtils.getLocalDateTimeOfTenant(), currentUser); disbursementTransaction.updateLoan(loan); - loan.getLoanTransactions().add(disbursementTransaction); + loan.addLoanTransaction(disbursementTransaction); } LocalDate recalculateFrom = null; final ScheduleGeneratorDTO scheduleGeneratorDTO = this.loanUtilService.buildScheduleGeneratorDTO(loan, recalculateFrom); @@ -903,7 +903,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf for (final Map.Entry mapEntry : changedTransactionDetail.getNewTransactionMappings().entrySet()) { this.loanTransactionRepository.save(mapEntry.getValue()); // update loan with references to the newly created transactions - loan.getLoanTransactions().add(mapEntry.getValue()); + loan.addLoanTransaction(mapEntry.getValue()); this.accountTransfersWritePlatformService.updateLoanTransaction(mapEntry.getKey(), mapEntry.getValue()); } } @@ -1017,7 +1017,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf for (final Map.Entry mapEntry : changedTransactionDetail.getNewTransactionMappings().entrySet()) { this.loanTransactionRepository.save(mapEntry.getValue()); // update loan with references to the newly created transactions - loan.getLoanTransactions().add(mapEntry.getValue()); + loan.addLoanTransaction(mapEntry.getValue()); this.accountTransfersWritePlatformService.updateLoanTransaction(mapEntry.getKey(), mapEntry.getValue()); } } @@ -1322,7 +1322,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf this.loanTransactionRepository.save(mapEntry.getValue()); // update loan with references to the newly created // transactions - loan.getLoanTransactions().add(mapEntry.getValue()); + loan.addLoanTransaction(mapEntry.getValue()); this.accountTransfersWritePlatformService.updateLoanTransaction(mapEntry.getKey(), mapEntry.getValue()); } } @@ -1384,7 +1384,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf this.loanTransactionRepository.save(mapEntry.getValue()); // update loan with references to the newly created // transactions - loan.getLoanTransactions().add(mapEntry.getValue()); + loan.addLoanTransaction(mapEntry.getValue()); this.accountTransfersWritePlatformService.updateLoanTransaction(mapEntry.getKey(), mapEntry.getValue()); } } @@ -1776,7 +1776,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf final LoanTransaction newTransferTransaction = LoanTransaction.initiateTransfer(loan.getOffice(), loan, transferDate, DateUtils.getLocalDateTimeOfTenant(), currentUser); - loan.getLoanTransactions().add(newTransferTransaction); + loan.addLoanTransaction(newTransferTransaction); loan.setLoanStatus(LoanStatus.TRANSFER_IN_PROGRESS.getValue()); this.loanTransactionRepository.save(newTransferTransaction); @@ -1803,7 +1803,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf final LoanTransaction newTransferAcceptanceTransaction = LoanTransaction.approveTransfer(acceptedInOffice, loan, transferDate, DateUtils.getLocalDateTimeOfTenant(), currentUser); - loan.getLoanTransactions().add(newTransferAcceptanceTransaction); + loan.addLoanTransaction(newTransferAcceptanceTransaction); if (loan.getTotalOverpaid() != null) { loan.setLoanStatus(LoanStatus.OVERPAID.getValue()); } else { @@ -1838,7 +1838,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf final LoanTransaction newTransferAcceptanceTransaction = LoanTransaction.withdrawTransfer(loan.getOffice(), loan, transferDate, DateUtils.getLocalDateTimeOfTenant(), currentUser); - loan.getLoanTransactions().add(newTransferAcceptanceTransaction); + loan.addLoanTransaction(newTransferAcceptanceTransaction); loan.setLoanStatus(LoanStatus.ACTIVE.getValue()); this.loanTransactionRepository.save(newTransferAcceptanceTransaction); @@ -2327,7 +2327,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf this.loanTransactionRepository.save(mapEntry.getValue()); // update loan with references to the newly created // transactions - loan.getLoanTransactions().add(mapEntry.getValue()); + loan.addLoanTransaction(mapEntry.getValue()); this.accountTransfersWritePlatformService.updateLoanTransaction(mapEntry.getKey(), mapEntry.getValue()); } } @@ -2348,7 +2348,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf private void addInstallmentIfPenaltyAppliedAfterLastDueDate(Loan loan, LocalDate lastChargeDate) { if (lastChargeDate != null) { - List installments = loan.fetchRepaymentScheduleInstallments(); + List installments = loan.getRepaymentScheduleInstallments(); LoanRepaymentScheduleInstallment lastInstallment = loan.fetchRepaymentScheduleInstallment(installments.size()); if (lastChargeDate.isAfter(lastInstallment.getDueDate())) { if (lastInstallment.isRecalculatedInterestComponent()) { @@ -2360,11 +2360,12 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf BigDecimal interest = BigDecimal.ZERO; BigDecimal feeCharges = BigDecimal.ZERO; BigDecimal penaltyCharges = BigDecimal.ONE; - final List compoundingDetails = null; + final Set compoundingDetails = null; LoanRepaymentScheduleInstallment newEntry = new LoanRepaymentScheduleInstallment(loan, installments.size() + 1, lastInstallment.getDueDate(), lastChargeDate, principal, interest, feeCharges, penaltyCharges, recalculatedInterestComponent, compoundingDetails); installments.add(newEntry); + loan.addLoanRepaymentScheduleInstallment(newEntry); } } } @@ -2722,7 +2723,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf this.loanTransactionRepository.save(mapEntry.getValue()); // update loan with references to the newly created // transactions - loan.getLoanTransactions().add(mapEntry.getValue()); + loan.addLoanTransaction(mapEntry.getValue()); this.accountTransfersWritePlatformService.updateLoanTransaction(mapEntry.getKey(), mapEntry.getValue()); } } diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/domain/LoanProduct.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/domain/LoanProduct.java index 53d60a796..c66e70b78 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/domain/LoanProduct.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/domain/LoanProduct.java @@ -60,8 +60,6 @@ import org.apache.fineract.portfolio.floatingrates.domain.FloatingRate; import org.apache.fineract.portfolio.fund.domain.Fund; import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.AprCalculator; import org.apache.fineract.portfolio.loanproduct.LoanProductConstants; -import org.hibernate.annotations.LazyCollection; -import org.hibernate.annotations.LazyCollectionOption; import org.joda.time.LocalDate; import org.springframework.data.jpa.domain.AbstractPersistable; @@ -133,8 +131,7 @@ public class LoanProduct extends AbstractPersistable { @Column(name = "external_id", length = 100, nullable = true, unique = true) private String externalId; - @LazyCollection(LazyCollectionOption.FALSE) - @OneToMany(cascade = CascadeType.ALL, mappedBy = "loanProduct", orphanRemoval = true) + @OneToMany(cascade = CascadeType.ALL, mappedBy = "loanProduct", orphanRemoval = true, fetch=FetchType.EAGER) private Set borrowerCycleVariations = new HashSet<>(); @Column(name = "overdue_days_for_npa", nullable = true) @@ -143,15 +140,13 @@ public class LoanProduct extends AbstractPersistable { @Column(name = "min_days_between_disbursal_and_first_repayment", nullable = true) private Integer minimumDaysBetweenDisbursalAndFirstRepayment; - @LazyCollection(LazyCollectionOption.FALSE) - @OneToOne(cascade = CascadeType.ALL, mappedBy = "loanProduct", optional = true, orphanRemoval = true) + @OneToOne(cascade = CascadeType.ALL, mappedBy = "loanProduct", optional = true, orphanRemoval = true, fetch=FetchType.EAGER) private LoanProductInterestRecalculationDetails productInterestRecalculationDetails; @Column(name = "hold_guarantee_funds") private boolean holdGuaranteeFunds; - @LazyCollection(LazyCollectionOption.FALSE) - @OneToOne(cascade = CascadeType.ALL, mappedBy = "loanProduct", optional = true, orphanRemoval = true) + @OneToOne(cascade = CascadeType.ALL, mappedBy = "loanProduct", optional = true, orphanRemoval = true, fetch=FetchType.EAGER) private LoanProductGuaranteeDetails loanProductGuaranteeDetails; @OneToOne(cascade = CascadeType.ALL, mappedBy = "loanProduct", optional = true, orphanRemoval = true) @@ -172,15 +167,13 @@ public class LoanProduct extends AbstractPersistable { @Column(name = "is_linked_to_floating_interest_rates", nullable = false) private boolean isLinkedToFloatingInterestRate; - @LazyCollection(LazyCollectionOption.FALSE) - @OneToOne(cascade = CascadeType.ALL, mappedBy = "loanProduct", optional = true, orphanRemoval = true) + @OneToOne(cascade = CascadeType.ALL, mappedBy = "loanProduct", optional = true, orphanRemoval = true, fetch=FetchType.EAGER) private LoanProductFloatingRates floatingRates; @Column(name = "allow_variabe_installments", nullable = false) private boolean allowVariabeInstallments; - @LazyCollection(LazyCollectionOption.FALSE) - @OneToOne(cascade = CascadeType.ALL, mappedBy = "loanProduct", optional = true, orphanRemoval = true) + @OneToOne(cascade = CascadeType.ALL, mappedBy = "loanProduct", optional = true, orphanRemoval = true, fetch=FetchType.EAGER) private LoanProductVariableInstallmentConfig variableInstallmentConfig; public static LoanProduct assembleFromJson(final Fund fund, final LoanTransactionProcessingStrategy loanTransactionProcessingStrategy, diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/DepositAccountDomainServiceJpa.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/DepositAccountDomainServiceJpa.java index 2bd27c2f4..05d2269c7 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/DepositAccountDomainServiceJpa.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/DepositAccountDomainServiceJpa.java @@ -466,7 +466,7 @@ public class DepositAccountDomainServiceJpa implements DepositAccountDomainServi } private void updateAlreadyPostedTransactions(final Set existingTransactionIds, final SavingsAccount savingsAccount) { - List transactions = savingsAccount.getTransactions(); + List transactions = savingsAccount.getTransactions() ; int size = transactions.size(); for (int i = size - 1;; i--) { SavingsAccountTransaction transaction = transactions.get(i); diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/DepositAccountInterestRateChart.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/DepositAccountInterestRateChart.java index 7365b0fe5..94bd39da3 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/DepositAccountInterestRateChart.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/DepositAccountInterestRateChart.java @@ -25,6 +25,7 @@ import java.util.Set; import javax.persistence.CascadeType; import javax.persistence.Embedded; import javax.persistence.Entity; +import javax.persistence.FetchType; import javax.persistence.JoinColumn; import javax.persistence.OneToMany; import javax.persistence.OneToOne; @@ -37,8 +38,6 @@ import org.apache.fineract.portfolio.interestratechart.domain.InterestRateChartS import org.apache.fineract.portfolio.interestratechart.incentive.AttributeIncentiveCalculation; import org.apache.fineract.portfolio.interestratechart.incentive.AttributeIncentiveCalculationFactory; import org.apache.fineract.portfolio.interestratechart.incentive.IncentiveDTO; -import org.hibernate.annotations.LazyCollection; -import org.hibernate.annotations.LazyCollectionOption; import org.joda.time.LocalDate; import org.springframework.data.jpa.domain.AbstractPersistable; @@ -53,8 +52,7 @@ public class DepositAccountInterestRateChart extends AbstractPersistable { @JoinColumn(name = "savings_account_id", nullable = false) private SavingsAccount account; - @LazyCollection(LazyCollectionOption.FALSE) - @OneToMany(mappedBy = "depositAccountInterestRateChart", cascade = CascadeType.ALL, orphanRemoval = true) + @OneToMany(mappedBy = "depositAccountInterestRateChart", cascade = CascadeType.ALL, orphanRemoval = true, fetch=FetchType.EAGER) private Set chartSlabs = new HashSet<>(); protected DepositAccountInterestRateChart() { diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/DepositAccountInterestRateChartSlabs.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/DepositAccountInterestRateChartSlabs.java index 02f88ec8a..0cca9c9a9 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/DepositAccountInterestRateChartSlabs.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/DepositAccountInterestRateChartSlabs.java @@ -24,6 +24,7 @@ import java.util.Set; import javax.persistence.CascadeType; import javax.persistence.Embedded; import javax.persistence.Entity; +import javax.persistence.FetchType; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.OneToMany; @@ -32,8 +33,6 @@ import javax.persistence.Table; import org.apache.fineract.portfolio.interestratechart.domain.InterestIncentives; import org.apache.fineract.portfolio.interestratechart.domain.InterestRateChartSlab; import org.apache.fineract.portfolio.interestratechart.domain.InterestRateChartSlabFields; -import org.hibernate.annotations.LazyCollection; -import org.hibernate.annotations.LazyCollectionOption; import org.springframework.data.jpa.domain.AbstractPersistable; @Entity @@ -47,8 +46,7 @@ public class DepositAccountInterestRateChartSlabs extends AbstractPersistable interestIncentives = new HashSet<>(); protected DepositAccountInterestRateChartSlabs() { diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/RecurringDepositAccount.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/RecurringDepositAccount.java index cc67fe2f0..295402756 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/RecurringDepositAccount.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/RecurringDepositAccount.java @@ -28,7 +28,9 @@ import java.math.MathContext; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; +import java.util.Comparator; import java.util.Date; +import java.util.HashSet; import java.util.List; import java.util.Locale; import java.util.Map; @@ -70,8 +72,6 @@ import org.apache.fineract.portfolio.savings.data.SavingsAccountTransactionDTO; import org.apache.fineract.portfolio.savings.domain.interest.PostingPeriod; import org.apache.fineract.portfolio.savings.service.SavingsEnumerations; import org.apache.fineract.useradministration.domain.AppUser; -import org.hibernate.annotations.LazyCollection; -import org.hibernate.annotations.LazyCollectionOption; import org.joda.time.LocalDate; import org.joda.time.format.DateTimeFormat; import org.joda.time.format.DateTimeFormatter; @@ -89,10 +89,13 @@ public class RecurringDepositAccount extends SavingsAccount { @OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "account") private DepositAccountInterestRateChart chart; - @LazyCollection(LazyCollectionOption.FALSE) - @OneToMany(cascade = CascadeType.ALL, mappedBy = "account", orphanRemoval = true) - private List depositScheduleInstallments = new ArrayList<>(); + @OneToMany(cascade = CascadeType.ALL, mappedBy = "account", orphanRemoval = true, fetch=FetchType.EAGER) + private Set depositScheduleInstallments = new HashSet<>(); + private transient List sortedDepositInstallments = null ; + + private transient boolean isDepositScheduleInstallmentDirty = false ; + protected RecurringDepositAccount() { // } @@ -620,7 +623,7 @@ public class RecurringDepositAccount extends SavingsAccount { if (postingTransaction == null) { final SavingsAccountTransaction newPostingTransaction = SavingsAccountTransaction.interestPosting(this, office(), interestPostingTransactionDate, interestEarnedToBePostedForPeriod); - this.transactions.add(newPostingTransaction); + addTransaction(newPostingTransaction); recalucateDailyBalanceDetails = true; } else { final boolean correctionRequired = postingTransaction.hasNotAmount(interestEarnedToBePostedForPeriod); @@ -628,7 +631,7 @@ public class RecurringDepositAccount extends SavingsAccount { postingTransaction.reverse(); final SavingsAccountTransaction newPostingTransaction = SavingsAccountTransaction.interestPosting(this, office(), interestPostingTransactionDate, interestEarnedToBePostedForPeriod); - this.transactions.add(newPostingTransaction); + addTransaction(newPostingTransaction); recalucateDailyBalanceDetails = true; } } @@ -660,7 +663,7 @@ public class RecurringDepositAccount extends SavingsAccount { if (!remainigInterestToBePosted.isZero()) { final SavingsAccountTransaction newPostingTransaction = SavingsAccountTransaction.interestPosting(this, office(), accountCloseDate, remainigInterestToBePosted); - this.transactions.add(newPostingTransaction); + addTransaction(newPostingTransaction); recalucateDailyBalance = true; } @@ -751,7 +754,8 @@ public class RecurringDepositAccount extends SavingsAccount { private Money totalInterestPosted() { Money interestPostedToDate = Money.zero(this.currency); - for (final SavingsAccountTransaction transaction : this.transactions) { + List trans = getTransactions() ; + for (final SavingsAccountTransaction transaction : trans) { if (transaction.isInterestPostingAndNotReversed()) { interestPostedToDate = interestPostedToDate.plus(transaction.getAmount(currency)); } @@ -1122,8 +1126,8 @@ public class RecurringDepositAccount extends SavingsAccount { } public void generateSchedule(final PeriodFrequencyType frequency, final Integer recurringEvery, final Calendar calendar) { - final List depositScheduleInstallments = depositScheduleInstallments(); - depositScheduleInstallments.clear(); + this.depositScheduleInstallments.clear(); + this.isDepositScheduleInstallmentDirty = true ; LocalDate installmentDate = null; if (this.isCalendarInherited()) { installmentDate = CalendarUtils.getNextScheduleDate(calendar, accountSubmittedOrActivationDate()); @@ -1137,7 +1141,7 @@ public class RecurringDepositAccount extends SavingsAccount { while (maturityDate.isAfter(installmentDate)) { final RecurringDepositScheduleInstallment installment = RecurringDepositScheduleInstallment.installment(this, installmentNumber, installmentDate.toDate(), depositAmount); - depositScheduleInstallments.add(installment); + addDepositScheduleInstallment(installment); installmentDate = DepositAccountUtils.calculateNextDepositDate(installmentDate, frequency, recurringEvery); installmentNumber += 1; } @@ -1155,12 +1159,19 @@ public class RecurringDepositAccount extends SavingsAccount { } private List depositScheduleInstallments() { - if (this.depositScheduleInstallments == null) { - this.depositScheduleInstallments = new ArrayList<>(); + if(this.isDepositScheduleInstallmentDirty || this.sortedDepositInstallments == null) { + this.sortedDepositInstallments = new ArrayList<>(this.depositScheduleInstallments) ; + this.sortedDepositInstallments.sort(new RecurringDepositScheduleInstallmentComparator()); + this.isDepositScheduleInstallmentDirty = false ; } - return this.depositScheduleInstallments; + return this.sortedDepositInstallments ; } + private void addDepositScheduleInstallment(final RecurringDepositScheduleInstallment installment) { + this.depositScheduleInstallments.add(installment) ; + isDepositScheduleInstallmentDirty = true ; + } + public boolean isCalendarInherited() { return this.recurringDetail.isCalendarInherited(); } @@ -1200,5 +1211,13 @@ public class RecurringDepositAccount extends SavingsAccount { public DepositAccountRecurringDetail getRecurringDetail() { return this.recurringDetail; } + + class RecurringDepositScheduleInstallmentComparator implements Comparator { + @Override + public int compare(final RecurringDepositScheduleInstallment o1, final RecurringDepositScheduleInstallment o2) { + final int comparsion = o1.installmentNumber().compareTo(o2.installmentNumber()); + return comparsion ; + } + } } \ No newline at end of file diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/RecurringDepositScheduleInstallment.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/RecurringDepositScheduleInstallment.java index b7cf0d6ab..af3d4d768 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/RecurringDepositScheduleInstallment.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/RecurringDepositScheduleInstallment.java @@ -241,4 +241,8 @@ public class RecurringDepositScheduleInstallment extends AbstractAuditableCustom this.depositAmount = newDepositAmount; this.resetDerivedFields(); } + + public Integer installmentNumber() { + return this.installmentNumber ; + } } \ No newline at end of file diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccount.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccount.java index 760ac7c85..ad0809e3c 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccount.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccount.java @@ -54,6 +54,7 @@ import javax.persistence.DiscriminatorType; import javax.persistence.DiscriminatorValue; import javax.persistence.Embedded; import javax.persistence.Entity; +import javax.persistence.FetchType; import javax.persistence.Inheritance; import javax.persistence.InheritanceType; import javax.persistence.JoinColumn; @@ -108,13 +109,10 @@ import org.apache.fineract.portfolio.tax.domain.TaxComponent; import org.apache.fineract.portfolio.tax.domain.TaxGroup; import org.apache.fineract.portfolio.tax.service.TaxUtils; import org.apache.fineract.useradministration.domain.AppUser; -import org.hibernate.annotations.LazyCollection; -import org.hibernate.annotations.LazyCollectionOption; import org.joda.time.LocalDate; import org.joda.time.format.DateTimeFormat; import org.joda.time.format.DateTimeFormatter; import org.springframework.data.jpa.domain.AbstractPersistable; -import org.springframework.transaction.annotation.Transactional; import org.springframework.util.CollectionUtils; import com.google.gson.JsonArray; @@ -148,7 +146,7 @@ public class SavingsAccount extends AbstractPersistable { @JoinColumn(name = "product_id", nullable = false) protected SavingsProduct product; - @ManyToOne + @ManyToOne(fetch=FetchType.LAZY) @JoinColumn(name = "field_officer_id", nullable = true) protected Staff savingsOfficer; @@ -165,7 +163,7 @@ public class SavingsAccount extends AbstractPersistable { @Column(name = "submittedon_date", nullable = true) protected Date submittedOnDate; - @ManyToOne(optional = true) + @ManyToOne(optional = true, fetch=FetchType.LAZY) @JoinColumn(name = "submittedon_userid", nullable = true) protected AppUser submittedBy; @@ -173,7 +171,7 @@ public class SavingsAccount extends AbstractPersistable { @Column(name = "rejectedon_date") protected Date rejectedOnDate; - @ManyToOne(optional = true) + @ManyToOne(optional = true, fetch=FetchType.LAZY) @JoinColumn(name = "rejectedon_userid", nullable = true) protected AppUser rejectedBy; @@ -181,7 +179,7 @@ public class SavingsAccount extends AbstractPersistable { @Column(name = "withdrawnon_date") protected Date withdrawnOnDate; - @ManyToOne(optional = true) + @ManyToOne(optional = true, fetch=FetchType.LAZY) @JoinColumn(name = "withdrawnon_userid", nullable = true) protected AppUser withdrawnBy; @@ -189,7 +187,7 @@ public class SavingsAccount extends AbstractPersistable { @Column(name = "approvedon_date") protected Date approvedOnDate; - @ManyToOne(optional = true) + @ManyToOne(optional = true, fetch=FetchType.LAZY) @JoinColumn(name = "approvedon_userid", nullable = true) protected AppUser approvedBy; @@ -197,7 +195,7 @@ public class SavingsAccount extends AbstractPersistable { @Column(name = "activatedon_date", nullable = true) protected Date activatedOnDate; - @ManyToOne(optional = true) + @ManyToOne(optional = true, fetch=FetchType.LAZY) @JoinColumn(name = "activatedon_userid", nullable = true) protected AppUser activatedBy; @@ -205,7 +203,7 @@ public class SavingsAccount extends AbstractPersistable { @Column(name = "closedon_date") protected Date closedOnDate; - @ManyToOne(optional = true) + @ManyToOne(optional = true, fetch=FetchType.LAZY) @JoinColumn(name = "closedon_userid", nullable = true) protected AppUser closedBy; @@ -294,16 +292,17 @@ public class SavingsAccount extends AbstractPersistable { protected SavingsAccountSummary summary; @OrderBy(value = "dateOf, createdDate, id") - @LazyCollection(LazyCollectionOption.FALSE) - @OneToMany(cascade = CascadeType.ALL, mappedBy = "savingsAccount", orphanRemoval = true) - protected final List transactions = new ArrayList<>(); - - @LazyCollection(LazyCollectionOption.FALSE) - @OneToMany(cascade = CascadeType.ALL, mappedBy = "savingsAccount", orphanRemoval = true) + @OneToMany(cascade = CascadeType.ALL, mappedBy = "savingsAccount", orphanRemoval = true, fetch=FetchType.EAGER) + protected final Set transactions = new HashSet<>(); + + private transient List orderedTransactions = null ; + + private transient boolean isTransactionsDirty = false ; + + @OneToMany(cascade = CascadeType.ALL, mappedBy = "savingsAccount", orphanRemoval = true, fetch=FetchType.EAGER) protected Set charges = new HashSet<>(); - @LazyCollection(LazyCollectionOption.FALSE) - @OneToMany(cascade = CascadeType.ALL, mappedBy = "savingsAccount", orphanRemoval = true) + @OneToMany(cascade = CascadeType.ALL, mappedBy = "savingsAccount", orphanRemoval = true, fetch=FetchType.EAGER) private Set savingsOfficerHistory; @Transient @@ -500,7 +499,7 @@ public class SavingsAccount extends AbstractPersistable { newPostingTransaction = SavingsAccountTransaction.overdraftInterest(this, office(), interestPostingTransactionDate, interestEarnedToBePostedForPeriod.negated()); } - this.transactions.add(newPostingTransaction); + addTransaction(newPostingTransaction); if (applyWithHoldTax) { createWithHoldTransaction(interestEarnedToBePostedForPeriod.getAmount(), interestPostingTransactionDate); } @@ -529,7 +528,7 @@ public class SavingsAccount extends AbstractPersistable { newPostingTransaction = SavingsAccountTransaction.overdraftInterest(this, office(), interestPostingTransactionDate, interestEarnedToBePostedForPeriod.negated()); } - this.transactions.add(newPostingTransaction); + addTransaction(newPostingTransaction); if (applyWithHoldTaxForOldTransaction) { createWithHoldTransaction(interestEarnedToBePostedForPeriod.getAmount(), interestPostingTransactionDate); } @@ -555,7 +554,8 @@ public class SavingsAccount extends AbstractPersistable { protected List findWithHoldTransactions() { final List withholdTransactions = new ArrayList<>(); - for (final SavingsAccountTransaction transaction : this.transactions) { + List trans = getTransactions() ; + for (final SavingsAccountTransaction transaction : trans) { if ((transaction.isWithHoldTaxAndNotReversed())) { withholdTransactions.add(transaction); } @@ -569,7 +569,8 @@ public class SavingsAccount extends AbstractPersistable { protected SavingsAccountTransaction findInterestPostingTransactionFor(final LocalDate postingDate) { SavingsAccountTransaction postingTransation = null; - for (final SavingsAccountTransaction transaction : this.transactions) { + List trans = getTransactions() ; + for (final SavingsAccountTransaction transaction : trans) { if ((transaction.isInterestPostingAndNotReversed() || transaction.isOverdraftInterestAndNotReversed()) && transaction.occursOn(postingDate)) { postingTransation = transaction; @@ -598,7 +599,7 @@ public class SavingsAccount extends AbstractPersistable { if (totalTax.compareTo(BigDecimal.ZERO) == 1) { SavingsAccountTransaction withholdTransaction = SavingsAccountTransaction.withHoldTax(this, office(), date, Money.of(currency, totalTax), taxSplit); - this.transactions.add(withholdTransaction); + addTransaction(withholdTransaction); isTaxAdded = true; } } @@ -621,7 +622,7 @@ public class SavingsAccount extends AbstractPersistable { withholdTransaction.reverse(); SavingsAccountTransaction newWithholdTransaction = SavingsAccountTransaction.withHoldTax(this, office(), withholdTransaction.transactionLocalDate(), Money.of(currency, totalTax), taxSplit); - this.transactions.add(newWithholdTransaction); + addTransaction(newWithholdTransaction); isTaxAdded = true; } } @@ -633,8 +634,8 @@ public class SavingsAccount extends AbstractPersistable { protected SavingsAccountTransaction findLastTransaction(final LocalDate date) { SavingsAccountTransaction savingsTransaction = null; - - for (final SavingsAccountTransaction transaction : this.transactions) { + List trans = getTransactions() ; + for (final SavingsAccountTransaction transaction : trans) { if (transaction.isNotReversed() && transaction.occursOn(date)) { savingsTransaction = transaction; break; @@ -763,7 +764,7 @@ public class SavingsAccount extends AbstractPersistable { orderedNonInterestPostingTransactions.add(transaction); } } - + orderedNonInterestPostingTransactions.sort(new SavingsAccountTransactionComparator()); return orderedNonInterestPostingTransactions; } @@ -819,7 +820,7 @@ public class SavingsAccount extends AbstractPersistable { accountTransaction.updateOverdraftAmount(overdraftAmount.getAmount()); } accountTransaction.updateRunningBalance(runningBalance); - this.transactions.add(accountTransaction); + addTransaction(accountTransaction); isTransactionsModified = true; } @@ -902,8 +903,7 @@ public class SavingsAccount extends AbstractPersistable { final SavingsAccountTransaction transaction = SavingsAccountTransaction.deposit(this, office(), transactionDTO.getPaymentDetail(), transactionDTO.getTransactionDate(), amount, transactionDTO.getCreatedDate(), transactionDTO.getAppUser(), savingsAccountTransactionType); - this.transactions.add(transaction); - + addTransaction(transaction); this.summary.updateSummary(this.currency, this.savingsAccountTransactionSummaryWrapper, this.transactions); if(this.sub_status.equals(SavingsAccountSubStatusEnum.INACTIVE.getValue()) @@ -990,8 +990,7 @@ public class SavingsAccount extends AbstractPersistable { final SavingsAccountTransaction transaction = SavingsAccountTransaction.withdrawal(this, office(), transactionDTO.getPaymentDetail(), transactionDTO.getTransactionDate(), transactionAmountMoney, transactionDTO.getCreatedDate(), transactionDTO.getAppUser()); - this.transactions.add(transaction); - + addTransaction(transaction); if (applyWithdrawFee) { // auto pay withdrawal fee payWithdrawalFee(transactionDTO.getTransactionAmount(), transactionDTO.getTransactionDate(), transactionDTO.getAppUser()); @@ -1410,7 +1409,8 @@ public class SavingsAccount extends AbstractPersistable { accountingBridgeData.put("isAccountTransfer", isAccountTransfer); final List> newSavingsTransactions = new ArrayList<>(); - for (final SavingsAccountTransaction transaction : this.transactions) { + List trans = getTransactions() ; + for (final SavingsAccountTransaction transaction : trans) { if (transaction.isReversed() && !existingReversedTransactionIds.contains(transaction.getId())) { newSavingsTransactions.add(transaction.toMapData(currencyData)); } else if (!existingTransactionIds.contains(transaction.getId())) { @@ -1425,8 +1425,8 @@ public class SavingsAccount extends AbstractPersistable { public Collection findExistingTransactionIds() { final Collection ids = new ArrayList<>(); - - for (final SavingsAccountTransaction transaction : this.transactions) { + List trans = getTransactions() ; + for (final SavingsAccountTransaction transaction : trans) { ids.add(transaction.getId()); } @@ -1436,8 +1436,8 @@ public class SavingsAccount extends AbstractPersistable { public Collection findExistingReversedTransactionIds() { final Collection ids = new ArrayList<>(); - - for (final SavingsAccountTransaction transaction : this.transactions) { + List trans = getTransactions() ; + for (final SavingsAccountTransaction transaction : trans) { if (transaction.isReversed()) { ids.add(transaction.getId()); } @@ -2266,9 +2266,19 @@ public class SavingsAccount extends AbstractPersistable { } public List getTransactions() { - return this.transactions; + if(this.orderedTransactions == null || isTransactionsDirty) { + this.orderedTransactions = new ArrayList<>(this.transactions) ; + this.orderedTransactions.sort(new SavingsAccountTransactionComparator()); + this.isTransactionsDirty = false ; + } + return orderedTransactions; } + public void addTransaction(final SavingsAccountTransaction transaction) { + this.transactions.add(transaction); + this.isTransactionsDirty = true ; + } + public void setStatus(final Integer status) { this.status = status; } @@ -2555,7 +2565,7 @@ public class SavingsAccount extends AbstractPersistable { final SavingsAccountChargePaidBy chargePaidBy = SavingsAccountChargePaidBy.instance(transaction, savingsAccountCharge, transaction .getAmount(this.getCurrency()).getAmount()); transaction.getSavingsAccountChargesPaid().add(chargePaidBy); - this.getTransactions().add(transaction); + this.transactions.add(transaction); } private SavingsAccountCharge getCharge(final Long savingsAccountChargeId) { @@ -2573,7 +2583,7 @@ public class SavingsAccount extends AbstractPersistable { } public Set charges() { - return (this.charges == null) ? new HashSet() : this.charges; + return (this.charges == null) ? new HashSet<>() : this.charges; } public void validateAccountValuesWithProduct() { diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccountCharge.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccountCharge.java index babb65b40..1c8f85c8f 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccountCharge.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccountCharge.java @@ -27,7 +27,6 @@ import static org.apache.fineract.portfolio.savings.SavingsApiConstants.localePa import java.math.BigDecimal; import java.math.MathContext; -import java.math.RoundingMode; import java.util.Date; import java.util.LinkedHashMap; import java.util.Map; @@ -709,7 +708,7 @@ public class SavingsAccountCharge extends AbstractPersistable { public int hashCode() { return new HashCodeBuilder(3, 5) // .append(getId()) // - .append(this.charge.getId()) // + //.append(this.charge.getId()) // .append(this.amount).append(getDueLocalDate()) // .toHashCode(); } diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccountSummary.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccountSummary.java index 735016d85..ea902d464 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccountSummary.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccountSummary.java @@ -21,6 +21,7 @@ package org.apache.fineract.portfolio.savings.domain; import java.math.BigDecimal; import java.util.Date; import java.util.List; +import java.util.Set; import javax.persistence.Column; import javax.persistence.Embeddable; @@ -90,7 +91,7 @@ public final class SavingsAccountSummary { } public void updateSummary(final MonetaryCurrency currency, final SavingsAccountTransactionSummaryWrapper wrapper, - final List transactions) { + final Set transactions) { this.totalDeposits = wrapper.calculateTotalDeposits(currency, transactions); this.totalWithdrawals = wrapper.calculateTotalWithdrawals(currency, transactions); diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccountTransaction.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccountTransaction.java index 8c4fc275a..c2f2cf434 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccountTransaction.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccountTransaction.java @@ -31,6 +31,7 @@ import java.util.Set; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; +import javax.persistence.FetchType; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.OneToMany; @@ -50,8 +51,6 @@ import org.apache.fineract.portfolio.savings.domain.interest.EndOfDayBalance; import org.apache.fineract.portfolio.savings.service.SavingsEnumerations; import org.apache.fineract.portfolio.tax.domain.TaxComponent; import org.apache.fineract.useradministration.domain.AppUser; -import org.hibernate.annotations.LazyCollection; -import org.hibernate.annotations.LazyCollectionOption; import org.joda.time.LocalDate; import org.springframework.data.jpa.domain.AbstractPersistable; import org.springframework.util.CollectionUtils; @@ -102,8 +101,7 @@ public final class SavingsAccountTransaction extends AbstractPersistable { @Column(name = "balance_number_of_days_derived", nullable = false) private Integer balanceNumberOfDays; - @LazyCollection(LazyCollectionOption.FALSE) - @OneToMany(cascade = CascadeType.ALL, mappedBy = "savingsAccountTransaction", orphanRemoval = true) + @OneToMany(cascade = CascadeType.ALL, mappedBy = "savingsAccountTransaction", orphanRemoval = true, fetch=FetchType.EAGER) private final Set savingsAccountChargesPaid = new HashSet<>(); @Column(name = "overdraft_amount_derived", scale = 6, precision = 19, nullable = true) @@ -117,8 +115,7 @@ public final class SavingsAccountTransaction extends AbstractPersistable { @JoinColumn(name = "appuser_id", nullable = true) private AppUser appUser; - @LazyCollection(LazyCollectionOption.FALSE) - @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true) + @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch=FetchType.EAGER) @JoinColumn(name = "savings_transaction_id", referencedColumnName = "id", nullable = false) private final List taxDetails = new ArrayList<>(); diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccountTransactionSummaryWrapper.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccountTransactionSummaryWrapper.java index 6f7ffe62f..0aceb2bc3 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccountTransactionSummaryWrapper.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccountTransactionSummaryWrapper.java @@ -19,7 +19,7 @@ package org.apache.fineract.portfolio.savings.domain; import java.math.BigDecimal; -import java.util.List; +import java.util.Set; import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency; import org.apache.fineract.organisation.monetary.domain.Money; @@ -32,7 +32,7 @@ import org.springframework.stereotype.Component; @Component public final class SavingsAccountTransactionSummaryWrapper { - public BigDecimal calculateTotalDeposits(final MonetaryCurrency currency, final List transactions) { + public BigDecimal calculateTotalDeposits(final MonetaryCurrency currency, final Set transactions) { Money total = Money.zero(currency); for (final SavingsAccountTransaction transaction : transactions) { if (transaction.isDepositAndNotReversed() || transaction.isDividendPayoutAndNotReversed()) { @@ -42,7 +42,7 @@ public final class SavingsAccountTransactionSummaryWrapper { return total.getAmountDefaultedToNullIfZero(); } - public BigDecimal calculateTotalWithdrawals(final MonetaryCurrency currency, final List transactions) { + public BigDecimal calculateTotalWithdrawals(final MonetaryCurrency currency, final Set transactions) { Money total = Money.zero(currency); for (final SavingsAccountTransaction transaction : transactions) { if (transaction.isWithdrawal() && transaction.isNotReversed()) { @@ -52,7 +52,7 @@ public final class SavingsAccountTransactionSummaryWrapper { return total.getAmountDefaultedToNullIfZero(); } - public BigDecimal calculateTotalInterestPosted(final MonetaryCurrency currency, final List transactions) { + public BigDecimal calculateTotalInterestPosted(final MonetaryCurrency currency, final Set transactions) { Money total = Money.zero(currency); for (final SavingsAccountTransaction transaction : transactions) { if (transaction.isInterestPostingAndNotReversed() && transaction.isNotReversed()) { @@ -62,7 +62,7 @@ public final class SavingsAccountTransactionSummaryWrapper { return total.getAmountDefaultedToNullIfZero(); } - public BigDecimal calculateTotalWithdrawalFees(final MonetaryCurrency currency, final List transactions) { + public BigDecimal calculateTotalWithdrawalFees(final MonetaryCurrency currency, final Set transactions) { Money total = Money.zero(currency); for (final SavingsAccountTransaction transaction : transactions) { if (transaction.isWithdrawalFeeAndNotReversed() && transaction.isNotReversed()) { @@ -72,7 +72,7 @@ public final class SavingsAccountTransactionSummaryWrapper { return total.getAmountDefaultedToNullIfZero(); } - public BigDecimal calculateTotalAnnualFees(final MonetaryCurrency currency, final List transactions) { + public BigDecimal calculateTotalAnnualFees(final MonetaryCurrency currency, final Set transactions) { Money total = Money.zero(currency); for (final SavingsAccountTransaction transaction : transactions) { if (transaction.isAnnualFeeAndNotReversed() && transaction.isNotReversed()) { @@ -82,7 +82,7 @@ public final class SavingsAccountTransactionSummaryWrapper { return total.getAmountDefaultedToNullIfZero(); } - public BigDecimal calculateTotalFeesCharge(final MonetaryCurrency currency, final List transactions) { + public BigDecimal calculateTotalFeesCharge(final MonetaryCurrency currency, final Set transactions) { Money total = Money.zero(currency); for (final SavingsAccountTransaction transaction : transactions) { if (transaction.isFeeChargeAndNotReversed()) { @@ -92,7 +92,7 @@ public final class SavingsAccountTransactionSummaryWrapper { return total.getAmountDefaultedToNullIfZero(); } - public BigDecimal calculateTotalFeesChargeWaived(final MonetaryCurrency currency, final List transactions) { + public BigDecimal calculateTotalFeesChargeWaived(final MonetaryCurrency currency, final Set transactions) { Money total = Money.zero(currency); for (final SavingsAccountTransaction transaction : transactions) { if (transaction.isWaiveFeeChargeAndNotReversed()) { @@ -102,7 +102,7 @@ public final class SavingsAccountTransactionSummaryWrapper { return total.getAmountDefaultedToNullIfZero(); } - public BigDecimal calculateTotalPenaltyCharge(final MonetaryCurrency currency, final List transactions) { + public BigDecimal calculateTotalPenaltyCharge(final MonetaryCurrency currency, final Set transactions) { Money total = Money.zero(currency); for (final SavingsAccountTransaction transaction : transactions) { if (transaction.isPenaltyChargeAndNotReversed()) { @@ -112,7 +112,7 @@ public final class SavingsAccountTransactionSummaryWrapper { return total.getAmountDefaultedToNullIfZero(); } - public BigDecimal calculateTotalPenaltyChargeWaived(final MonetaryCurrency currency, final List transactions) { + public BigDecimal calculateTotalPenaltyChargeWaived(final MonetaryCurrency currency, final Set transactions) { Money total = Money.zero(currency); for (final SavingsAccountTransaction transaction : transactions) { if (transaction.isWaivePenaltyChargeAndNotReversed()) { @@ -122,7 +122,7 @@ public final class SavingsAccountTransactionSummaryWrapper { return total.getAmountDefaultedToNullIfZero(); } - public BigDecimal calculateTotalOverdraftInterest(MonetaryCurrency currency, List transactions) { + public BigDecimal calculateTotalOverdraftInterest(MonetaryCurrency currency, Set transactions) { Money total = Money.zero(currency); for (final SavingsAccountTransaction transaction : transactions) { if (transaction.isOverdraftInterestAndNotReversed()) { @@ -131,7 +131,7 @@ public final class SavingsAccountTransactionSummaryWrapper { } return total.getAmountDefaultedToNullIfZero(); } - public BigDecimal calculateTotalWithholdTaxWithdrawal(MonetaryCurrency currency, List transactions) { + public BigDecimal calculateTotalWithholdTaxWithdrawal(MonetaryCurrency currency, Set transactions) { Money total = Money.zero(currency); for (final SavingsAccountTransaction transaction : transactions) { if (transaction.isWithHoldTaxAndNotReversed()) { diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/DepositAccountWritePlatformServiceJpaRepositoryImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/DepositAccountWritePlatformServiceJpaRepositoryImpl.java index 3a5a7a804..75ed667b6 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/DepositAccountWritePlatformServiceJpaRepositoryImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/DepositAccountWritePlatformServiceJpaRepositoryImpl.java @@ -918,7 +918,7 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo final SavingsAccountTransaction newTransferTransaction = SavingsAccountTransaction.initiateTransfer(savingsAccount, savingsAccount.office(), transferDate, user); - savingsAccount.getTransactions().add(newTransferTransaction); + savingsAccount.addTransaction(newTransferTransaction); savingsAccount.setStatus(SavingsAccountStatusType.TRANSFER_IN_PROGRESS.getValue()); final MathContext mc = MathContext.DECIMAL64; boolean isInterestTransfer = false; @@ -951,7 +951,7 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo final SavingsAccountTransaction withdrawtransferTransaction = SavingsAccountTransaction.withdrawTransfer(savingsAccount, savingsAccount.office(), transferDate, user); - savingsAccount.getTransactions().add(withdrawtransferTransaction); + savingsAccount.addTransaction(withdrawtransferTransaction); savingsAccount.setStatus(SavingsAccountStatusType.ACTIVE.getValue()); final MathContext mc = MathContext.DECIMAL64; boolean isInterestTransfer = false; @@ -991,7 +991,7 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo final SavingsAccountTransaction acceptTransferTransaction = SavingsAccountTransaction.approveTransfer(savingsAccount, acceptedInOffice, transferDate, user); - savingsAccount.getTransactions().add(acceptTransferTransaction); + savingsAccount.addTransaction(acceptTransferTransaction); savingsAccount.setStatus(SavingsAccountStatusType.ACTIVE.getValue()); if (fieldOfficer != null) { savingsAccount.reassignSavingsOfficer(fieldOfficer, transferDate); diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsAccountWritePlatformServiceJpaRepositoryImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsAccountWritePlatformServiceJpaRepositoryImpl.java index ff757d882..15a3e43aa 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsAccountWritePlatformServiceJpaRepositoryImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsAccountWritePlatformServiceJpaRepositoryImpl.java @@ -18,6 +18,25 @@ */ package org.apache.fineract.portfolio.savings.service; +import static org.apache.fineract.portfolio.savings.SavingsApiConstants.SAVINGS_ACCOUNT_CHARGE_RESOURCE_NAME; +import static org.apache.fineract.portfolio.savings.SavingsApiConstants.SAVINGS_ACCOUNT_RESOURCE_NAME; +import static org.apache.fineract.portfolio.savings.SavingsApiConstants.amountParamName; +import static org.apache.fineract.portfolio.savings.SavingsApiConstants.chargeIdParamName; +import static org.apache.fineract.portfolio.savings.SavingsApiConstants.dueAsOfDateParamName; +import static org.apache.fineract.portfolio.savings.SavingsApiConstants.withHoldTaxParamName; +import static org.apache.fineract.portfolio.savings.SavingsApiConstants.withdrawBalanceParamName; + +import java.math.BigDecimal; +import java.math.MathContext; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Set; + import org.apache.commons.lang.StringUtils; import org.apache.fineract.accounting.journalentry.service.JournalEntryWritePlatformService; import org.apache.fineract.infrastructure.configuration.domain.ConfigurationDomainService; @@ -88,25 +107,6 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.CollectionUtils; -import java.math.BigDecimal; -import java.math.MathContext; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Set; - -import static org.apache.fineract.portfolio.savings.SavingsApiConstants.SAVINGS_ACCOUNT_CHARGE_RESOURCE_NAME; -import static org.apache.fineract.portfolio.savings.SavingsApiConstants.SAVINGS_ACCOUNT_RESOURCE_NAME; -import static org.apache.fineract.portfolio.savings.SavingsApiConstants.amountParamName; -import static org.apache.fineract.portfolio.savings.SavingsApiConstants.chargeIdParamName; -import static org.apache.fineract.portfolio.savings.SavingsApiConstants.dueAsOfDateParamName; -import static org.apache.fineract.portfolio.savings.SavingsApiConstants.withdrawBalanceParamName; -import static org.apache.fineract.portfolio.savings.SavingsApiConstants.withHoldTaxParamName; - @Service public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements SavingsAccountWritePlatformService { @@ -673,7 +673,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi final SavingsAccountTransaction newTransferTransaction = SavingsAccountTransaction.initiateTransfer(savingsAccount, savingsAccount.office(), transferDate, user); - savingsAccount.getTransactions().add(newTransferTransaction); + savingsAccount.addTransaction(newTransferTransaction); savingsAccount.setStatus(SavingsAccountStatusType.TRANSFER_IN_PROGRESS.getValue()); final MathContext mc = MathContext.DECIMAL64; boolean isInterestTransfer = false; @@ -705,7 +705,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi final SavingsAccountTransaction withdrawtransferTransaction = SavingsAccountTransaction.withdrawTransfer(savingsAccount, savingsAccount.office(), transferDate, user); - savingsAccount.getTransactions().add(withdrawtransferTransaction); + savingsAccount.addTransaction(withdrawtransferTransaction); savingsAccount.setStatus(SavingsAccountStatusType.ACTIVE.getValue()); final MathContext mc = MathContext.DECIMAL64; boolean isInterestTransfer = false; @@ -745,7 +745,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi final SavingsAccountTransaction acceptTransferTransaction = SavingsAccountTransaction.approveTransfer(savingsAccount, acceptedInOffice, transferDate, user); - savingsAccount.getTransactions().add(acceptTransferTransaction); + savingsAccount.addTransaction(acceptTransferTransaction); savingsAccount.setStatus(SavingsAccountStatusType.ACTIVE.getValue()); if (fieldOfficer != null) { savingsAccount.reassignSavingsOfficer(fieldOfficer, transferDate); diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/domain/ShareAccount.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/domain/ShareAccount.java index 59827cb6b..7467c4371 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/domain/ShareAccount.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/domain/ShareAccount.java @@ -28,6 +28,7 @@ import javax.persistence.Embedded; import javax.persistence.Entity; import javax.persistence.EnumType; import javax.persistence.Enumerated; +import javax.persistence.FetchType; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.OneToMany; @@ -44,8 +45,6 @@ import org.apache.fineract.portfolio.common.domain.PeriodFrequencyType; import org.apache.fineract.portfolio.savings.domain.SavingsAccount; import org.apache.fineract.portfolio.shareproducts.domain.ShareProduct; import org.apache.fineract.useradministration.domain.AppUser; -import org.hibernate.annotations.LazyCollection; -import org.hibernate.annotations.LazyCollectionOption; import org.springframework.data.jpa.domain.AbstractPersistable; @Entity @@ -133,8 +132,7 @@ public class ShareAccount extends AbstractPersistable { @JoinColumn(name = "savings_account_id", nullable = true) private SavingsAccount savingsAccount; - @LazyCollection(LazyCollectionOption.FALSE) - @OneToMany(cascade = CascadeType.ALL, mappedBy = "shareAccount", orphanRemoval = true) + @OneToMany(cascade = CascadeType.ALL, mappedBy = "shareAccount", orphanRemoval = true, fetch=FetchType.EAGER) private Set shareAccountTransactions; @Column(name = "lockin_period_frequency") @@ -151,8 +149,7 @@ public class ShareAccount extends AbstractPersistable { @Column(name = "minimum_active_period_frequency_enum", nullable = true) private PeriodFrequencyType minimumActivePeriodFrequencyType; - @LazyCollection(LazyCollectionOption.FALSE) - @OneToMany(cascade = CascadeType.ALL, mappedBy = "shareAccount", orphanRemoval = true) + @OneToMany(cascade = CascadeType.ALL, mappedBy = "shareAccount", orphanRemoval = true, fetch=FetchType.EAGER) private Set charges; @Transient diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/domain/ShareAccountTransaction.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/domain/ShareAccountTransaction.java index fb79206c3..186b18932 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/domain/ShareAccountTransaction.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/domain/ShareAccountTransaction.java @@ -26,6 +26,7 @@ import java.util.Set; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; +import javax.persistence.FetchType; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.OneToMany; @@ -33,8 +34,6 @@ import javax.persistence.Table; import javax.persistence.Temporal; import javax.persistence.TemporalType; -import org.hibernate.annotations.LazyCollection; -import org.hibernate.annotations.LazyCollectionOption; import org.springframework.data.jpa.domain.AbstractPersistable; @Entity @@ -73,8 +72,7 @@ public class ShareAccountTransaction extends AbstractPersistable { @Column(name = "is_active", nullable = false) private boolean active = true ; - @LazyCollection(LazyCollectionOption.FALSE) - @OneToMany(cascade = CascadeType.ALL, mappedBy = "shareAccountTransaction", orphanRemoval = true) + @OneToMany(cascade = CascadeType.ALL, mappedBy = "shareAccountTransaction", orphanRemoval = true, fetch=FetchType.EAGER) private final Set shareAccountChargesPaid = new HashSet<>(); protected ShareAccountTransaction() { diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareproducts/domain/ShareProduct.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareproducts/domain/ShareProduct.java index f14efd54b..14cc73ad5 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareproducts/domain/ShareProduct.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareproducts/domain/ShareProduct.java @@ -46,8 +46,6 @@ import org.apache.fineract.portfolio.charge.domain.Charge; import org.apache.fineract.portfolio.common.domain.PeriodFrequencyType; import org.apache.fineract.portfolio.shareproducts.data.ShareProductMarketPriceData; import org.apache.fineract.useradministration.domain.AppUser; -import org.hibernate.annotations.LazyCollection; -import org.hibernate.annotations.LazyCollectionOption; import org.joda.time.DateTime; @Entity @@ -102,8 +100,7 @@ public class ShareProduct extends AbstractAuditableCustom { private Long maximumShares; @OrderBy(value = "fromDate,id") - @LazyCollection(LazyCollectionOption.FALSE) - @OneToMany(cascade = CascadeType.ALL, mappedBy = "product", orphanRemoval = true) + @OneToMany(cascade = CascadeType.ALL, mappedBy = "product", orphanRemoval = true, fetch=FetchType.EAGER) Set marketPrice; @ManyToMany(fetch = FetchType.EAGER) diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareproducts/domain/ShareProductDividendPayOutDetails.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareproducts/domain/ShareProductDividendPayOutDetails.java index d282899ed..f429e3d24 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareproducts/domain/ShareProductDividendPayOutDetails.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareproducts/domain/ShareProductDividendPayOutDetails.java @@ -26,6 +26,7 @@ import java.util.List; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; +import javax.persistence.FetchType; import javax.persistence.JoinColumn; import javax.persistence.OneToMany; import javax.persistence.Table; @@ -35,8 +36,6 @@ import javax.persistence.TemporalType; import org.apache.fineract.infrastructure.core.domain.AbstractAuditableCustom; import org.apache.fineract.portfolio.shareaccounts.domain.ShareAccountDividendDetails; import org.apache.fineract.useradministration.domain.AppUser; -import org.hibernate.annotations.LazyCollection; -import org.hibernate.annotations.LazyCollectionOption; import org.joda.time.LocalDate; @Entity @@ -60,8 +59,7 @@ public class ShareProductDividendPayOutDetails extends AbstractAuditableCustom accountDividendDetails = new ArrayList<>(); diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/domain/TaxComponent.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/domain/TaxComponent.java index 32ec96b2d..8b8ba23f5 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/domain/TaxComponent.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/domain/TaxComponent.java @@ -23,12 +23,15 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; +import javax.persistence.FetchType; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.OneToMany; @@ -44,8 +47,6 @@ import org.apache.fineract.infrastructure.core.domain.AbstractAuditableCustom; import org.apache.fineract.infrastructure.core.service.DateUtils; import org.apache.fineract.portfolio.tax.api.TaxApiConstants; import org.apache.fineract.useradministration.domain.AppUser; -import org.hibernate.annotations.LazyCollection; -import org.hibernate.annotations.LazyCollectionOption; import org.joda.time.LocalDate; @Entity @@ -76,14 +77,12 @@ public class TaxComponent extends AbstractAuditableCustom { @Temporal(TemporalType.DATE) private Date startDate; - @LazyCollection(LazyCollectionOption.FALSE) - @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true) + @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch=FetchType.EAGER) @JoinColumn(name = "tax_component_id", referencedColumnName = "id", nullable = false) - private List taxComponentHistories = new ArrayList<>(); + private Set taxComponentHistories = new HashSet<>(); - @LazyCollection(LazyCollectionOption.TRUE) - @OneToMany(cascade = CascadeType.DETACH, mappedBy = "taxComponent", orphanRemoval = false) - private List taxGroupMappings = new ArrayList<>(); + @OneToMany(cascade = CascadeType.DETACH, mappedBy = "taxComponent", orphanRemoval = false, fetch=FetchType.EAGER) + private Set taxGroupMappings = new HashSet<>(); protected TaxComponent() { @@ -182,11 +181,11 @@ public class TaxComponent extends AbstractAuditableCustom { return target != null && target.isAfter(startDate()); } - public List getTaxComponentHistories() { + public Set getTaxComponentHistories() { return this.taxComponentHistories; } - public List getTaxGroupMappings() { + public Set getTaxGroupMappings() { return this.taxGroupMappings; } diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/domain/TaxGroup.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/domain/TaxGroup.java index 0e780f394..59c2b346f 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/domain/TaxGroup.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/domain/TaxGroup.java @@ -20,12 +20,15 @@ package org.apache.fineract.portfolio.tax.domain; import java.util.ArrayList; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; +import javax.persistence.FetchType; import javax.persistence.JoinColumn; import javax.persistence.OneToMany; import javax.persistence.Table; @@ -36,8 +39,6 @@ import org.apache.fineract.infrastructure.core.domain.AbstractAuditableCustom; import org.apache.fineract.portfolio.tax.api.TaxApiConstants; import org.apache.fineract.portfolio.tax.exception.TaxMappingNotFoundException; import org.apache.fineract.useradministration.domain.AppUser; -import org.hibernate.annotations.LazyCollection; -import org.hibernate.annotations.LazyCollectionOption; @Entity @Table(name = "m_tax_group") @@ -46,25 +47,24 @@ public class TaxGroup extends AbstractAuditableCustom { @Column(name = "name", length = 100) private String name; - @LazyCollection(LazyCollectionOption.FALSE) - @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true) + @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch=FetchType.EAGER) @JoinColumn(name = "tax_group_id", referencedColumnName = "id", nullable = false) - private List taxGroupMappings = new ArrayList<>(); + private Set taxGroupMappings = new HashSet<>(); protected TaxGroup() { } - private TaxGroup(final String name, final List taxGroupMappings) { + private TaxGroup(final String name, final Set taxGroupMappings) { this.name = name; this.taxGroupMappings = taxGroupMappings; } - public static TaxGroup createTaxGroup(final String name, final List taxGroupMappings) { + public static TaxGroup createTaxGroup(final String name, final Set taxGroupMappings) { return new TaxGroup(name, taxGroupMappings); } - public Map update(final JsonCommand command, final List taxGroupMappings) { + public Map update(final JsonCommand command, final Set taxGroupMappings) { final Map changes = new HashMap<>(); if (command.isChangeInStringParameterNamed(TaxApiConstants.nameParamName, this.name)) { @@ -106,7 +106,7 @@ public class TaxGroup extends AbstractAuditableCustom { return null; } - public List getTaxGroupMappings() { + public Set getTaxGroupMappings() { return this.taxGroupMappings; } diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/serialization/TaxValidator.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/serialization/TaxValidator.java index 6df786e94..eecb1801e 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/serialization/TaxValidator.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/serialization/TaxValidator.java @@ -266,7 +266,7 @@ public class TaxValidator { throwExceptionIfValidationWarningsExist(dataValidationErrors); } - public void validateTaxGroupEndDateAndTaxComponent(final TaxGroup taxGroup, final List groupMappings) { + public void validateTaxGroupEndDateAndTaxComponent(final TaxGroup taxGroup, final Set groupMappings) { final List dataValidationErrors = new ArrayList<>(); final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("tax.group"); @@ -293,7 +293,7 @@ public class TaxValidator { public void validateTaxGroup(final TaxGroup taxGroup) { final List dataValidationErrors = new ArrayList<>(); final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("tax.group"); - List groupMappings = taxGroup.getTaxGroupMappings(); + Set groupMappings = taxGroup.getTaxGroupMappings(); validateGroupTotal(groupMappings, baseDataValidator, "total.percentage"); validateOverlappingComponents(groupMappings, baseDataValidator); throwExceptionIfValidationWarningsExist(dataValidationErrors); @@ -318,7 +318,7 @@ public class TaxValidator { baseDataValidator.reset().parameter(TaxApiConstants.startDateParamName).value(startDate).validateDateAfter(existingStartDate); } - private void validateOverlappingComponents(final List taxMappings, final DataValidatorBuilder baseDataValidator) { + private void validateOverlappingComponents(final Set taxMappings, final DataValidatorBuilder baseDataValidator) { for (TaxGroupMappings groupMappingsOne : taxMappings) { final List mappings = new ArrayList<>(taxMappings); mappings.remove(groupMappingsOne); @@ -338,7 +338,7 @@ public class TaxValidator { } } - private void validateGroupTotal(final List taxMappings, final DataValidatorBuilder baseDataValidator, + private void validateGroupTotal(final Set taxMappings, final DataValidatorBuilder baseDataValidator, final String paramenter) { for (TaxGroupMappings groupMappingsOne : taxMappings) { Collection dates = groupMappingsOne.getTaxComponent().allStartDates(); diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/service/TaxAssembler.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/service/TaxAssembler.java index 1e5ad9206..be41011d4 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/service/TaxAssembler.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/service/TaxAssembler.java @@ -20,8 +20,10 @@ package org.apache.fineract.portfolio.tax.service; import java.math.BigDecimal; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; import java.util.Locale; +import java.util.Set; import org.apache.fineract.accounting.glaccount.domain.GLAccount; import org.apache.fineract.accounting.glaccount.domain.GLAccountRepositoryWrapper; @@ -114,12 +116,12 @@ public class TaxAssembler { final String name = this.fromApiJsonHelper.extractStringNamed(TaxApiConstants.nameParamName, element); boolean isUpdate = false; - final List groupMappings = assembleTaxGroupMappingsFrom(command, isUpdate); + final Set groupMappings = assembleTaxGroupMappingsFrom(command, isUpdate); return TaxGroup.createTaxGroup(name, groupMappings); } - public List assembleTaxGroupMappingsFrom(final JsonCommand command, boolean isUpdate) { - List groupMappings = new ArrayList<>(); + public Set assembleTaxGroupMappingsFrom(final JsonCommand command, boolean isUpdate) { + Set groupMappings = new HashSet<>(); final JsonElement element = command.parsedJson(); final JsonObject topLevelJsonElement = element.getAsJsonObject(); diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/service/TaxUtils.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/service/TaxUtils.java index 02368df89..1acc202ad 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/service/TaxUtils.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/service/TaxUtils.java @@ -22,6 +22,7 @@ import java.math.BigDecimal; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Set; import org.apache.fineract.organisation.monetary.domain.MoneyHelper; import org.apache.fineract.portfolio.tax.domain.TaxComponent; @@ -31,7 +32,7 @@ import org.joda.time.LocalDate; public class TaxUtils { public static Map splitTax(final BigDecimal amount, final LocalDate date, - final List taxGroupMappings, final int scale) { + final Set taxGroupMappings, final int scale) { Map map = new HashMap<>(3); if (amount != null) { final double amountVal = amount.doubleValue(); @@ -51,7 +52,7 @@ public class TaxUtils { return map; } - public static BigDecimal incomeAmount(final BigDecimal amount, final LocalDate date, final List taxGroupMappings, + public static BigDecimal incomeAmount(final BigDecimal amount, final LocalDate date, final Set taxGroupMappings, final int scale) { Map map = splitTax(amount, date, taxGroupMappings, scale); return incomeAmount(amount, map); diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/service/TaxWritePlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/service/TaxWritePlatformServiceImpl.java index a96b57dbc..30ecf261f 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/service/TaxWritePlatformServiceImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/service/TaxWritePlatformServiceImpl.java @@ -18,8 +18,8 @@ */ package org.apache.fineract.portfolio.tax.service; -import java.util.List; import java.util.Map; +import java.util.Set; import org.apache.fineract.infrastructure.core.api.JsonCommand; import org.apache.fineract.infrastructure.core.data.CommandProcessingResult; @@ -98,7 +98,7 @@ public class TaxWritePlatformServiceImpl implements TaxWritePlatformService { this.validator.validateForTaxGroupUpdate(command.json()); final TaxGroup taxGroup = this.taxGroupRepositoryWrapper.findOneWithNotFoundDetection(id); final boolean isUpdate = true; - List groupMappings = this.taxAssembler.assembleTaxGroupMappingsFrom(command, isUpdate); + Set groupMappings = this.taxAssembler.assembleTaxGroupMappingsFrom(command, isUpdate); this.validator.validateTaxGroupEndDateAndTaxComponent(taxGroup, groupMappings); Map changes = taxGroup.update(command, groupMappings); this.validator.validateTaxGroup(taxGroup); diff --git a/fineract-provider/src/main/java/org/apache/fineract/useradministration/domain/AppUser.java b/fineract-provider/src/main/java/org/apache/fineract/useradministration/domain/AppUser.java index 7bf95586f..d52ede0ac 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/useradministration/domain/AppUser.java +++ b/fineract-provider/src/main/java/org/apache/fineract/useradministration/domain/AppUser.java @@ -52,8 +52,6 @@ import org.apache.fineract.organisation.office.domain.Office; import org.apache.fineract.organisation.staff.domain.Staff; import org.apache.fineract.portfolio.client.domain.Client; import org.apache.fineract.useradministration.service.AppUserConstants; -import org.hibernate.annotations.LazyCollection; -import org.hibernate.annotations.LazyCollectionOption; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.data.jpa.domain.AbstractPersistable; @@ -122,8 +120,7 @@ public class AppUser extends AbstractPersistable implements PlatformUser { @Column(name = "is_self_service_user", nullable = false) private boolean isSelfServiceUser; - @LazyCollection(LazyCollectionOption.FALSE) - @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true) + @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch=FetchType.EAGER) @JoinColumn(name = "appuser_id", referencedColumnName= "id", nullable = false) private Set appUserClientMappings = new HashSet<>(); diff --git a/fineract-provider/src/test/java/org/apache/fineract/portfolio/loanaccount/LoanRepaymentScheduleInstallmentBuilder.java b/fineract-provider/src/test/java/org/apache/fineract/portfolio/loanaccount/LoanRepaymentScheduleInstallmentBuilder.java index 5e6ee294a..5a10f12fb 100644 --- a/fineract-provider/src/test/java/org/apache/fineract/portfolio/loanaccount/LoanRepaymentScheduleInstallmentBuilder.java +++ b/fineract-provider/src/test/java/org/apache/fineract/portfolio/loanaccount/LoanRepaymentScheduleInstallmentBuilder.java @@ -18,7 +18,7 @@ */ package org.apache.fineract.portfolio.loanaccount; -import java.util.List; +import java.util.Set; import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency; import org.apache.fineract.organisation.monetary.domain.Money; @@ -49,7 +49,7 @@ public class LoanRepaymentScheduleInstallmentBuilder { } public LoanRepaymentScheduleInstallment build() { - final List compoundingDetails = null; + final Set compoundingDetails = null; final LoanRepaymentScheduleInstallment installment = new LoanRepaymentScheduleInstallment(this.loan, this.installmentNumber, this.fromDate, this.dueDate, this.principal.getAmount(), this.interest.getAmount(), this.feeCharges.getAmount(), this.penaltyCharges.getAmount(), this.recalculatedInterestComponent, compoundingDetails);