Fix inconsistenant Date and Date time handling
This commit is contained in:
committed by
Arnold Gálovics
parent
7fb61d028e
commit
65c6b18ed1
+2
-2
@@ -46,9 +46,9 @@ public class AccrualAccountingWritePlatformServiceImpl implements AccrualAccount
|
|||||||
@Override
|
@Override
|
||||||
public CommandProcessingResult executeLoansPeriodicAccrual(JsonCommand command) {
|
public CommandProcessingResult executeLoansPeriodicAccrual(JsonCommand command) {
|
||||||
this.accountingDataValidator.validateLoanPeriodicAccrualData(command.json());
|
this.accountingDataValidator.validateLoanPeriodicAccrualData(command.json());
|
||||||
LocalDate tilldate = command.localDateValueOfParameterNamed(accrueTillParamName);
|
LocalDate tillDate = command.localDateValueOfParameterNamed(accrueTillParamName);
|
||||||
try {
|
try {
|
||||||
this.loanAccrualPlatformService.addPeriodicAccruals(tilldate);
|
this.loanAccrualPlatformService.addPeriodicAccruals(tillDate);
|
||||||
} catch (MultiException e) {
|
} catch (MultiException e) {
|
||||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
|
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
|
||||||
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
|
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
|
||||||
|
|||||||
+12
@@ -26,6 +26,8 @@ import java.sql.Timestamp;
|
|||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.LocalTime;
|
import java.time.LocalTime;
|
||||||
|
import java.time.OffsetDateTime;
|
||||||
|
import java.time.ZoneOffset;
|
||||||
import java.time.ZonedDateTime;
|
import java.time.ZonedDateTime;
|
||||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||||
import org.springframework.jdbc.support.JdbcUtils;
|
import org.springframework.jdbc.support.JdbcUtils;
|
||||||
@@ -133,4 +135,14 @@ public final class JdbcSupport {
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static OffsetDateTime getOffsetDateTime(ResultSet rs, String columnName) throws SQLException {
|
||||||
|
final Timestamp timestamp = rs.getTimestamp(columnName);
|
||||||
|
if (timestamp != null) {
|
||||||
|
OffsetDateTime offsetDateTimeAtUTC = OffsetDateTime.of(timestamp.toLocalDateTime(), ZoneOffset.UTC);
|
||||||
|
return offsetDateTimeAtUTC
|
||||||
|
.withOffsetSameInstant(DateUtils.getDateTimeZoneOfTenant().getRules().getOffset(offsetDateTimeAtUTC.toInstant()));
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-1
@@ -22,6 +22,7 @@ import org.apache.fineract.infrastructure.core.service.RoutingDataSourceServiceF
|
|||||||
import org.apache.fineract.infrastructure.core.service.database.DatabaseSpecificSQLGenerator;
|
import org.apache.fineract.infrastructure.core.service.database.DatabaseSpecificSQLGenerator;
|
||||||
import org.apache.fineract.infrastructure.core.service.database.DatabaseTypeResolver;
|
import org.apache.fineract.infrastructure.core.service.database.DatabaseTypeResolver;
|
||||||
import org.apache.fineract.infrastructure.jobs.service.JobName;
|
import org.apache.fineract.infrastructure.jobs.service.JobName;
|
||||||
|
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
|
||||||
import org.springframework.batch.core.Job;
|
import org.springframework.batch.core.Job;
|
||||||
import org.springframework.batch.core.Step;
|
import org.springframework.batch.core.Step;
|
||||||
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
|
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
|
||||||
@@ -46,6 +47,9 @@ public class UpdateNpaConfig {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private DatabaseSpecificSQLGenerator sqlGenerator;
|
private DatabaseSpecificSQLGenerator sqlGenerator;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private PlatformSecurityContext platformSecurityContext;
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
protected Step updateNpaStep() {
|
protected Step updateNpaStep() {
|
||||||
return steps.get(JobName.UPDATE_NPA.name()).tasklet(updateNpaTasklet()).build();
|
return steps.get(JobName.UPDATE_NPA.name()).tasklet(updateNpaTasklet()).build();
|
||||||
@@ -58,6 +62,6 @@ public class UpdateNpaConfig {
|
|||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public UpdateNpaTasklet updateNpaTasklet() {
|
public UpdateNpaTasklet updateNpaTasklet() {
|
||||||
return new UpdateNpaTasklet(dataSourceServiceFactory, databaseTypeResolver, sqlGenerator);
|
return new UpdateNpaTasklet(dataSourceServiceFactory, databaseTypeResolver, sqlGenerator, platformSecurityContext);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+15
-6
@@ -20,10 +20,13 @@ package org.apache.fineract.infrastructure.jobs.service.updatenpa;
|
|||||||
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||||
import org.apache.fineract.infrastructure.core.service.RoutingDataSourceServiceFactory;
|
import org.apache.fineract.infrastructure.core.service.RoutingDataSourceServiceFactory;
|
||||||
import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil;
|
import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil;
|
||||||
import org.apache.fineract.infrastructure.core.service.database.DatabaseSpecificSQLGenerator;
|
import org.apache.fineract.infrastructure.core.service.database.DatabaseSpecificSQLGenerator;
|
||||||
import org.apache.fineract.infrastructure.core.service.database.DatabaseTypeResolver;
|
import org.apache.fineract.infrastructure.core.service.database.DatabaseTypeResolver;
|
||||||
|
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
|
||||||
|
import org.apache.fineract.useradministration.domain.AppUser;
|
||||||
import org.springframework.batch.core.StepContribution;
|
import org.springframework.batch.core.StepContribution;
|
||||||
import org.springframework.batch.core.scope.context.ChunkContext;
|
import org.springframework.batch.core.scope.context.ChunkContext;
|
||||||
import org.springframework.batch.core.step.tasklet.Tasklet;
|
import org.springframework.batch.core.step.tasklet.Tasklet;
|
||||||
@@ -37,9 +40,11 @@ public class UpdateNpaTasklet implements Tasklet {
|
|||||||
private final RoutingDataSourceServiceFactory dataSourceServiceFactory;
|
private final RoutingDataSourceServiceFactory dataSourceServiceFactory;
|
||||||
private final DatabaseTypeResolver databaseTypeResolver;
|
private final DatabaseTypeResolver databaseTypeResolver;
|
||||||
private final DatabaseSpecificSQLGenerator sqlGenerator;
|
private final DatabaseSpecificSQLGenerator sqlGenerator;
|
||||||
|
private final PlatformSecurityContext context;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
|
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
|
||||||
|
AppUser user = context.getAuthenticatedUserIfPresent();
|
||||||
final JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSourceServiceFactory.determineDataSourceService().retrieveDataSource());
|
final JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSourceServiceFactory.determineDataSourceService().retrieveDataSource());
|
||||||
|
|
||||||
final StringBuilder resetNPASqlBuilder = new StringBuilder();
|
final StringBuilder resetNPASqlBuilder = new StringBuilder();
|
||||||
@@ -52,11 +57,13 @@ public class UpdateNpaTasklet implements Tasklet {
|
|||||||
String wherePart = " where loan.id = sl.id ";
|
String wherePart = " where loan.id = sl.id ";
|
||||||
|
|
||||||
if (databaseTypeResolver.isMySQL()) {
|
if (databaseTypeResolver.isMySQL()) {
|
||||||
resetNPASqlBuilder.append(", ").append(fromPart).append(" set loan.is_npa = false").append(wherePart);
|
resetNPASqlBuilder.append(", ").append(fromPart).append(" set loan.is_npa = false")
|
||||||
|
.append(", loan.last_modified_by = ?, loan.last_modified_on_utc = ? ").append(wherePart);
|
||||||
} else {
|
} else {
|
||||||
resetNPASqlBuilder.append("set is_npa = false").append(" FROM ").append(fromPart).append(wherePart);
|
resetNPASqlBuilder.append("set is_npa = false").append(", last_modified_by = ?, last_modified_on_utc = ? ").append(" FROM ")
|
||||||
|
.append(fromPart).append(wherePart);
|
||||||
}
|
}
|
||||||
jdbcTemplate.update(resetNPASqlBuilder.toString());
|
jdbcTemplate.update(resetNPASqlBuilder.toString(), user.getId(), DateUtils.getOffsetDateTimeOfTenant());
|
||||||
|
|
||||||
final StringBuilder updateSqlBuilder = new StringBuilder(900);
|
final StringBuilder updateSqlBuilder = new StringBuilder(900);
|
||||||
|
|
||||||
@@ -68,12 +75,14 @@ public class UpdateNpaTasklet implements Tasklet {
|
|||||||
wherePart = " where ml.id=sl.id ";
|
wherePart = " where ml.id=sl.id ";
|
||||||
updateSqlBuilder.append("UPDATE m_loan as ml ");
|
updateSqlBuilder.append("UPDATE m_loan as ml ");
|
||||||
if (databaseTypeResolver.isMySQL()) {
|
if (databaseTypeResolver.isMySQL()) {
|
||||||
updateSqlBuilder.append(", ").append(fromPart).append(" SET ml.is_npa = true").append(wherePart);
|
updateSqlBuilder.append(", ").append(fromPart).append(" SET ml.is_npa = true")
|
||||||
|
.append(", ml.last_modified_by = ?, ml.last_modified_on_utc = ? ").append(wherePart);
|
||||||
} else {
|
} else {
|
||||||
updateSqlBuilder.append(" SET is_npa = true").append(" FROM ").append(fromPart).append(wherePart);
|
updateSqlBuilder.append(" SET is_npa = true").append(", last_modified_by = ?, last_modified_on_utc = ? ").append(" FROM ")
|
||||||
|
.append(fromPart).append(wherePart);
|
||||||
}
|
}
|
||||||
|
|
||||||
final int result = jdbcTemplate.update(updateSqlBuilder.toString());
|
final int result = jdbcTemplate.update(updateSqlBuilder.toString(), user.getId(), DateUtils.getOffsetDateTimeOfTenant());
|
||||||
|
|
||||||
log.info("{}: Records affected by updateNPA: {}", ThreadLocalContextUtil.getTenant().getName(), result);
|
log.info("{}: Records affected by updateNPA: {}", ThreadLocalContextUtil.getTenant().getName(), result);
|
||||||
return RepeatStatus.FINISHED;
|
return RepeatStatus.FINISHED;
|
||||||
|
|||||||
+26
-23
@@ -20,7 +20,6 @@ package org.apache.fineract.portfolio.client.domain;
|
|||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.time.LocalDateTime;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
@@ -39,18 +38,17 @@ import javax.persistence.Transient;
|
|||||||
import javax.persistence.UniqueConstraint;
|
import javax.persistence.UniqueConstraint;
|
||||||
import org.apache.fineract.accounting.glaccount.domain.GLAccount;
|
import org.apache.fineract.accounting.glaccount.domain.GLAccount;
|
||||||
import org.apache.fineract.infrastructure.core.data.EnumOptionData;
|
import org.apache.fineract.infrastructure.core.data.EnumOptionData;
|
||||||
import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom;
|
import org.apache.fineract.infrastructure.core.domain.AbstractAuditableWithUTCDateTimeCustom;
|
||||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||||
import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency;
|
import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency;
|
||||||
import org.apache.fineract.organisation.monetary.domain.Money;
|
import org.apache.fineract.organisation.monetary.domain.Money;
|
||||||
import org.apache.fineract.organisation.office.domain.Office;
|
import org.apache.fineract.organisation.office.domain.Office;
|
||||||
import org.apache.fineract.organisation.office.domain.OrganisationCurrency;
|
import org.apache.fineract.organisation.office.domain.OrganisationCurrency;
|
||||||
import org.apache.fineract.portfolio.paymentdetail.domain.PaymentDetail;
|
import org.apache.fineract.portfolio.paymentdetail.domain.PaymentDetail;
|
||||||
import org.apache.fineract.useradministration.domain.AppUser;
|
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "m_client_transaction", uniqueConstraints = { @UniqueConstraint(columnNames = { "external_id" }, name = "external_id") })
|
@Table(name = "m_client_transaction", uniqueConstraints = { @UniqueConstraint(columnNames = { "external_id" }, name = "external_id") })
|
||||||
public class ClientTransaction extends AbstractPersistableCustom {
|
public class ClientTransaction extends AbstractAuditableWithUTCDateTimeCustom {
|
||||||
|
|
||||||
@ManyToOne(optional = false)
|
@ManyToOne(optional = false)
|
||||||
@JoinColumn(name = "client_id", nullable = false)
|
@JoinColumn(name = "client_id", nullable = false)
|
||||||
@@ -73,6 +71,9 @@ public class ClientTransaction extends AbstractPersistableCustom {
|
|||||||
@Column(name = "transaction_date", nullable = false)
|
@Column(name = "transaction_date", nullable = false)
|
||||||
private LocalDate dateOf;
|
private LocalDate dateOf;
|
||||||
|
|
||||||
|
@Column(name = "submitted_on_date", nullable = false)
|
||||||
|
private LocalDate submittedOnDate;
|
||||||
|
|
||||||
@Column(name = "amount", scale = 6, precision = 19, nullable = false)
|
@Column(name = "amount", scale = 6, precision = 19, nullable = false)
|
||||||
private BigDecimal amount;
|
private BigDecimal amount;
|
||||||
|
|
||||||
@@ -82,12 +83,11 @@ public class ClientTransaction extends AbstractPersistableCustom {
|
|||||||
@Column(name = "external_id", length = 100, nullable = true, unique = true)
|
@Column(name = "external_id", length = 100, nullable = true, unique = true)
|
||||||
private String externalId;
|
private String externalId;
|
||||||
|
|
||||||
@Column(name = "created_date", nullable = false)
|
/*
|
||||||
private LocalDateTime createdDate;
|
* Deprecated since common Auditable fields were introduced. Columns and data left untouched to help migration.
|
||||||
|
*
|
||||||
@ManyToOne
|
* @Column(name = "created_date", nullable = false) private LocalDateTime createdDate;
|
||||||
@JoinColumn(name = "appuser_id", nullable = true)
|
*/
|
||||||
private AppUser appUser;
|
|
||||||
|
|
||||||
@OneToMany(cascade = CascadeType.ALL, mappedBy = "clientTransaction", orphanRemoval = true, fetch = FetchType.EAGER)
|
@OneToMany(cascade = CascadeType.ALL, mappedBy = "clientTransaction", orphanRemoval = true, fetch = FetchType.EAGER)
|
||||||
private Set<ClientChargePaidBy> clientChargePaidByCollection = new HashSet<>();
|
private Set<ClientChargePaidBy> clientChargePaidByCollection = new HashSet<>();
|
||||||
@@ -97,37 +97,36 @@ public class ClientTransaction extends AbstractPersistableCustom {
|
|||||||
|
|
||||||
protected ClientTransaction() {}
|
protected ClientTransaction() {}
|
||||||
|
|
||||||
public static ClientTransaction payCharge(final Client client, final Office office, PaymentDetail paymentDetail, final LocalDate date,
|
public static ClientTransaction payCharge(final Client client, final Office office, PaymentDetail paymentDetail,
|
||||||
final Money amount, final String currencyCode, final AppUser appUser) {
|
final LocalDate transactionDate, final Money amount, final String currencyCode) {
|
||||||
final boolean isReversed = false;
|
final boolean isReversed = false;
|
||||||
final String externalId = null;
|
final String externalId = null;
|
||||||
return new ClientTransaction(client, office, paymentDetail, ClientTransactionType.PAY_CHARGE.getValue(), date, amount, isReversed,
|
return new ClientTransaction(client, office, paymentDetail, ClientTransactionType.PAY_CHARGE.getValue(), transactionDate, amount,
|
||||||
externalId, DateUtils.getLocalDateTimeOfTenant(), currencyCode, appUser);
|
isReversed, externalId, currencyCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ClientTransaction waiver(final Client client, final Office office, final LocalDate date, final Money amount,
|
public static ClientTransaction waiver(final Client client, final Office office, final LocalDate transactionDate, final Money amount,
|
||||||
final String currencyCode, final AppUser appUser) {
|
final String currencyCode) {
|
||||||
final boolean isReversed = false;
|
final boolean isReversed = false;
|
||||||
final String externalId = null;
|
final String externalId = null;
|
||||||
final PaymentDetail paymentDetail = null;
|
final PaymentDetail paymentDetail = null;
|
||||||
return new ClientTransaction(client, office, paymentDetail, ClientTransactionType.WAIVE_CHARGE.getValue(), date, amount, isReversed,
|
return new ClientTransaction(client, office, paymentDetail, ClientTransactionType.WAIVE_CHARGE.getValue(), transactionDate, amount,
|
||||||
externalId, DateUtils.getLocalDateTimeOfTenant(), currencyCode, appUser);
|
isReversed, externalId, currencyCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ClientTransaction(Client client, Office office, PaymentDetail paymentDetail, Integer typeOf, LocalDate transactionLocalDate,
|
public ClientTransaction(Client client, Office office, PaymentDetail paymentDetail, Integer typeOf, LocalDate transactionDate,
|
||||||
Money amount, boolean reversed, String externalId, LocalDateTime createdDate, String currencyCode, AppUser appUser) {
|
Money amount, boolean reversed, String externalId, String currencyCode) {
|
||||||
|
|
||||||
this.client = client;
|
this.client = client;
|
||||||
this.office = office;
|
this.office = office;
|
||||||
this.paymentDetail = paymentDetail;
|
this.paymentDetail = paymentDetail;
|
||||||
this.typeOf = typeOf;
|
this.typeOf = typeOf;
|
||||||
this.dateOf = transactionLocalDate;
|
this.dateOf = transactionDate;
|
||||||
this.amount = amount.getAmount();
|
this.amount = amount.getAmount();
|
||||||
this.reversed = reversed;
|
this.reversed = reversed;
|
||||||
this.externalId = externalId;
|
this.externalId = externalId;
|
||||||
this.createdDate = createdDate;
|
|
||||||
this.currencyCode = currencyCode;
|
this.currencyCode = currencyCode;
|
||||||
this.appUser = appUser;
|
this.submittedOnDate = DateUtils.getBusinessLocalDate();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void reverse() {
|
public void reverse() {
|
||||||
@@ -226,4 +225,8 @@ public class ClientTransaction extends AbstractPersistableCustom {
|
|||||||
return this.dateOf;
|
return this.dateOf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public LocalDate getSubmittedOnDate() {
|
||||||
|
return this.submittedOnDate;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-13
@@ -54,7 +54,6 @@ import org.apache.fineract.portfolio.client.domain.ClientTransaction;
|
|||||||
import org.apache.fineract.portfolio.client.domain.ClientTransactionRepository;
|
import org.apache.fineract.portfolio.client.domain.ClientTransactionRepository;
|
||||||
import org.apache.fineract.portfolio.paymentdetail.domain.PaymentDetail;
|
import org.apache.fineract.portfolio.paymentdetail.domain.PaymentDetail;
|
||||||
import org.apache.fineract.portfolio.paymentdetail.service.PaymentDetailWritePlatformService;
|
import org.apache.fineract.portfolio.paymentdetail.service.PaymentDetailWritePlatformService;
|
||||||
import org.apache.fineract.useradministration.domain.AppUser;
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
@@ -174,7 +173,7 @@ public class ClientChargeWritePlatformServiceJpaRepositoryImpl implements Client
|
|||||||
final PaymentDetail paymentDetail = this.paymentDetailWritePlatformService.createAndPersistPaymentDetail(command, changes);
|
final PaymentDetail paymentDetail = this.paymentDetailWritePlatformService.createAndPersistPaymentDetail(command, changes);
|
||||||
|
|
||||||
ClientTransaction clientTransaction = ClientTransaction.payCharge(client, client.getOffice(), paymentDetail, transactionDate,
|
ClientTransaction clientTransaction = ClientTransaction.payCharge(client, client.getOffice(), paymentDetail, transactionDate,
|
||||||
chargePaid, clientCharge.getCurrency().getCode(), getAppUserIfPresent());
|
chargePaid, clientCharge.getCurrency().getCode());
|
||||||
this.clientTransactionRepository.saveAndFlush(clientTransaction);
|
this.clientTransactionRepository.saveAndFlush(clientTransaction);
|
||||||
|
|
||||||
// update charge paid by associations
|
// update charge paid by associations
|
||||||
@@ -217,7 +216,7 @@ public class ClientChargeWritePlatformServiceJpaRepositoryImpl implements Client
|
|||||||
|
|
||||||
// create Waiver Transaction
|
// create Waiver Transaction
|
||||||
ClientTransaction clientTransaction = ClientTransaction.waiver(client, client.getOffice(), transactionDate, waivedAmount,
|
ClientTransaction clientTransaction = ClientTransaction.waiver(client, client.getOffice(), transactionDate, waivedAmount,
|
||||||
clientCharge.getCurrency().getCode(), getAppUserIfPresent());
|
clientCharge.getCurrency().getCode());
|
||||||
this.clientTransactionRepository.saveAndFlush(clientTransaction);
|
this.clientTransactionRepository.saveAndFlush(clientTransaction);
|
||||||
|
|
||||||
// update charge paid by associations
|
// update charge paid by associations
|
||||||
@@ -392,7 +391,8 @@ public class ClientChargeWritePlatformServiceJpaRepositoryImpl implements Client
|
|||||||
/**
|
/**
|
||||||
* Ensures that the charge transaction date (for payments) is not on a holiday or a non working day
|
* Ensures that the charge transaction date (for payments) is not on a holiday or a non working day
|
||||||
*
|
*
|
||||||
* @param savingsAccountCharge
|
* @param transactionDate
|
||||||
|
* @param clientCharge
|
||||||
* @param fmt
|
* @param fmt
|
||||||
*/
|
*/
|
||||||
private void validateTransactionDateOnWorkingDay(final LocalDate transactionDate, final ClientCharge clientCharge,
|
private void validateTransactionDateOnWorkingDay(final LocalDate transactionDate, final ClientCharge clientCharge,
|
||||||
@@ -406,7 +406,8 @@ public class ClientChargeWritePlatformServiceJpaRepositoryImpl implements Client
|
|||||||
* @param date
|
* @param date
|
||||||
* @param officeId
|
* @param officeId
|
||||||
* @param jsonPropertyName
|
* @param jsonPropertyName
|
||||||
* @param errorMessageFragment
|
* @param errorMessageFragmentForActivityOnHoliday
|
||||||
|
* @param errorMessageFragmentForActivityOnNonWorkingDay
|
||||||
* @param fmt
|
* @param fmt
|
||||||
*/
|
*/
|
||||||
private void validateActivityDateFallOnAWorkingDay(final LocalDate date, final Long officeId, final String jsonPropertyName,
|
private void validateActivityDateFallOnAWorkingDay(final LocalDate date, final Long officeId, final String jsonPropertyName,
|
||||||
@@ -436,14 +437,6 @@ public class ClientChargeWritePlatformServiceJpaRepositoryImpl implements Client
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private AppUser getAppUserIfPresent() {
|
|
||||||
AppUser user = null;
|
|
||||||
if (this.context != null) {
|
|
||||||
user = this.context.getAuthenticatedUserIfPresent();
|
|
||||||
}
|
|
||||||
return user;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void handleDataIntegrityIssues(@SuppressWarnings("unused") final Long clientId, final Long clientChargeId,
|
private void handleDataIntegrityIssues(@SuppressWarnings("unused") final Long clientId, final Long clientChargeId,
|
||||||
final Throwable realCause, final NonTransientDataAccessException dve) {
|
final Throwable realCause, final NonTransientDataAccessException dve) {
|
||||||
|
|
||||||
|
|||||||
+3
-3
@@ -68,7 +68,7 @@ public class ClientTransactionReadPlatformServiceImpl implements ClientTransacti
|
|||||||
final StringBuilder sqlBuilder = new StringBuilder(400);
|
final StringBuilder sqlBuilder = new StringBuilder(400);
|
||||||
sqlBuilder.append("tr.id as transactionId, tr.transaction_type_enum as transactionType, ");
|
sqlBuilder.append("tr.id as transactionId, tr.transaction_type_enum as transactionType, ");
|
||||||
sqlBuilder.append("tr.transaction_date as transactionDate, tr.amount as transactionAmount, ");
|
sqlBuilder.append("tr.transaction_date as transactionDate, tr.amount as transactionAmount, ");
|
||||||
sqlBuilder.append("tr.created_date as submittedOnDate, tr.is_reversed as reversed, ");
|
sqlBuilder.append("tr.submitted_on_date as submittedOnDate, tr.is_reversed as reversed, ");
|
||||||
sqlBuilder.append("tr.external_id as externalId, o.name as officeName, o.id as officeId, ");
|
sqlBuilder.append("tr.external_id as externalId, o.name as officeName, o.id as officeId, ");
|
||||||
sqlBuilder.append("c.id as clientId, c.account_no as accountNo, ccpb.client_charge_id as clientChargeId, ");
|
sqlBuilder.append("c.id as clientId, c.account_no as accountNo, ccpb.client_charge_id as clientChargeId, ");
|
||||||
sqlBuilder.append("pd.payment_type_id as paymentType,pd.account_number as accountNumber,pd.check_number as checkNumber, ");
|
sqlBuilder.append("pd.payment_type_id as paymentType,pd.account_number as accountNumber,pd.check_number as checkNumber, ");
|
||||||
@@ -143,7 +143,7 @@ public class ClientTransactionReadPlatformServiceImpl implements ClientTransacti
|
|||||||
sqlBuilder.append("select " + sqlGenerator.calcFoundRows() + " ").append(this.clientTransactionMapper.schema())
|
sqlBuilder.append("select " + sqlGenerator.calcFoundRows() + " ").append(this.clientTransactionMapper.schema())
|
||||||
.append(" where c.id = ? ");
|
.append(" where c.id = ? ");
|
||||||
parameters[0] = clientId;
|
parameters[0] = clientId;
|
||||||
sqlBuilder.append(" order by tr.transaction_date DESC, tr.created_date DESC, tr.id DESC ");
|
sqlBuilder.append(" order by tr.transaction_date DESC, tr.submitted_on_date DESC, tr.id DESC ");
|
||||||
|
|
||||||
// apply limit and offsets
|
// apply limit and offsets
|
||||||
|
|
||||||
@@ -169,7 +169,7 @@ public class ClientTransactionReadPlatformServiceImpl implements ClientTransacti
|
|||||||
sql = sql + " and ccpb.client_charge_id = ?";
|
sql = sql + " and ccpb.client_charge_id = ?";
|
||||||
}
|
}
|
||||||
parameters[0] = clientId;
|
parameters[0] = clientId;
|
||||||
sql = sql + " order by tr.transaction_date DESC, tr.created_date DESC, tr.id DESC";
|
sql = sql + " order by tr.transaction_date DESC, tr.submitted_on_date DESC, tr.id DESC";
|
||||||
return this.jdbcTemplate.query(sql, this.clientTransactionMapper, parameters); // NOSONAR
|
return this.jdbcTemplate.query(sql, this.clientTransactionMapper, parameters); // NOSONAR
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+7
-7
@@ -19,7 +19,7 @@
|
|||||||
package org.apache.fineract.portfolio.floatingrates.data;
|
package org.apache.fineract.portfolio.floatingrates.data;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.time.LocalDate;
|
import java.time.OffsetDateTime;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import org.apache.commons.lang3.builder.CompareToBuilder;
|
import org.apache.commons.lang3.builder.CompareToBuilder;
|
||||||
import org.apache.commons.lang3.builder.EqualsBuilder;
|
import org.apache.commons.lang3.builder.EqualsBuilder;
|
||||||
@@ -33,15 +33,15 @@ public class FloatingRateData implements Comparable<FloatingRateData>, Serializa
|
|||||||
private final boolean isBaseLendingRate;
|
private final boolean isBaseLendingRate;
|
||||||
private final boolean isActive;
|
private final boolean isActive;
|
||||||
private final String createdBy;
|
private final String createdBy;
|
||||||
private final LocalDate createdOn;
|
private final OffsetDateTime createdOn;
|
||||||
private final String modifiedBy;
|
private final String modifiedBy;
|
||||||
private final LocalDate modifiedOn;
|
private final OffsetDateTime modifiedOn;
|
||||||
private final List<FloatingRatePeriodData> ratePeriods;
|
private final List<FloatingRatePeriodData> ratePeriods;
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
private final List<EnumOptionData> interestRateFrequencyTypeOptions;
|
private final List<EnumOptionData> interestRateFrequencyTypeOptions;
|
||||||
|
|
||||||
public FloatingRateData(Long id, String name, boolean isBaseLendingRate, boolean isActive, String createdBy, LocalDate createdOn,
|
public FloatingRateData(Long id, String name, boolean isBaseLendingRate, boolean isActive, String createdBy, OffsetDateTime createdOn,
|
||||||
String modifiedBy, LocalDate modifiedOn, List<FloatingRatePeriodData> ratePeriods,
|
String modifiedBy, OffsetDateTime modifiedOn, List<FloatingRatePeriodData> ratePeriods,
|
||||||
List<EnumOptionData> interestRateFrequencyTypeOptions) {
|
List<EnumOptionData> interestRateFrequencyTypeOptions) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
@@ -75,7 +75,7 @@ public class FloatingRateData implements Comparable<FloatingRateData>, Serializa
|
|||||||
return this.createdBy;
|
return this.createdBy;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LocalDate getCreatedOn() {
|
public OffsetDateTime getCreatedOn() {
|
||||||
return this.createdOn;
|
return this.createdOn;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,7 +83,7 @@ public class FloatingRateData implements Comparable<FloatingRateData>, Serializa
|
|||||||
return this.modifiedBy;
|
return this.modifiedBy;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LocalDate getModifiedOn() {
|
public OffsetDateTime getModifiedOn() {
|
||||||
return this.modifiedOn;
|
return this.modifiedOn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+15
-6
@@ -21,7 +21,7 @@ package org.apache.fineract.portfolio.floatingrates.data;
|
|||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.time.LocalDateTime;
|
import java.time.OffsetDateTime;
|
||||||
import org.apache.commons.lang3.builder.CompareToBuilder;
|
import org.apache.commons.lang3.builder.CompareToBuilder;
|
||||||
import org.apache.commons.lang3.builder.EqualsBuilder;
|
import org.apache.commons.lang3.builder.EqualsBuilder;
|
||||||
import org.apache.commons.lang3.builder.HashCodeBuilder;
|
import org.apache.commons.lang3.builder.HashCodeBuilder;
|
||||||
@@ -34,12 +34,12 @@ public class FloatingRatePeriodData implements Comparable<FloatingRatePeriodData
|
|||||||
private boolean isDifferentialToBaseLendingRate;
|
private boolean isDifferentialToBaseLendingRate;
|
||||||
private boolean isActive;
|
private boolean isActive;
|
||||||
private String createdBy;
|
private String createdBy;
|
||||||
private LocalDateTime createdOn;
|
private OffsetDateTime createdOn;
|
||||||
private String modifiedBy;
|
private String modifiedBy;
|
||||||
private LocalDateTime modifiedOn;
|
private OffsetDateTime modifiedOn;
|
||||||
|
|
||||||
public FloatingRatePeriodData(Long id, LocalDate fromDate, BigDecimal interestRate, boolean isDifferentialToBaseLendingRate,
|
public FloatingRatePeriodData(Long id, LocalDate fromDate, BigDecimal interestRate, boolean isDifferentialToBaseLendingRate,
|
||||||
boolean isActive, String createdBy, LocalDateTime createdOn, String modifiedBy, LocalDateTime modifiedOn) {
|
boolean isActive, String createdBy, OffsetDateTime createdOn, String modifiedBy, OffsetDateTime modifiedOn) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.fromDate = fromDate;
|
this.fromDate = fromDate;
|
||||||
this.interestRate = interestRate;
|
this.interestRate = interestRate;
|
||||||
@@ -51,6 +51,15 @@ public class FloatingRatePeriodData implements Comparable<FloatingRatePeriodData
|
|||||||
this.modifiedOn = modifiedOn;
|
this.modifiedOn = modifiedOn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public FloatingRatePeriodData(Long id, LocalDate fromDate, BigDecimal interestRate, boolean isDifferentialToBaseLendingRate,
|
||||||
|
boolean isActive) {
|
||||||
|
this.id = id;
|
||||||
|
this.fromDate = fromDate;
|
||||||
|
this.interestRate = interestRate;
|
||||||
|
this.isDifferentialToBaseLendingRate = isDifferentialToBaseLendingRate;
|
||||||
|
this.isActive = isActive;
|
||||||
|
}
|
||||||
|
|
||||||
public Long getId() {
|
public Long getId() {
|
||||||
return this.id;
|
return this.id;
|
||||||
}
|
}
|
||||||
@@ -79,7 +88,7 @@ public class FloatingRatePeriodData implements Comparable<FloatingRatePeriodData
|
|||||||
return this.createdBy;
|
return this.createdBy;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LocalDateTime getCreatedOn() {
|
public OffsetDateTime getCreatedOn() {
|
||||||
return this.createdOn;
|
return this.createdOn;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,7 +96,7 @@ public class FloatingRatePeriodData implements Comparable<FloatingRatePeriodData
|
|||||||
return this.modifiedBy;
|
return this.modifiedBy;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LocalDateTime getModifiedOn() {
|
public OffsetDateTime getModifiedOn() {
|
||||||
return this.modifiedOn;
|
return this.modifiedOn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+19
-56
@@ -23,7 +23,6 @@ import com.google.gson.JsonElement;
|
|||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.time.LocalDateTime;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
@@ -34,24 +33,20 @@ import javax.persistence.CascadeType;
|
|||||||
import javax.persistence.Column;
|
import javax.persistence.Column;
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
import javax.persistence.FetchType;
|
import javax.persistence.FetchType;
|
||||||
import javax.persistence.JoinColumn;
|
|
||||||
import javax.persistence.ManyToOne;
|
|
||||||
import javax.persistence.OneToMany;
|
import javax.persistence.OneToMany;
|
||||||
import javax.persistence.OrderBy;
|
import javax.persistence.OrderBy;
|
||||||
import javax.persistence.Table;
|
import javax.persistence.Table;
|
||||||
import javax.persistence.UniqueConstraint;
|
import javax.persistence.UniqueConstraint;
|
||||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||||
import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom;
|
import org.apache.fineract.infrastructure.core.domain.AbstractAuditableWithUTCDateTimeCustom;
|
||||||
import org.apache.fineract.infrastructure.core.serialization.JsonParserHelper;
|
import org.apache.fineract.infrastructure.core.serialization.JsonParserHelper;
|
||||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||||
import org.apache.fineract.portfolio.floatingrates.data.FloatingRateDTO;
|
import org.apache.fineract.portfolio.floatingrates.data.FloatingRateDTO;
|
||||||
import org.apache.fineract.portfolio.floatingrates.data.FloatingRatePeriodData;
|
import org.apache.fineract.portfolio.floatingrates.data.FloatingRatePeriodData;
|
||||||
import org.apache.fineract.useradministration.domain.AppUser;
|
|
||||||
|
|
||||||
//TODO: refactor to use AbstractAuditableCustom!
|
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "m_floating_rates", uniqueConstraints = { @UniqueConstraint(columnNames = { "name" }, name = "unq_name") })
|
@Table(name = "m_floating_rates", uniqueConstraints = { @UniqueConstraint(columnNames = { "name" }, name = "unq_name") })
|
||||||
public class FloatingRate extends AbstractPersistableCustom {
|
public class FloatingRate extends AbstractAuditableWithUTCDateTimeCustom {
|
||||||
|
|
||||||
@Column(name = "name", length = 200, unique = true, nullable = false)
|
@Column(name = "name", length = 200, unique = true, nullable = false)
|
||||||
private String name;
|
private String name;
|
||||||
@@ -66,34 +61,23 @@ public class FloatingRate extends AbstractPersistableCustom {
|
|||||||
@OneToMany(cascade = CascadeType.ALL, mappedBy = "floatingRate", orphanRemoval = true, fetch = FetchType.EAGER)
|
@OneToMany(cascade = CascadeType.ALL, mappedBy = "floatingRate", orphanRemoval = true, fetch = FetchType.EAGER)
|
||||||
private List<FloatingRatePeriod> floatingRatePeriods;
|
private List<FloatingRatePeriod> floatingRatePeriods;
|
||||||
|
|
||||||
@ManyToOne(optional = true, fetch = FetchType.LAZY)
|
/*
|
||||||
@JoinColumn(name = "createdby_id", nullable = false)
|
* Deprecated since common Auditable fields were introduced. Columns and data left untouched to help migration.
|
||||||
private AppUser createdBy;
|
*
|
||||||
|
* @Column(name = "created_date", nullable = false) private LocalDateTime createdOn;
|
||||||
@ManyToOne(optional = true, fetch = FetchType.LAZY)
|
*
|
||||||
@JoinColumn(name = "lastmodifiedby_id", nullable = false)
|
* @Column(name = "lastmodified_date", nullable = false) private LocalDateTime modifiedOn;
|
||||||
private AppUser modifiedBy;
|
*/
|
||||||
|
|
||||||
@Column(name = "created_date", nullable = false)
|
|
||||||
private LocalDateTime createdOn;
|
|
||||||
|
|
||||||
@Column(name = "lastmodified_date", nullable = false)
|
|
||||||
private LocalDateTime modifiedOn;
|
|
||||||
|
|
||||||
public FloatingRate() {
|
public FloatingRate() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public FloatingRate(String name, boolean isBaseLendingRate, boolean isActive, List<FloatingRatePeriod> floatingRatePeriods,
|
public FloatingRate(String name, boolean isBaseLendingRate, boolean isActive, List<FloatingRatePeriod> floatingRatePeriods) {
|
||||||
AppUser createdBy, AppUser modifiedBy, LocalDateTime createdOn, LocalDateTime modifiedOn) {
|
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.isBaseLendingRate = isBaseLendingRate;
|
this.isBaseLendingRate = isBaseLendingRate;
|
||||||
this.isActive = isActive;
|
this.isActive = isActive;
|
||||||
this.floatingRatePeriods = floatingRatePeriods;
|
this.floatingRatePeriods = floatingRatePeriods;
|
||||||
this.createdBy = createdBy;
|
|
||||||
this.createdOn = createdOn;
|
|
||||||
this.modifiedBy = modifiedBy;
|
|
||||||
this.modifiedOn = modifiedOn;
|
|
||||||
if (floatingRatePeriods != null) {
|
if (floatingRatePeriods != null) {
|
||||||
for (FloatingRatePeriod ratePeriod : floatingRatePeriods) {
|
for (FloatingRatePeriod ratePeriod : floatingRatePeriods) {
|
||||||
ratePeriod.updateFloatingRate(this);
|
ratePeriod.updateFloatingRate(this);
|
||||||
@@ -101,20 +85,19 @@ public class FloatingRate extends AbstractPersistableCustom {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static FloatingRate createNew(AppUser currentUser, JsonCommand command) {
|
public static FloatingRate createNew(JsonCommand command) {
|
||||||
|
|
||||||
final String name = command.stringValueOfParameterNamed("name");
|
final String name = command.stringValueOfParameterNamed("name");
|
||||||
final boolean isBaseLendingRate = command.parameterExists("isBaseLendingRate")
|
final boolean isBaseLendingRate = command.parameterExists("isBaseLendingRate")
|
||||||
? command.booleanPrimitiveValueOfParameterNamed("isBaseLendingRate")
|
? command.booleanPrimitiveValueOfParameterNamed("isBaseLendingRate")
|
||||||
: false;
|
: false;
|
||||||
final boolean isActive = command.parameterExists("isActive") ? command.booleanPrimitiveValueOfParameterNamed("isActive") : true;
|
final boolean isActive = command.parameterExists("isActive") ? command.booleanPrimitiveValueOfParameterNamed("isActive") : true;
|
||||||
final List<FloatingRatePeriod> floatingRatePeriods = getRatePeriods(currentUser, command);
|
final List<FloatingRatePeriod> floatingRatePeriods = getRatePeriods(command);
|
||||||
final LocalDateTime currentDate = DateUtils.getLocalDateTimeOfSystem();
|
|
||||||
|
|
||||||
return new FloatingRate(name, isBaseLendingRate, isActive, floatingRatePeriods, currentUser, currentUser, currentDate, currentDate);
|
return new FloatingRate(name, isBaseLendingRate, isActive, floatingRatePeriods);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<FloatingRatePeriod> getRatePeriods(final AppUser currentUser, final JsonCommand command) {
|
private static List<FloatingRatePeriod> getRatePeriods(final JsonCommand command) {
|
||||||
if (!command.parameterExists("ratePeriods")) {
|
if (!command.parameterExists("ratePeriods")) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -129,9 +112,7 @@ public class FloatingRate extends AbstractPersistableCustom {
|
|||||||
? ratePeriodObject.get("isDifferentialToBaseLendingRate").getAsBoolean()
|
? ratePeriodObject.get("isDifferentialToBaseLendingRate").getAsBoolean()
|
||||||
: false;
|
: false;
|
||||||
final boolean isActive = true;
|
final boolean isActive = true;
|
||||||
final LocalDateTime currentDate = DateUtils.getLocalDateTimeOfSystem();
|
ratePeriods.add(new FloatingRatePeriod(fromDate, interestRate, isDifferentialToBaseLendingRate, isActive));
|
||||||
ratePeriods.add(new FloatingRatePeriod(fromDate, interestRate, isDifferentialToBaseLendingRate, isActive, currentUser,
|
|
||||||
currentUser, currentDate, currentDate));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ratePeriods;
|
return ratePeriods;
|
||||||
@@ -153,23 +134,7 @@ public class FloatingRate extends AbstractPersistableCustom {
|
|||||||
return this.floatingRatePeriods;
|
return this.floatingRatePeriods;
|
||||||
}
|
}
|
||||||
|
|
||||||
public AppUser getCreatedBy() {
|
public Map<String, Object> update(final JsonCommand command) {
|
||||||
return this.createdBy;
|
|
||||||
}
|
|
||||||
|
|
||||||
public AppUser getModifiedBy() {
|
|
||||||
return this.modifiedBy;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LocalDateTime getCreatedOn() {
|
|
||||||
return this.createdOn;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LocalDateTime getModifiedOn() {
|
|
||||||
return this.modifiedOn;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<String, Object> update(final JsonCommand command, final AppUser appUser) {
|
|
||||||
|
|
||||||
final Map<String, Object> actualChanges = new LinkedHashMap<>(9);
|
final Map<String, Object> actualChanges = new LinkedHashMap<>(9);
|
||||||
|
|
||||||
@@ -191,24 +156,22 @@ public class FloatingRate extends AbstractPersistableCustom {
|
|||||||
this.isActive = newValue;
|
this.isActive = newValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
final List<FloatingRatePeriod> newRatePeriods = getRatePeriods(appUser, command);
|
final List<FloatingRatePeriod> newRatePeriods = getRatePeriods(command);
|
||||||
if (newRatePeriods != null && !newRatePeriods.isEmpty()) {
|
if (newRatePeriods != null && !newRatePeriods.isEmpty()) {
|
||||||
updateRatePeriods(newRatePeriods, appUser);
|
updateRatePeriods(newRatePeriods);
|
||||||
actualChanges.put("ratePeriods", command.jsonFragment("ratePeriods"));
|
actualChanges.put("ratePeriods", command.jsonFragment("ratePeriods"));
|
||||||
}
|
}
|
||||||
|
|
||||||
return actualChanges;
|
return actualChanges;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateRatePeriods(final List<FloatingRatePeriod> newRatePeriods, final AppUser appUser) {
|
private void updateRatePeriods(final List<FloatingRatePeriod> newRatePeriods) {
|
||||||
final LocalDate today = DateUtils.getBusinessLocalDate();
|
final LocalDate today = DateUtils.getBusinessLocalDate();
|
||||||
if (this.floatingRatePeriods != null) {
|
if (this.floatingRatePeriods != null) {
|
||||||
for (FloatingRatePeriod ratePeriod : this.floatingRatePeriods) {
|
for (FloatingRatePeriod ratePeriod : this.floatingRatePeriods) {
|
||||||
LocalDate fromDate = ratePeriod.getFromDate();
|
LocalDate fromDate = ratePeriod.getFromDate();
|
||||||
if (fromDate.isAfter(today)) {
|
if (fromDate.isAfter(today)) {
|
||||||
ratePeriod.setActive(false);
|
ratePeriod.setActive(false);
|
||||||
ratePeriod.setModifiedBy(appUser);
|
|
||||||
ratePeriod.setModifiedOn(DateUtils.getLocalDateTimeOfSystem());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+14
-59
@@ -20,22 +20,18 @@ package org.apache.fineract.portfolio.floatingrates.domain;
|
|||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.time.LocalDateTime;
|
|
||||||
import javax.persistence.Column;
|
import javax.persistence.Column;
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
import javax.persistence.FetchType;
|
|
||||||
import javax.persistence.JoinColumn;
|
import javax.persistence.JoinColumn;
|
||||||
import javax.persistence.ManyToOne;
|
import javax.persistence.ManyToOne;
|
||||||
import javax.persistence.Table;
|
import javax.persistence.Table;
|
||||||
import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom;
|
import org.apache.fineract.infrastructure.core.domain.AbstractAuditableWithUTCDateTimeCustom;
|
||||||
import org.apache.fineract.portfolio.floatingrates.data.FloatingRateDTO;
|
import org.apache.fineract.portfolio.floatingrates.data.FloatingRateDTO;
|
||||||
import org.apache.fineract.portfolio.floatingrates.data.FloatingRatePeriodData;
|
import org.apache.fineract.portfolio.floatingrates.data.FloatingRatePeriodData;
|
||||||
import org.apache.fineract.useradministration.domain.AppUser;
|
|
||||||
|
|
||||||
//TODO: refactor to use AbstractAuditableCustom!
|
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "m_floating_rates_periods")
|
@Table(name = "m_floating_rates_periods")
|
||||||
public class FloatingRatePeriod extends AbstractPersistableCustom {
|
public class FloatingRatePeriod extends AbstractAuditableWithUTCDateTimeCustom {
|
||||||
|
|
||||||
@ManyToOne
|
@ManyToOne
|
||||||
@JoinColumn(name = "floating_rates_id", nullable = false)
|
@JoinColumn(name = "floating_rates_id", nullable = false)
|
||||||
@@ -53,41 +49,30 @@ public class FloatingRatePeriod extends AbstractPersistableCustom {
|
|||||||
@Column(name = "is_active", nullable = false)
|
@Column(name = "is_active", nullable = false)
|
||||||
private boolean isActive;
|
private boolean isActive;
|
||||||
|
|
||||||
@ManyToOne(optional = true, fetch = FetchType.LAZY)
|
/*
|
||||||
@JoinColumn(name = "createdby_id", nullable = false)
|
* Deprecated since common Auditable fields were introduced. Columns and data left untouched to help migration.
|
||||||
private AppUser createdBy;
|
*
|
||||||
|
* @Column(name = "created_date", nullable = false) private LocalDateTime createdOn;
|
||||||
@ManyToOne(optional = true, fetch = FetchType.LAZY)
|
*
|
||||||
@JoinColumn(name = "lastmodifiedby_id", nullable = false)
|
* @Column(name = "lastmodified_date", nullable = false) private LocalDateTime modifiedOn;
|
||||||
private AppUser modifiedBy;
|
*/
|
||||||
|
|
||||||
@Column(name = "created_date", nullable = false)
|
|
||||||
private LocalDateTime createdOn;
|
|
||||||
|
|
||||||
@Column(name = "lastmodified_date", nullable = false)
|
|
||||||
private LocalDateTime modifiedOn;
|
|
||||||
|
|
||||||
public FloatingRatePeriod() {
|
public FloatingRatePeriod() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public FloatingRatePeriod(LocalDate fromDate, BigDecimal interestRate, boolean isDifferentialToBaseLendingRate, boolean isActive,
|
public FloatingRatePeriod(LocalDate fromDate, BigDecimal interestRate, boolean isDifferentialToBaseLendingRate, boolean isActive) {
|
||||||
AppUser createdBy, AppUser modifiedBy, LocalDateTime createdOn, LocalDateTime modifiedOn) {
|
|
||||||
this.fromDate = fromDate;
|
this.fromDate = fromDate;
|
||||||
this.interestRate = interestRate;
|
this.interestRate = interestRate;
|
||||||
this.isDifferentialToBaseLendingRate = isDifferentialToBaseLendingRate;
|
this.isDifferentialToBaseLendingRate = isDifferentialToBaseLendingRate;
|
||||||
this.isActive = isActive;
|
this.isActive = isActive;
|
||||||
this.createdBy = createdBy;
|
|
||||||
this.modifiedBy = modifiedBy;
|
|
||||||
this.createdOn = createdOn;
|
|
||||||
this.modifiedOn = modifiedOn;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateFloatingRate(FloatingRate floatingRate) {
|
public void updateFloatingRate(FloatingRate floatingRate) {
|
||||||
this.floatingRate = floatingRate;
|
this.floatingRate = floatingRate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public FloatingRate getFloatingRatesId() {
|
public FloatingRate getFloatingRate() {
|
||||||
return this.floatingRate;
|
return this.floatingRate;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -107,32 +92,8 @@ public class FloatingRatePeriod extends AbstractPersistableCustom {
|
|||||||
return this.isActive;
|
return this.isActive;
|
||||||
}
|
}
|
||||||
|
|
||||||
public AppUser getCreatedBy() {
|
public void setActive(boolean isActive) {
|
||||||
return this.createdBy;
|
this.isActive = isActive;
|
||||||
}
|
|
||||||
|
|
||||||
public AppUser getModifiedBy() {
|
|
||||||
return this.modifiedBy;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LocalDateTime getCreatedOn() {
|
|
||||||
return this.createdOn;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LocalDateTime getModifiedOn() {
|
|
||||||
return this.modifiedOn;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setModifiedBy(AppUser modifiedBy) {
|
|
||||||
this.modifiedBy = modifiedBy;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setModifiedOn(LocalDateTime modifiedOn) {
|
|
||||||
this.modifiedOn = modifiedOn;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setActive(boolean b) {
|
|
||||||
this.isActive = b;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public LocalDate fetchFromDate() {
|
public LocalDate fetchFromDate() {
|
||||||
@@ -147,13 +108,7 @@ public class FloatingRatePeriod extends AbstractPersistableCustom {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final LocalDate fromDate = getFromDate();
|
final LocalDate fromDate = getFromDate();
|
||||||
final LocalDateTime createdOn = getCreatedOn();
|
return new FloatingRatePeriodData(getId(), fromDate, interest, isDifferentialToBaseLendingRate(), isActive());
|
||||||
final LocalDateTime modifiedOn = getModifiedOn();
|
|
||||||
|
|
||||||
String createdBy = getCreatedBy() != null ? getCreatedBy().getUsername() : null;
|
|
||||||
String modifiedBy = getModifiedBy() != null ? getModifiedBy().getUsername() : null;
|
|
||||||
return new FloatingRatePeriodData(getId(), fromDate, interest, isDifferentialToBaseLendingRate(), isActive(), createdBy, createdOn,
|
|
||||||
modifiedBy, modifiedOn);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-10
@@ -25,11 +25,9 @@ import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
|||||||
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
|
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
|
||||||
import org.apache.fineract.infrastructure.core.data.CommandProcessingResultBuilder;
|
import org.apache.fineract.infrastructure.core.data.CommandProcessingResultBuilder;
|
||||||
import org.apache.fineract.infrastructure.core.exception.PlatformDataIntegrityException;
|
import org.apache.fineract.infrastructure.core.exception.PlatformDataIntegrityException;
|
||||||
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
|
|
||||||
import org.apache.fineract.portfolio.floatingrates.domain.FloatingRate;
|
import org.apache.fineract.portfolio.floatingrates.domain.FloatingRate;
|
||||||
import org.apache.fineract.portfolio.floatingrates.domain.FloatingRateRepositoryWrapper;
|
import org.apache.fineract.portfolio.floatingrates.domain.FloatingRateRepositoryWrapper;
|
||||||
import org.apache.fineract.portfolio.floatingrates.serialization.FloatingRateDataValidator;
|
import org.apache.fineract.portfolio.floatingrates.serialization.FloatingRateDataValidator;
|
||||||
import org.apache.fineract.useradministration.domain.AppUser;
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
@@ -42,14 +40,12 @@ import org.springframework.transaction.annotation.Transactional;
|
|||||||
public class FloatingRateWritePlatformServiceImpl implements FloatingRateWritePlatformService {
|
public class FloatingRateWritePlatformServiceImpl implements FloatingRateWritePlatformService {
|
||||||
|
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(FloatingRateWritePlatformServiceImpl.class);
|
private static final Logger LOG = LoggerFactory.getLogger(FloatingRateWritePlatformServiceImpl.class);
|
||||||
private final PlatformSecurityContext context;
|
|
||||||
private final FloatingRateDataValidator fromApiJsonDeserializer;
|
private final FloatingRateDataValidator fromApiJsonDeserializer;
|
||||||
private final FloatingRateRepositoryWrapper floatingRateRepository;
|
private final FloatingRateRepositoryWrapper floatingRateRepository;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public FloatingRateWritePlatformServiceImpl(final PlatformSecurityContext context,
|
public FloatingRateWritePlatformServiceImpl(final FloatingRateDataValidator fromApiJsonDeserializer,
|
||||||
final FloatingRateDataValidator fromApiJsonDeserializer, final FloatingRateRepositoryWrapper floatingRateRepository) {
|
final FloatingRateRepositoryWrapper floatingRateRepository) {
|
||||||
this.context = context;
|
|
||||||
this.fromApiJsonDeserializer = fromApiJsonDeserializer;
|
this.fromApiJsonDeserializer = fromApiJsonDeserializer;
|
||||||
this.floatingRateRepository = floatingRateRepository;
|
this.floatingRateRepository = floatingRateRepository;
|
||||||
}
|
}
|
||||||
@@ -59,8 +55,7 @@ public class FloatingRateWritePlatformServiceImpl implements FloatingRateWritePl
|
|||||||
public CommandProcessingResult createFloatingRate(final JsonCommand command) {
|
public CommandProcessingResult createFloatingRate(final JsonCommand command) {
|
||||||
try {
|
try {
|
||||||
this.fromApiJsonDeserializer.validateForCreate(command.json());
|
this.fromApiJsonDeserializer.validateForCreate(command.json());
|
||||||
final AppUser currentUser = this.context.authenticatedUser();
|
final FloatingRate newFloatingRate = FloatingRate.createNew(command);
|
||||||
final FloatingRate newFloatingRate = FloatingRate.createNew(currentUser, command);
|
|
||||||
this.floatingRateRepository.saveAndFlush(newFloatingRate);
|
this.floatingRateRepository.saveAndFlush(newFloatingRate);
|
||||||
return new CommandProcessingResultBuilder() //
|
return new CommandProcessingResultBuilder() //
|
||||||
.withCommandId(command.commandId()) //
|
.withCommandId(command.commandId()) //
|
||||||
@@ -82,8 +77,7 @@ public class FloatingRateWritePlatformServiceImpl implements FloatingRateWritePl
|
|||||||
try {
|
try {
|
||||||
final FloatingRate floatingRateForUpdate = this.floatingRateRepository.findOneWithNotFoundDetection(command.entityId());
|
final FloatingRate floatingRateForUpdate = this.floatingRateRepository.findOneWithNotFoundDetection(command.entityId());
|
||||||
this.fromApiJsonDeserializer.validateForUpdate(command.json(), floatingRateForUpdate);
|
this.fromApiJsonDeserializer.validateForUpdate(command.json(), floatingRateForUpdate);
|
||||||
final AppUser currentUser = this.context.authenticatedUser();
|
final Map<String, Object> changes = floatingRateForUpdate.update(command);
|
||||||
final Map<String, Object> changes = floatingRateForUpdate.update(command, currentUser);
|
|
||||||
|
|
||||||
if (!changes.isEmpty()) {
|
if (!changes.isEmpty()) {
|
||||||
this.floatingRateRepository.save(floatingRateForUpdate);
|
this.floatingRateRepository.save(floatingRateForUpdate);
|
||||||
|
|||||||
+23
-7
@@ -24,8 +24,10 @@ import java.sql.ResultSet;
|
|||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.OffsetDateTime;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import org.apache.fineract.infrastructure.core.domain.JdbcSupport;
|
import org.apache.fineract.infrastructure.core.domain.JdbcSupport;
|
||||||
|
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||||
import org.apache.fineract.portfolio.floatingrates.data.FloatingRateData;
|
import org.apache.fineract.portfolio.floatingrates.data.FloatingRateData;
|
||||||
import org.apache.fineract.portfolio.floatingrates.data.FloatingRatePeriodData;
|
import org.apache.fineract.portfolio.floatingrates.data.FloatingRatePeriodData;
|
||||||
import org.apache.fineract.portfolio.floatingrates.data.InterestRatePeriodData;
|
import org.apache.fineract.portfolio.floatingrates.data.InterestRatePeriodData;
|
||||||
@@ -106,7 +108,8 @@ public class FloatingRatesReadPlatformServiceImpl implements FloatingRatesReadPl
|
|||||||
private final StringBuilder sqlQuery = new StringBuilder().append("rate.id as id, ").append("rate.name as name, ")
|
private final StringBuilder sqlQuery = new StringBuilder().append("rate.id as id, ").append("rate.name as name, ")
|
||||||
.append("rate.is_base_lending_rate as isBaseLendingRate, ").append("rate.is_active as isActive, ")
|
.append("rate.is_base_lending_rate as isBaseLendingRate, ").append("rate.is_active as isActive, ")
|
||||||
.append("crappu.username as createdBy, ").append("rate.created_date as createdOn, ")
|
.append("crappu.username as createdBy, ").append("rate.created_date as createdOn, ")
|
||||||
.append("moappu.username as modifiedBy, ").append("rate.lastmodified_date as modifiedOn ")
|
.append("rate.created_on_utc as createdOnUTC, ").append("moappu.username as modifiedBy, ")
|
||||||
|
.append("rate.lastmodified_date as modifiedOn, ").append("rate.last_modified_on_utc as modifiedOnUTC ")
|
||||||
.append("FROM m_floating_rates as rate ").append("LEFT JOIN m_appuser as crappu on rate.createdby_id = crappu.id ")
|
.append("FROM m_floating_rates as rate ").append("LEFT JOIN m_appuser as crappu on rate.createdby_id = crappu.id ")
|
||||||
.append("LEFT JOIN m_appuser as moappu on rate.lastmodifiedby_id = moappu.id ");
|
.append("LEFT JOIN m_appuser as moappu on rate.lastmodifiedby_id = moappu.id ");
|
||||||
|
|
||||||
@@ -121,10 +124,16 @@ public class FloatingRatesReadPlatformServiceImpl implements FloatingRatesReadPl
|
|||||||
final boolean isBaseLendingRate = rs.getBoolean("isBaseLendingRate");
|
final boolean isBaseLendingRate = rs.getBoolean("isBaseLendingRate");
|
||||||
final boolean isActive = rs.getBoolean("isActive");
|
final boolean isActive = rs.getBoolean("isActive");
|
||||||
final String createdBy = rs.getString("createdBy");
|
final String createdBy = rs.getString("createdBy");
|
||||||
final LocalDate createdOn = JdbcSupport.getLocalDate(rs, "createdOn");
|
final LocalDateTime createdOnLocal = JdbcSupport.getLocalDateTime(rs, "createdOn");
|
||||||
|
final OffsetDateTime createdOnUtc = JdbcSupport.getOffsetDateTime(rs, "createdOnUTC");
|
||||||
final String modifiedBy = rs.getString("modifiedBy");
|
final String modifiedBy = rs.getString("modifiedBy");
|
||||||
final LocalDate modifiedOn = JdbcSupport.getLocalDate(rs, "modifiedOn");
|
final LocalDateTime modifiedOnLocal = JdbcSupport.getLocalDateTime(rs, "modifiedOn");
|
||||||
|
final OffsetDateTime modifiedOnUtc = JdbcSupport.getOffsetDateTime(rs, "modifiedOnUTC");
|
||||||
List<FloatingRatePeriodData> ratePeriods = null;
|
List<FloatingRatePeriodData> ratePeriods = null;
|
||||||
|
final OffsetDateTime createdOn = createdOnUtc != null ? createdOnUtc
|
||||||
|
: OffsetDateTime.of(createdOnLocal, DateUtils.getDateTimeZoneOfTenant().getRules().getOffset(createdOnLocal));
|
||||||
|
final OffsetDateTime modifiedOn = modifiedOnUtc != null ? modifiedOnUtc
|
||||||
|
: OffsetDateTime.of(modifiedOnLocal, DateUtils.getDateTimeZoneOfTenant().getRules().getOffset(modifiedOnLocal));
|
||||||
if (addRatePeriods) {
|
if (addRatePeriods) {
|
||||||
FloatingRatePeriodRowMapper ratePeriodMapper = new FloatingRatePeriodRowMapper();
|
FloatingRatePeriodRowMapper ratePeriodMapper = new FloatingRatePeriodRowMapper();
|
||||||
final String sql = "select " + ratePeriodMapper.schema()
|
final String sql = "select " + ratePeriodMapper.schema()
|
||||||
@@ -146,8 +155,9 @@ public class FloatingRatesReadPlatformServiceImpl implements FloatingRatesReadPl
|
|||||||
.append("period.interest_rate as interestRate, ")
|
.append("period.interest_rate as interestRate, ")
|
||||||
.append("period.is_differential_to_base_lending_rate as isDifferentialToBaseLendingRate, ")
|
.append("period.is_differential_to_base_lending_rate as isDifferentialToBaseLendingRate, ")
|
||||||
.append("period.is_active as isActive, ").append("crappu.username as createdBy, ")
|
.append("period.is_active as isActive, ").append("crappu.username as createdBy, ")
|
||||||
.append("period.created_date as createdOn, ").append("moappu.username as modifiedBy, ")
|
.append("period.created_date as createdOn, ").append("rate.created_on_utc as createdOnUTC, ")
|
||||||
.append("period.lastmodified_date as modifiedOn ").append("FROM m_floating_rates_periods as period ")
|
.append("moappu.username as modifiedBy, ").append("period.lastmodified_date as modifiedOn, ")
|
||||||
|
.append("rate.last_modified_on_utc as modifiedOnUTC ").append("FROM m_floating_rates_periods as period ")
|
||||||
.append("LEFT JOIN m_appuser as crappu on period.createdby_id = crappu.id ")
|
.append("LEFT JOIN m_appuser as crappu on period.createdby_id = crappu.id ")
|
||||||
.append("LEFT JOIN m_appuser as moappu on period.lastmodifiedby_id = moappu.id ");
|
.append("LEFT JOIN m_appuser as moappu on period.lastmodifiedby_id = moappu.id ");
|
||||||
|
|
||||||
@@ -159,9 +169,15 @@ public class FloatingRatesReadPlatformServiceImpl implements FloatingRatesReadPl
|
|||||||
final boolean isDifferentialToBaseLendingRate = rs.getBoolean("isDifferentialToBaseLendingRate");
|
final boolean isDifferentialToBaseLendingRate = rs.getBoolean("isDifferentialToBaseLendingRate");
|
||||||
final boolean isActive = rs.getBoolean("isActive");
|
final boolean isActive = rs.getBoolean("isActive");
|
||||||
final String createdBy = rs.getString("createdBy");
|
final String createdBy = rs.getString("createdBy");
|
||||||
final LocalDateTime createdOn = JdbcSupport.getLocalDateTime(rs, "createdOn");
|
final LocalDateTime createdOnLocal = JdbcSupport.getLocalDateTime(rs, "createdOn");
|
||||||
|
final OffsetDateTime createdOnUtc = JdbcSupport.getOffsetDateTime(rs, "createdOnUTC");
|
||||||
final String modifiedBy = rs.getString("modifiedBy");
|
final String modifiedBy = rs.getString("modifiedBy");
|
||||||
final LocalDateTime modifiedOn = JdbcSupport.getLocalDateTime(rs, "modifiedOn");
|
final LocalDateTime modifiedOnLocal = JdbcSupport.getLocalDateTime(rs, "modifiedOn");
|
||||||
|
final OffsetDateTime modifiedOnUtc = JdbcSupport.getOffsetDateTime(rs, "modifiedOnUTC");
|
||||||
|
final OffsetDateTime createdOn = createdOnUtc != null ? createdOnUtc
|
||||||
|
: OffsetDateTime.of(createdOnLocal, DateUtils.getDateTimeZoneOfTenant().getRules().getOffset(createdOnLocal));
|
||||||
|
final OffsetDateTime modifiedOn = modifiedOnUtc != null ? modifiedOnUtc
|
||||||
|
: OffsetDateTime.of(modifiedOnLocal, DateUtils.getDateTimeZoneOfTenant().getRules().getOffset(modifiedOnLocal));
|
||||||
return new FloatingRatePeriodData(id, fromDate, interestRate, isDifferentialToBaseLendingRate, isActive, createdBy, createdOn,
|
return new FloatingRatePeriodData(id, fromDate, interestRate, isDifferentialToBaseLendingRate, isActive, createdBy, createdOn,
|
||||||
modifiedBy, modifiedOn);
|
modifiedBy, modifiedOn);
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-6
@@ -45,15 +45,15 @@ public class AddAccrualEntriesTasklet implements Tasklet {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
|
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
|
||||||
Collection<LoanScheduleAccrualData> loanScheduleAccrualDatas = loanReadPlatformService.retriveScheduleAccrualData();
|
Collection<LoanScheduleAccrualData> loanScheduleAccrualDataList = loanReadPlatformService.retriveScheduleAccrualData();
|
||||||
Map<Long, Collection<LoanScheduleAccrualData>> loanDataMap = new HashMap<>();
|
Map<Long, Collection<LoanScheduleAccrualData>> loanDataMap = new HashMap<>();
|
||||||
for (final LoanScheduleAccrualData accrualData : loanScheduleAccrualDatas) {
|
for (final LoanScheduleAccrualData accrualData : loanScheduleAccrualDataList) {
|
||||||
if (loanDataMap.containsKey(accrualData.getLoanId())) {
|
if (loanDataMap.containsKey(accrualData.getLoanId())) {
|
||||||
loanDataMap.get(accrualData.getLoanId()).add(accrualData);
|
loanDataMap.get(accrualData.getLoanId()).add(accrualData);
|
||||||
} else {
|
} else {
|
||||||
Collection<LoanScheduleAccrualData> accrualDatas = new ArrayList<>();
|
Collection<LoanScheduleAccrualData> accrualDataList = new ArrayList<>();
|
||||||
accrualDatas.add(accrualData);
|
accrualDataList.add(accrualData);
|
||||||
loanDataMap.put(accrualData.getLoanId(), accrualDatas);
|
loanDataMap.put(accrualData.getLoanId(), accrualDataList);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -62,7 +62,7 @@ public class AddAccrualEntriesTasklet implements Tasklet {
|
|||||||
try {
|
try {
|
||||||
loanAccrualWritePlatformService.addAccrualAccounting(mapEntry.getKey(), mapEntry.getValue());
|
loanAccrualWritePlatformService.addAccrualAccounting(mapEntry.getKey(), mapEntry.getValue());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("Failed to add accural transaction for loan {}", mapEntry.getKey(), e);
|
log.error("Failed to add accrual transaction for loan {}", mapEntry.getKey(), e);
|
||||||
errors.add(e);
|
errors.add(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-10
@@ -39,31 +39,31 @@ public class LoanAccrualPlatformServiceImpl implements LoanAccrualPlatformServic
|
|||||||
private final LoanAccrualWritePlatformService loanAccrualWritePlatformService;
|
private final LoanAccrualWritePlatformService loanAccrualWritePlatformService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addPeriodicAccruals(final LocalDate tilldate) throws JobExecutionException {
|
public void addPeriodicAccruals(final LocalDate tillDate) throws JobExecutionException {
|
||||||
Collection<LoanScheduleAccrualData> loanScheduleAccrualDatas = this.loanReadPlatformService.retrivePeriodicAccrualData(tilldate);
|
Collection<LoanScheduleAccrualData> loanScheduleAccrualDataList = this.loanReadPlatformService.retrivePeriodicAccrualData(tillDate);
|
||||||
addPeriodicAccruals(tilldate, loanScheduleAccrualDatas);
|
addPeriodicAccruals(tillDate, loanScheduleAccrualDataList);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addPeriodicAccruals(final LocalDate tilldate, Collection<LoanScheduleAccrualData> loanScheduleAccrualDatas)
|
public void addPeriodicAccruals(final LocalDate tillDate, Collection<LoanScheduleAccrualData> loanScheduleAccrualDataList)
|
||||||
throws JobExecutionException {
|
throws JobExecutionException {
|
||||||
Map<Long, Collection<LoanScheduleAccrualData>> loanDataMap = new HashMap<>();
|
Map<Long, Collection<LoanScheduleAccrualData>> loanDataMap = new HashMap<>();
|
||||||
for (final LoanScheduleAccrualData accrualData : loanScheduleAccrualDatas) {
|
for (final LoanScheduleAccrualData accrualData : loanScheduleAccrualDataList) {
|
||||||
if (loanDataMap.containsKey(accrualData.getLoanId())) {
|
if (loanDataMap.containsKey(accrualData.getLoanId())) {
|
||||||
loanDataMap.get(accrualData.getLoanId()).add(accrualData);
|
loanDataMap.get(accrualData.getLoanId()).add(accrualData);
|
||||||
} else {
|
} else {
|
||||||
Collection<LoanScheduleAccrualData> accrualDatas = new ArrayList<>();
|
Collection<LoanScheduleAccrualData> accrualDataList = new ArrayList<>();
|
||||||
accrualDatas.add(accrualData);
|
accrualDataList.add(accrualData);
|
||||||
loanDataMap.put(accrualData.getLoanId(), accrualDatas);
|
loanDataMap.put(accrualData.getLoanId(), accrualDataList);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Throwable> errors = new ArrayList<>();
|
List<Throwable> errors = new ArrayList<>();
|
||||||
for (Map.Entry<Long, Collection<LoanScheduleAccrualData>> mapEntry : loanDataMap.entrySet()) {
|
for (Map.Entry<Long, Collection<LoanScheduleAccrualData>> mapEntry : loanDataMap.entrySet()) {
|
||||||
try {
|
try {
|
||||||
this.loanAccrualWritePlatformService.addPeriodicAccruals(tilldate, mapEntry.getKey(), mapEntry.getValue());
|
this.loanAccrualWritePlatformService.addPeriodicAccruals(tillDate, mapEntry.getKey(), mapEntry.getValue());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("Failed to add accural transaction for loan {}", mapEntry.getKey(), e);
|
log.error("Failed to add accrual transaction for loan {}", mapEntry.getKey(), e);
|
||||||
errors.add(e);
|
errors.add(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+106
-105
@@ -32,6 +32,7 @@ import lombok.RequiredArgsConstructor;
|
|||||||
import org.apache.fineract.accounting.journalentry.service.JournalEntryWritePlatformService;
|
import org.apache.fineract.accounting.journalentry.service.JournalEntryWritePlatformService;
|
||||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||||
import org.apache.fineract.infrastructure.core.service.database.DatabaseSpecificSQLGenerator;
|
import org.apache.fineract.infrastructure.core.service.database.DatabaseSpecificSQLGenerator;
|
||||||
|
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
|
||||||
import org.apache.fineract.organisation.monetary.domain.ApplicationCurrency;
|
import org.apache.fineract.organisation.monetary.domain.ApplicationCurrency;
|
||||||
import org.apache.fineract.organisation.monetary.domain.ApplicationCurrencyRepositoryWrapper;
|
import org.apache.fineract.organisation.monetary.domain.ApplicationCurrencyRepositoryWrapper;
|
||||||
import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency;
|
import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency;
|
||||||
@@ -47,6 +48,7 @@ import org.apache.fineract.portfolio.loanaccount.domain.LoanTransactionType;
|
|||||||
import org.apache.fineract.portfolio.loanaccount.exception.LoanNotFoundException;
|
import org.apache.fineract.portfolio.loanaccount.exception.LoanNotFoundException;
|
||||||
import org.apache.fineract.portfolio.loanaccount.loanschedule.data.LoanSchedulePeriodData;
|
import org.apache.fineract.portfolio.loanaccount.loanschedule.data.LoanSchedulePeriodData;
|
||||||
import org.apache.fineract.portfolio.loanproduct.service.LoanEnumerations;
|
import org.apache.fineract.portfolio.loanproduct.service.LoanEnumerations;
|
||||||
|
import org.apache.fineract.useradministration.domain.AppUser;
|
||||||
import org.apache.fineract.useradministration.domain.AppUserRepositoryWrapper;
|
import org.apache.fineract.useradministration.domain.AppUserRepositoryWrapper;
|
||||||
import org.springframework.dao.DataAccessException;
|
import org.springframework.dao.DataAccessException;
|
||||||
import org.springframework.jdbc.core.JdbcTemplate;
|
import org.springframework.jdbc.core.JdbcTemplate;
|
||||||
@@ -63,63 +65,62 @@ public class LoanAccrualWritePlatformServiceImpl implements LoanAccrualWritePlat
|
|||||||
private final DatabaseSpecificSQLGenerator sqlGenerator;
|
private final DatabaseSpecificSQLGenerator sqlGenerator;
|
||||||
private final JournalEntryWritePlatformService journalEntryWritePlatformService;
|
private final JournalEntryWritePlatformService journalEntryWritePlatformService;
|
||||||
private final AppUserRepositoryWrapper userRepository;
|
private final AppUserRepositoryWrapper userRepository;
|
||||||
|
private final PlatformSecurityContext context;
|
||||||
private final LoanRepositoryWrapper loanRepositoryWrapper;
|
private final LoanRepositoryWrapper loanRepositoryWrapper;
|
||||||
private final ApplicationCurrencyRepositoryWrapper applicationCurrencyRepository;
|
private final ApplicationCurrencyRepositoryWrapper applicationCurrencyRepository;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional
|
@Transactional
|
||||||
public void addAccrualAccounting(final Long loanId, final Collection<LoanScheduleAccrualData> loanScheduleAccrualDatas)
|
public void addAccrualAccounting(final Long loanId, final Collection<LoanScheduleAccrualData> loanScheduleAccrualData) {
|
||||||
throws Exception {
|
|
||||||
Collection<LoanChargeData> chargeData = this.loanChargeReadPlatformService.retrieveLoanChargesForAccural(loanId);
|
Collection<LoanChargeData> chargeData = this.loanChargeReadPlatformService.retrieveLoanChargesForAccural(loanId);
|
||||||
Collection<LoanSchedulePeriodData> loanWaiverScheduleData = new ArrayList<>(1);
|
Collection<LoanSchedulePeriodData> loanWaiverScheduleData = new ArrayList<>(1);
|
||||||
Collection<LoanTransactionData> loanWaiverTansactionData = new ArrayList<>(1);
|
Collection<LoanTransactionData> loanWaiverTransactionData = new ArrayList<>(1);
|
||||||
|
|
||||||
for (final LoanScheduleAccrualData accrualData : loanScheduleAccrualDatas) {
|
for (final LoanScheduleAccrualData accrualData : loanScheduleAccrualData) {
|
||||||
if (accrualData.getWaivedInterestIncome() != null && loanWaiverScheduleData.isEmpty()) {
|
if (accrualData.getWaivedInterestIncome() != null && loanWaiverScheduleData.isEmpty()) {
|
||||||
loanWaiverScheduleData = this.loanReadPlatformService.fetchWaiverInterestRepaymentData(accrualData.getLoanId());
|
loanWaiverScheduleData = this.loanReadPlatformService.fetchWaiverInterestRepaymentData(accrualData.getLoanId());
|
||||||
loanWaiverTansactionData = this.loanReadPlatformService.retrieveWaiverLoanTransactions(accrualData.getLoanId());
|
loanWaiverTransactionData = this.loanReadPlatformService.retrieveWaiverLoanTransactions(accrualData.getLoanId());
|
||||||
}
|
}
|
||||||
updateCharges(chargeData, accrualData, accrualData.getFromDateAsLocaldate(), accrualData.getDueDateAsLocaldate());
|
updateCharges(chargeData, accrualData, accrualData.getFromDateAsLocaldate(), accrualData.getDueDateAsLocaldate());
|
||||||
updateInterestIncome(accrualData, loanWaiverTansactionData, loanWaiverScheduleData, accrualData.getDueDateAsLocaldate());
|
updateInterestIncome(accrualData, loanWaiverTransactionData, loanWaiverScheduleData, accrualData.getDueDateAsLocaldate());
|
||||||
addAccrualAccounting(accrualData);
|
addAccrualAccounting(accrualData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional
|
@Transactional
|
||||||
public void addPeriodicAccruals(final LocalDate tilldate, Long loanId, Collection<LoanScheduleAccrualData> loanScheduleAccrualDatas)
|
public void addPeriodicAccruals(final LocalDate tillDate, Long loanId, Collection<LoanScheduleAccrualData> loanScheduleAccrualData) {
|
||||||
throws Exception {
|
|
||||||
boolean firstTime = true;
|
boolean firstTime = true;
|
||||||
LocalDate accruredTill = null;
|
LocalDate accruedTill = null;
|
||||||
Collection<LoanChargeData> chargeData = this.loanChargeReadPlatformService.retrieveLoanChargesForAccural(loanId);
|
Collection<LoanChargeData> chargeData = this.loanChargeReadPlatformService.retrieveLoanChargesForAccural(loanId);
|
||||||
Collection<LoanSchedulePeriodData> loanWaiverScheduleData = new ArrayList<>(1);
|
Collection<LoanSchedulePeriodData> loanWaiverScheduleData = new ArrayList<>(1);
|
||||||
Collection<LoanTransactionData> loanWaiverTansactionData = new ArrayList<>(1);
|
Collection<LoanTransactionData> loanWaiverTransactionData = new ArrayList<>(1);
|
||||||
for (final LoanScheduleAccrualData accrualData : loanScheduleAccrualDatas) {
|
for (final LoanScheduleAccrualData accrualData : loanScheduleAccrualData) {
|
||||||
if (accrualData.getWaivedInterestIncome() != null && loanWaiverScheduleData.isEmpty()) {
|
if (accrualData.getWaivedInterestIncome() != null && loanWaiverScheduleData.isEmpty()) {
|
||||||
loanWaiverScheduleData = this.loanReadPlatformService.fetchWaiverInterestRepaymentData(accrualData.getLoanId());
|
loanWaiverScheduleData = this.loanReadPlatformService.fetchWaiverInterestRepaymentData(accrualData.getLoanId());
|
||||||
loanWaiverTansactionData = this.loanReadPlatformService.retrieveWaiverLoanTransactions(accrualData.getLoanId());
|
loanWaiverTransactionData = this.loanReadPlatformService.retrieveWaiverLoanTransactions(accrualData.getLoanId());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (accrualData.getDueDateAsLocaldate().isAfter(tilldate)) {
|
if (accrualData.getDueDateAsLocaldate().isAfter(tillDate)) {
|
||||||
if (accruredTill == null || firstTime) {
|
if (accruedTill == null || firstTime) {
|
||||||
accruredTill = accrualData.getAccruedTill();
|
accruedTill = accrualData.getAccruedTill();
|
||||||
firstTime = false;
|
firstTime = false;
|
||||||
}
|
}
|
||||||
if (accruredTill == null || accruredTill.isBefore(tilldate)) {
|
if (accruedTill == null || accruedTill.isBefore(tillDate)) {
|
||||||
updateCharges(chargeData, accrualData, accrualData.getFromDateAsLocaldate(), tilldate);
|
updateCharges(chargeData, accrualData, accrualData.getFromDateAsLocaldate(), tillDate);
|
||||||
updateInterestIncome(accrualData, loanWaiverTansactionData, loanWaiverScheduleData, tilldate);
|
updateInterestIncome(accrualData, loanWaiverTransactionData, loanWaiverScheduleData, tillDate);
|
||||||
addAccrualTillSpecificDate(tilldate, accrualData);
|
addAccrualTillSpecificDate(tillDate, accrualData);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
updateCharges(chargeData, accrualData, accrualData.getFromDateAsLocaldate(), accrualData.getDueDateAsLocaldate());
|
updateCharges(chargeData, accrualData, accrualData.getFromDateAsLocaldate(), accrualData.getDueDateAsLocaldate());
|
||||||
updateInterestIncome(accrualData, loanWaiverTansactionData, loanWaiverScheduleData, tilldate);
|
updateInterestIncome(accrualData, loanWaiverTransactionData, loanWaiverScheduleData, tillDate);
|
||||||
addAccrualAccounting(accrualData);
|
addAccrualAccounting(accrualData);
|
||||||
accruredTill = accrualData.getDueDateAsLocaldate();
|
accruedTill = accrualData.getDueDateAsLocaldate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addAccrualTillSpecificDate(final LocalDate tilldate, final LoanScheduleAccrualData accrualData) throws Exception {
|
private void addAccrualTillSpecificDate(final LocalDate tillDate, final LoanScheduleAccrualData accrualData) {
|
||||||
LocalDate interestStartDate = accrualData.getFromDateAsLocaldate();
|
LocalDate interestStartDate = accrualData.getFromDateAsLocaldate();
|
||||||
if (accrualData.getInterestCalculatedFrom() != null
|
if (accrualData.getInterestCalculatedFrom() != null
|
||||||
&& accrualData.getFromDateAsLocaldate().isBefore(accrualData.getInterestCalculatedFrom())) {
|
&& accrualData.getFromDateAsLocaldate().isBefore(accrualData.getInterestCalculatedFrom())) {
|
||||||
@@ -133,150 +134,150 @@ public class LoanAccrualWritePlatformServiceImpl implements LoanAccrualWritePlat
|
|||||||
int totalNumberOfDays = Math.toIntExact(ChronoUnit.DAYS.between(interestStartDate, accrualData.getDueDateAsLocaldate()));
|
int totalNumberOfDays = Math.toIntExact(ChronoUnit.DAYS.between(interestStartDate, accrualData.getDueDateAsLocaldate()));
|
||||||
LocalDate startDate = accrualData.getFromDateAsLocaldate();
|
LocalDate startDate = accrualData.getFromDateAsLocaldate();
|
||||||
if (accrualData.getInterestCalculatedFrom() != null && startDate.isBefore(accrualData.getInterestCalculatedFrom())) {
|
if (accrualData.getInterestCalculatedFrom() != null && startDate.isBefore(accrualData.getInterestCalculatedFrom())) {
|
||||||
if (accrualData.getInterestCalculatedFrom().isBefore(tilldate)) {
|
if (accrualData.getInterestCalculatedFrom().isBefore(tillDate)) {
|
||||||
startDate = accrualData.getInterestCalculatedFrom();
|
startDate = accrualData.getInterestCalculatedFrom();
|
||||||
} else {
|
} else {
|
||||||
startDate = tilldate;
|
startDate = tillDate;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int daysToBeAccrued = Math.toIntExact(ChronoUnit.DAYS.between(startDate, tilldate));
|
int daysToBeAccrued = Math.toIntExact(ChronoUnit.DAYS.between(startDate, tillDate));
|
||||||
double interestPerDay = accrualData.getAccruableIncome().doubleValue() / totalNumberOfDays;
|
double interestPerDay = accrualData.getAccruableIncome().doubleValue() / totalNumberOfDays;
|
||||||
BigDecimal amount = BigDecimal.ZERO;
|
BigDecimal amount = BigDecimal.ZERO;
|
||||||
BigDecimal interestportion = null;
|
BigDecimal interestPortion;
|
||||||
BigDecimal feeportion = accrualData.getDueDateFeeIncome();
|
BigDecimal feePortion = accrualData.getDueDateFeeIncome();
|
||||||
BigDecimal penaltyportion = accrualData.getDueDatePenaltyIncome();
|
BigDecimal penaltyPortion = accrualData.getDueDatePenaltyIncome();
|
||||||
if (daysToBeAccrued >= totalNumberOfDays) {
|
if (daysToBeAccrued >= totalNumberOfDays) {
|
||||||
interestportion = accrualData.getAccruableIncome();
|
interestPortion = accrualData.getAccruableIncome();
|
||||||
} else {
|
} else {
|
||||||
double iterest = interestPerDay * daysToBeAccrued;
|
interestPortion = BigDecimal.valueOf(interestPerDay * daysToBeAccrued);
|
||||||
interestportion = BigDecimal.valueOf(iterest);
|
|
||||||
}
|
}
|
||||||
interestportion = interestportion.setScale(accrualData.getCurrencyData().decimalPlaces(), MoneyHelper.getRoundingMode());
|
interestPortion = interestPortion.setScale(accrualData.getCurrencyData().decimalPlaces(), MoneyHelper.getRoundingMode());
|
||||||
|
|
||||||
BigDecimal totalAccInterest = accrualData.getAccruedInterestIncome();
|
BigDecimal totalAccInterest = accrualData.getAccruedInterestIncome();
|
||||||
BigDecimal totalAccPenalty = accrualData.getAccruedPenaltyIncome();
|
BigDecimal totalAccPenalty = accrualData.getAccruedPenaltyIncome();
|
||||||
BigDecimal totalAccFee = accrualData.getAccruedFeeIncome();
|
BigDecimal totalAccFee = accrualData.getAccruedFeeIncome();
|
||||||
|
|
||||||
if (interestportion != null) {
|
if (totalAccInterest == null) {
|
||||||
if (totalAccInterest == null) {
|
totalAccInterest = BigDecimal.ZERO;
|
||||||
totalAccInterest = BigDecimal.ZERO;
|
|
||||||
}
|
|
||||||
interestportion = interestportion.subtract(totalAccInterest);
|
|
||||||
amount = amount.add(interestportion);
|
|
||||||
totalAccInterest = totalAccInterest.add(interestportion);
|
|
||||||
if (interestportion.compareTo(BigDecimal.ZERO) == 0) {
|
|
||||||
interestportion = null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (feeportion != null) {
|
interestPortion = interestPortion.subtract(totalAccInterest);
|
||||||
|
amount = amount.add(interestPortion);
|
||||||
|
totalAccInterest = totalAccInterest.add(interestPortion);
|
||||||
|
if (interestPortion.compareTo(BigDecimal.ZERO) == 0) {
|
||||||
|
interestPortion = null;
|
||||||
|
}
|
||||||
|
if (feePortion != null) {
|
||||||
if (totalAccFee == null) {
|
if (totalAccFee == null) {
|
||||||
totalAccFee = BigDecimal.ZERO;
|
totalAccFee = BigDecimal.ZERO;
|
||||||
}
|
}
|
||||||
feeportion = feeportion.subtract(totalAccFee);
|
feePortion = feePortion.subtract(totalAccFee);
|
||||||
amount = amount.add(feeportion);
|
amount = amount.add(feePortion);
|
||||||
totalAccFee = totalAccFee.add(feeportion);
|
totalAccFee = totalAccFee.add(feePortion);
|
||||||
if (feeportion.compareTo(BigDecimal.ZERO) == 0) {
|
if (feePortion.compareTo(BigDecimal.ZERO) == 0) {
|
||||||
feeportion = null;
|
feePortion = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (penaltyportion != null) {
|
if (penaltyPortion != null) {
|
||||||
if (totalAccPenalty == null) {
|
if (totalAccPenalty == null) {
|
||||||
totalAccPenalty = BigDecimal.ZERO;
|
totalAccPenalty = BigDecimal.ZERO;
|
||||||
}
|
}
|
||||||
penaltyportion = penaltyportion.subtract(totalAccPenalty);
|
penaltyPortion = penaltyPortion.subtract(totalAccPenalty);
|
||||||
amount = amount.add(penaltyportion);
|
amount = amount.add(penaltyPortion);
|
||||||
totalAccPenalty = totalAccPenalty.add(penaltyportion);
|
totalAccPenalty = totalAccPenalty.add(penaltyPortion);
|
||||||
if (penaltyportion.compareTo(BigDecimal.ZERO) == 0) {
|
if (penaltyPortion.compareTo(BigDecimal.ZERO) == 0) {
|
||||||
penaltyportion = null;
|
penaltyPortion = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (amount.compareTo(BigDecimal.ZERO) > 0) {
|
if (amount.compareTo(BigDecimal.ZERO) > 0) {
|
||||||
addAccrualAccounting(accrualData, amount, interestportion, totalAccInterest, feeportion, totalAccFee, penaltyportion,
|
addAccrualAccounting(accrualData, amount, interestPortion, totalAccInterest, feePortion, totalAccFee, penaltyPortion,
|
||||||
totalAccPenalty, tilldate);
|
totalAccPenalty, tillDate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
public void addAccrualAccounting(LoanScheduleAccrualData scheduleAccrualData) throws Exception {
|
public void addAccrualAccounting(LoanScheduleAccrualData scheduleAccrualData) {
|
||||||
|
|
||||||
BigDecimal amount = BigDecimal.ZERO;
|
BigDecimal amount = BigDecimal.ZERO;
|
||||||
BigDecimal interestportion = null;
|
BigDecimal interestPortion = null;
|
||||||
BigDecimal totalAccInterest = null;
|
BigDecimal totalAccInterest = null;
|
||||||
if (scheduleAccrualData.getAccruableIncome() != null) {
|
if (scheduleAccrualData.getAccruableIncome() != null) {
|
||||||
interestportion = scheduleAccrualData.getAccruableIncome();
|
interestPortion = scheduleAccrualData.getAccruableIncome();
|
||||||
totalAccInterest = interestportion;
|
totalAccInterest = interestPortion;
|
||||||
if (scheduleAccrualData.getAccruedInterestIncome() != null) {
|
if (scheduleAccrualData.getAccruedInterestIncome() != null) {
|
||||||
interestportion = interestportion.subtract(scheduleAccrualData.getAccruedInterestIncome());
|
interestPortion = interestPortion.subtract(scheduleAccrualData.getAccruedInterestIncome());
|
||||||
}
|
}
|
||||||
amount = amount.add(interestportion);
|
amount = amount.add(interestPortion);
|
||||||
if (interestportion.compareTo(BigDecimal.ZERO) == 0) {
|
if (interestPortion.compareTo(BigDecimal.ZERO) == 0) {
|
||||||
interestportion = null;
|
interestPortion = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BigDecimal feeportion = null;
|
BigDecimal feePortion = null;
|
||||||
BigDecimal totalAccFee = null;
|
BigDecimal totalAccFee = null;
|
||||||
if (scheduleAccrualData.getDueDateFeeIncome() != null) {
|
if (scheduleAccrualData.getDueDateFeeIncome() != null) {
|
||||||
feeportion = scheduleAccrualData.getDueDateFeeIncome();
|
feePortion = scheduleAccrualData.getDueDateFeeIncome();
|
||||||
totalAccFee = feeportion;
|
totalAccFee = feePortion;
|
||||||
if (scheduleAccrualData.getAccruedFeeIncome() != null) {
|
if (scheduleAccrualData.getAccruedFeeIncome() != null) {
|
||||||
feeportion = feeportion.subtract(scheduleAccrualData.getAccruedFeeIncome());
|
feePortion = feePortion.subtract(scheduleAccrualData.getAccruedFeeIncome());
|
||||||
}
|
}
|
||||||
amount = amount.add(feeportion);
|
amount = amount.add(feePortion);
|
||||||
if (feeportion.compareTo(BigDecimal.ZERO) == 0) {
|
if (feePortion.compareTo(BigDecimal.ZERO) == 0) {
|
||||||
feeportion = null;
|
feePortion = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BigDecimal penaltyportion = null;
|
BigDecimal penaltyPortion = null;
|
||||||
BigDecimal totalAccPenalty = null;
|
BigDecimal totalAccPenalty = null;
|
||||||
if (scheduleAccrualData.getDueDatePenaltyIncome() != null) {
|
if (scheduleAccrualData.getDueDatePenaltyIncome() != null) {
|
||||||
penaltyportion = scheduleAccrualData.getDueDatePenaltyIncome();
|
penaltyPortion = scheduleAccrualData.getDueDatePenaltyIncome();
|
||||||
totalAccPenalty = penaltyportion;
|
totalAccPenalty = penaltyPortion;
|
||||||
if (scheduleAccrualData.getAccruedPenaltyIncome() != null) {
|
if (scheduleAccrualData.getAccruedPenaltyIncome() != null) {
|
||||||
penaltyportion = penaltyportion.subtract(scheduleAccrualData.getAccruedPenaltyIncome());
|
penaltyPortion = penaltyPortion.subtract(scheduleAccrualData.getAccruedPenaltyIncome());
|
||||||
}
|
}
|
||||||
amount = amount.add(penaltyportion);
|
amount = amount.add(penaltyPortion);
|
||||||
if (penaltyportion.compareTo(BigDecimal.ZERO) == 0) {
|
if (penaltyPortion.compareTo(BigDecimal.ZERO) == 0) {
|
||||||
penaltyportion = null;
|
penaltyPortion = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (amount.compareTo(BigDecimal.ZERO) > 0) {
|
if (amount.compareTo(BigDecimal.ZERO) > 0) {
|
||||||
addAccrualAccounting(scheduleAccrualData, amount, interestportion, totalAccInterest, feeportion, totalAccFee, penaltyportion,
|
addAccrualAccounting(scheduleAccrualData, amount, interestPortion, totalAccInterest, feePortion, totalAccFee, penaltyPortion,
|
||||||
totalAccPenalty, scheduleAccrualData.getDueDateAsLocaldate());
|
totalAccPenalty, scheduleAccrualData.getDueDateAsLocaldate());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addAccrualAccounting(LoanScheduleAccrualData scheduleAccrualData, BigDecimal amount, BigDecimal interestportion,
|
private void addAccrualAccounting(LoanScheduleAccrualData scheduleAccrualData, BigDecimal amount, BigDecimal interestPortion,
|
||||||
BigDecimal totalAccInterest, BigDecimal feeportion, BigDecimal totalAccFee, BigDecimal penaltyportion,
|
BigDecimal totalAccInterest, BigDecimal feePortion, BigDecimal totalAccFee, BigDecimal penaltyPortion,
|
||||||
BigDecimal totalAccPenalty, final LocalDate accruedTill) throws DataAccessException {
|
BigDecimal totalAccPenalty, final LocalDate accruedTill) throws DataAccessException {
|
||||||
|
AppUser user = context.authenticatedUser();
|
||||||
String transactionSql = "INSERT INTO m_loan_transaction (loan_id,office_id,is_reversed,transaction_type_enum,transaction_date,amount,interest_portion_derived,"
|
String transactionSql = "INSERT INTO m_loan_transaction (loan_id,office_id,is_reversed,transaction_type_enum,transaction_date,amount,interest_portion_derived,"
|
||||||
+ "fee_charges_portion_derived,penalty_charges_portion_derived, submitted_on_date) VALUES (?, ?, false, ?, ?, ?, ?, ?, ?, ?)";
|
+ "fee_charges_portion_derived,penalty_charges_portion_derived, submitted_on_date, created_by, last_modified_by, created_on_utc, last_modified_on_utc) "
|
||||||
|
+ "VALUES (?, ?, false, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
|
||||||
this.jdbcTemplate.update(transactionSql, scheduleAccrualData.getLoanId(), scheduleAccrualData.getOfficeId(),
|
this.jdbcTemplate.update(transactionSql, scheduleAccrualData.getLoanId(), scheduleAccrualData.getOfficeId(),
|
||||||
LoanTransactionType.ACCRUAL.getValue(), accruedTill, amount, interestportion, feeportion, penaltyportion,
|
LoanTransactionType.ACCRUAL.getValue(), accruedTill, amount, interestPortion, feePortion, penaltyPortion,
|
||||||
DateUtils.getBusinessLocalDate());
|
DateUtils.getBusinessLocalDate(), user.getId(), user.getId(), DateUtils.getOffsetDateTimeOfTenant(),
|
||||||
@SuppressWarnings("deprecation")
|
DateUtils.getOffsetDateTimeOfTenant());
|
||||||
final Long transactonId = this.jdbcTemplate.queryForObject("SELECT " + sqlGenerator.lastInsertId(), Long.class); // NOSONAR
|
final Long transactionId = this.jdbcTemplate.queryForObject("SELECT " + sqlGenerator.lastInsertId(), Long.class); // NOSONAR
|
||||||
|
|
||||||
Map<LoanChargeData, BigDecimal> applicableCharges = scheduleAccrualData.getApplicableCharges();
|
Map<LoanChargeData, BigDecimal> applicableCharges = scheduleAccrualData.getApplicableCharges();
|
||||||
String chargespaidSql = "INSERT INTO m_loan_charge_paid_by (loan_transaction_id, loan_charge_id, amount,installment_number) VALUES (?,?,?,?)";
|
String chargesPaidSql = "INSERT INTO m_loan_charge_paid_by (loan_transaction_id, loan_charge_id, amount,installment_number) VALUES (?,?,?,?)";
|
||||||
for (Map.Entry<LoanChargeData, BigDecimal> entry : applicableCharges.entrySet()) {
|
for (Map.Entry<LoanChargeData, BigDecimal> entry : applicableCharges.entrySet()) {
|
||||||
LoanChargeData chargeData = entry.getKey();
|
LoanChargeData chargeData = entry.getKey();
|
||||||
this.jdbcTemplate.update(chargespaidSql, transactonId, chargeData.getId(), entry.getValue(),
|
this.jdbcTemplate.update(chargesPaidSql, transactionId, chargeData.getId(), entry.getValue(),
|
||||||
scheduleAccrualData.getInstallmentNumber());
|
scheduleAccrualData.getInstallmentNumber());
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, Object> transactionMap = toMapData(transactonId, amount, interestportion, feeportion, penaltyportion,
|
Map<String, Object> transactionMap = toMapData(transactionId, amount, interestPortion, feePortion, penaltyPortion,
|
||||||
scheduleAccrualData, accruedTill);
|
scheduleAccrualData, accruedTill);
|
||||||
|
|
||||||
String repaymetUpdatesql = "UPDATE m_loan_repayment_schedule SET accrual_interest_derived=?, accrual_fee_charges_derived=?, "
|
String repaymentUpdateSql = "UPDATE m_loan_repayment_schedule SET accrual_interest_derived=?, accrual_fee_charges_derived=?, "
|
||||||
+ "accrual_penalty_charges_derived=? WHERE id=?";
|
+ "accrual_penalty_charges_derived=? WHERE id=?";
|
||||||
this.jdbcTemplate.update(repaymetUpdatesql, totalAccInterest, totalAccFee, totalAccPenalty,
|
this.jdbcTemplate.update(repaymentUpdateSql, totalAccInterest, totalAccFee, totalAccPenalty,
|
||||||
scheduleAccrualData.getRepaymentScheduleId());
|
scheduleAccrualData.getRepaymentScheduleId());
|
||||||
|
|
||||||
String updateLoan = "UPDATE m_loan SET accrued_till=? WHERE id=?";
|
String updateLoan = "UPDATE m_loan SET accrued_till=?, last_modified_by=?, last_modified_on_utc=? WHERE id=?";
|
||||||
this.jdbcTemplate.update(updateLoan, accruedTill, scheduleAccrualData.getLoanId());
|
this.jdbcTemplate.update(updateLoan, accruedTill, user.getId(), DateUtils.getOffsetDateTimeOfTenant(),
|
||||||
|
scheduleAccrualData.getLoanId());
|
||||||
final Map<String, Object> accountingBridgeData = deriveAccountingBridgeData(scheduleAccrualData, transactionMap);
|
final Map<String, Object> accountingBridgeData = deriveAccountingBridgeData(scheduleAccrualData, transactionMap);
|
||||||
this.journalEntryWritePlatformService.createJournalEntriesForLoan(accountingBridgeData);
|
this.journalEntryWritePlatformService.createJournalEntriesForLoan(accountingBridgeData);
|
||||||
}
|
}
|
||||||
@@ -301,9 +302,9 @@ public class LoanAccrualWritePlatformServiceImpl implements LoanAccrualWritePlat
|
|||||||
return accountingBridgeData;
|
return accountingBridgeData;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, Object> toMapData(final Long id, final BigDecimal amount, final BigDecimal interestportion,
|
public Map<String, Object> toMapData(final Long id, final BigDecimal amount, final BigDecimal interestPortion,
|
||||||
final BigDecimal feeportion, final BigDecimal penaltyportion, final LoanScheduleAccrualData loanScheduleAccrualData,
|
final BigDecimal feePortion, final BigDecimal penaltyPortion, final LoanScheduleAccrualData loanScheduleAccrualData,
|
||||||
final LocalDate accruredTill) {
|
final LocalDate accruedTill) {
|
||||||
final Map<String, Object> thisTransactionData = new LinkedHashMap<>();
|
final Map<String, Object> thisTransactionData = new LinkedHashMap<>();
|
||||||
|
|
||||||
final LoanTransactionEnumData transactionType = LoanEnumerations.transactionType(LoanTransactionType.ACCRUAL);
|
final LoanTransactionEnumData transactionType = LoanEnumerations.transactionType(LoanTransactionType.ACCRUAL);
|
||||||
@@ -312,13 +313,13 @@ public class LoanAccrualWritePlatformServiceImpl implements LoanAccrualWritePlat
|
|||||||
thisTransactionData.put("officeId", loanScheduleAccrualData.getOfficeId());
|
thisTransactionData.put("officeId", loanScheduleAccrualData.getOfficeId());
|
||||||
thisTransactionData.put("type", transactionType);
|
thisTransactionData.put("type", transactionType);
|
||||||
thisTransactionData.put("reversed", false);
|
thisTransactionData.put("reversed", false);
|
||||||
thisTransactionData.put("date", accruredTill);
|
thisTransactionData.put("date", accruedTill);
|
||||||
thisTransactionData.put("currency", loanScheduleAccrualData.getCurrencyData());
|
thisTransactionData.put("currency", loanScheduleAccrualData.getCurrencyData());
|
||||||
thisTransactionData.put("amount", amount);
|
thisTransactionData.put("amount", amount);
|
||||||
thisTransactionData.put("principalPortion", null);
|
thisTransactionData.put("principalPortion", null);
|
||||||
thisTransactionData.put("interestPortion", interestportion);
|
thisTransactionData.put("interestPortion", interestPortion);
|
||||||
thisTransactionData.put("feeChargesPortion", feeportion);
|
thisTransactionData.put("feeChargesPortion", feePortion);
|
||||||
thisTransactionData.put("penaltyChargesPortion", penaltyportion);
|
thisTransactionData.put("penaltyChargesPortion", penaltyPortion);
|
||||||
thisTransactionData.put("overPaymentPortion", null);
|
thisTransactionData.put("overPaymentPortion", null);
|
||||||
|
|
||||||
Map<LoanChargeData, BigDecimal> applicableCharges = loanScheduleAccrualData.getApplicableCharges();
|
Map<LoanChargeData, BigDecimal> applicableCharges = loanScheduleAccrualData.getApplicableCharges();
|
||||||
@@ -411,8 +412,8 @@ public class LoanAccrualWritePlatformServiceImpl implements LoanAccrualWritePlat
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void updateInterestIncome(final LoanScheduleAccrualData accrualData,
|
private void updateInterestIncome(final LoanScheduleAccrualData accrualData,
|
||||||
final Collection<LoanTransactionData> loanWaiverTansactions, final Collection<LoanSchedulePeriodData> loanSchedulePeriodDatas,
|
final Collection<LoanTransactionData> loanWaiverTransactions,
|
||||||
final LocalDate tilldate) {
|
final Collection<LoanSchedulePeriodData> loanSchedulePeriodDataList, final LocalDate tillDate) {
|
||||||
|
|
||||||
BigDecimal interestIncome = BigDecimal.ZERO;
|
BigDecimal interestIncome = BigDecimal.ZERO;
|
||||||
if (accrualData.getInterestIncome() != null) {
|
if (accrualData.getInterestIncome() != null) {
|
||||||
@@ -424,17 +425,17 @@ public class LoanAccrualWritePlatformServiceImpl implements LoanAccrualWritePlat
|
|||||||
BigDecimal remainingAmt = BigDecimal.ZERO;
|
BigDecimal remainingAmt = BigDecimal.ZERO;
|
||||||
Collection<LoanTransactionData> loanTransactionDatas = new ArrayList<>();
|
Collection<LoanTransactionData> loanTransactionDatas = new ArrayList<>();
|
||||||
|
|
||||||
for (LoanTransactionData loanTransactionData : loanWaiverTansactions) {
|
for (LoanTransactionData loanTransactionData : loanWaiverTransactions) {
|
||||||
if (!loanTransactionData.dateOf().isAfter(accrualData.getFromDateAsLocaldate())
|
if (!loanTransactionData.dateOf().isAfter(accrualData.getFromDateAsLocaldate())
|
||||||
|| (loanTransactionData.dateOf().isAfter(accrualData.getFromDateAsLocaldate())
|
|| (loanTransactionData.dateOf().isAfter(accrualData.getFromDateAsLocaldate())
|
||||||
&& !loanTransactionData.dateOf().isAfter(accrualData.getDueDateAsLocaldate())
|
&& !loanTransactionData.dateOf().isAfter(accrualData.getDueDateAsLocaldate())
|
||||||
&& !loanTransactionData.dateOf().isAfter(tilldate))) {
|
&& !loanTransactionData.dateOf().isAfter(tillDate))) {
|
||||||
loanTransactionDatas.add(loanTransactionData);
|
loanTransactionDatas.add(loanTransactionData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Iterator<LoanTransactionData> iterator = loanTransactionDatas.iterator();
|
Iterator<LoanTransactionData> iterator = loanTransactionDatas.iterator();
|
||||||
for (LoanSchedulePeriodData loanSchedulePeriodData : loanSchedulePeriodDatas) {
|
for (LoanSchedulePeriodData loanSchedulePeriodData : loanSchedulePeriodDataList) {
|
||||||
if (recognized.compareTo(BigDecimal.ZERO) <= 0 && unrecognized.compareTo(BigDecimal.ZERO) <= 0 && iterator.hasNext()) {
|
if (recognized.compareTo(BigDecimal.ZERO) <= 0 && unrecognized.compareTo(BigDecimal.ZERO) <= 0 && iterator.hasNext()) {
|
||||||
LoanTransactionData loanTransactionData = iterator.next();
|
LoanTransactionData loanTransactionData = iterator.next();
|
||||||
recognized = recognized.add(loanTransactionData.getInterestPortion());
|
recognized = recognized.add(loanTransactionData.getInterestPortion());
|
||||||
|
|||||||
@@ -42,4 +42,6 @@
|
|||||||
<include file="parts/0020_add_audit_entries.xml" relativeToChangelogFile="true"/>
|
<include file="parts/0020_add_audit_entries.xml" relativeToChangelogFile="true"/>
|
||||||
<include file="parts/0021_add_spring_batch_db_structure.xml" relativeToChangelogFile="true"/>
|
<include file="parts/0021_add_spring_batch_db_structure.xml" relativeToChangelogFile="true"/>
|
||||||
<include file="parts/0022_add_batch_business_step_configuration_table.xml" relativeToChangelogFile="true"/>
|
<include file="parts/0022_add_batch_business_step_configuration_table.xml" relativeToChangelogFile="true"/>
|
||||||
|
<include file="parts/0023_use_the_proper_date_or_datetime_type.xml" relativeToChangelogFile="true"/>
|
||||||
|
<include file="parts/0024_add_audit_entries.xml" relativeToChangelogFile="true"/>
|
||||||
</databaseChangeLog>
|
</databaseChangeLog>
|
||||||
|
|||||||
+41
@@ -0,0 +1,41 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
|
||||||
|
Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
or more contributor license agreements. See the NOTICE file
|
||||||
|
distributed with this work for additional information
|
||||||
|
regarding copyright ownership. The ASF licenses this file
|
||||||
|
to you under the Apache License, Version 2.0 (the
|
||||||
|
"License"); you may not use this file except in compliance
|
||||||
|
with the License. You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing,
|
||||||
|
software distributed under the License is distributed on an
|
||||||
|
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
KIND, either express or implied. See the License for the
|
||||||
|
specific language governing permissions and limitations
|
||||||
|
under the License.
|
||||||
|
|
||||||
|
-->
|
||||||
|
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.1.xsd">
|
||||||
|
|
||||||
|
<changeSet author="fineract" id="1">
|
||||||
|
<modifyDataType tableName="m_client_non_person" columnName="incorp_validity_till" newDataType="date"/>
|
||||||
|
<modifyDataType tableName="m_floating_rates_periods" columnName="from_date" newDataType="date"/>
|
||||||
|
<modifyDataType tableName="m_holiday" columnName="from_date" newDataType="date"/>
|
||||||
|
<modifyDataType tableName="m_holiday" columnName="to_date" newDataType="date"/>
|
||||||
|
<modifyDataType tableName="m_holiday" columnName="repayments_rescheduled_to" newDataType="date"/>
|
||||||
|
<modifyDataType tableName="m_loan_disbursement_detail" columnName="expected_disburse_date" newDataType="date"/>
|
||||||
|
<modifyDataType tableName="m_loan_disbursement_detail" columnName="disbursedon_date" newDataType="date"/>
|
||||||
|
<modifyDataType tableName="m_share_product" columnName="start_date" newDataType="date"/>
|
||||||
|
<modifyDataType tableName="m_share_product" columnName="end_date" newDataType="date"/>
|
||||||
|
<modifyDataType tableName="m_surveys" columnName="valid_from" newDataType="date"/>
|
||||||
|
<modifyDataType tableName="m_surveys" columnName="valid_to" newDataType="date"/>
|
||||||
|
</changeSet>
|
||||||
|
|
||||||
|
|
||||||
|
</databaseChangeLog>
|
||||||
+241
@@ -0,0 +1,241 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
|
||||||
|
Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
or more contributor license agreements. See the NOTICE file
|
||||||
|
distributed with this work for additional information
|
||||||
|
regarding copyright ownership. The ASF licenses this file
|
||||||
|
to you under the Apache License, Version 2.0 (the
|
||||||
|
"License"); you may not use this file except in compliance
|
||||||
|
with the License. You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing,
|
||||||
|
software distributed under the License is distributed on an
|
||||||
|
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
KIND, either express or implied. See the License for the
|
||||||
|
specific language governing permissions and limitations
|
||||||
|
under the License.
|
||||||
|
|
||||||
|
-->
|
||||||
|
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.1.xsd">
|
||||||
|
<!--Client-->
|
||||||
|
<changeSet id="client-4" author="fineract" context="mysql">
|
||||||
|
<preConditions onFail="MARK_RAN">
|
||||||
|
<sqlCheck expectedResult="0">select count(*) from m_client</sqlCheck>
|
||||||
|
</preConditions>
|
||||||
|
<addNotNullConstraint tableName="m_client" columnName="created_on_utc" columnDataType="DATETIME"/>
|
||||||
|
<addNotNullConstraint tableName="m_client" columnName="created_by" columnDataType="BIGINT"/>
|
||||||
|
<addNotNullConstraint tableName="m_client" columnName="last_modified_on_utc" columnDataType="DATETIME"/>
|
||||||
|
<addNotNullConstraint tableName="m_client" columnName="last_modified_by" columnDataType="BIGINT"/>
|
||||||
|
</changeSet>
|
||||||
|
<changeSet id="client-4" author="fineract" context="postgresql">
|
||||||
|
<preConditions onFail="MARK_RAN">
|
||||||
|
<sqlCheck expectedResult="0">select count(*) from m_client</sqlCheck>
|
||||||
|
</preConditions>
|
||||||
|
<addNotNullConstraint tableName="m_client" columnName="created_on_utc" columnDataType="TIMESTAMP WITH TIME ZONE"/>
|
||||||
|
<addNotNullConstraint tableName="m_client" columnName="created_by" columnDataType="BIGINT"/>
|
||||||
|
<addNotNullConstraint tableName="m_client" columnName="last_modified_on_utc" columnDataType="TIMESTAMP WITH TIME ZONE"/>
|
||||||
|
<addNotNullConstraint tableName="m_client" columnName="last_modified_by" columnDataType="BIGINT"/>
|
||||||
|
</changeSet>
|
||||||
|
<!--Loan-->
|
||||||
|
<changeSet id="loan-7" author="fineract" context="mysql">
|
||||||
|
<preConditions onFail="MARK_RAN">
|
||||||
|
<sqlCheck expectedResult="0">select count(*) from m_loan</sqlCheck>
|
||||||
|
</preConditions>
|
||||||
|
<addNotNullConstraint tableName="m_loan" columnName="created_on_utc" columnDataType="DATETIME"/>
|
||||||
|
<addNotNullConstraint tableName="m_loan" columnName="created_by" columnDataType="BIGINT"/>
|
||||||
|
<addNotNullConstraint tableName="m_loan" columnName="last_modified_on_utc" columnDataType="DATETIME"/>
|
||||||
|
<addNotNullConstraint tableName="m_loan" columnName="last_modified_by" columnDataType="BIGINT"/>
|
||||||
|
</changeSet>
|
||||||
|
<changeSet id="loan-7" author="fineract" context="postgresql">
|
||||||
|
<preConditions onFail="MARK_RAN">
|
||||||
|
<sqlCheck expectedResult="0">select count(*) from m_loan</sqlCheck>
|
||||||
|
</preConditions>
|
||||||
|
<addNotNullConstraint tableName="m_loan" columnName="created_on_utc" columnDataType="TIMESTAMP WITH TIME ZONE"/>
|
||||||
|
<addNotNullConstraint tableName="m_loan" columnName="created_by" columnDataType="BIGINT"/>
|
||||||
|
<addNotNullConstraint tableName="m_loan" columnName="last_modified_on_utc" columnDataType="TIMESTAMP WITH TIME ZONE"/>
|
||||||
|
<addNotNullConstraint tableName="m_loan" columnName="last_modified_by" columnDataType="BIGINT"/>
|
||||||
|
</changeSet>
|
||||||
|
<!-- Loan transactions -->
|
||||||
|
<changeSet id="loan-transaction-13" author="fineract" context="mysql">
|
||||||
|
<preConditions onFail="MARK_RAN">
|
||||||
|
<sqlCheck expectedResult="0">select count(*) from m_loan_transaction</sqlCheck>
|
||||||
|
</preConditions>
|
||||||
|
<addNotNullConstraint tableName="m_loan_transaction" columnName="created_on_utc" columnDataType="DATETIME"/>
|
||||||
|
<addNotNullConstraint tableName="m_loan_transaction" columnName="created_by" columnDataType="BIGINT"/>
|
||||||
|
<addNotNullConstraint tableName="m_loan_transaction" columnName="last_modified_on_utc" columnDataType="DATETIME"/>
|
||||||
|
<addNotNullConstraint tableName="m_loan_transaction" columnName="last_modified_by" columnDataType="BIGINT"/>
|
||||||
|
</changeSet>
|
||||||
|
<changeSet id="loan-transaction-13" author="fineract" context="postgresql">
|
||||||
|
<preConditions onFail="MARK_RAN">
|
||||||
|
<sqlCheck expectedResult="0">select count(*) from m_loan_transaction</sqlCheck>
|
||||||
|
</preConditions>
|
||||||
|
<addNotNullConstraint tableName="m_loan_transaction" columnName="created_on_utc" columnDataType="TIMESTAMP WITH TIME ZONE"/>
|
||||||
|
<addNotNullConstraint tableName="m_loan_transaction" columnName="created_by" columnDataType="BIGINT"/>
|
||||||
|
<addNotNullConstraint tableName="m_loan_transaction" columnName="last_modified_on_utc" columnDataType="TIMESTAMP WITH TIME ZONE"/>
|
||||||
|
<addNotNullConstraint tableName="m_loan_transaction" columnName="last_modified_by" columnDataType="BIGINT"/>
|
||||||
|
</changeSet>
|
||||||
|
<!-- Client transaction -->
|
||||||
|
<changeSet author="fineract" id="client-transaction-1" context="mysql">
|
||||||
|
<addColumn tableName="m_client_transaction">
|
||||||
|
<column name="created_on_utc" type="DATETIME"/>
|
||||||
|
<column name="created_by" type="BIGINT" valueComputed="appuser_id"/>
|
||||||
|
<column name="last_modified_by" type="BIGINT"/>
|
||||||
|
<column name="last_modified_on_utc" type="DATETIME"/>
|
||||||
|
</addColumn>
|
||||||
|
</changeSet>
|
||||||
|
<changeSet author="fineract" id="client-transaction-1" context="postgresql">
|
||||||
|
<addColumn tableName="m_client_transaction">
|
||||||
|
<column name="created_on_utc" type="TIMESTAMP WITH TIME ZONE"/>
|
||||||
|
<column name="created_by" type="BIGINT" valueComputed="appuser_id"/>
|
||||||
|
<column name="last_modified_by" type="BIGINT"/>
|
||||||
|
<column name="last_modified_on_utc" type="TIMESTAMP WITH TIME ZONE"/>
|
||||||
|
</addColumn>
|
||||||
|
</changeSet>
|
||||||
|
<changeSet id="client-transaction-2" author="fineract">
|
||||||
|
<addColumn tableName="m_client_transaction">
|
||||||
|
<column name="submitted_on_date" type="DATE" valueComputed="created_date">
|
||||||
|
<constraints nullable="false"/>
|
||||||
|
</column>
|
||||||
|
</addColumn>
|
||||||
|
</changeSet>
|
||||||
|
<changeSet author="fineract" id="client-transaction-3">
|
||||||
|
<addForeignKeyConstraint baseColumnNames="created_by" baseTableName="m_client_transaction"
|
||||||
|
constraintName="FK_client_transaction_created_by" deferrable="false" initiallyDeferred="false"
|
||||||
|
onDelete="RESTRICT" onUpdate="RESTRICT" referencedColumnNames="id"
|
||||||
|
referencedTableName="m_appuser" validate="true"/>
|
||||||
|
<addForeignKeyConstraint baseColumnNames="last_modified_by" baseTableName="m_client_transaction"
|
||||||
|
constraintName="FK_client_transaction_last_modified_by" deferrable="false" initiallyDeferred="false"
|
||||||
|
onDelete="RESTRICT" onUpdate="RESTRICT" referencedColumnNames="id"
|
||||||
|
referencedTableName="m_appuser" validate="true"/>
|
||||||
|
</changeSet>
|
||||||
|
<changeSet id="client-transaction-4" author="fineract">
|
||||||
|
<dropForeignKeyConstraint baseTableName="m_client_transaction" constraintName="FK_m_client_transaction_m_appuser"/>
|
||||||
|
<dropColumn tableName="m_client_transaction">
|
||||||
|
<column name="appuser_id"/>
|
||||||
|
</dropColumn>
|
||||||
|
</changeSet>
|
||||||
|
<changeSet id="client-transaction-5" author="fineract" context="mysql">
|
||||||
|
<preConditions onFail="MARK_RAN">
|
||||||
|
<sqlCheck expectedResult="0">select count(*) from m_client_transaction</sqlCheck>
|
||||||
|
</preConditions>
|
||||||
|
<addNotNullConstraint tableName="m_client_transaction" columnName="created_on_utc" columnDataType="DATETIME"/>
|
||||||
|
<addNotNullConstraint tableName="m_client_transaction" columnName="created_by" columnDataType="BIGINT"/>
|
||||||
|
<addNotNullConstraint tableName="m_client_transaction" columnName="last_modified_on_utc" columnDataType="DATETIME"/>
|
||||||
|
<addNotNullConstraint tableName="m_client_transaction" columnName="last_modified_by" columnDataType="BIGINT"/>
|
||||||
|
</changeSet>
|
||||||
|
<changeSet id="client-transaction-5" author="fineract" context="postgresql">
|
||||||
|
<preConditions onFail="MARK_RAN">
|
||||||
|
<sqlCheck expectedResult="0">select count(*) from m_client_transaction</sqlCheck>
|
||||||
|
</preConditions>
|
||||||
|
<addNotNullConstraint tableName="m_client_transaction" columnName="created_on_utc" columnDataType="TIMESTAMP WITH TIME ZONE"/>
|
||||||
|
<addNotNullConstraint tableName="m_client_transaction" columnName="created_by" columnDataType="BIGINT"/>
|
||||||
|
<addNotNullConstraint tableName="m_client_transaction" columnName="last_modified_on_utc" columnDataType="TIMESTAMP WITH TIME ZONE"/>
|
||||||
|
<addNotNullConstraint tableName="m_client_transaction" columnName="last_modified_by" columnDataType="BIGINT"/>
|
||||||
|
</changeSet>
|
||||||
|
<changeSet id="client-transaction-6" author="fineract">
|
||||||
|
<dropNotNullConstraint tableName="m_client_transaction" columnName="created_date" columnDataType="datetime"/>
|
||||||
|
</changeSet>
|
||||||
|
<!-- Floating rate -->
|
||||||
|
<changeSet author="fineract" id="floating-rate-1" context="mysql">
|
||||||
|
<addColumn tableName="m_floating_rates">
|
||||||
|
<column name="created_on_utc" type="DATETIME"/>
|
||||||
|
<column name="last_modified_on_utc" type="DATETIME"/>
|
||||||
|
</addColumn>
|
||||||
|
</changeSet>
|
||||||
|
<changeSet author="fineract" id="floating-rate-1" context="postgresql">
|
||||||
|
<addColumn tableName="m_floating_rates">
|
||||||
|
<column name="created_on_utc" type="TIMESTAMP WITH TIME ZONE"/>
|
||||||
|
<column name="last_modified_on_utc" type="TIMESTAMP WITH TIME ZONE"/>
|
||||||
|
</addColumn>
|
||||||
|
</changeSet>
|
||||||
|
<changeSet id="floating-rate-2" author="fineract">
|
||||||
|
<renameColumn tableName="m_floating_rates" oldColumnName="createdby_id" newColumnName="created_by" columnDataType="BIGINT"/>
|
||||||
|
<renameColumn tableName="m_floating_rates" oldColumnName="lastmodifiedby_id" newColumnName="last_modified_by" columnDataType="BIGINT"/>
|
||||||
|
</changeSet>
|
||||||
|
<changeSet author="fineract" id="floating-rate-3">
|
||||||
|
<addForeignKeyConstraint baseColumnNames="created_by" baseTableName="m_floating_rates"
|
||||||
|
constraintName="FK_floating_rates_created_by" deferrable="false" initiallyDeferred="false"
|
||||||
|
onDelete="RESTRICT" onUpdate="RESTRICT" referencedColumnNames="id"
|
||||||
|
referencedTableName="m_appuser" validate="true"/>
|
||||||
|
<addForeignKeyConstraint baseColumnNames="last_modified_by" baseTableName="m_floating_rates"
|
||||||
|
constraintName="FK_floating_rates_last_modified_by" deferrable="false" initiallyDeferred="false"
|
||||||
|
onDelete="RESTRICT" onUpdate="RESTRICT" referencedColumnNames="id"
|
||||||
|
referencedTableName="m_appuser" validate="true"/>
|
||||||
|
</changeSet>
|
||||||
|
<changeSet id="floating-rate-4" author="fineract" context="mysql">
|
||||||
|
<preConditions onFail="MARK_RAN">
|
||||||
|
<sqlCheck expectedResult="0">select count(*) from m_floating_rates</sqlCheck>
|
||||||
|
</preConditions>
|
||||||
|
<addNotNullConstraint tableName="m_floating_rates" columnName="created_on_utc" columnDataType="DATETIME"/>
|
||||||
|
<addNotNullConstraint tableName="m_floating_rates" columnName="created_by" columnDataType="BIGINT"/>
|
||||||
|
<addNotNullConstraint tableName="m_floating_rates" columnName="last_modified_on_utc" columnDataType="DATETIME"/>
|
||||||
|
<addNotNullConstraint tableName="m_floating_rates" columnName="last_modified_by" columnDataType="BIGINT"/>
|
||||||
|
</changeSet>
|
||||||
|
<changeSet id="floating-rate-4" author="fineract" context="postgresql">
|
||||||
|
<preConditions onFail="MARK_RAN">
|
||||||
|
<sqlCheck expectedResult="0">select count(*) from m_client_transaction</sqlCheck>
|
||||||
|
</preConditions>
|
||||||
|
<addNotNullConstraint tableName="m_floating_rates" columnName="created_on_utc" columnDataType="TIMESTAMP WITH TIME ZONE"/>
|
||||||
|
<addNotNullConstraint tableName="m_floating_rates" columnName="created_by" columnDataType="BIGINT"/>
|
||||||
|
<addNotNullConstraint tableName="m_floating_rates" columnName="last_modified_on_utc" columnDataType="TIMESTAMP WITH TIME ZONE"/>
|
||||||
|
<addNotNullConstraint tableName="m_floating_rates" columnName="last_modified_by" columnDataType="BIGINT"/>
|
||||||
|
</changeSet>
|
||||||
|
<changeSet id="floating-rate-5" author="fineract">
|
||||||
|
<dropNotNullConstraint tableName="m_floating_rates" columnName="created_date" columnDataType="datetime"/>
|
||||||
|
<dropNotNullConstraint tableName="m_floating_rates" columnName="lastmodified_date" columnDataType="datetime"/>
|
||||||
|
</changeSet>
|
||||||
|
<!-- Floating rates period -->
|
||||||
|
<changeSet author="fineract" id="floating-rate-period-1" context="mysql">
|
||||||
|
<addColumn tableName="m_floating_rates_periods">
|
||||||
|
<column name="created_on_utc" type="DATETIME"/>
|
||||||
|
<column name="last_modified_on_utc" type="DATETIME"/>
|
||||||
|
</addColumn>
|
||||||
|
</changeSet>
|
||||||
|
<changeSet author="fineract" id="floating-rate-period-1" context="postgresql">
|
||||||
|
<addColumn tableName="m_floating_rates_periods">
|
||||||
|
<column name="created_on_utc" type="TIMESTAMP WITH TIME ZONE"/>
|
||||||
|
<column name="last_modified_on_utc" type="TIMESTAMP WITH TIME ZONE"/>
|
||||||
|
</addColumn>
|
||||||
|
</changeSet>
|
||||||
|
<changeSet id="floating-rate-period-2" author="fineract">
|
||||||
|
<renameColumn tableName="m_floating_rates_periods" oldColumnName="createdby_id" newColumnName="created_by" columnDataType="BIGINT"/>
|
||||||
|
<renameColumn tableName="m_floating_rates_periods" oldColumnName="lastmodifiedby_id" newColumnName="last_modified_by" columnDataType="BIGINT"/>
|
||||||
|
</changeSet>
|
||||||
|
<changeSet author="fineract" id="floating-rate-period-3">
|
||||||
|
<addForeignKeyConstraint baseColumnNames="created_by" baseTableName="m_floating_rates_periods"
|
||||||
|
constraintName="FK_floating_rates_period_created_by" deferrable="false" initiallyDeferred="false"
|
||||||
|
onDelete="RESTRICT" onUpdate="RESTRICT" referencedColumnNames="id"
|
||||||
|
referencedTableName="m_appuser" validate="true"/>
|
||||||
|
<addForeignKeyConstraint baseColumnNames="last_modified_by" baseTableName="m_floating_rates_periods"
|
||||||
|
constraintName="FK_floating_rates_period_last_modified_by" deferrable="false" initiallyDeferred="false"
|
||||||
|
onDelete="RESTRICT" onUpdate="RESTRICT" referencedColumnNames="id"
|
||||||
|
referencedTableName="m_appuser" validate="true"/>
|
||||||
|
</changeSet>
|
||||||
|
<changeSet id="floating-rate-period-4" author="fineract" context="mysql">
|
||||||
|
<preConditions onFail="MARK_RAN">
|
||||||
|
<sqlCheck expectedResult="0">select count(*) from m_floating_rates_periods</sqlCheck>
|
||||||
|
</preConditions>
|
||||||
|
<addNotNullConstraint tableName="m_floating_rates_periods" columnName="created_on_utc" columnDataType="DATETIME"/>
|
||||||
|
<addNotNullConstraint tableName="m_floating_rates_periods" columnName="created_by" columnDataType="BIGINT"/>
|
||||||
|
<addNotNullConstraint tableName="m_floating_rates_periods" columnName="last_modified_on_utc" columnDataType="DATETIME"/>
|
||||||
|
<addNotNullConstraint tableName="m_floating_rates_periods" columnName="last_modified_by" columnDataType="BIGINT"/>
|
||||||
|
</changeSet>
|
||||||
|
<changeSet id="floating-rate-period-4" author="fineract" context="postgresql">
|
||||||
|
<preConditions onFail="MARK_RAN">
|
||||||
|
<sqlCheck expectedResult="0">select count(*) from m_floating_rates_periods</sqlCheck>
|
||||||
|
</preConditions>
|
||||||
|
<addNotNullConstraint tableName="m_floating_rates_periods" columnName="created_on_utc" columnDataType="TIMESTAMP WITH TIME ZONE"/>
|
||||||
|
<addNotNullConstraint tableName="m_floating_rates_periods" columnName="created_by" columnDataType="BIGINT"/>
|
||||||
|
<addNotNullConstraint tableName="m_floating_rates_periods" columnName="last_modified_on_utc" columnDataType="TIMESTAMP WITH TIME ZONE"/>
|
||||||
|
<addNotNullConstraint tableName="m_floating_rates_periods" columnName="last_modified_by" columnDataType="BIGINT"/>
|
||||||
|
</changeSet>
|
||||||
|
<changeSet id="floating-rate-period-5" author="fineract">
|
||||||
|
<dropNotNullConstraint tableName="m_floating_rates_periods" columnName="created_date" columnDataType="datetime"/>
|
||||||
|
<dropNotNullConstraint tableName="m_floating_rates_periods" columnName="lastmodified_date" columnDataType="datetime"/>
|
||||||
|
</changeSet>
|
||||||
|
</databaseChangeLog>
|
||||||
+38
-50
@@ -30,7 +30,10 @@ import java.math.BigDecimal;
|
|||||||
import java.math.RoundingMode;
|
import java.math.RoundingMode;
|
||||||
import java.text.DateFormat;
|
import java.text.DateFormat;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.time.LocalDate;
|
||||||
import java.time.ZonedDateTime;
|
import java.time.ZonedDateTime;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.time.format.DateTimeFormatterBuilder;
|
||||||
import java.time.temporal.ChronoUnit;
|
import java.time.temporal.ChronoUnit;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@@ -442,7 +445,7 @@ public class FixedDepositTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testFixedDepositAccountClosureTypeWithdrawal_WITH_HOLD_TAX() throws InterruptedException {
|
public void testFixedDepositAccountClosureTypeWithdrawal_WITH_HOLD_TAX() {
|
||||||
this.fixedDepositProductHelper = new FixedDepositProductHelper(this.requestSpec, this.responseSpec);
|
this.fixedDepositProductHelper = new FixedDepositProductHelper(this.requestSpec, this.responseSpec);
|
||||||
this.accountHelper = new AccountHelper(this.requestSpec, this.responseSpec);
|
this.accountHelper = new AccountHelper(this.requestSpec, this.responseSpec);
|
||||||
this.savingsAccountHelper = new SavingsAccountHelper(this.requestSpec, this.responseSpec);
|
this.savingsAccountHelper = new SavingsAccountHelper(this.requestSpec, this.responseSpec);
|
||||||
@@ -457,30 +460,23 @@ public class FixedDepositTest {
|
|||||||
final Account liabilityAccount = this.accountHelper.createLiabilityAccount();
|
final Account liabilityAccount = this.accountHelper.createLiabilityAccount();
|
||||||
final Account liabilityAccountForTax = this.accountHelper.createLiabilityAccount();
|
final Account liabilityAccountForTax = this.accountHelper.createLiabilityAccount();
|
||||||
|
|
||||||
DateFormat dateFormat = new SimpleDateFormat("dd MMMM yyyy", Locale.US);
|
DateTimeFormatter monthDayFormat = new DateTimeFormatterBuilder().appendPattern("dd MMM").toFormatter();
|
||||||
DateFormat monthDayFormat = new SimpleDateFormat("dd MMM", Locale.US);
|
DateTimeFormatter currentDateFormat = new DateTimeFormatterBuilder().appendPattern("dd").toFormatter();
|
||||||
DateFormat currentDateFormat = new SimpleDateFormat("dd");
|
|
||||||
|
|
||||||
Calendar todaysDate = Calendar.getInstance();
|
LocalDate todaysDate = Utils.getLocalDateOfTenant();
|
||||||
todaysDate.add(Calendar.MONTH, -20);
|
todaysDate = todaysDate.minusMonths(20);
|
||||||
final String VALID_FROM = dateFormat.format(todaysDate.getTime());
|
final String VALID_FROM = Utils.dateFormatter.format(todaysDate);
|
||||||
todaysDate.add(Calendar.YEAR, 10);
|
todaysDate = todaysDate.plusYears(10);
|
||||||
final String VALID_TO = dateFormat.format(todaysDate.getTime());
|
final String VALID_TO = Utils.dateFormatter.format(todaysDate);
|
||||||
|
|
||||||
todaysDate = Calendar.getInstance();
|
todaysDate = Utils.getLocalDateOfTenant();
|
||||||
todaysDate.add(Calendar.MONTH, -20);
|
todaysDate = todaysDate.minusMonths(20);
|
||||||
final String SUBMITTED_ON_DATE = dateFormat.format(todaysDate.getTime());
|
final String SUBMITTED_ON_DATE = Utils.dateFormatter.format(todaysDate);
|
||||||
final String APPROVED_ON_DATE = dateFormat.format(todaysDate.getTime());
|
final String APPROVED_ON_DATE = Utils.dateFormatter.format(todaysDate);
|
||||||
final String ACTIVATION_DATE = dateFormat.format(todaysDate.getTime());
|
final String ACTIVATION_DATE = Utils.dateFormatter.format(todaysDate);
|
||||||
monthDayFormat.format(todaysDate.getTime());
|
|
||||||
|
|
||||||
Integer currentDate = Integer.valueOf(currentDateFormat.format(todaysDate.getTime()));
|
LocalDate closedOn = todaysDate.plusMonths(14);
|
||||||
Integer daysInMonth = todaysDate.getActualMaximum(Calendar.DATE);
|
final String CLOSED_ON_DATE = Utils.dateFormatter.format(closedOn);
|
||||||
int numberOfDaysLeft = daysInMonth - currentDate + 1;
|
|
||||||
todaysDate.add(Calendar.DATE, numberOfDaysLeft);
|
|
||||||
Calendar closedOn = Calendar.getInstance();
|
|
||||||
closedOn.add(Calendar.MONTH, -6);
|
|
||||||
final String CLOSED_ON_DATE = dateFormat.format(closedOn.getTime());
|
|
||||||
|
|
||||||
Integer clientId = ClientHelper.createClient(requestSpec, responseSpec);
|
Integer clientId = ClientHelper.createClient(requestSpec, responseSpec);
|
||||||
Assertions.assertNotNull(clientId);
|
Assertions.assertNotNull(clientId);
|
||||||
@@ -1282,26 +1278,23 @@ public class FixedDepositTest {
|
|||||||
this.savingsAccountHelper = new SavingsAccountHelper(this.requestSpec, this.responseSpec);
|
this.savingsAccountHelper = new SavingsAccountHelper(this.requestSpec, this.responseSpec);
|
||||||
this.fixedDepositAccountHelper = new FixedDepositAccountHelper(this.requestSpec, this.responseSpec);
|
this.fixedDepositAccountHelper = new FixedDepositAccountHelper(this.requestSpec, this.responseSpec);
|
||||||
|
|
||||||
DateFormat dateFormat = new SimpleDateFormat("dd MMMM yyyy", Locale.US);
|
DateTimeFormatter dateFormat = Utils.dateFormatter;
|
||||||
DateFormat monthDayFormat = new SimpleDateFormat("dd MMM", Locale.US);
|
|
||||||
DateFormat currentDateFormat = new SimpleDateFormat("dd");
|
|
||||||
|
|
||||||
Calendar todaysDate = Calendar.getInstance();
|
LocalDate todaysDate = Utils.getLocalDateOfTenant();
|
||||||
todaysDate.add(Calendar.MONTH, -3);
|
todaysDate = todaysDate.minusMonths(3);
|
||||||
final String VALID_FROM = dateFormat.format(todaysDate.getTime());
|
final String VALID_FROM = dateFormat.format(todaysDate);
|
||||||
todaysDate.add(Calendar.YEAR, 10);
|
todaysDate = todaysDate.plusYears(10);
|
||||||
final String VALID_TO = dateFormat.format(todaysDate.getTime());
|
final String VALID_TO = dateFormat.format(todaysDate);
|
||||||
|
|
||||||
todaysDate = Calendar.getInstance();
|
todaysDate = Utils.getLocalDateOfTenant();
|
||||||
todaysDate.add(Calendar.MONTH, -1);
|
todaysDate = todaysDate.minusMonths(1);
|
||||||
todaysDate.add(Calendar.DAY_OF_MONTH, -1);
|
todaysDate = todaysDate.minusDays(1);
|
||||||
final String SUBMITTED_ON_DATE = dateFormat.format(todaysDate.getTime());
|
final String SUBMITTED_ON_DATE = dateFormat.format(todaysDate);
|
||||||
final String APPROVED_ON_DATE = dateFormat.format(todaysDate.getTime());
|
final String APPROVED_ON_DATE = dateFormat.format(todaysDate);
|
||||||
final String ACTIVATION_DATE = dateFormat.format(todaysDate.getTime());
|
final String ACTIVATION_DATE = dateFormat.format(todaysDate);
|
||||||
monthDayFormat.format(todaysDate.getTime());
|
|
||||||
todaysDate.add(Calendar.MONTH, 1);
|
todaysDate = Utils.getLocalDateOfTenant();
|
||||||
todaysDate.add(Calendar.DAY_OF_MONTH, 1);
|
final String CLOSED_ON_DATE = dateFormat.format(todaysDate);
|
||||||
final String CLOSED_ON_DATE = dateFormat.format(todaysDate.getTime());
|
|
||||||
|
|
||||||
Integer clientId = ClientHelper.createClient(this.requestSpec, this.responseSpec);
|
Integer clientId = ClientHelper.createClient(this.requestSpec, this.responseSpec);
|
||||||
Assertions.assertNotNull(clientId);
|
Assertions.assertNotNull(clientId);
|
||||||
@@ -1345,18 +1338,13 @@ public class FixedDepositTest {
|
|||||||
log.info("per day = {}", perDay);
|
log.info("per day = {}", perDay);
|
||||||
double interestPerDay = interestRateInFraction * perDay;
|
double interestPerDay = interestRateInFraction * perDay;
|
||||||
|
|
||||||
todaysDate.add(Calendar.MONTH, -1);
|
todaysDate = todaysDate.minusMonths(1);
|
||||||
todaysDate.add(Calendar.DAY_OF_MONTH, -1);
|
todaysDate = todaysDate.minusDays(1);
|
||||||
Integer currentDate = Integer.valueOf(currentDateFormat.format(todaysDate.getTime()));
|
|
||||||
Integer daysInMonth = todaysDate.getActualMaximum(Calendar.DATE);
|
Float interestPerMonth = (float) (interestPerDay * principal * ChronoUnit.DAYS.between(todaysDate, Utils.getLocalDateOfTenant()));
|
||||||
daysInMonth = daysInMonth - currentDate + 1;
|
|
||||||
Float interestPerMonth = (float) (interestPerDay * principal * daysInMonth);
|
|
||||||
principal += interestPerMonth;
|
principal += interestPerMonth;
|
||||||
todaysDate.add(Calendar.DATE, daysInMonth);
|
log.info("{}", Utils.dateFormatter.format(todaysDate));
|
||||||
log.info("{}", monthDayFormat.format(todaysDate.getTime()));
|
|
||||||
interestPerMonth = (float) (interestPerDay * principal * currentDate);
|
|
||||||
log.info("IPM = {}", interestPerMonth);
|
log.info("IPM = {}", interestPerMonth);
|
||||||
principal += interestPerMonth;
|
|
||||||
log.info("principal = {}", principal);
|
log.info("principal = {}", principal);
|
||||||
|
|
||||||
Integer transactionIdForPostInterest = this.fixedDepositAccountHelper.postInterestForFixedDeposit(fixedDepositAccountId);
|
Integer transactionIdForPostInterest = this.fixedDepositAccountHelper.postInterestForFixedDeposit(fixedDepositAccountId);
|
||||||
|
|||||||
Reference in New Issue
Block a user