This is an automated email from the ASF dual-hosted git repository.
arnold pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract.git
The following commit(s) were added to refs/heads/develop by this push:
new 65c6b18ed Fix inconsistenant Date and Date time handling
65c6b18ed is described below
commit 65c6b18ed13f4e208dec053e01b39e7d5e94928f
Author: Adam Saghy <[email protected]>
AuthorDate: Mon Aug 1 10:48:06 2022 +0200
Fix inconsistenant Date and Date time handling
---
.../AccrualAccountingWritePlatformServiceImpl.java | 4 +-
.../infrastructure/core/domain/JdbcSupport.java | 12 +
.../jobs/service/updatenpa/UpdateNpaConfig.java | 6 +-
.../jobs/service/updatenpa/UpdateNpaTasklet.java | 21 +-
.../portfolio/client/domain/ClientTransaction.java | 49 +++--
...hargeWritePlatformServiceJpaRepositoryImpl.java | 19 +-
.../ClientTransactionReadPlatformServiceImpl.java | 6 +-
.../floatingrates/data/FloatingRateData.java | 14 +-
.../floatingrates/data/FloatingRatePeriodData.java | 21 +-
.../floatingrates/domain/FloatingRate.java | 75 ++-----
.../floatingrates/domain/FloatingRatePeriod.java | 73 ++-----
.../FloatingRateWritePlatformServiceImpl.java | 14 +-
.../FloatingRatesReadPlatformServiceImpl.java | 30 ++-
.../AddAccrualEntriesTasklet.java | 12 +-
.../service/LoanAccrualPlatformServiceImpl.java | 20 +-
.../LoanAccrualWritePlatformServiceImpl.java | 211 +++++++++---------
.../db/changelog/tenant/changelog-tenant.xml | 2 +
.../0023_use_the_proper_date_or_datetime_type.xml | 41 ++++
.../tenant/parts/0024_add_audit_entries.xml | 241 +++++++++++++++++++++
.../integrationtests/FixedDepositTest.java | 88 ++++----
20 files changed, 595 insertions(+), 364 deletions(-)
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/accounting/accrual/service/AccrualAccountingWritePlatformServiceImpl.java
b/fineract-provider/src/main/java/org/apache/fineract/accounting/accrual/service/AccrualAccountingWritePlatformServiceImpl.java
index 3ce56a237..7856cf65e 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/accounting/accrual/service/AccrualAccountingWritePlatformServiceImpl.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/accounting/accrual/service/AccrualAccountingWritePlatformServiceImpl.java
@@ -46,9 +46,9 @@ public class AccrualAccountingWritePlatformServiceImpl
implements AccrualAccount
@Override
public CommandProcessingResult executeLoansPeriodicAccrual(JsonCommand
command) {
this.accountingDataValidator.validateLoanPeriodicAccrualData(command.json());
- LocalDate tilldate =
command.localDateValueOfParameterNamed(accrueTillParamName);
+ LocalDate tillDate =
command.localDateValueOfParameterNamed(accrueTillParamName);
try {
- this.loanAccrualPlatformService.addPeriodicAccruals(tilldate);
+ this.loanAccrualPlatformService.addPeriodicAccruals(tillDate);
} catch (MultiException e) {
final List<ApiParameterError> dataValidationErrors = new
ArrayList<>();
final DataValidatorBuilder baseDataValidator = new
DataValidatorBuilder(dataValidationErrors)
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/domain/JdbcSupport.java
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/domain/JdbcSupport.java
index 74728c2c3..2be81ae87 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/domain/JdbcSupport.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/domain/JdbcSupport.java
@@ -26,6 +26,8 @@ import java.sql.Timestamp;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
+import java.time.OffsetDateTime;
+import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import org.apache.fineract.infrastructure.core.service.DateUtils;
import org.springframework.jdbc.support.JdbcUtils;
@@ -133,4 +135,14 @@ public final class JdbcSupport {
}
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;
+ }
}
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/service/updatenpa/UpdateNpaConfig.java
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/service/updatenpa/UpdateNpaConfig.java
index 861537566..b0c72d164 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/service/updatenpa/UpdateNpaConfig.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/service/updatenpa/UpdateNpaConfig.java
@@ -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.DatabaseTypeResolver;
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.Step;
import
org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
@@ -46,6 +47,9 @@ public class UpdateNpaConfig {
@Autowired
private DatabaseSpecificSQLGenerator sqlGenerator;
+ @Autowired
+ private PlatformSecurityContext platformSecurityContext;
+
@Bean
protected Step updateNpaStep() {
return
steps.get(JobName.UPDATE_NPA.name()).tasklet(updateNpaTasklet()).build();
@@ -58,6 +62,6 @@ public class UpdateNpaConfig {
@Bean
public UpdateNpaTasklet updateNpaTasklet() {
- return new UpdateNpaTasklet(dataSourceServiceFactory,
databaseTypeResolver, sqlGenerator);
+ return new UpdateNpaTasklet(dataSourceServiceFactory,
databaseTypeResolver, sqlGenerator, platformSecurityContext);
}
}
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/service/updatenpa/UpdateNpaTasklet.java
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/service/updatenpa/UpdateNpaTasklet.java
index 60836514e..d2de9abae 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/service/updatenpa/UpdateNpaTasklet.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/service/updatenpa/UpdateNpaTasklet.java
@@ -20,10 +20,13 @@ package
org.apache.fineract.infrastructure.jobs.service.updatenpa;
import lombok.RequiredArgsConstructor;
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.ThreadLocalContextUtil;
import
org.apache.fineract.infrastructure.core.service.database.DatabaseSpecificSQLGenerator;
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.scope.context.ChunkContext;
import org.springframework.batch.core.step.tasklet.Tasklet;
@@ -37,9 +40,11 @@ public class UpdateNpaTasklet implements Tasklet {
private final RoutingDataSourceServiceFactory dataSourceServiceFactory;
private final DatabaseTypeResolver databaseTypeResolver;
private final DatabaseSpecificSQLGenerator sqlGenerator;
+ private final PlatformSecurityContext context;
@Override
public RepeatStatus execute(StepContribution contribution, ChunkContext
chunkContext) throws Exception {
+ AppUser user = context.getAuthenticatedUserIfPresent();
final JdbcTemplate jdbcTemplate = new
JdbcTemplate(dataSourceServiceFactory.determineDataSourceService().retrieveDataSource());
final StringBuilder resetNPASqlBuilder = new StringBuilder();
@@ -52,11 +57,13 @@ public class UpdateNpaTasklet implements Tasklet {
String wherePart = " where loan.id = sl.id ";
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 {
- 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);
@@ -68,12 +75,14 @@ public class UpdateNpaTasklet implements Tasklet {
wherePart = " where ml.id=sl.id ";
updateSqlBuilder.append("UPDATE m_loan as ml ");
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 {
- 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);
return RepeatStatus.FINISHED;
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/domain/ClientTransaction.java
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/domain/ClientTransaction.java
index 0023d9025..b292b521f 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/domain/ClientTransaction.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/domain/ClientTransaction.java
@@ -20,7 +20,6 @@ package org.apache.fineract.portfolio.client.domain;
import java.math.BigDecimal;
import java.time.LocalDate;
-import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedHashMap;
@@ -39,18 +38,17 @@ import javax.persistence.Transient;
import javax.persistence.UniqueConstraint;
import org.apache.fineract.accounting.glaccount.domain.GLAccount;
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.organisation.monetary.domain.MonetaryCurrency;
import org.apache.fineract.organisation.monetary.domain.Money;
import org.apache.fineract.organisation.office.domain.Office;
import org.apache.fineract.organisation.office.domain.OrganisationCurrency;
import org.apache.fineract.portfolio.paymentdetail.domain.PaymentDetail;
-import org.apache.fineract.useradministration.domain.AppUser;
@Entity
@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)
@JoinColumn(name = "client_id", nullable = false)
@@ -73,6 +71,9 @@ public class ClientTransaction extends
AbstractPersistableCustom {
@Column(name = "transaction_date", nullable = false)
private LocalDate dateOf;
+ @Column(name = "submitted_on_date", nullable = false)
+ private LocalDate submittedOnDate;
+
@Column(name = "amount", scale = 6, precision = 19, nullable = false)
private BigDecimal amount;
@@ -82,12 +83,11 @@ public class ClientTransaction extends
AbstractPersistableCustom {
@Column(name = "external_id", length = 100, nullable = true, unique = true)
private String externalId;
- @Column(name = "created_date", nullable = false)
- private LocalDateTime createdDate;
-
- @ManyToOne
- @JoinColumn(name = "appuser_id", nullable = true)
- private AppUser appUser;
+ /*
+ * Deprecated since common Auditable fields were introduced. Columns and
data left untouched to help migration.
+ *
+ * @Column(name = "created_date", nullable = false) private LocalDateTime
createdDate;
+ */
@OneToMany(cascade = CascadeType.ALL, mappedBy = "clientTransaction",
orphanRemoval = true, fetch = FetchType.EAGER)
private Set<ClientChargePaidBy> clientChargePaidByCollection = new
HashSet<>();
@@ -97,37 +97,36 @@ public class ClientTransaction extends
AbstractPersistableCustom {
protected ClientTransaction() {}
- public static ClientTransaction payCharge(final Client client, final
Office office, PaymentDetail paymentDetail, final LocalDate date,
- final Money amount, final String currencyCode, final AppUser
appUser) {
+ public static ClientTransaction payCharge(final Client client, final
Office office, PaymentDetail paymentDetail,
+ final LocalDate transactionDate, final Money amount, final String
currencyCode) {
final boolean isReversed = false;
final String externalId = null;
- return new ClientTransaction(client, office, paymentDetail,
ClientTransactionType.PAY_CHARGE.getValue(), date, amount, isReversed,
- externalId, DateUtils.getLocalDateTimeOfTenant(),
currencyCode, appUser);
+ return new ClientTransaction(client, office, paymentDetail,
ClientTransactionType.PAY_CHARGE.getValue(), transactionDate, amount,
+ isReversed, externalId, currencyCode);
}
- public static ClientTransaction waiver(final Client client, final Office
office, final LocalDate date, final Money amount,
- final String currencyCode, final AppUser appUser) {
+ public static ClientTransaction waiver(final Client client, final Office
office, final LocalDate transactionDate, final Money amount,
+ final String currencyCode) {
final boolean isReversed = false;
final String externalId = null;
final PaymentDetail paymentDetail = null;
- return new ClientTransaction(client, office, paymentDetail,
ClientTransactionType.WAIVE_CHARGE.getValue(), date, amount, isReversed,
- externalId, DateUtils.getLocalDateTimeOfTenant(),
currencyCode, appUser);
+ return new ClientTransaction(client, office, paymentDetail,
ClientTransactionType.WAIVE_CHARGE.getValue(), transactionDate, amount,
+ isReversed, externalId, currencyCode);
}
- public ClientTransaction(Client client, Office office, PaymentDetail
paymentDetail, Integer typeOf, LocalDate transactionLocalDate,
- Money amount, boolean reversed, String externalId, LocalDateTime
createdDate, String currencyCode, AppUser appUser) {
+ public ClientTransaction(Client client, Office office, PaymentDetail
paymentDetail, Integer typeOf, LocalDate transactionDate,
+ Money amount, boolean reversed, String externalId, String
currencyCode) {
this.client = client;
this.office = office;
this.paymentDetail = paymentDetail;
this.typeOf = typeOf;
- this.dateOf = transactionLocalDate;
+ this.dateOf = transactionDate;
this.amount = amount.getAmount();
this.reversed = reversed;
this.externalId = externalId;
- this.createdDate = createdDate;
this.currencyCode = currencyCode;
- this.appUser = appUser;
+ this.submittedOnDate = DateUtils.getBusinessLocalDate();
}
public void reverse() {
@@ -226,4 +225,8 @@ public class ClientTransaction extends
AbstractPersistableCustom {
return this.dateOf;
}
+ public LocalDate getSubmittedOnDate() {
+ return this.submittedOnDate;
+ }
+
}
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/service/ClientChargeWritePlatformServiceJpaRepositoryImpl.java
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/service/ClientChargeWritePlatformServiceJpaRepositoryImpl.java
index 8b3a65e17..f0133d0bc 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/service/ClientChargeWritePlatformServiceJpaRepositoryImpl.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/service/ClientChargeWritePlatformServiceJpaRepositoryImpl.java
@@ -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.paymentdetail.domain.PaymentDetail;
import
org.apache.fineract.portfolio.paymentdetail.service.PaymentDetailWritePlatformService;
-import org.apache.fineract.useradministration.domain.AppUser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@@ -174,7 +173,7 @@ public class
ClientChargeWritePlatformServiceJpaRepositoryImpl implements Client
final PaymentDetail paymentDetail =
this.paymentDetailWritePlatformService.createAndPersistPaymentDetail(command,
changes);
ClientTransaction clientTransaction =
ClientTransaction.payCharge(client, client.getOffice(), paymentDetail,
transactionDate,
- chargePaid, clientCharge.getCurrency().getCode(),
getAppUserIfPresent());
+ chargePaid, clientCharge.getCurrency().getCode());
this.clientTransactionRepository.saveAndFlush(clientTransaction);
// update charge paid by associations
@@ -217,7 +216,7 @@ public class
ClientChargeWritePlatformServiceJpaRepositoryImpl implements Client
// create Waiver Transaction
ClientTransaction clientTransaction =
ClientTransaction.waiver(client, client.getOffice(), transactionDate,
waivedAmount,
- clientCharge.getCurrency().getCode(),
getAppUserIfPresent());
+ clientCharge.getCurrency().getCode());
this.clientTransactionRepository.saveAndFlush(clientTransaction);
// 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
*
- * @param savingsAccountCharge
+ * @param transactionDate
+ * @param clientCharge
* @param fmt
*/
private void validateTransactionDateOnWorkingDay(final LocalDate
transactionDate, final ClientCharge clientCharge,
@@ -406,7 +406,8 @@ public class
ClientChargeWritePlatformServiceJpaRepositoryImpl implements Client
* @param date
* @param officeId
* @param jsonPropertyName
- * @param errorMessageFragment
+ * @param errorMessageFragmentForActivityOnHoliday
+ * @param errorMessageFragmentForActivityOnNonWorkingDay
* @param fmt
*/
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,
final Throwable realCause, final NonTransientDataAccessException
dve) {
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/service/ClientTransactionReadPlatformServiceImpl.java
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/service/ClientTransactionReadPlatformServiceImpl.java
index 5f9194de9..476c6aad9 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/service/ClientTransactionReadPlatformServiceImpl.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/service/ClientTransactionReadPlatformServiceImpl.java
@@ -68,7 +68,7 @@ public class ClientTransactionReadPlatformServiceImpl
implements ClientTransacti
final StringBuilder sqlBuilder = new StringBuilder(400);
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.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("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,
");
@@ -143,7 +143,7 @@ public class ClientTransactionReadPlatformServiceImpl
implements ClientTransacti
sqlBuilder.append("select " + sqlGenerator.calcFoundRows() + "
").append(this.clientTransactionMapper.schema())
.append(" where c.id = ? ");
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
@@ -169,7 +169,7 @@ public class ClientTransactionReadPlatformServiceImpl
implements ClientTransacti
sql = sql + " and ccpb.client_charge_id = ?";
}
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
}
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/floatingrates/data/FloatingRateData.java
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/floatingrates/data/FloatingRateData.java
index 5d88d25f7..f443a9d93 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/floatingrates/data/FloatingRateData.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/floatingrates/data/FloatingRateData.java
@@ -19,7 +19,7 @@
package org.apache.fineract.portfolio.floatingrates.data;
import java.io.Serializable;
-import java.time.LocalDate;
+import java.time.OffsetDateTime;
import java.util.List;
import org.apache.commons.lang3.builder.CompareToBuilder;
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 isActive;
private final String createdBy;
- private final LocalDate createdOn;
+ private final OffsetDateTime createdOn;
private final String modifiedBy;
- private final LocalDate modifiedOn;
+ private final OffsetDateTime modifiedOn;
private final List<FloatingRatePeriodData> ratePeriods;
@SuppressWarnings("unused")
private final List<EnumOptionData> interestRateFrequencyTypeOptions;
- public FloatingRateData(Long id, String name, boolean isBaseLendingRate,
boolean isActive, String createdBy, LocalDate createdOn,
- String modifiedBy, LocalDate modifiedOn,
List<FloatingRatePeriodData> ratePeriods,
+ public FloatingRateData(Long id, String name, boolean isBaseLendingRate,
boolean isActive, String createdBy, OffsetDateTime createdOn,
+ String modifiedBy, OffsetDateTime modifiedOn,
List<FloatingRatePeriodData> ratePeriods,
List<EnumOptionData> interestRateFrequencyTypeOptions) {
this.id = id;
this.name = name;
@@ -75,7 +75,7 @@ public class FloatingRateData implements
Comparable<FloatingRateData>, Serializa
return this.createdBy;
}
- public LocalDate getCreatedOn() {
+ public OffsetDateTime getCreatedOn() {
return this.createdOn;
}
@@ -83,7 +83,7 @@ public class FloatingRateData implements
Comparable<FloatingRateData>, Serializa
return this.modifiedBy;
}
- public LocalDate getModifiedOn() {
+ public OffsetDateTime getModifiedOn() {
return this.modifiedOn;
}
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/floatingrates/data/FloatingRatePeriodData.java
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/floatingrates/data/FloatingRatePeriodData.java
index fd2c14d78..93516f1a9 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/floatingrates/data/FloatingRatePeriodData.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/floatingrates/data/FloatingRatePeriodData.java
@@ -21,7 +21,7 @@ package org.apache.fineract.portfolio.floatingrates.data;
import java.io.Serializable;
import java.math.BigDecimal;
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.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
@@ -34,12 +34,12 @@ public class FloatingRatePeriodData implements
Comparable<FloatingRatePeriodData
private boolean isDifferentialToBaseLendingRate;
private boolean isActive;
private String createdBy;
- private LocalDateTime createdOn;
+ private OffsetDateTime createdOn;
private String modifiedBy;
- private LocalDateTime modifiedOn;
+ private OffsetDateTime modifiedOn;
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.fromDate = fromDate;
this.interestRate = interestRate;
@@ -51,6 +51,15 @@ public class FloatingRatePeriodData implements
Comparable<FloatingRatePeriodData
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() {
return this.id;
}
@@ -79,7 +88,7 @@ public class FloatingRatePeriodData implements
Comparable<FloatingRatePeriodData
return this.createdBy;
}
- public LocalDateTime getCreatedOn() {
+ public OffsetDateTime getCreatedOn() {
return this.createdOn;
}
@@ -87,7 +96,7 @@ public class FloatingRatePeriodData implements
Comparable<FloatingRatePeriodData
return this.modifiedBy;
}
- public LocalDateTime getModifiedOn() {
+ public OffsetDateTime getModifiedOn() {
return this.modifiedOn;
}
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/floatingrates/domain/FloatingRate.java
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/floatingrates/domain/FloatingRate.java
index a7e252f21..4fc93e6ba 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/floatingrates/domain/FloatingRate.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/floatingrates/domain/FloatingRate.java
@@ -23,7 +23,6 @@ import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import java.math.BigDecimal;
import java.time.LocalDate;
-import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
@@ -34,24 +33,20 @@ import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
-import javax.persistence.JoinColumn;
-import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OrderBy;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
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.service.DateUtils;
import org.apache.fineract.portfolio.floatingrates.data.FloatingRateDTO;
import org.apache.fineract.portfolio.floatingrates.data.FloatingRatePeriodData;
-import org.apache.fineract.useradministration.domain.AppUser;
-//TODO: refactor to use AbstractAuditableCustom!
@Entity
@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)
private String name;
@@ -66,34 +61,23 @@ public class FloatingRate extends AbstractPersistableCustom
{
@OneToMany(cascade = CascadeType.ALL, mappedBy = "floatingRate",
orphanRemoval = true, fetch = FetchType.EAGER)
private List<FloatingRatePeriod> floatingRatePeriods;
- @ManyToOne(optional = true, fetch = FetchType.LAZY)
- @JoinColumn(name = "createdby_id", nullable = false)
- private AppUser createdBy;
-
- @ManyToOne(optional = true, fetch = FetchType.LAZY)
- @JoinColumn(name = "lastmodifiedby_id", nullable = false)
- private AppUser modifiedBy;
-
- @Column(name = "created_date", nullable = false)
- private LocalDateTime createdOn;
-
- @Column(name = "lastmodified_date", nullable = false)
- private LocalDateTime modifiedOn;
+ /*
+ * Deprecated since common Auditable fields were introduced. Columns and
data left untouched to help migration.
+ *
+ * @Column(name = "created_date", nullable = false) private LocalDateTime
createdOn;
+ *
+ * @Column(name = "lastmodified_date", nullable = false) private
LocalDateTime modifiedOn;
+ */
public FloatingRate() {
}
- public FloatingRate(String name, boolean isBaseLendingRate, boolean
isActive, List<FloatingRatePeriod> floatingRatePeriods,
- AppUser createdBy, AppUser modifiedBy, LocalDateTime createdOn,
LocalDateTime modifiedOn) {
+ public FloatingRate(String name, boolean isBaseLendingRate, boolean
isActive, List<FloatingRatePeriod> floatingRatePeriods) {
this.name = name;
this.isBaseLendingRate = isBaseLendingRate;
this.isActive = isActive;
this.floatingRatePeriods = floatingRatePeriods;
- this.createdBy = createdBy;
- this.createdOn = createdOn;
- this.modifiedBy = modifiedBy;
- this.modifiedOn = modifiedOn;
if (floatingRatePeriods != null) {
for (FloatingRatePeriod ratePeriod : floatingRatePeriods) {
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 boolean isBaseLendingRate =
command.parameterExists("isBaseLendingRate")
?
command.booleanPrimitiveValueOfParameterNamed("isBaseLendingRate")
: false;
final boolean isActive = command.parameterExists("isActive") ?
command.booleanPrimitiveValueOfParameterNamed("isActive") : true;
- final List<FloatingRatePeriod> floatingRatePeriods =
getRatePeriods(currentUser, command);
- final LocalDateTime currentDate = DateUtils.getLocalDateTimeOfSystem();
+ final List<FloatingRatePeriod> floatingRatePeriods =
getRatePeriods(command);
- 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")) {
return null;
}
@@ -129,9 +112,7 @@ public class FloatingRate extends AbstractPersistableCustom
{
?
ratePeriodObject.get("isDifferentialToBaseLendingRate").getAsBoolean()
: false;
final boolean isActive = true;
- final LocalDateTime currentDate =
DateUtils.getLocalDateTimeOfSystem();
- ratePeriods.add(new FloatingRatePeriod(fromDate, interestRate,
isDifferentialToBaseLendingRate, isActive, currentUser,
- currentUser, currentDate, currentDate));
+ ratePeriods.add(new FloatingRatePeriod(fromDate, interestRate,
isDifferentialToBaseLendingRate, isActive));
}
return ratePeriods;
@@ -153,23 +134,7 @@ public class FloatingRate extends
AbstractPersistableCustom {
return this.floatingRatePeriods;
}
- public AppUser getCreatedBy() {
- 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) {
+ public Map<String, Object> update(final JsonCommand command) {
final Map<String, Object> actualChanges = new LinkedHashMap<>(9);
@@ -191,24 +156,22 @@ public class FloatingRate extends
AbstractPersistableCustom {
this.isActive = newValue;
}
- final List<FloatingRatePeriod> newRatePeriods =
getRatePeriods(appUser, command);
+ final List<FloatingRatePeriod> newRatePeriods =
getRatePeriods(command);
if (newRatePeriods != null && !newRatePeriods.isEmpty()) {
- updateRatePeriods(newRatePeriods, appUser);
+ updateRatePeriods(newRatePeriods);
actualChanges.put("ratePeriods",
command.jsonFragment("ratePeriods"));
}
return actualChanges;
}
- private void updateRatePeriods(final List<FloatingRatePeriod>
newRatePeriods, final AppUser appUser) {
+ private void updateRatePeriods(final List<FloatingRatePeriod>
newRatePeriods) {
final LocalDate today = DateUtils.getBusinessLocalDate();
if (this.floatingRatePeriods != null) {
for (FloatingRatePeriod ratePeriod : this.floatingRatePeriods) {
LocalDate fromDate = ratePeriod.getFromDate();
if (fromDate.isAfter(today)) {
ratePeriod.setActive(false);
- ratePeriod.setModifiedBy(appUser);
-
ratePeriod.setModifiedOn(DateUtils.getLocalDateTimeOfSystem());
}
}
}
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/floatingrates/domain/FloatingRatePeriod.java
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/floatingrates/domain/FloatingRatePeriod.java
index f85bd8be5..0e244f81f 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/floatingrates/domain/FloatingRatePeriod.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/floatingrates/domain/FloatingRatePeriod.java
@@ -20,22 +20,18 @@ package org.apache.fineract.portfolio.floatingrates.domain;
import java.math.BigDecimal;
import java.time.LocalDate;
-import java.time.LocalDateTime;
import javax.persistence.Column;
import javax.persistence.Entity;
-import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
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.FloatingRatePeriodData;
-import org.apache.fineract.useradministration.domain.AppUser;
-//TODO: refactor to use AbstractAuditableCustom!
@Entity
@Table(name = "m_floating_rates_periods")
-public class FloatingRatePeriod extends AbstractPersistableCustom {
+public class FloatingRatePeriod extends AbstractAuditableWithUTCDateTimeCustom
{
@ManyToOne
@JoinColumn(name = "floating_rates_id", nullable = false)
@@ -53,41 +49,30 @@ public class FloatingRatePeriod extends
AbstractPersistableCustom {
@Column(name = "is_active", nullable = false)
private boolean isActive;
- @ManyToOne(optional = true, fetch = FetchType.LAZY)
- @JoinColumn(name = "createdby_id", nullable = false)
- private AppUser createdBy;
-
- @ManyToOne(optional = true, fetch = FetchType.LAZY)
- @JoinColumn(name = "lastmodifiedby_id", nullable = false)
- private AppUser modifiedBy;
-
- @Column(name = "created_date", nullable = false)
- private LocalDateTime createdOn;
-
- @Column(name = "lastmodified_date", nullable = false)
- private LocalDateTime modifiedOn;
+ /*
+ * Deprecated since common Auditable fields were introduced. Columns and
data left untouched to help migration.
+ *
+ * @Column(name = "created_date", nullable = false) private LocalDateTime
createdOn;
+ *
+ * @Column(name = "lastmodified_date", nullable = false) private
LocalDateTime modifiedOn;
+ */
public FloatingRatePeriod() {
}
- public FloatingRatePeriod(LocalDate fromDate, BigDecimal interestRate,
boolean isDifferentialToBaseLendingRate, boolean isActive,
- AppUser createdBy, AppUser modifiedBy, LocalDateTime createdOn,
LocalDateTime modifiedOn) {
+ public FloatingRatePeriod(LocalDate fromDate, BigDecimal interestRate,
boolean isDifferentialToBaseLendingRate, boolean isActive) {
this.fromDate = fromDate;
this.interestRate = interestRate;
this.isDifferentialToBaseLendingRate = isDifferentialToBaseLendingRate;
this.isActive = isActive;
- this.createdBy = createdBy;
- this.modifiedBy = modifiedBy;
- this.createdOn = createdOn;
- this.modifiedOn = modifiedOn;
}
public void updateFloatingRate(FloatingRate floatingRate) {
this.floatingRate = floatingRate;
}
- public FloatingRate getFloatingRatesId() {
+ public FloatingRate getFloatingRate() {
return this.floatingRate;
}
@@ -107,32 +92,8 @@ public class FloatingRatePeriod extends
AbstractPersistableCustom {
return this.isActive;
}
- public AppUser getCreatedBy() {
- return this.createdBy;
- }
-
- 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 void setActive(boolean isActive) {
+ this.isActive = isActive;
}
public LocalDate fetchFromDate() {
@@ -147,13 +108,7 @@ public class FloatingRatePeriod extends
AbstractPersistableCustom {
}
final LocalDate fromDate = getFromDate();
- final LocalDateTime createdOn = getCreatedOn();
- 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);
+ return new FloatingRatePeriodData(getId(), fromDate, interest,
isDifferentialToBaseLendingRate(), isActive());
}
}
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/floatingrates/service/FloatingRateWritePlatformServiceImpl.java
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/floatingrates/service/FloatingRateWritePlatformServiceImpl.java
index fabba549c..730b27b07 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/floatingrates/service/FloatingRateWritePlatformServiceImpl.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/floatingrates/service/FloatingRateWritePlatformServiceImpl.java
@@ -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.CommandProcessingResultBuilder;
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.FloatingRateRepositoryWrapper;
import
org.apache.fineract.portfolio.floatingrates.serialization.FloatingRateDataValidator;
-import org.apache.fineract.useradministration.domain.AppUser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@@ -42,14 +40,12 @@ import
org.springframework.transaction.annotation.Transactional;
public class FloatingRateWritePlatformServiceImpl implements
FloatingRateWritePlatformService {
private static final Logger LOG =
LoggerFactory.getLogger(FloatingRateWritePlatformServiceImpl.class);
- private final PlatformSecurityContext context;
private final FloatingRateDataValidator fromApiJsonDeserializer;
private final FloatingRateRepositoryWrapper floatingRateRepository;
@Autowired
- public FloatingRateWritePlatformServiceImpl(final PlatformSecurityContext
context,
- final FloatingRateDataValidator fromApiJsonDeserializer, final
FloatingRateRepositoryWrapper floatingRateRepository) {
- this.context = context;
+ public FloatingRateWritePlatformServiceImpl(final
FloatingRateDataValidator fromApiJsonDeserializer,
+ final FloatingRateRepositoryWrapper floatingRateRepository) {
this.fromApiJsonDeserializer = fromApiJsonDeserializer;
this.floatingRateRepository = floatingRateRepository;
}
@@ -59,8 +55,7 @@ public class FloatingRateWritePlatformServiceImpl implements
FloatingRateWritePl
public CommandProcessingResult createFloatingRate(final JsonCommand
command) {
try {
this.fromApiJsonDeserializer.validateForCreate(command.json());
- final AppUser currentUser = this.context.authenticatedUser();
- final FloatingRate newFloatingRate =
FloatingRate.createNew(currentUser, command);
+ final FloatingRate newFloatingRate =
FloatingRate.createNew(command);
this.floatingRateRepository.saveAndFlush(newFloatingRate);
return new CommandProcessingResultBuilder() //
.withCommandId(command.commandId()) //
@@ -82,8 +77,7 @@ public class FloatingRateWritePlatformServiceImpl implements
FloatingRateWritePl
try {
final FloatingRate floatingRateForUpdate =
this.floatingRateRepository.findOneWithNotFoundDetection(command.entityId());
this.fromApiJsonDeserializer.validateForUpdate(command.json(),
floatingRateForUpdate);
- final AppUser currentUser = this.context.authenticatedUser();
- final Map<String, Object> changes =
floatingRateForUpdate.update(command, currentUser);
+ final Map<String, Object> changes =
floatingRateForUpdate.update(command);
if (!changes.isEmpty()) {
this.floatingRateRepository.save(floatingRateForUpdate);
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/floatingrates/service/FloatingRatesReadPlatformServiceImpl.java
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/floatingrates/service/FloatingRatesReadPlatformServiceImpl.java
index 7439a93c0..9d8bcea3a 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/floatingrates/service/FloatingRatesReadPlatformServiceImpl.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/floatingrates/service/FloatingRatesReadPlatformServiceImpl.java
@@ -24,8 +24,10 @@ import java.sql.ResultSet;
import java.sql.SQLException;
import java.time.LocalDate;
import java.time.LocalDateTime;
+import java.time.OffsetDateTime;
import java.util.List;
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.FloatingRatePeriodData;
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, ")
.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("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("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 isActive = rs.getBoolean("isActive");
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 LocalDate modifiedOn = JdbcSupport.getLocalDate(rs,
"modifiedOn");
+ final LocalDateTime modifiedOnLocal =
JdbcSupport.getLocalDateTime(rs, "modifiedOn");
+ final OffsetDateTime modifiedOnUtc =
JdbcSupport.getOffsetDateTime(rs, "modifiedOnUTC");
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) {
FloatingRatePeriodRowMapper ratePeriodMapper = new
FloatingRatePeriodRowMapper();
final String sql = "select " + ratePeriodMapper.schema()
@@ -146,8 +155,9 @@ public class FloatingRatesReadPlatformServiceImpl
implements FloatingRatesReadPl
.append("period.interest_rate as interestRate, ")
.append("period.is_differential_to_base_lending_rate as
isDifferentialToBaseLendingRate, ")
.append("period.is_active as isActive,
").append("crappu.username as createdBy, ")
- .append("period.created_date as createdOn,
").append("moappu.username as modifiedBy, ")
- .append("period.lastmodified_date as modifiedOn
").append("FROM m_floating_rates_periods as period ")
+ .append("period.created_date as createdOn,
").append("rate.created_on_utc as createdOnUTC, ")
+ .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 moappu on
period.lastmodifiedby_id = moappu.id ");
@@ -159,9 +169,15 @@ public class FloatingRatesReadPlatformServiceImpl
implements FloatingRatesReadPl
final boolean isDifferentialToBaseLendingRate =
rs.getBoolean("isDifferentialToBaseLendingRate");
final boolean isActive = rs.getBoolean("isActive");
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 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,
modifiedBy, modifiedOn);
}
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/jobs/addaccrualentries/AddAccrualEntriesTasklet.java
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/jobs/addaccrualentries/AddAccrualEntriesTasklet.java
index d5777093c..12be78e39 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/jobs/addaccrualentries/AddAccrualEntriesTasklet.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/jobs/addaccrualentries/AddAccrualEntriesTasklet.java
@@ -45,15 +45,15 @@ public class AddAccrualEntriesTasklet implements Tasklet {
@Override
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<>();
- for (final LoanScheduleAccrualData accrualData :
loanScheduleAccrualDatas) {
+ for (final LoanScheduleAccrualData accrualData :
loanScheduleAccrualDataList) {
if (loanDataMap.containsKey(accrualData.getLoanId())) {
loanDataMap.get(accrualData.getLoanId()).add(accrualData);
} else {
- Collection<LoanScheduleAccrualData> accrualDatas = new
ArrayList<>();
- accrualDatas.add(accrualData);
- loanDataMap.put(accrualData.getLoanId(), accrualDatas);
+ Collection<LoanScheduleAccrualData> accrualDataList = new
ArrayList<>();
+ accrualDataList.add(accrualData);
+ loanDataMap.put(accrualData.getLoanId(), accrualDataList);
}
}
@@ -62,7 +62,7 @@ public class AddAccrualEntriesTasklet implements Tasklet {
try {
loanAccrualWritePlatformService.addAccrualAccounting(mapEntry.getKey(),
mapEntry.getValue());
} 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);
}
}
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanAccrualPlatformServiceImpl.java
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanAccrualPlatformServiceImpl.java
index bdaf03a10..f181bd81f 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanAccrualPlatformServiceImpl.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanAccrualPlatformServiceImpl.java
@@ -39,31 +39,31 @@ public class LoanAccrualPlatformServiceImpl implements
LoanAccrualPlatformServic
private final LoanAccrualWritePlatformService
loanAccrualWritePlatformService;
@Override
- public void addPeriodicAccruals(final LocalDate tilldate) throws
JobExecutionException {
- Collection<LoanScheduleAccrualData> loanScheduleAccrualDatas =
this.loanReadPlatformService.retrivePeriodicAccrualData(tilldate);
- addPeriodicAccruals(tilldate, loanScheduleAccrualDatas);
+ public void addPeriodicAccruals(final LocalDate tillDate) throws
JobExecutionException {
+ Collection<LoanScheduleAccrualData> loanScheduleAccrualDataList =
this.loanReadPlatformService.retrivePeriodicAccrualData(tillDate);
+ addPeriodicAccruals(tillDate, loanScheduleAccrualDataList);
}
@Override
- public void addPeriodicAccruals(final LocalDate tilldate,
Collection<LoanScheduleAccrualData> loanScheduleAccrualDatas)
+ public void addPeriodicAccruals(final LocalDate tillDate,
Collection<LoanScheduleAccrualData> loanScheduleAccrualDataList)
throws JobExecutionException {
Map<Long, Collection<LoanScheduleAccrualData>> loanDataMap = new
HashMap<>();
- for (final LoanScheduleAccrualData accrualData :
loanScheduleAccrualDatas) {
+ for (final LoanScheduleAccrualData accrualData :
loanScheduleAccrualDataList) {
if (loanDataMap.containsKey(accrualData.getLoanId())) {
loanDataMap.get(accrualData.getLoanId()).add(accrualData);
} else {
- Collection<LoanScheduleAccrualData> accrualDatas = new
ArrayList<>();
- accrualDatas.add(accrualData);
- loanDataMap.put(accrualData.getLoanId(), accrualDatas);
+ Collection<LoanScheduleAccrualData> accrualDataList = new
ArrayList<>();
+ accrualDataList.add(accrualData);
+ loanDataMap.put(accrualData.getLoanId(), accrualDataList);
}
}
List<Throwable> errors = new ArrayList<>();
for (Map.Entry<Long, Collection<LoanScheduleAccrualData>> mapEntry :
loanDataMap.entrySet()) {
try {
-
this.loanAccrualWritePlatformService.addPeriodicAccruals(tilldate,
mapEntry.getKey(), mapEntry.getValue());
+
this.loanAccrualWritePlatformService.addPeriodicAccruals(tillDate,
mapEntry.getKey(), mapEntry.getValue());
} 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);
}
}
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanAccrualWritePlatformServiceImpl.java
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanAccrualWritePlatformServiceImpl.java
index 2042b7cc2..2f21fffdc 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanAccrualWritePlatformServiceImpl.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanAccrualWritePlatformServiceImpl.java
@@ -32,6 +32,7 @@ import lombok.RequiredArgsConstructor;
import
org.apache.fineract.accounting.journalentry.service.JournalEntryWritePlatformService;
import org.apache.fineract.infrastructure.core.service.DateUtils;
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.ApplicationCurrencyRepositoryWrapper;
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.loanschedule.data.LoanSchedulePeriodData;
import org.apache.fineract.portfolio.loanproduct.service.LoanEnumerations;
+import org.apache.fineract.useradministration.domain.AppUser;
import org.apache.fineract.useradministration.domain.AppUserRepositoryWrapper;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
@@ -63,63 +65,62 @@ public class LoanAccrualWritePlatformServiceImpl implements
LoanAccrualWritePlat
private final DatabaseSpecificSQLGenerator sqlGenerator;
private final JournalEntryWritePlatformService
journalEntryWritePlatformService;
private final AppUserRepositoryWrapper userRepository;
+ private final PlatformSecurityContext context;
private final LoanRepositoryWrapper loanRepositoryWrapper;
private final ApplicationCurrencyRepositoryWrapper
applicationCurrencyRepository;
@Override
@Transactional
- public void addAccrualAccounting(final Long loanId, final
Collection<LoanScheduleAccrualData> loanScheduleAccrualDatas)
- throws Exception {
+ public void addAccrualAccounting(final Long loanId, final
Collection<LoanScheduleAccrualData> loanScheduleAccrualData) {
Collection<LoanChargeData> chargeData =
this.loanChargeReadPlatformService.retrieveLoanChargesForAccural(loanId);
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()) {
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());
- updateInterestIncome(accrualData, loanWaiverTansactionData,
loanWaiverScheduleData, accrualData.getDueDateAsLocaldate());
+ updateInterestIncome(accrualData, loanWaiverTransactionData,
loanWaiverScheduleData, accrualData.getDueDateAsLocaldate());
addAccrualAccounting(accrualData);
}
}
@Override
@Transactional
- public void addPeriodicAccruals(final LocalDate tilldate, Long loanId,
Collection<LoanScheduleAccrualData> loanScheduleAccrualDatas)
- throws Exception {
+ public void addPeriodicAccruals(final LocalDate tillDate, Long loanId,
Collection<LoanScheduleAccrualData> loanScheduleAccrualData) {
boolean firstTime = true;
- LocalDate accruredTill = null;
+ LocalDate accruedTill = null;
Collection<LoanChargeData> chargeData =
this.loanChargeReadPlatformService.retrieveLoanChargesForAccural(loanId);
Collection<LoanSchedulePeriodData> loanWaiverScheduleData = new
ArrayList<>(1);
- Collection<LoanTransactionData> loanWaiverTansactionData = new
ArrayList<>(1);
- for (final LoanScheduleAccrualData accrualData :
loanScheduleAccrualDatas) {
+ Collection<LoanTransactionData> loanWaiverTransactionData = new
ArrayList<>(1);
+ for (final LoanScheduleAccrualData accrualData :
loanScheduleAccrualData) {
if (accrualData.getWaivedInterestIncome() != null &&
loanWaiverScheduleData.isEmpty()) {
loanWaiverScheduleData =
this.loanReadPlatformService.fetchWaiverInterestRepaymentData(accrualData.getLoanId());
- loanWaiverTansactionData =
this.loanReadPlatformService.retrieveWaiverLoanTransactions(accrualData.getLoanId());
+ loanWaiverTransactionData =
this.loanReadPlatformService.retrieveWaiverLoanTransactions(accrualData.getLoanId());
}
- if (accrualData.getDueDateAsLocaldate().isAfter(tilldate)) {
- if (accruredTill == null || firstTime) {
- accruredTill = accrualData.getAccruedTill();
+ if (accrualData.getDueDateAsLocaldate().isAfter(tillDate)) {
+ if (accruedTill == null || firstTime) {
+ accruedTill = accrualData.getAccruedTill();
firstTime = false;
}
- if (accruredTill == null || accruredTill.isBefore(tilldate)) {
- updateCharges(chargeData, accrualData,
accrualData.getFromDateAsLocaldate(), tilldate);
- updateInterestIncome(accrualData,
loanWaiverTansactionData, loanWaiverScheduleData, tilldate);
- addAccrualTillSpecificDate(tilldate, accrualData);
+ if (accruedTill == null || accruedTill.isBefore(tillDate)) {
+ updateCharges(chargeData, accrualData,
accrualData.getFromDateAsLocaldate(), tillDate);
+ updateInterestIncome(accrualData,
loanWaiverTransactionData, loanWaiverScheduleData, tillDate);
+ addAccrualTillSpecificDate(tillDate, accrualData);
}
} else {
updateCharges(chargeData, accrualData,
accrualData.getFromDateAsLocaldate(), accrualData.getDueDateAsLocaldate());
- updateInterestIncome(accrualData, loanWaiverTansactionData,
loanWaiverScheduleData, tilldate);
+ updateInterestIncome(accrualData, loanWaiverTransactionData,
loanWaiverScheduleData, tillDate);
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();
if (accrualData.getInterestCalculatedFrom() != null
&&
accrualData.getFromDateAsLocaldate().isBefore(accrualData.getInterestCalculatedFrom()))
{
@@ -133,150 +134,150 @@ public class LoanAccrualWritePlatformServiceImpl
implements LoanAccrualWritePlat
int totalNumberOfDays =
Math.toIntExact(ChronoUnit.DAYS.between(interestStartDate,
accrualData.getDueDateAsLocaldate()));
LocalDate startDate = accrualData.getFromDateAsLocaldate();
if (accrualData.getInterestCalculatedFrom() != null &&
startDate.isBefore(accrualData.getInterestCalculatedFrom())) {
- if (accrualData.getInterestCalculatedFrom().isBefore(tilldate)) {
+ if (accrualData.getInterestCalculatedFrom().isBefore(tillDate)) {
startDate = accrualData.getInterestCalculatedFrom();
} 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;
BigDecimal amount = BigDecimal.ZERO;
- BigDecimal interestportion = null;
- BigDecimal feeportion = accrualData.getDueDateFeeIncome();
- BigDecimal penaltyportion = accrualData.getDueDatePenaltyIncome();
+ BigDecimal interestPortion;
+ BigDecimal feePortion = accrualData.getDueDateFeeIncome();
+ BigDecimal penaltyPortion = accrualData.getDueDatePenaltyIncome();
if (daysToBeAccrued >= totalNumberOfDays) {
- interestportion = accrualData.getAccruableIncome();
+ interestPortion = accrualData.getAccruableIncome();
} else {
- double iterest = interestPerDay * daysToBeAccrued;
- interestportion = BigDecimal.valueOf(iterest);
+ interestPortion = BigDecimal.valueOf(interestPerDay *
daysToBeAccrued);
}
- interestportion =
interestportion.setScale(accrualData.getCurrencyData().decimalPlaces(),
MoneyHelper.getRoundingMode());
+ interestPortion =
interestPortion.setScale(accrualData.getCurrencyData().decimalPlaces(),
MoneyHelper.getRoundingMode());
BigDecimal totalAccInterest = accrualData.getAccruedInterestIncome();
BigDecimal totalAccPenalty = accrualData.getAccruedPenaltyIncome();
BigDecimal totalAccFee = accrualData.getAccruedFeeIncome();
- if (interestportion != null) {
- if (totalAccInterest == null) {
- totalAccInterest = BigDecimal.ZERO;
- }
- interestportion = interestportion.subtract(totalAccInterest);
- amount = amount.add(interestportion);
- totalAccInterest = totalAccInterest.add(interestportion);
- if (interestportion.compareTo(BigDecimal.ZERO) == 0) {
- interestportion = null;
- }
+ if (totalAccInterest == null) {
+ 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) {
+ if (feePortion != null) {
if (totalAccFee == null) {
totalAccFee = BigDecimal.ZERO;
}
- feeportion = feeportion.subtract(totalAccFee);
- amount = amount.add(feeportion);
- totalAccFee = totalAccFee.add(feeportion);
- if (feeportion.compareTo(BigDecimal.ZERO) == 0) {
- feeportion = null;
+ feePortion = feePortion.subtract(totalAccFee);
+ amount = amount.add(feePortion);
+ totalAccFee = totalAccFee.add(feePortion);
+ if (feePortion.compareTo(BigDecimal.ZERO) == 0) {
+ feePortion = null;
}
}
- if (penaltyportion != null) {
+ if (penaltyPortion != null) {
if (totalAccPenalty == null) {
totalAccPenalty = BigDecimal.ZERO;
}
- penaltyportion = penaltyportion.subtract(totalAccPenalty);
- amount = amount.add(penaltyportion);
- totalAccPenalty = totalAccPenalty.add(penaltyportion);
- if (penaltyportion.compareTo(BigDecimal.ZERO) == 0) {
- penaltyportion = null;
+ penaltyPortion = penaltyPortion.subtract(totalAccPenalty);
+ amount = amount.add(penaltyPortion);
+ totalAccPenalty = totalAccPenalty.add(penaltyPortion);
+ if (penaltyPortion.compareTo(BigDecimal.ZERO) == 0) {
+ penaltyPortion = null;
}
}
if (amount.compareTo(BigDecimal.ZERO) > 0) {
- addAccrualAccounting(accrualData, amount, interestportion,
totalAccInterest, feeportion, totalAccFee, penaltyportion,
- totalAccPenalty, tilldate);
+ addAccrualAccounting(accrualData, amount, interestPortion,
totalAccInterest, feePortion, totalAccFee, penaltyPortion,
+ totalAccPenalty, tillDate);
}
}
@Transactional
- public void addAccrualAccounting(LoanScheduleAccrualData
scheduleAccrualData) throws Exception {
+ public void addAccrualAccounting(LoanScheduleAccrualData
scheduleAccrualData) {
BigDecimal amount = BigDecimal.ZERO;
- BigDecimal interestportion = null;
+ BigDecimal interestPortion = null;
BigDecimal totalAccInterest = null;
if (scheduleAccrualData.getAccruableIncome() != null) {
- interestportion = scheduleAccrualData.getAccruableIncome();
- totalAccInterest = interestportion;
+ interestPortion = scheduleAccrualData.getAccruableIncome();
+ totalAccInterest = interestPortion;
if (scheduleAccrualData.getAccruedInterestIncome() != null) {
- interestportion =
interestportion.subtract(scheduleAccrualData.getAccruedInterestIncome());
+ interestPortion =
interestPortion.subtract(scheduleAccrualData.getAccruedInterestIncome());
}
- amount = amount.add(interestportion);
- if (interestportion.compareTo(BigDecimal.ZERO) == 0) {
- interestportion = null;
+ amount = amount.add(interestPortion);
+ if (interestPortion.compareTo(BigDecimal.ZERO) == 0) {
+ interestPortion = null;
}
}
- BigDecimal feeportion = null;
+ BigDecimal feePortion = null;
BigDecimal totalAccFee = null;
if (scheduleAccrualData.getDueDateFeeIncome() != null) {
- feeportion = scheduleAccrualData.getDueDateFeeIncome();
- totalAccFee = feeportion;
+ feePortion = scheduleAccrualData.getDueDateFeeIncome();
+ totalAccFee = feePortion;
if (scheduleAccrualData.getAccruedFeeIncome() != null) {
- feeportion =
feeportion.subtract(scheduleAccrualData.getAccruedFeeIncome());
+ feePortion =
feePortion.subtract(scheduleAccrualData.getAccruedFeeIncome());
}
- amount = amount.add(feeportion);
- if (feeportion.compareTo(BigDecimal.ZERO) == 0) {
- feeportion = null;
+ amount = amount.add(feePortion);
+ if (feePortion.compareTo(BigDecimal.ZERO) == 0) {
+ feePortion = null;
}
}
- BigDecimal penaltyportion = null;
+ BigDecimal penaltyPortion = null;
BigDecimal totalAccPenalty = null;
if (scheduleAccrualData.getDueDatePenaltyIncome() != null) {
- penaltyportion = scheduleAccrualData.getDueDatePenaltyIncome();
- totalAccPenalty = penaltyportion;
+ penaltyPortion = scheduleAccrualData.getDueDatePenaltyIncome();
+ totalAccPenalty = penaltyPortion;
if (scheduleAccrualData.getAccruedPenaltyIncome() != null) {
- penaltyportion =
penaltyportion.subtract(scheduleAccrualData.getAccruedPenaltyIncome());
+ penaltyPortion =
penaltyPortion.subtract(scheduleAccrualData.getAccruedPenaltyIncome());
}
- amount = amount.add(penaltyportion);
- if (penaltyportion.compareTo(BigDecimal.ZERO) == 0) {
- penaltyportion = null;
+ amount = amount.add(penaltyPortion);
+ if (penaltyPortion.compareTo(BigDecimal.ZERO) == 0) {
+ penaltyPortion = null;
}
}
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());
}
}
- private void addAccrualAccounting(LoanScheduleAccrualData
scheduleAccrualData, BigDecimal amount, BigDecimal interestportion,
- BigDecimal totalAccInterest, BigDecimal feeportion, BigDecimal
totalAccFee, BigDecimal penaltyportion,
+ private void addAccrualAccounting(LoanScheduleAccrualData
scheduleAccrualData, BigDecimal amount, BigDecimal interestPortion,
+ BigDecimal totalAccInterest, BigDecimal feePortion, BigDecimal
totalAccFee, BigDecimal penaltyPortion,
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,"
- +
"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(),
- LoanTransactionType.ACCRUAL.getValue(), accruedTill, amount,
interestportion, feeportion, penaltyportion,
- DateUtils.getBusinessLocalDate());
- @SuppressWarnings("deprecation")
- final Long transactonId = this.jdbcTemplate.queryForObject("SELECT " +
sqlGenerator.lastInsertId(), Long.class); // NOSONAR
+ LoanTransactionType.ACCRUAL.getValue(), accruedTill, amount,
interestPortion, feePortion, penaltyPortion,
+ DateUtils.getBusinessLocalDate(), user.getId(), user.getId(),
DateUtils.getOffsetDateTimeOfTenant(),
+ DateUtils.getOffsetDateTimeOfTenant());
+ final Long transactionId = this.jdbcTemplate.queryForObject("SELECT "
+ sqlGenerator.lastInsertId(), Long.class); // NOSONAR
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()) {
LoanChargeData chargeData = entry.getKey();
- this.jdbcTemplate.update(chargespaidSql, transactonId,
chargeData.getId(), entry.getValue(),
+ this.jdbcTemplate.update(chargesPaidSql, transactionId,
chargeData.getId(), entry.getValue(),
scheduleAccrualData.getInstallmentNumber());
}
- Map<String, Object> transactionMap = toMapData(transactonId, amount,
interestportion, feeportion, penaltyportion,
+ Map<String, Object> transactionMap = toMapData(transactionId, amount,
interestPortion, feePortion, penaltyPortion,
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=?";
- this.jdbcTemplate.update(repaymetUpdatesql, totalAccInterest,
totalAccFee, totalAccPenalty,
+ this.jdbcTemplate.update(repaymentUpdateSql, totalAccInterest,
totalAccFee, totalAccPenalty,
scheduleAccrualData.getRepaymentScheduleId());
- String updateLoan = "UPDATE m_loan SET accrued_till=? WHERE id=?";
- this.jdbcTemplate.update(updateLoan, accruedTill,
scheduleAccrualData.getLoanId());
+ String updateLoan = "UPDATE m_loan SET accrued_till=?,
last_modified_by=?, last_modified_on_utc=? WHERE id=?";
+ this.jdbcTemplate.update(updateLoan, accruedTill, user.getId(),
DateUtils.getOffsetDateTimeOfTenant(),
+ scheduleAccrualData.getLoanId());
final Map<String, Object> accountingBridgeData =
deriveAccountingBridgeData(scheduleAccrualData, transactionMap);
this.journalEntryWritePlatformService.createJournalEntriesForLoan(accountingBridgeData);
}
@@ -301,9 +302,9 @@ public class LoanAccrualWritePlatformServiceImpl implements
LoanAccrualWritePlat
return accountingBridgeData;
}
- public Map<String, Object> toMapData(final Long id, final BigDecimal
amount, final BigDecimal interestportion,
- final BigDecimal feeportion, final BigDecimal penaltyportion,
final LoanScheduleAccrualData loanScheduleAccrualData,
- final LocalDate accruredTill) {
+ public Map<String, Object> toMapData(final Long id, final BigDecimal
amount, final BigDecimal interestPortion,
+ final BigDecimal feePortion, final BigDecimal penaltyPortion,
final LoanScheduleAccrualData loanScheduleAccrualData,
+ final LocalDate accruedTill) {
final Map<String, Object> thisTransactionData = new LinkedHashMap<>();
final LoanTransactionEnumData transactionType =
LoanEnumerations.transactionType(LoanTransactionType.ACCRUAL);
@@ -312,13 +313,13 @@ public class LoanAccrualWritePlatformServiceImpl
implements LoanAccrualWritePlat
thisTransactionData.put("officeId",
loanScheduleAccrualData.getOfficeId());
thisTransactionData.put("type", transactionType);
thisTransactionData.put("reversed", false);
- thisTransactionData.put("date", accruredTill);
+ thisTransactionData.put("date", accruedTill);
thisTransactionData.put("currency",
loanScheduleAccrualData.getCurrencyData());
thisTransactionData.put("amount", amount);
thisTransactionData.put("principalPortion", null);
- thisTransactionData.put("interestPortion", interestportion);
- thisTransactionData.put("feeChargesPortion", feeportion);
- thisTransactionData.put("penaltyChargesPortion", penaltyportion);
+ thisTransactionData.put("interestPortion", interestPortion);
+ thisTransactionData.put("feeChargesPortion", feePortion);
+ thisTransactionData.put("penaltyChargesPortion", penaltyPortion);
thisTransactionData.put("overPaymentPortion", null);
Map<LoanChargeData, BigDecimal> applicableCharges =
loanScheduleAccrualData.getApplicableCharges();
@@ -411,8 +412,8 @@ public class LoanAccrualWritePlatformServiceImpl implements
LoanAccrualWritePlat
}
private void updateInterestIncome(final LoanScheduleAccrualData
accrualData,
- final Collection<LoanTransactionData> loanWaiverTansactions, final
Collection<LoanSchedulePeriodData> loanSchedulePeriodDatas,
- final LocalDate tilldate) {
+ final Collection<LoanTransactionData> loanWaiverTransactions,
+ final Collection<LoanSchedulePeriodData>
loanSchedulePeriodDataList, final LocalDate tillDate) {
BigDecimal interestIncome = BigDecimal.ZERO;
if (accrualData.getInterestIncome() != null) {
@@ -424,17 +425,17 @@ public class LoanAccrualWritePlatformServiceImpl
implements LoanAccrualWritePlat
BigDecimal remainingAmt = BigDecimal.ZERO;
Collection<LoanTransactionData> loanTransactionDatas = new
ArrayList<>();
- for (LoanTransactionData loanTransactionData :
loanWaiverTansactions) {
+ for (LoanTransactionData loanTransactionData :
loanWaiverTransactions) {
if
(!loanTransactionData.dateOf().isAfter(accrualData.getFromDateAsLocaldate())
||
(loanTransactionData.dateOf().isAfter(accrualData.getFromDateAsLocaldate())
&&
!loanTransactionData.dateOf().isAfter(accrualData.getDueDateAsLocaldate())
- &&
!loanTransactionData.dateOf().isAfter(tilldate))) {
+ &&
!loanTransactionData.dateOf().isAfter(tillDate))) {
loanTransactionDatas.add(loanTransactionData);
}
}
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()) {
LoanTransactionData loanTransactionData = iterator.next();
recognized =
recognized.add(loanTransactionData.getInterestPortion());
diff --git
a/fineract-provider/src/main/resources/db/changelog/tenant/changelog-tenant.xml
b/fineract-provider/src/main/resources/db/changelog/tenant/changelog-tenant.xml
index 7f3d90b79..cb283230e 100644
---
a/fineract-provider/src/main/resources/db/changelog/tenant/changelog-tenant.xml
+++
b/fineract-provider/src/main/resources/db/changelog/tenant/changelog-tenant.xml
@@ -42,4 +42,6 @@
<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/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>
diff --git
a/fineract-provider/src/main/resources/db/changelog/tenant/parts/0023_use_the_proper_date_or_datetime_type.xml
b/fineract-provider/src/main/resources/db/changelog/tenant/parts/0023_use_the_proper_date_or_datetime_type.xml
new file mode 100644
index 000000000..2a2ea0562
--- /dev/null
+++
b/fineract-provider/src/main/resources/db/changelog/tenant/parts/0023_use_the_proper_date_or_datetime_type.xml
@@ -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>
diff --git
a/fineract-provider/src/main/resources/db/changelog/tenant/parts/0024_add_audit_entries.xml
b/fineract-provider/src/main/resources/db/changelog/tenant/parts/0024_add_audit_entries.xml
new file mode 100644
index 000000000..739751d04
--- /dev/null
+++
b/fineract-provider/src/main/resources/db/changelog/tenant/parts/0024_add_audit_entries.xml
@@ -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>
diff --git
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/FixedDepositTest.java
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/FixedDepositTest.java
index 63e5a5f69..fd4bc8036 100644
---
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/FixedDepositTest.java
+++
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/FixedDepositTest.java
@@ -30,7 +30,10 @@ import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
+import java.time.LocalDate;
import java.time.ZonedDateTime;
+import java.time.format.DateTimeFormatter;
+import java.time.format.DateTimeFormatterBuilder;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.Arrays;
@@ -442,7 +445,7 @@ public class FixedDepositTest {
}
@Test
- public void testFixedDepositAccountClosureTypeWithdrawal_WITH_HOLD_TAX()
throws InterruptedException {
+ public void testFixedDepositAccountClosureTypeWithdrawal_WITH_HOLD_TAX() {
this.fixedDepositProductHelper = new
FixedDepositProductHelper(this.requestSpec, this.responseSpec);
this.accountHelper = new AccountHelper(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 liabilityAccountForTax =
this.accountHelper.createLiabilityAccount();
- DateFormat dateFormat = new SimpleDateFormat("dd MMMM yyyy",
Locale.US);
- DateFormat monthDayFormat = new SimpleDateFormat("dd MMM", Locale.US);
- DateFormat currentDateFormat = new SimpleDateFormat("dd");
+ DateTimeFormatter monthDayFormat = new
DateTimeFormatterBuilder().appendPattern("dd MMM").toFormatter();
+ DateTimeFormatter currentDateFormat = new
DateTimeFormatterBuilder().appendPattern("dd").toFormatter();
- Calendar todaysDate = Calendar.getInstance();
- todaysDate.add(Calendar.MONTH, -20);
- final String VALID_FROM = dateFormat.format(todaysDate.getTime());
- todaysDate.add(Calendar.YEAR, 10);
- final String VALID_TO = dateFormat.format(todaysDate.getTime());
+ LocalDate todaysDate = Utils.getLocalDateOfTenant();
+ todaysDate = todaysDate.minusMonths(20);
+ final String VALID_FROM = Utils.dateFormatter.format(todaysDate);
+ todaysDate = todaysDate.plusYears(10);
+ final String VALID_TO = Utils.dateFormatter.format(todaysDate);
- todaysDate = Calendar.getInstance();
- todaysDate.add(Calendar.MONTH, -20);
- final String SUBMITTED_ON_DATE =
dateFormat.format(todaysDate.getTime());
- final String APPROVED_ON_DATE =
dateFormat.format(todaysDate.getTime());
- final String ACTIVATION_DATE = dateFormat.format(todaysDate.getTime());
- monthDayFormat.format(todaysDate.getTime());
+ todaysDate = Utils.getLocalDateOfTenant();
+ todaysDate = todaysDate.minusMonths(20);
+ final String SUBMITTED_ON_DATE =
Utils.dateFormatter.format(todaysDate);
+ final String APPROVED_ON_DATE = Utils.dateFormatter.format(todaysDate);
+ final String ACTIVATION_DATE = Utils.dateFormatter.format(todaysDate);
- Integer currentDate =
Integer.valueOf(currentDateFormat.format(todaysDate.getTime()));
- Integer daysInMonth = todaysDate.getActualMaximum(Calendar.DATE);
- 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());
+ LocalDate closedOn = todaysDate.plusMonths(14);
+ final String CLOSED_ON_DATE = Utils.dateFormatter.format(closedOn);
Integer clientId = ClientHelper.createClient(requestSpec,
responseSpec);
Assertions.assertNotNull(clientId);
@@ -1282,26 +1278,23 @@ public class FixedDepositTest {
this.savingsAccountHelper = new SavingsAccountHelper(this.requestSpec,
this.responseSpec);
this.fixedDepositAccountHelper = new
FixedDepositAccountHelper(this.requestSpec, this.responseSpec);
- DateFormat dateFormat = new SimpleDateFormat("dd MMMM yyyy",
Locale.US);
- DateFormat monthDayFormat = new SimpleDateFormat("dd MMM", Locale.US);
- DateFormat currentDateFormat = new SimpleDateFormat("dd");
+ DateTimeFormatter dateFormat = Utils.dateFormatter;
- Calendar todaysDate = Calendar.getInstance();
- todaysDate.add(Calendar.MONTH, -3);
- final String VALID_FROM = dateFormat.format(todaysDate.getTime());
- todaysDate.add(Calendar.YEAR, 10);
- final String VALID_TO = dateFormat.format(todaysDate.getTime());
+ LocalDate todaysDate = Utils.getLocalDateOfTenant();
+ todaysDate = todaysDate.minusMonths(3);
+ final String VALID_FROM = dateFormat.format(todaysDate);
+ todaysDate = todaysDate.plusYears(10);
+ final String VALID_TO = dateFormat.format(todaysDate);
- todaysDate = Calendar.getInstance();
- todaysDate.add(Calendar.MONTH, -1);
- todaysDate.add(Calendar.DAY_OF_MONTH, -1);
- final String SUBMITTED_ON_DATE =
dateFormat.format(todaysDate.getTime());
- final String APPROVED_ON_DATE =
dateFormat.format(todaysDate.getTime());
- final String ACTIVATION_DATE = dateFormat.format(todaysDate.getTime());
- monthDayFormat.format(todaysDate.getTime());
- todaysDate.add(Calendar.MONTH, 1);
- todaysDate.add(Calendar.DAY_OF_MONTH, 1);
- final String CLOSED_ON_DATE = dateFormat.format(todaysDate.getTime());
+ todaysDate = Utils.getLocalDateOfTenant();
+ todaysDate = todaysDate.minusMonths(1);
+ todaysDate = todaysDate.minusDays(1);
+ final String SUBMITTED_ON_DATE = dateFormat.format(todaysDate);
+ final String APPROVED_ON_DATE = dateFormat.format(todaysDate);
+ final String ACTIVATION_DATE = dateFormat.format(todaysDate);
+
+ todaysDate = Utils.getLocalDateOfTenant();
+ final String CLOSED_ON_DATE = dateFormat.format(todaysDate);
Integer clientId = ClientHelper.createClient(this.requestSpec,
this.responseSpec);
Assertions.assertNotNull(clientId);
@@ -1345,18 +1338,13 @@ public class FixedDepositTest {
log.info("per day = {}", perDay);
double interestPerDay = interestRateInFraction * perDay;
- todaysDate.add(Calendar.MONTH, -1);
- todaysDate.add(Calendar.DAY_OF_MONTH, -1);
- Integer currentDate =
Integer.valueOf(currentDateFormat.format(todaysDate.getTime()));
- Integer daysInMonth = todaysDate.getActualMaximum(Calendar.DATE);
- daysInMonth = daysInMonth - currentDate + 1;
- Float interestPerMonth = (float) (interestPerDay * principal *
daysInMonth);
+ todaysDate = todaysDate.minusMonths(1);
+ todaysDate = todaysDate.minusDays(1);
+
+ Float interestPerMonth = (float) (interestPerDay * principal *
ChronoUnit.DAYS.between(todaysDate, Utils.getLocalDateOfTenant()));
principal += interestPerMonth;
- todaysDate.add(Calendar.DATE, daysInMonth);
- log.info("{}", monthDayFormat.format(todaysDate.getTime()));
- interestPerMonth = (float) (interestPerDay * principal * currentDate);
+ log.info("{}", Utils.dateFormatter.format(todaysDate));
log.info("IPM = {}", interestPerMonth);
- principal += interestPerMonth;
log.info("principal = {}", principal);
Integer transactionIdForPostInterest =
this.fixedDepositAccountHelper.postInterestForFixedDeposit(fixedDepositAccountId);