FINERACT-1955: Timezone handling of Savings account
This commit is contained in:
+2
-2
@@ -67,7 +67,7 @@ public abstract class AbstractAuditableCustom extends AbstractPersistableCustom
|
||||
|
||||
@Override
|
||||
public Optional<LocalDateTime> getCreatedDate() {
|
||||
return null == this.createdDate ? Optional.empty() : Optional.of(this.createdDate);
|
||||
return Optional.ofNullable(this.createdDate);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -87,7 +87,7 @@ public abstract class AbstractAuditableCustom extends AbstractPersistableCustom
|
||||
|
||||
@Override
|
||||
public Optional<LocalDateTime> getLastModifiedDate() {
|
||||
return null == this.lastModifiedDate ? Optional.empty() : Optional.of(this.lastModifiedDate);
|
||||
return Optional.ofNullable(this.lastModifiedDate);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+18
-13
@@ -25,8 +25,10 @@ import static org.apache.fineract.infrastructure.core.domain.AuditableFieldsCons
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.MappedSuperclass;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import java.time.OffsetDateTime;
|
||||
import java.util.Optional;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
@@ -44,7 +46,7 @@ import org.springframework.data.jpa.domain.AbstractAuditable;
|
||||
@MappedSuperclass
|
||||
@Getter
|
||||
@Setter
|
||||
@NoArgsConstructor
|
||||
@NoArgsConstructor(access = AccessLevel.PROTECTED)
|
||||
public abstract class AbstractAuditableWithUTCDateTimeCustom extends AbstractPersistableCustom
|
||||
implements Auditable<Long, Long, OffsetDateTime> {
|
||||
|
||||
@@ -67,33 +69,36 @@ public abstract class AbstractAuditableWithUTCDateTimeCustom extends AbstractPer
|
||||
private OffsetDateTime lastModifiedDate;
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public Optional<Long> getCreatedBy() {
|
||||
return Optional.ofNullable(this.createdBy);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public Optional<OffsetDateTime> getCreatedDate() {
|
||||
if (this.createdDate == null) {
|
||||
return Optional.empty();
|
||||
} else {
|
||||
return Optional.of(this.createdDate
|
||||
.withOffsetSameInstant(DateUtils.getDateTimeZoneOfTenant().getRules().getOffset(this.createdDate.toInstant())));
|
||||
}
|
||||
return Optional.ofNullable(createdDate);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public OffsetDateTime getCreatedDateTime() {
|
||||
return getCreatedDate().orElseGet(DateUtils::getAuditOffsetDateTime);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public Optional<Long> getLastModifiedBy() {
|
||||
return Optional.ofNullable(this.lastModifiedBy);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public Optional<OffsetDateTime> getLastModifiedDate() {
|
||||
if (this.lastModifiedDate == null) {
|
||||
return Optional.empty();
|
||||
} else {
|
||||
return Optional.of(this.lastModifiedDate
|
||||
.withOffsetSameInstant(DateUtils.getDateTimeZoneOfTenant().getRules().getOffset(this.lastModifiedDate.toInstant())));
|
||||
}
|
||||
return Optional.ofNullable(lastModifiedDate);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public OffsetDateTime getLastModifiedDateTime() {
|
||||
return getLastModifiedDate().orElseGet(DateUtils::getAuditOffsetDateTime);
|
||||
}
|
||||
}
|
||||
|
||||
+195
-18
@@ -20,6 +20,7 @@ package org.apache.fineract.infrastructure.core.service;
|
||||
|
||||
import static java.time.temporal.ChronoUnit.DAYS;
|
||||
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.OffsetDateTime;
|
||||
@@ -33,7 +34,6 @@ import java.util.Locale;
|
||||
import org.apache.fineract.infrastructure.core.data.ApiParameterError;
|
||||
import org.apache.fineract.infrastructure.core.domain.FineractPlatformTenant;
|
||||
import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public final class DateUtils {
|
||||
|
||||
@@ -46,6 +46,8 @@ public final class DateUtils {
|
||||
|
||||
}
|
||||
|
||||
// DateTime
|
||||
|
||||
public static ZoneId getSystemZoneId() {
|
||||
return ZoneId.systemDefault();
|
||||
}
|
||||
@@ -56,27 +58,38 @@ public final class DateUtils {
|
||||
}
|
||||
|
||||
public static LocalDate getLocalDateOfTenant() {
|
||||
final ZoneId zone = getDateTimeZoneOfTenant();
|
||||
return LocalDate.now(zone);
|
||||
return LocalDate.now(getDateTimeZoneOfTenant());
|
||||
}
|
||||
|
||||
public static LocalDateTime getLocalDateTimeOfTenant() {
|
||||
final ZoneId zone = getDateTimeZoneOfTenant();
|
||||
return LocalDateTime.now(zone).truncatedTo(ChronoUnit.SECONDS);
|
||||
return getLocalDateTimeOfTenant(null);
|
||||
}
|
||||
|
||||
public static OffsetDateTime getOffsetDateTimeOfTenant() {
|
||||
final ZoneId zone = getDateTimeZoneOfTenant();
|
||||
return OffsetDateTime.now(zone).truncatedTo(ChronoUnit.SECONDS);
|
||||
public static LocalDateTime getLocalDateTimeOfTenant(ChronoUnit truncate) {
|
||||
LocalDateTime now = LocalDateTime.now(getDateTimeZoneOfTenant());
|
||||
return truncate == null ? now : now.truncatedTo(truncate);
|
||||
}
|
||||
|
||||
public static OffsetDateTime getOffsetDateTimeOfTenantWithMostPrecision() {
|
||||
final ZoneId zone = getDateTimeZoneOfTenant();
|
||||
return OffsetDateTime.now(zone);
|
||||
return getOffsetDateTimeOfTenant(null);
|
||||
}
|
||||
|
||||
public static OffsetDateTime getOffsetDateTimeOfTenant() {
|
||||
return getOffsetDateTimeOfTenant(null);
|
||||
}
|
||||
|
||||
public static OffsetDateTime getOffsetDateTimeOfTenant(ChronoUnit truncate) {
|
||||
OffsetDateTime now = OffsetDateTime.now(getDateTimeZoneOfTenant());
|
||||
return truncate == null ? now : now.truncatedTo(truncate);
|
||||
}
|
||||
|
||||
public static LocalDateTime getLocalDateTimeOfSystem() {
|
||||
return LocalDateTime.now(ZoneId.systemDefault()).truncatedTo(ChronoUnit.SECONDS);
|
||||
return getLocalDateTimeOfSystem(null);
|
||||
}
|
||||
|
||||
public static LocalDateTime getLocalDateTimeOfSystem(ChronoUnit truncate) {
|
||||
LocalDateTime now = LocalDateTime.now(ZoneId.systemDefault());
|
||||
return truncate == null ? now : now.truncatedTo(truncate);
|
||||
}
|
||||
|
||||
public static LocalDateTime getAuditLocalDateTime() {
|
||||
@@ -87,22 +100,176 @@ public final class DateUtils {
|
||||
return OffsetDateTime.now(ZoneOffset.UTC);
|
||||
}
|
||||
|
||||
public static boolean isDateInTheFuture(final LocalDate localDate) {
|
||||
return localDate.isAfter(getBusinessLocalDate());
|
||||
public static int compare(LocalDateTime first, LocalDateTime second) {
|
||||
return compare(first, second, null);
|
||||
}
|
||||
|
||||
public static int compare(LocalDateTime first, LocalDateTime second, ChronoUnit truncate) {
|
||||
if (first == null) {
|
||||
return second == null ? 0 : -1;
|
||||
}
|
||||
if (second == null) {
|
||||
return 1;
|
||||
}
|
||||
return truncate == null ? first.compareTo(second) : first.truncatedTo(truncate).compareTo(second.truncatedTo(truncate));
|
||||
}
|
||||
|
||||
public static boolean isEqual(LocalDateTime first, LocalDateTime second) {
|
||||
return isEqual(first, second, null);
|
||||
}
|
||||
|
||||
public static boolean isEqual(LocalDateTime first, LocalDateTime second, ChronoUnit truncate) {
|
||||
return compare(first, second, truncate) == 0;
|
||||
}
|
||||
|
||||
public static boolean isEqualTenantDateTime(LocalDateTime dateTime) {
|
||||
return isEqualTenantDateTime(dateTime, null);
|
||||
}
|
||||
|
||||
public static boolean isEqualTenantDateTime(LocalDateTime dateTime, ChronoUnit truncate) {
|
||||
return isEqual(dateTime, getLocalDateTimeOfTenant(), truncate);
|
||||
}
|
||||
|
||||
public static boolean isEqualSystemDateTime(LocalDateTime dateTime) {
|
||||
return isEqualSystemDateTime(dateTime, null);
|
||||
}
|
||||
|
||||
public static boolean isEqualSystemDateTime(LocalDateTime dateTime, ChronoUnit truncate) {
|
||||
return isEqual(dateTime, getLocalDateTimeOfSystem(), truncate);
|
||||
}
|
||||
|
||||
public static boolean isBefore(LocalDateTime first, LocalDateTime second) {
|
||||
return isBefore(first, second, null);
|
||||
}
|
||||
|
||||
public static boolean isBefore(LocalDateTime first, LocalDateTime second, ChronoUnit truncate) {
|
||||
return compare(first, second, truncate) < 0;
|
||||
}
|
||||
|
||||
public static boolean isBeforeTenantDateTime(LocalDateTime dateTime) {
|
||||
return isBeforeTenantDateTime(dateTime, null);
|
||||
}
|
||||
|
||||
public static boolean isBeforeTenantDateTime(LocalDateTime dateTime, ChronoUnit truncate) {
|
||||
return isBefore(dateTime, getLocalDateTimeOfTenant(), truncate);
|
||||
}
|
||||
|
||||
public static boolean isBeforeSystemDateTime(LocalDateTime dateTime) {
|
||||
return isBeforeSystemDateTime(dateTime, null);
|
||||
}
|
||||
|
||||
public static boolean isBeforeSystemDateTime(LocalDateTime dateTime, ChronoUnit truncate) {
|
||||
return isBefore(dateTime, getLocalDateTimeOfSystem(), truncate);
|
||||
}
|
||||
|
||||
public static boolean isAfter(LocalDateTime first, LocalDateTime second) {
|
||||
return isAfter(first, second, null);
|
||||
}
|
||||
|
||||
public static boolean isAfter(LocalDateTime first, LocalDateTime second, ChronoUnit truncate) {
|
||||
return compare(first, second, truncate) > 0;
|
||||
}
|
||||
|
||||
public static boolean isAfterTenantDateTime(LocalDateTime dateTime) {
|
||||
return isAfterTenantDateTime(dateTime, null);
|
||||
}
|
||||
|
||||
public static boolean isAfterTenantDateTime(LocalDateTime dateTime, ChronoUnit truncate) {
|
||||
return isAfter(dateTime, getLocalDateTimeOfTenant(), truncate);
|
||||
}
|
||||
|
||||
public static boolean isAfterSystemDateTime(LocalDateTime dateTime) {
|
||||
return isAfterSystemDateTime(dateTime, null);
|
||||
}
|
||||
|
||||
public static boolean isAfterSystemDateTime(LocalDateTime dateTime, ChronoUnit truncate) {
|
||||
return isAfter(dateTime, getLocalDateTimeOfSystem(), truncate);
|
||||
}
|
||||
|
||||
public static int compare(OffsetDateTime first, OffsetDateTime second) {
|
||||
return compare(first, second, null);
|
||||
}
|
||||
|
||||
public static int compare(OffsetDateTime first, OffsetDateTime second, ChronoUnit truncate) {
|
||||
if (first == null) {
|
||||
return second == null ? 0 : -1;
|
||||
}
|
||||
if (second == null) {
|
||||
return 1;
|
||||
}
|
||||
return truncate == null ? first.compareTo(second) : first.truncatedTo(truncate).compareTo(second.truncatedTo(truncate));
|
||||
}
|
||||
|
||||
public static boolean isEqual(OffsetDateTime first, OffsetDateTime second) {
|
||||
return isEqual(first, second, null);
|
||||
}
|
||||
|
||||
public static boolean isEqual(OffsetDateTime first, OffsetDateTime second, ChronoUnit truncate) {
|
||||
return compare(first, second, truncate) == 0;
|
||||
}
|
||||
|
||||
public static boolean isEqualTenantDateTime(OffsetDateTime dateTime) {
|
||||
return isEqualTenantDateTime(dateTime, null);
|
||||
}
|
||||
|
||||
public static boolean isEqualTenantDateTime(OffsetDateTime dateTime, ChronoUnit truncate) {
|
||||
return isEqual(dateTime, getOffsetDateTimeOfTenant(), truncate);
|
||||
}
|
||||
|
||||
public static boolean isBefore(OffsetDateTime first, OffsetDateTime second) {
|
||||
return isBefore(first, second, null);
|
||||
}
|
||||
|
||||
public static boolean isBefore(OffsetDateTime first, OffsetDateTime second, ChronoUnit truncate) {
|
||||
return compare(first, second, truncate) < 0;
|
||||
}
|
||||
|
||||
public static boolean isBeforeTenantDateTime(OffsetDateTime dateTime) {
|
||||
return isBeforeTenantDateTime(dateTime, null);
|
||||
}
|
||||
|
||||
public static boolean isBeforeTenantDateTime(OffsetDateTime dateTime, ChronoUnit truncate) {
|
||||
return isBefore(dateTime, getOffsetDateTimeOfTenant(), truncate);
|
||||
}
|
||||
|
||||
public static boolean isAfter(OffsetDateTime first, OffsetDateTime second) {
|
||||
return isAfter(first, second, null);
|
||||
}
|
||||
|
||||
public static boolean isAfter(OffsetDateTime first, OffsetDateTime second, ChronoUnit truncate) {
|
||||
return compare(first, second, truncate) > 0;
|
||||
}
|
||||
|
||||
public static boolean isAfterTenantDateTime(OffsetDateTime dateTime) {
|
||||
return isAfterTenantDateTime(dateTime, null);
|
||||
}
|
||||
|
||||
public static boolean isAfterTenantDateTime(OffsetDateTime dateTime, ChronoUnit truncate) {
|
||||
return isAfter(dateTime, getOffsetDateTimeOfTenant(), truncate);
|
||||
}
|
||||
|
||||
// Date
|
||||
|
||||
public static LocalDate getBusinessLocalDate() {
|
||||
return ThreadLocalContextUtil.getBusinessDate();
|
||||
}
|
||||
|
||||
public static long getDifferenceInDays(final LocalDate localDateBefore, final LocalDate localDateAfter) {
|
||||
return DAYS.between(localDateBefore, localDateAfter);
|
||||
}
|
||||
|
||||
public static int compareToBusinessDate(LocalDate date) {
|
||||
return compare(date, getBusinessLocalDate());
|
||||
}
|
||||
|
||||
public static boolean isEqualTenantDate(LocalDate date) {
|
||||
return isEqual(date, getLocalDateOfTenant());
|
||||
}
|
||||
|
||||
public static boolean isBeforeTenantDate(LocalDate date) {
|
||||
return isBefore(date, getLocalDateOfTenant());
|
||||
}
|
||||
|
||||
public static boolean isAfterTenantDate(LocalDate date) {
|
||||
return isAfter(date, getLocalDateOfTenant());
|
||||
}
|
||||
|
||||
public static boolean isEqualBusinessDate(LocalDate date) {
|
||||
return isEqual(date, getBusinessLocalDate());
|
||||
}
|
||||
@@ -115,8 +282,12 @@ public final class DateUtils {
|
||||
return isAfter(date, getBusinessLocalDate());
|
||||
}
|
||||
|
||||
public static boolean isDateInTheFuture(final LocalDate localDate) {
|
||||
return isAfterBusinessDate(localDate);
|
||||
}
|
||||
|
||||
public static int compare(LocalDate first, LocalDate second) {
|
||||
return first == null ? (second == null ? 0 : -1) : first.compareTo(second);
|
||||
return first == null ? (second == null ? 0 : -1) : (second == null ? 1 : first.compareTo(second));
|
||||
}
|
||||
|
||||
public static boolean isEqual(LocalDate first, LocalDate second) {
|
||||
@@ -131,6 +302,12 @@ public final class DateUtils {
|
||||
return first != null && (second == null || first.isAfter(second));
|
||||
}
|
||||
|
||||
public static long getDifferenceInDays(final LocalDate localDateBefore, final LocalDate localDateAfter) {
|
||||
return DAYS.between(localDateBefore, localDateAfter);
|
||||
}
|
||||
|
||||
// Parse, format
|
||||
|
||||
public static LocalDate parseLocalDate(String stringDate) {
|
||||
return parseLocalDate(stringDate, null);
|
||||
}
|
||||
|
||||
@@ -259,7 +259,7 @@ public final class Group extends AbstractPersistableCustom {
|
||||
}
|
||||
|
||||
public boolean isActivatedAfter(final LocalDate submittedOn) {
|
||||
return getActivationLocalDate().isAfter(submittedOn);
|
||||
return DateUtils.isAfter(getActivationDate(), submittedOn);
|
||||
}
|
||||
|
||||
public boolean isNotActive() {
|
||||
@@ -267,11 +267,7 @@ public final class Group extends AbstractPersistableCustom {
|
||||
}
|
||||
|
||||
public boolean isActive() {
|
||||
return this.status != null ? GroupingTypeStatus.fromInt(this.status).isActive() : false;
|
||||
}
|
||||
|
||||
private boolean isDateInTheFuture(final LocalDate localDate) {
|
||||
return localDate.isAfter(DateUtils.getBusinessLocalDate());
|
||||
return this.status != null && GroupingTypeStatus.fromInt(this.status).isActive();
|
||||
}
|
||||
|
||||
public boolean isNotPending() {
|
||||
@@ -316,7 +312,7 @@ public final class Group extends AbstractPersistableCustom {
|
||||
final String dateFormatAsInput = command.dateFormat();
|
||||
final String localeAsInput = command.locale();
|
||||
|
||||
if (command.isChangeInLocalDateParameterNamed(GroupingTypesApiConstants.activationDateParamName, getActivationLocalDate())) {
|
||||
if (command.isChangeInLocalDateParameterNamed(GroupingTypesApiConstants.activationDateParamName, getActivationDate())) {
|
||||
final String valueAsInput = command.stringValueOfParameterNamed(GroupingTypesApiConstants.activationDateParamName);
|
||||
actualChanges.put(GroupingTypesApiConstants.activationDateParamName, valueAsInput);
|
||||
actualChanges.put(GroupingTypesApiConstants.dateFormatParamName, dateFormatAsInput);
|
||||
@@ -347,7 +343,7 @@ public final class Group extends AbstractPersistableCustom {
|
||||
return this.submittedOnDate;
|
||||
}
|
||||
|
||||
public LocalDate getActivationLocalDate() {
|
||||
public LocalDate getActivationDate() {
|
||||
return this.activationDate;
|
||||
}
|
||||
|
||||
@@ -494,7 +490,7 @@ public final class Group extends AbstractPersistableCustom {
|
||||
}
|
||||
|
||||
public boolean isChildGroup() {
|
||||
return this.parent == null ? false : true;
|
||||
return this.parent != null;
|
||||
|
||||
}
|
||||
|
||||
@@ -503,18 +499,17 @@ public final class Group extends AbstractPersistableCustom {
|
||||
}
|
||||
|
||||
public void close(final AppUser currentUser, final CodeValue closureReason, final LocalDate closureDate) {
|
||||
|
||||
if (isClosed()) {
|
||||
final String errorMessage = "Group with identifier " + getId() + " is alread closed.";
|
||||
throw new InvalidGroupStateTransitionException(this.groupLevel.getLevelName(), "close", "already.closed", errorMessage,
|
||||
getId());
|
||||
}
|
||||
|
||||
if (isNotPending() && getActivationLocalDate().isAfter(closureDate)) {
|
||||
if (isNotPending() && DateUtils.isAfter(getActivationDate(), closureDate)) {
|
||||
final String errorMessage = "The Group closure Date " + closureDate + " cannot be before the group Activation Date "
|
||||
+ getActivationLocalDate() + ".";
|
||||
+ getActivationDate() + ".";
|
||||
throw new InvalidGroupStateTransitionException(this.groupLevel.getLevelName(), "close",
|
||||
"date.cannot.before.group.actvation.date", errorMessage, closureDate, getActivationLocalDate());
|
||||
"date.cannot.before.group.actvation.date", errorMessage, closureDate, getActivationDate());
|
||||
}
|
||||
|
||||
this.closureReason = closureReason;
|
||||
@@ -644,9 +639,7 @@ public final class Group extends AbstractPersistableCustom {
|
||||
}
|
||||
|
||||
private void validateActivationDate(final List<ApiParameterError> dataValidationErrors) {
|
||||
|
||||
if (getSubmittedOnDate() != null && isDateInTheFuture(getSubmittedOnDate())) {
|
||||
|
||||
if (getSubmittedOnDate() != null && DateUtils.isDateInTheFuture(getSubmittedOnDate())) {
|
||||
final String defaultUserMessage = "Submitted on date cannot be in the future.";
|
||||
final String globalisationMessageCode = "error.msg.group.submittedOnDate.in.the.future";
|
||||
final ApiParameterError error = ApiParameterError.parameterError(globalisationMessageCode, defaultUserMessage,
|
||||
@@ -654,31 +647,26 @@ public final class Group extends AbstractPersistableCustom {
|
||||
|
||||
dataValidationErrors.add(error);
|
||||
}
|
||||
|
||||
if (getActivationLocalDate() != null && getSubmittedOnDate() != null && getSubmittedOnDate().isAfter(getActivationLocalDate())) {
|
||||
|
||||
if (getActivationDate() != null && DateUtils.isAfter(getSubmittedOnDate(), getActivationDate())) {
|
||||
final String defaultUserMessage = "Submitted on date cannot be after the activation date";
|
||||
final ApiParameterError error = ApiParameterError.parameterError("error.msg.group.submittedOnDate.after.activation.date",
|
||||
defaultUserMessage, GroupingTypesApiConstants.submittedOnDateParamName, this.submittedOnDate);
|
||||
|
||||
dataValidationErrors.add(error);
|
||||
}
|
||||
|
||||
if (getActivationLocalDate() != null && isDateInTheFuture(getActivationLocalDate())) {
|
||||
|
||||
if (getActivationDate() != null && DateUtils.isDateInTheFuture(getActivationDate())) {
|
||||
final String defaultUserMessage = "Activation date cannot be in the future.";
|
||||
final ApiParameterError error = ApiParameterError.parameterError("error.msg.group.activationDate.in.the.future",
|
||||
defaultUserMessage, GroupingTypesApiConstants.activationDateParamName, getActivationLocalDate());
|
||||
defaultUserMessage, GroupingTypesApiConstants.activationDateParamName, getActivationDate());
|
||||
|
||||
dataValidationErrors.add(error);
|
||||
}
|
||||
|
||||
if (getActivationLocalDate() != null) {
|
||||
if (this.office.isOpeningDateAfter(getActivationLocalDate())) {
|
||||
if (getActivationDate() != null) {
|
||||
if (this.office.isOpeningDateAfter(getActivationDate())) {
|
||||
final String defaultUserMessage = "Activation date cannot be a date before the office opening date.";
|
||||
final ApiParameterError error = ApiParameterError.parameterError(
|
||||
"error.msg.group.activationDate.cannot.be.before.office.activation.date", defaultUserMessage,
|
||||
GroupingTypesApiConstants.activationDateParamName, getActivationLocalDate());
|
||||
GroupingTypesApiConstants.activationDateParamName, getActivationDate());
|
||||
dataValidationErrors.add(error);
|
||||
}
|
||||
}
|
||||
|
||||
+11
-13
@@ -402,7 +402,7 @@ public final class SavingsAccountTransactionData implements Serializable {
|
||||
}
|
||||
|
||||
public boolean occursOn(final LocalDate occursOnDate) {
|
||||
return getTransactionDate().isEqual(occursOnDate);
|
||||
return DateUtils.isEqual(occursOnDate, getTransactionDate());
|
||||
}
|
||||
|
||||
public EndOfDayBalance toEndOfDayBalanceBoundedBy(final Money openingBalance, final LocalDateInterval boundedBy,
|
||||
@@ -416,7 +416,7 @@ public final class SavingsAccountTransactionData implements Serializable {
|
||||
LocalDate balanceStartDate = getTransactionDate();
|
||||
LocalDate balanceEndDate = getEndOfBalanceLocalDate();
|
||||
|
||||
if (boundedBy.startDate().isAfter(balanceStartDate)) {
|
||||
if (DateUtils.isAfter(boundedBy.startDate(), balanceStartDate)) {
|
||||
balanceStartDate = boundedBy.startDate();
|
||||
final LocalDateInterval spanOfBalance = LocalDateInterval.create(balanceStartDate, balanceEndDate);
|
||||
numberOfDaysOfBalance = spanOfBalance.daysInPeriodInclusiveOfEndDate();
|
||||
@@ -432,7 +432,7 @@ public final class SavingsAccountTransactionData implements Serializable {
|
||||
}
|
||||
}
|
||||
|
||||
if (balanceEndDate.isAfter(boundedBy.endDate())) {
|
||||
if (DateUtils.isAfter(balanceEndDate, boundedBy.endDate())) {
|
||||
balanceEndDate = boundedBy.endDate();
|
||||
final LocalDateInterval spanOfBalance = LocalDateInterval.create(balanceStartDate, balanceEndDate);
|
||||
numberOfDaysOfBalance = spanOfBalance.daysInPeriodInclusiveOfEndDate();
|
||||
@@ -479,7 +479,7 @@ public final class SavingsAccountTransactionData implements Serializable {
|
||||
|
||||
public void updateCumulativeBalanceAndDates(final MonetaryCurrency currency, final LocalDate endOfBalanceDate) {
|
||||
// balance end date should not be before transaction date
|
||||
if (endOfBalanceDate != null && endOfBalanceDate.isBefore(this.transactionDate)) {
|
||||
if (endOfBalanceDate != null && DateUtils.isBefore(endOfBalanceDate, this.transactionDate)) {
|
||||
this.balanceEndDate = this.transactionDate;
|
||||
} else if (endOfBalanceDate != null) {
|
||||
this.balanceEndDate = endOfBalanceDate;
|
||||
@@ -501,7 +501,7 @@ public final class SavingsAccountTransactionData implements Serializable {
|
||||
|
||||
public boolean isFeeCharge() {
|
||||
final SavingsAccountChargesPaidByData chargePaidBy = getSavingsAccountChargePaidBy();
|
||||
return (isPayCharge() && chargePaidBy != null) ? chargePaidBy.isFeeCharge() : false;
|
||||
return isPayCharge() && chargePaidBy != null && chargePaidBy.isFeeCharge();
|
||||
}
|
||||
|
||||
public void setChargesPaidByData(final SavingsAccountChargesPaidByData savingsAccountChargesPaidByData) {
|
||||
@@ -518,7 +518,7 @@ public final class SavingsAccountTransactionData implements Serializable {
|
||||
|
||||
public boolean isPenaltyCharge() {
|
||||
final SavingsAccountChargesPaidByData chargePaidBy = getSavingsAccountChargePaidBy();
|
||||
return (isPayCharge() && chargePaidBy != null) ? chargePaidBy.isPenaltyCharge() : false;
|
||||
return isPayCharge() && chargePaidBy != null && chargePaidBy.isPenaltyCharge();
|
||||
}
|
||||
|
||||
public boolean isWaiveFeeChargeAndNotReversed() {
|
||||
@@ -527,7 +527,7 @@ public final class SavingsAccountTransactionData implements Serializable {
|
||||
|
||||
public boolean isWaiveFeeCharge() {
|
||||
final SavingsAccountChargesPaidByData chargePaidBy = getSavingsAccountChargePaidBy();
|
||||
return (isWaiveCharge() && chargePaidBy != null) ? chargePaidBy.isFeeCharge() : false;
|
||||
return isWaiveCharge() && chargePaidBy != null && chargePaidBy.isFeeCharge();
|
||||
}
|
||||
|
||||
public boolean isWaiveCharge() {
|
||||
@@ -540,7 +540,7 @@ public final class SavingsAccountTransactionData implements Serializable {
|
||||
|
||||
public boolean isWaivePenaltyCharge() {
|
||||
final SavingsAccountChargesPaidByData chargePaidBy = getSavingsAccountChargePaidBy();
|
||||
return (isWaiveCharge() && chargePaidBy != null) ? chargePaidBy.isPenaltyCharge() : false;
|
||||
return isWaiveCharge() && chargePaidBy != null && chargePaidBy.isPenaltyCharge();
|
||||
}
|
||||
|
||||
private SavingsAccountChargesPaidByData getSavingsAccountChargePaidBy() {
|
||||
@@ -572,7 +572,7 @@ public final class SavingsAccountTransactionData implements Serializable {
|
||||
thisTransactionData.put("id", getId());
|
||||
thisTransactionData.put("officeId", officeId);
|
||||
thisTransactionData.put("type", transactionType);
|
||||
thisTransactionData.put("reversed", Boolean.valueOf(isReversed()));
|
||||
thisTransactionData.put("reversed", isReversed());
|
||||
thisTransactionData.put("date", getTransactionDate());
|
||||
thisTransactionData.put("currency", currencyData);
|
||||
thisTransactionData.put("amount", this.amount);
|
||||
@@ -582,10 +582,8 @@ public final class SavingsAccountTransactionData implements Serializable {
|
||||
thisTransactionData.put("paymentTypeId", this.paymentDetailData.getPaymentType().getId());
|
||||
}
|
||||
|
||||
/***
|
||||
* Sending data in a map, though in savings we currently expect a transaction to always repay a single charge
|
||||
* (or may repay a part of a single charge too)
|
||||
***/
|
||||
// Sending data in a map, though in savings we currently expect a transaction to always repay a single charge
|
||||
// (or may repay a part of a single charge too)
|
||||
if (!this.chargesPaidByData.isEmpty()) {
|
||||
final List<Map<String, Object>> savingsChargesPaidData = new ArrayList<>();
|
||||
for (final SavingsAccountChargesPaidByData chargePaidBy : this.chargesPaidByData) {
|
||||
|
||||
+6
-7
@@ -25,6 +25,7 @@ import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import org.apache.fineract.infrastructure.core.domain.LocalDateInterval;
|
||||
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.portfolio.account.service.AccountTransfersReadPlatformService;
|
||||
@@ -55,8 +56,7 @@ public final class SavingsHelper {
|
||||
LocalDate periodEndDate = periodStartDate;
|
||||
LocalDate actualPeriodStartDate = periodStartDate;
|
||||
|
||||
while (!periodStartDate.isAfter(interestPostingUpToDate) && !periodEndDate.isAfter(interestPostingUpToDate)) {
|
||||
|
||||
while (!DateUtils.isAfter(periodStartDate, interestPostingUpToDate) && !DateUtils.isAfter(periodEndDate, interestPostingUpToDate)) {
|
||||
final LocalDate interestPostingLocalDate = determineInterestPostingPeriodEndDateFrom(periodStartDate, postingPeriodType,
|
||||
interestPostingUpToDate, financialYearBeginningMonth);
|
||||
|
||||
@@ -64,8 +64,7 @@ public final class SavingsHelper {
|
||||
|
||||
if (!postInterestAsOn.isEmpty()) {
|
||||
for (LocalDate transactiondate : postInterestAsOn) {
|
||||
if (periodStartDate.isBefore(transactiondate)
|
||||
&& (periodEndDate.isAfter(transactiondate) || periodEndDate.isEqual(transactiondate))) {
|
||||
if (DateUtils.isAfter(transactiondate, periodStartDate) && !DateUtils.isAfter(transactiondate, periodEndDate)) {
|
||||
periodEndDate = transactiondate.minusDays(1);
|
||||
actualPeriodStartDate = periodEndDate;
|
||||
break;
|
||||
@@ -75,7 +74,7 @@ public final class SavingsHelper {
|
||||
|
||||
postingPeriods.add(LocalDateInterval.create(periodStartDate, periodEndDate));
|
||||
|
||||
if (actualPeriodStartDate.isEqual(periodEndDate)) {
|
||||
if (DateUtils.isEqual(actualPeriodStartDate, periodEndDate)) {
|
||||
periodEndDate = actualPeriodStartDate.plusDays(1);
|
||||
periodStartDate = actualPeriodStartDate.plusDays(1);
|
||||
} else {
|
||||
@@ -128,7 +127,7 @@ public final class SavingsHelper {
|
||||
break;
|
||||
case QUATERLY:
|
||||
for (LocalDate quarterlyDate : quarterlyDates) {
|
||||
if (quarterlyDate.isAfter(periodStartDate)) {
|
||||
if (DateUtils.isAfter(quarterlyDate, periodStartDate)) {
|
||||
periodEndDate = quarterlyDate;
|
||||
isEndDateSet = true;
|
||||
break;
|
||||
@@ -141,7 +140,7 @@ public final class SavingsHelper {
|
||||
break;
|
||||
case BIANNUAL:
|
||||
for (LocalDate biannualDate : biannualDates) {
|
||||
if (biannualDate.isAfter(periodStartDate)) {
|
||||
if (DateUtils.isAfter(biannualDate, periodStartDate)) {
|
||||
periodEndDate = biannualDate;
|
||||
isEndDateSet = true;
|
||||
break;
|
||||
|
||||
+2
-1
@@ -21,6 +21,7 @@ package org.apache.fineract.portfolio.savings.domain.interest;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||
import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency;
|
||||
import org.apache.fineract.organisation.monetary.domain.Money;
|
||||
|
||||
@@ -59,7 +60,7 @@ public class CompoundInterestHelper {
|
||||
// account and if already transfered then it includes in interest
|
||||
// calculation.
|
||||
if (!(postingPeriod.isInterestTransfered() || !interestTransferEnabled
|
||||
|| (lockUntil != null && !postingPeriod.dateOfPostingTransaction().isAfter(lockUntil)))) {
|
||||
|| (lockUntil != null && !DateUtils.isAfter(postingPeriod.dateOfPostingTransaction(), lockUntil)))) {
|
||||
compoundInterestValues.setcompoundedInterest(BigDecimal.ZERO);
|
||||
}
|
||||
}
|
||||
|
||||
+4
-5
@@ -22,6 +22,7 @@ import java.math.BigDecimal;
|
||||
import java.math.MathContext;
|
||||
import java.time.LocalDate;
|
||||
import org.apache.fineract.infrastructure.core.domain.LocalDateInterval;
|
||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||
import org.apache.fineract.organisation.monetary.domain.Money;
|
||||
import org.apache.fineract.organisation.monetary.domain.MoneyHelper;
|
||||
|
||||
@@ -136,7 +137,6 @@ public class EndOfDayBalance {
|
||||
* @return
|
||||
*/
|
||||
public EndOfDayBalance upTo(final LocalDateInterval compoundingPeriodInterval, final LocalDate upToInterestCalculationDate) {
|
||||
|
||||
Money startingBalance = this.openingBalance;
|
||||
LocalDate balanceStartDate = this.date;
|
||||
|
||||
@@ -144,7 +144,7 @@ public class EndOfDayBalance {
|
||||
|
||||
int daysOfBalance = this.numberOfDays;
|
||||
|
||||
if (this.date.isBefore(compoundingPeriodInterval.startDate())) {
|
||||
if (DateUtils.isBefore(this.date, compoundingPeriodInterval.startDate())) {
|
||||
balanceStartDate = compoundingPeriodInterval.startDate();
|
||||
startingBalance = this.endOfDayBalance;
|
||||
final LocalDateInterval balancePeriodInterval = LocalDateInterval.create(balanceStartDate, oldBalanceEndDate);
|
||||
@@ -152,12 +152,12 @@ public class EndOfDayBalance {
|
||||
}
|
||||
|
||||
LocalDate balanceEndDate = balanceStartDate.plusDays(daysOfBalance - 1);
|
||||
if (balanceEndDate.isAfter(compoundingPeriodInterval.endDate())) {
|
||||
if (DateUtils.isAfter(balanceEndDate, compoundingPeriodInterval.endDate())) {
|
||||
balanceEndDate = compoundingPeriodInterval.endDate();
|
||||
final LocalDateInterval balancePeriodInterval = LocalDateInterval.create(balanceStartDate, balanceEndDate);
|
||||
daysOfBalance = balancePeriodInterval.daysInPeriodInclusiveOfEndDate();
|
||||
}
|
||||
if (balanceEndDate.isAfter(upToInterestCalculationDate)) {
|
||||
if (DateUtils.isAfter(balanceEndDate, upToInterestCalculationDate)) {
|
||||
balanceEndDate = upToInterestCalculationDate;
|
||||
final LocalDateInterval balancePeriodInterval = LocalDateInterval.create(balanceStartDate, balanceEndDate);
|
||||
daysOfBalance = balancePeriodInterval.daysInPeriodInclusiveOfEndDate();
|
||||
@@ -167,7 +167,6 @@ public class EndOfDayBalance {
|
||||
}
|
||||
|
||||
public boolean contains(final LocalDateInterval compoundingPeriodInterval) {
|
||||
|
||||
final LocalDate balanceUpToDate = this.date.plusDays(this.numberOfDays - 1);
|
||||
|
||||
final LocalDateInterval balanceInterval = LocalDateInterval.create(this.date, balanceUpToDate);
|
||||
|
||||
+15
-17
@@ -132,7 +132,7 @@ public final class PostingPeriod {
|
||||
LocalDate balanceEndDate = periodInterval.endDate();
|
||||
Integer numberOfDaysOfBalance = periodInterval.daysInPeriodInclusiveOfEndDate();
|
||||
|
||||
if (balanceEndDate.isAfter(upToInterestCalculationDate)) {
|
||||
if (DateUtils.isAfter(balanceEndDate, upToInterestCalculationDate)) {
|
||||
balanceEndDate = upToInterestCalculationDate;
|
||||
final LocalDateInterval spanOfBalance = LocalDateInterval.create(balanceStartDate, balanceEndDate);
|
||||
numberOfDaysOfBalance = spanOfBalance.daysInPeriodInclusiveOfEndDate();
|
||||
@@ -206,7 +206,7 @@ public final class PostingPeriod {
|
||||
LocalDate balanceEndDate = periodInterval.endDate();
|
||||
Integer numberOfDaysOfBalance = periodInterval.daysInPeriodInclusiveOfEndDate();
|
||||
|
||||
if (balanceEndDate.isAfter(upToInterestCalculationDate)) {
|
||||
if (DateUtils.isAfter(balanceEndDate, upToInterestCalculationDate)) {
|
||||
balanceEndDate = upToInterestCalculationDate;
|
||||
final LocalDateInterval spanOfBalance = LocalDateInterval.create(balanceStartDate, balanceEndDate);
|
||||
numberOfDaysOfBalance = spanOfBalance.daysInPeriodInclusiveOfEndDate();
|
||||
@@ -328,23 +328,21 @@ public final class PostingPeriod {
|
||||
compoundingPeriods.add(compoundingPeriod);
|
||||
break;
|
||||
case MONTHLY:
|
||||
|
||||
final LocalDate postingPeriodEndDate = postingPeriodInterval.endDate();
|
||||
|
||||
LocalDate periodStartDate = postingPeriodInterval.startDate();
|
||||
LocalDate periodEndDate = periodStartDate;
|
||||
|
||||
while (!periodStartDate.isAfter(postingPeriodEndDate) && !periodEndDate.isAfter(postingPeriodEndDate)) {
|
||||
|
||||
while (!DateUtils.isAfter(periodStartDate, postingPeriodEndDate)
|
||||
&& !DateUtils.isAfter(periodEndDate, postingPeriodEndDate)) {
|
||||
periodEndDate = determineInterestPeriodEndDateFrom(periodStartDate, interestPeriodType, upToInterestCalculationDate,
|
||||
financialYearBeginningMonth);
|
||||
if (periodEndDate.isAfter(postingPeriodEndDate)) {
|
||||
if (DateUtils.isAfter(periodEndDate, postingPeriodEndDate)) {
|
||||
periodEndDate = postingPeriodEndDate;
|
||||
}
|
||||
|
||||
final LocalDateInterval compoundingPeriodInterval = LocalDateInterval.create(periodStartDate, periodEndDate);
|
||||
if (postingPeriodInterval.contains(compoundingPeriodInterval)) {
|
||||
|
||||
compoundingPeriod = MonthlyCompoundingPeriod.create(compoundingPeriodInterval, allEndOfDayBalances,
|
||||
upToInterestCalculationDate);
|
||||
compoundingPeriods.add(compoundingPeriod);
|
||||
@@ -364,17 +362,16 @@ public final class PostingPeriod {
|
||||
periodStartDate = postingPeriodInterval.startDate();
|
||||
periodEndDate = periodStartDate;
|
||||
|
||||
while (!periodStartDate.isAfter(qPostingPeriodEndDate) && !periodEndDate.isAfter(qPostingPeriodEndDate)) {
|
||||
|
||||
while (!DateUtils.isAfter(periodStartDate, qPostingPeriodEndDate)
|
||||
&& !DateUtils.isAfter(periodEndDate, qPostingPeriodEndDate)) {
|
||||
periodEndDate = determineInterestPeriodEndDateFrom(periodStartDate, interestPeriodType, upToInterestCalculationDate,
|
||||
financialYearBeginningMonth);
|
||||
if (periodEndDate.isAfter(qPostingPeriodEndDate)) {
|
||||
if (DateUtils.isAfter(periodEndDate, qPostingPeriodEndDate)) {
|
||||
periodEndDate = qPostingPeriodEndDate;
|
||||
}
|
||||
|
||||
final LocalDateInterval compoundingPeriodInterval = LocalDateInterval.create(periodStartDate, periodEndDate);
|
||||
if (postingPeriodInterval.contains(compoundingPeriodInterval)) {
|
||||
|
||||
compoundingPeriod = QuarterlyCompoundingPeriod.create(compoundingPeriodInterval, allEndOfDayBalances,
|
||||
upToInterestCalculationDate);
|
||||
compoundingPeriods.add(compoundingPeriod);
|
||||
@@ -390,11 +387,11 @@ public final class PostingPeriod {
|
||||
periodStartDate = postingPeriodInterval.startDate();
|
||||
periodEndDate = periodStartDate;
|
||||
|
||||
while (!periodStartDate.isAfter(bPostingPeriodEndDate) && !periodEndDate.isAfter(bPostingPeriodEndDate)) {
|
||||
|
||||
while (!DateUtils.isAfter(periodStartDate, bPostingPeriodEndDate)
|
||||
&& !DateUtils.isAfter(periodEndDate, bPostingPeriodEndDate)) {
|
||||
periodEndDate = determineInterestPeriodEndDateFrom(periodStartDate, interestPeriodType, upToInterestCalculationDate,
|
||||
financialYearBeginningMonth);
|
||||
if (periodEndDate.isAfter(bPostingPeriodEndDate)) {
|
||||
if (DateUtils.isAfter(periodEndDate, bPostingPeriodEndDate)) {
|
||||
periodEndDate = bPostingPeriodEndDate;
|
||||
}
|
||||
|
||||
@@ -416,11 +413,12 @@ public final class PostingPeriod {
|
||||
periodStartDate = postingPeriodInterval.startDate();
|
||||
periodEndDate = periodStartDate;
|
||||
|
||||
while (!periodStartDate.isAfter(aPostingPeriodEndDate) && !periodEndDate.isAfter(aPostingPeriodEndDate)) {
|
||||
while (!DateUtils.isAfter(periodStartDate, aPostingPeriodEndDate)
|
||||
&& !DateUtils.isAfter(periodEndDate, aPostingPeriodEndDate)) {
|
||||
|
||||
periodEndDate = determineInterestPeriodEndDateFrom(periodStartDate, interestPeriodType, upToInterestCalculationDate,
|
||||
financialYearBeginningMonth);
|
||||
if (periodEndDate.isAfter(aPostingPeriodEndDate)) {
|
||||
if (DateUtils.isAfter(periodEndDate, aPostingPeriodEndDate)) {
|
||||
periodEndDate = aPostingPeriodEndDate;
|
||||
}
|
||||
|
||||
@@ -483,7 +481,7 @@ public final class PostingPeriod {
|
||||
case ANNUAL:
|
||||
periodEndDate = periodStartDate.withMonth(previousMonth);
|
||||
periodEndDate = periodEndDate.with(TemporalAdjusters.lastDayOfMonth());
|
||||
if (periodEndDate.isBefore(periodStartDate)) {
|
||||
if (DateUtils.isBefore(periodEndDate, periodStartDate)) {
|
||||
periodEndDate = periodEndDate.plusYears(1);
|
||||
}
|
||||
break;
|
||||
|
||||
+4
-4
@@ -23,6 +23,7 @@ import java.time.LocalDate;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.fineract.infrastructure.core.domain.LocalDateInterval;
|
||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||
import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency;
|
||||
import org.apache.fineract.organisation.monetary.domain.Money;
|
||||
|
||||
@@ -54,7 +55,7 @@ public class SavingsAccountTransactionDetailsForPostingPeriod {
|
||||
}
|
||||
|
||||
public boolean occursOn(final LocalDate occursOnDate) {
|
||||
return getTransactionDate().isEqual(occursOnDate);
|
||||
return DateUtils.isEqual(occursOnDate, getTransactionDate());
|
||||
}
|
||||
|
||||
public EndOfDayBalance toEndOfDayBalance(final Money openingBalance) {
|
||||
@@ -92,7 +93,6 @@ public class SavingsAccountTransactionDetailsForPostingPeriod {
|
||||
}
|
||||
|
||||
public EndOfDayBalance toEndOfDayBalanceBoundedBy(final Money openingBalance, final LocalDateInterval boundedBy) {
|
||||
|
||||
final MonetaryCurrency currency = openingBalance.getCurrency();
|
||||
Money endOfDayBalance = openingBalance.copy();
|
||||
|
||||
@@ -101,7 +101,7 @@ public class SavingsAccountTransactionDetailsForPostingPeriod {
|
||||
LocalDate balanceStartDate = getTransactionDate();
|
||||
LocalDate balanceEndDate = getEndOfBalanceDate();
|
||||
|
||||
if (boundedBy.startDate().isAfter(balanceStartDate)) {
|
||||
if (DateUtils.isAfter(boundedBy.startDate(), balanceStartDate)) {
|
||||
balanceStartDate = boundedBy.startDate();
|
||||
final LocalDateInterval spanOfBalance = LocalDateInterval.create(balanceStartDate, balanceEndDate);
|
||||
numberOfDaysOfBalance = spanOfBalance.daysInPeriodInclusiveOfEndDate();
|
||||
@@ -121,7 +121,7 @@ public class SavingsAccountTransactionDetailsForPostingPeriod {
|
||||
}
|
||||
}
|
||||
|
||||
if (balanceEndDate.isAfter(boundedBy.endDate())) {
|
||||
if (DateUtils.isAfter(balanceEndDate, boundedBy.endDate())) {
|
||||
balanceEndDate = boundedBy.endDate();
|
||||
final LocalDateInterval spanOfBalance = LocalDateInterval.create(balanceStartDate, balanceEndDate);
|
||||
numberOfDaysOfBalance = spanOfBalance.daysInPeriodInclusiveOfEndDate();
|
||||
|
||||
+2
-2
@@ -1609,7 +1609,7 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom {
|
||||
final String errorMessage = "The date on which a loan is submitted cannot be earlier than client's activation date.";
|
||||
throw new InvalidLoanStateTransitionException("submittal", "cannot.be.before.client.activation.date", errorMessage,
|
||||
getSubmittedOnDate());
|
||||
} else if (this.group != null && DateUtils.isBefore(getSubmittedOnDate(), this.group.getActivationLocalDate())) {
|
||||
} else if (this.group != null && DateUtils.isBefore(getSubmittedOnDate(), this.group.getActivationDate())) {
|
||||
final String errorMessage = "The date on which a loan is submitted cannot be earlier than groups's activation date.";
|
||||
throw new InvalidLoanStateTransitionException("submittal", "cannot.be.before.group.activation.date", errorMessage,
|
||||
getSubmittedOnDate());
|
||||
@@ -2124,7 +2124,7 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom {
|
||||
if (this.group != null && this.group.isActivatedAfter(submittedOn)) {
|
||||
final String errorMessage = "The date on which a loan is submitted cannot be earlier than groups's activation date.";
|
||||
throw new InvalidLoanStateTransitionException("submittal", "cannot.be.before.group.activation.date", errorMessage, submittedOn,
|
||||
group.getActivationLocalDate());
|
||||
group.getActivationDate());
|
||||
}
|
||||
|
||||
if (DateUtils.isAfter(submittedOn, getExpectedDisbursedOnLocalDate())) {
|
||||
|
||||
+1
@@ -850,6 +850,7 @@ public class LoanTransaction extends AbstractAuditableWithUTCDateTimeCustom {
|
||||
this.manuallyAdjustedOrReversed = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public OffsetDateTime getCreatedDateTime() {
|
||||
return (this.getCreatedDate().isPresent() ? this.getCreatedDate().get() : DateUtils.getOffsetDateTimeOfTenantWithMostPrecision());
|
||||
}
|
||||
|
||||
+14
-39
@@ -119,7 +119,7 @@ public class SmsCampaign extends AbstractPersistableCustom {
|
||||
|
||||
private SmsCampaign(final String campaignName, final Integer campaignType, final Integer triggerType, final Report businessRuleId,
|
||||
final Long providerId, final String paramValue, final String message, final LocalDate submittedOnDate,
|
||||
final AppUser submittedBy, final String recurrence, final LocalDateTime localDateTime, final boolean isNotification) {
|
||||
final AppUser submittedBy, final String recurrence, final LocalDateTime recurrenceStartDate, final boolean isNotification) {
|
||||
this.campaignName = campaignName;
|
||||
this.campaignType = campaignType;
|
||||
this.triggerType = SmsCampaignTriggerType.fromInt(triggerType).getValue();
|
||||
@@ -131,18 +131,12 @@ public class SmsCampaign extends AbstractPersistableCustom {
|
||||
this.submittedOnDate = submittedOnDate;
|
||||
this.submittedBy = submittedBy;
|
||||
this.recurrence = recurrence;
|
||||
LocalDateTime recurrenceStartDate = LocalDateTime.now(DateUtils.getDateTimeZoneOfTenant());
|
||||
this.isVisible = true;
|
||||
if (localDateTime != null) {
|
||||
this.recurrenceStartDate = localDateTime;
|
||||
} else {
|
||||
this.recurrenceStartDate = recurrenceStartDate;
|
||||
}
|
||||
this.recurrenceStartDate = recurrenceStartDate;
|
||||
this.isNotification = isNotification;
|
||||
}
|
||||
|
||||
public static SmsCampaign instance(final AppUser submittedBy, final Report report, final JsonCommand command) {
|
||||
|
||||
final String campaignName = command.stringValueOfParameterNamed(SmsCampaignValidator.campaignName);
|
||||
final Long campaignType = command.longValueOfParameterNamed(SmsCampaignValidator.campaignType);
|
||||
final Long triggerType = command.longValueOfParameterNamed(SmsCampaignValidator.triggerType);
|
||||
@@ -164,10 +158,11 @@ public class SmsCampaign extends AbstractPersistableCustom {
|
||||
}
|
||||
String recurrence = null;
|
||||
|
||||
LocalDateTime recurrenceStartDate = LocalDateTime.now(DateUtils.getDateTimeZoneOfTenant());
|
||||
LocalDateTime recurrenceStartDate = null;
|
||||
if (SmsCampaignTriggerType.fromInt(triggerType.intValue()).isSchedule()) {
|
||||
final Locale locale = command.extractLocale();
|
||||
String dateTimeFormat;
|
||||
recurrenceStartDate = DateUtils.getLocalDateTimeOfTenant();
|
||||
if (command.hasParameter(SmsCampaignValidator.dateTimeFormat)) {
|
||||
dateTimeFormat = command.stringValueOfParameterNamed(SmsCampaignValidator.dateTimeFormat);
|
||||
final DateTimeFormatter fmt = DateTimeFormatter.ofPattern(dateTimeFormat).withLocale(locale);
|
||||
@@ -177,8 +172,6 @@ public class SmsCampaign extends AbstractPersistableCustom {
|
||||
}
|
||||
recurrence = constructRecurrence(command);
|
||||
}
|
||||
} else {
|
||||
recurrenceStartDate = null;
|
||||
}
|
||||
|
||||
return new SmsCampaign(campaignName, campaignType.intValue(), triggerType.intValue(), report, providerId, paramValue, message,
|
||||
@@ -186,7 +179,6 @@ public class SmsCampaign extends AbstractPersistableCustom {
|
||||
}
|
||||
|
||||
public Map<String, Object> update(JsonCommand command) {
|
||||
|
||||
final Map<String, Object> actualChanges = new LinkedHashMap<>(5);
|
||||
|
||||
if (command.isChangeInStringParameterNamed(SmsCampaignValidator.campaignName, this.campaignName)) {
|
||||
@@ -255,7 +247,6 @@ public class SmsCampaign extends AbstractPersistableCustom {
|
||||
}
|
||||
|
||||
public void activate(final AppUser currentUser, final DateTimeFormatter formatter, final LocalDate activationLocalDate) {
|
||||
|
||||
if (isActive()) {
|
||||
// handle errors if already activated
|
||||
final String defaultUserMessage = "Cannot activate campaign. Campaign is already active.";
|
||||
@@ -297,7 +288,6 @@ public class SmsCampaign extends AbstractPersistableCustom {
|
||||
}
|
||||
|
||||
public void reactivate(final AppUser currentUser, final DateTimeFormatter dateTimeFormat, final LocalDate reactivateLocalDate) {
|
||||
|
||||
if (!isClosed()) {
|
||||
// handle errors if already activated
|
||||
final String defaultUserMessage = "Cannot reactivate campaign. Campaign must be in closed state.";
|
||||
@@ -384,66 +374,55 @@ public class SmsCampaign extends AbstractPersistableCustom {
|
||||
}
|
||||
|
||||
private void validateActivationDate(final List<ApiParameterError> dataValidationErrors) {
|
||||
|
||||
if (getSubmittedOnDate() != null && isDateInTheFuture(getSubmittedOnDate())) {
|
||||
|
||||
if (DateUtils.isDateInTheFuture(getSubmittedOnDate())) {
|
||||
final String defaultUserMessage = "submitted date cannot be in the future.";
|
||||
final ApiParameterError error = ApiParameterError.parameterError("error.msg.campaign.submittedOnDate.in.the.future",
|
||||
defaultUserMessage, SmsCampaignValidator.submittedOnDateParamName, this.submittedOnDate);
|
||||
|
||||
dataValidationErrors.add(error);
|
||||
}
|
||||
|
||||
if (getActivationLocalDate() != null && getSubmittedOnDate() != null && getSubmittedOnDate().isAfter(getActivationLocalDate())) {
|
||||
|
||||
if (getActivationDate() != null && DateUtils.isAfter(getSubmittedOnDate(), getActivationDate())) {
|
||||
final String defaultUserMessage = "submitted date cannot be after the activation date";
|
||||
final ApiParameterError error = ApiParameterError.parameterError("error.msg.campaign.submittedOnDate.after.activation.date",
|
||||
defaultUserMessage, SmsCampaignValidator.submittedOnDateParamName, this.submittedOnDate);
|
||||
|
||||
dataValidationErrors.add(error);
|
||||
}
|
||||
|
||||
if (getActivationLocalDate() != null && isDateInTheFuture(getActivationLocalDate())) {
|
||||
|
||||
if (DateUtils.isDateInTheFuture(getActivationDate())) {
|
||||
final String defaultUserMessage = "Activation date cannot be in the future.";
|
||||
final ApiParameterError error = ApiParameterError.parameterError("error.msg.campaign.activationDate.in.the.future",
|
||||
defaultUserMessage, SmsCampaignValidator.activationDateParamName, getActivationLocalDate());
|
||||
defaultUserMessage, SmsCampaignValidator.activationDateParamName, getActivationDate());
|
||||
|
||||
dataValidationErrors.add(error);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void validateReactivationDate(final List<ApiParameterError> dataValidationErrors) {
|
||||
if (getActivationLocalDate() != null && isDateInTheFuture(getActivationLocalDate())) {
|
||||
|
||||
if (DateUtils.isDateInTheFuture(getActivationDate())) {
|
||||
final String defaultUserMessage = "Activation date cannot be in the future.";
|
||||
final ApiParameterError error = ApiParameterError.parameterError("error.msg.campaign.activationDate.in.the.future",
|
||||
defaultUserMessage, SmsCampaignValidator.activationDateParamName, getActivationLocalDate());
|
||||
defaultUserMessage, SmsCampaignValidator.activationDateParamName, getActivationDate());
|
||||
|
||||
dataValidationErrors.add(error);
|
||||
}
|
||||
if (getActivationLocalDate() != null && getSubmittedOnDate() != null && getSubmittedOnDate().isAfter(getActivationLocalDate())) {
|
||||
|
||||
if (getActivationDate() != null && DateUtils.isAfter(getSubmittedOnDate(), getActivationDate())) {
|
||||
final String defaultUserMessage = "submitted date cannot be after the activation date";
|
||||
final ApiParameterError error = ApiParameterError.parameterError("error.msg.campaign.submittedOnDate.after.activation.date",
|
||||
defaultUserMessage, SmsCampaignValidator.submittedOnDateParamName, this.submittedOnDate);
|
||||
|
||||
dataValidationErrors.add(error);
|
||||
}
|
||||
if (getSubmittedOnDate() != null && isDateInTheFuture(getSubmittedOnDate())) {
|
||||
|
||||
if (DateUtils.isDateInTheFuture(getSubmittedOnDate())) {
|
||||
final String defaultUserMessage = "submitted date cannot be in the future.";
|
||||
final ApiParameterError error = ApiParameterError.parameterError("error.msg.campaign.submittedOnDate.in.the.future",
|
||||
defaultUserMessage, SmsCampaignValidator.submittedOnDateParamName, this.submittedOnDate);
|
||||
|
||||
dataValidationErrors.add(error);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void validateClosureDate(final List<ApiParameterError> dataValidationErrors) {
|
||||
if (getClosureDate() != null && isDateInTheFuture(getClosureDate())) {
|
||||
if (DateUtils.isDateInTheFuture(getClosureDate())) {
|
||||
final String defaultUserMessage = "closure date cannot be in the future.";
|
||||
final ApiParameterError error = ApiParameterError.parameterError("error.msg.campaign.closureDate.in.the.future",
|
||||
defaultUserMessage, SmsCampaignValidator.closureDateParamName, this.closureDate);
|
||||
@@ -461,14 +440,10 @@ public class SmsCampaign extends AbstractPersistableCustom {
|
||||
return this.closureDate;
|
||||
}
|
||||
|
||||
public LocalDate getActivationLocalDate() {
|
||||
public LocalDate getActivationDate() {
|
||||
return this.approvedOnDate;
|
||||
}
|
||||
|
||||
private boolean isDateInTheFuture(final LocalDate localDate) {
|
||||
return localDate.isAfter(DateUtils.getBusinessLocalDate());
|
||||
}
|
||||
|
||||
public Report getBusinessRuleId() {
|
||||
return this.businessRuleId;
|
||||
}
|
||||
|
||||
+1
-1
@@ -365,7 +365,7 @@ public class SmsCampaignDomainServiceImpl implements SmsCampaignDomainService {
|
||||
smsParams.put("depositAmount", savingsAccountTransaction.getAmount(savingsAccount.getCurrency()));
|
||||
smsParams.put("balance", savingsAccount.getWithdrawableBalance());
|
||||
smsParams.put("officeId", client.getOffice().getId());
|
||||
smsParams.put("transactionDate", savingsAccountTransaction.getTransactionLocalDate().format(dateFormatter));
|
||||
smsParams.put("transactionDate", savingsAccountTransaction.getTransactionDate().format(dateFormatter));
|
||||
smsParams.put("savingsTransactionId", savingsAccountTransaction.getId());
|
||||
|
||||
if (client.getStaff() != null) {
|
||||
|
||||
+18
-43
@@ -30,7 +30,6 @@ import java.io.StringReader;
|
||||
import java.io.StringWriter;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
@@ -54,12 +53,10 @@ import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||
import org.apache.fineract.infrastructure.core.api.JsonQuery;
|
||||
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.apache.fineract.infrastructure.core.data.CommandProcessingResultBuilder;
|
||||
import org.apache.fineract.infrastructure.core.domain.FineractPlatformTenant;
|
||||
import org.apache.fineract.infrastructure.core.exception.GeneralPlatformDomainRuleException;
|
||||
import org.apache.fineract.infrastructure.core.exception.PlatformDataIntegrityException;
|
||||
import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
|
||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||
import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil;
|
||||
import org.apache.fineract.infrastructure.dataqueries.data.GenericResultsetData;
|
||||
import org.apache.fineract.infrastructure.dataqueries.domain.Report;
|
||||
import org.apache.fineract.infrastructure.dataqueries.domain.ReportRepository;
|
||||
@@ -107,16 +104,16 @@ public class SmsCampaignWritePlatformServiceJpaImpl implements SmsCampaignWriteP
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult create(JsonCommand command) {
|
||||
|
||||
final AppUser currentUser = this.context.authenticatedUser();
|
||||
this.smsCampaignValidator.validateCreate(command.json());
|
||||
final Long runReportId = command.longValueOfParameterNamed(SmsCampaignValidator.runReportId);
|
||||
Report report = this.reportRepository.findById(runReportId).orElseThrow(() -> new ReportNotFoundException(runReportId));
|
||||
LocalDateTime tenantDateTime = DateUtils.getLocalDateTimeOfTenant();
|
||||
SmsCampaign smsCampaign = SmsCampaign.instance(currentUser, report, command);
|
||||
if (smsCampaign.getRecurrenceStartDate() != null
|
||||
&& smsCampaign.getRecurrenceStartDate().isBefore(DateUtils.getLocalDateTimeOfTenant())) {
|
||||
LocalDateTime recurrenceStartDate = smsCampaign.getRecurrenceStartDate();
|
||||
if (recurrenceStartDate != null && DateUtils.isBefore(recurrenceStartDate, tenantDateTime)) {
|
||||
throw new GeneralPlatformDomainRuleException("error.msg.campaign.recurrenceStartDate.in.the.past",
|
||||
"Recurrence start date cannot be the past date.", smsCampaign.getRecurrenceStartDate());
|
||||
"Recurrence start date cannot be the past date.", recurrenceStartDate);
|
||||
}
|
||||
this.smsCampaignRepository.saveAndFlush(smsCampaign);
|
||||
|
||||
@@ -380,17 +377,15 @@ public class SmsCampaignWritePlatformServiceJpaImpl implements SmsCampaignWriteP
|
||||
if (smsCampaign.isDirect()) {
|
||||
insertDirectCampaignIntoSmsOutboundTable(smsCampaign);
|
||||
} else if (smsCampaign.isSchedule()) {
|
||||
|
||||
/**
|
||||
* if recurrence start date is in the future calculate next trigger date if not use recurrence start date us
|
||||
* next trigger date when activating
|
||||
*/
|
||||
// if recurrence start date is in the future calculate next trigger date if not use recurrence start date us
|
||||
// next trigger date when activating
|
||||
LocalDateTime nextTriggerDate = null;
|
||||
if (smsCampaign.getRecurrenceStartDateTime().isBefore(tenantDateTime())) {
|
||||
nextTriggerDate = CalendarUtils.getNextRecurringDate(smsCampaign.getRecurrence(), smsCampaign.getRecurrenceStartDate(),
|
||||
DateUtils.getLocalDateTimeOfTenant());
|
||||
LocalDateTime tenantDateTime = DateUtils.getLocalDateTimeOfTenant();
|
||||
LocalDateTime recurrenceStartDate = smsCampaign.getRecurrenceStartDate();
|
||||
if (DateUtils.isBefore(recurrenceStartDate, tenantDateTime)) {
|
||||
nextTriggerDate = CalendarUtils.getNextRecurringDate(smsCampaign.getRecurrence(), recurrenceStartDate, tenantDateTime);
|
||||
} else {
|
||||
nextTriggerDate = smsCampaign.getRecurrenceStartDate();
|
||||
nextTriggerDate = recurrenceStartDate;
|
||||
}
|
||||
|
||||
smsCampaign.setNextTriggerDate(nextTriggerDate);
|
||||
@@ -517,7 +512,6 @@ public class SmsCampaignWritePlatformServiceJpaImpl implements SmsCampaignWriteP
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult reactivateSmsCampaign(final Long campaignId, JsonCommand command) {
|
||||
|
||||
this.smsCampaignValidator.validateActivation(command.json());
|
||||
|
||||
final AppUser currentUser = this.context.authenticatedUser();
|
||||
@@ -532,21 +526,16 @@ public class SmsCampaignWritePlatformServiceJpaImpl implements SmsCampaignWriteP
|
||||
if (smsCampaign.isDirect()) {
|
||||
insertDirectCampaignIntoSmsOutboundTable(smsCampaign);
|
||||
} else if (smsCampaign.isSchedule()) {
|
||||
|
||||
/**
|
||||
* if recurrence start date is in the future calculate next trigger date if not use recurrence start date us
|
||||
* next trigger date when activating
|
||||
*/
|
||||
// if recurrence start date is in the past, calculate next trigger date, otherwise use recurrence start date
|
||||
// as next trigger date when activating
|
||||
LocalDateTime nextTriggerDate = null;
|
||||
if (smsCampaign.getRecurrenceStartDateTime().isBefore(tenantDateTime())) {
|
||||
nextTriggerDate = CalendarUtils.getNextRecurringDate(smsCampaign.getRecurrence(), smsCampaign.getRecurrenceStartDate(),
|
||||
DateUtils.getLocalDateTimeOfTenant());
|
||||
LocalDateTime tenantDateTime = DateUtils.getLocalDateTimeOfTenant();
|
||||
LocalDateTime recurrenceStartDate = smsCampaign.getRecurrenceStartDate();
|
||||
if (DateUtils.isBefore(recurrenceStartDate, tenantDateTime)) {
|
||||
nextTriggerDate = CalendarUtils.getNextRecurringDate(smsCampaign.getRecurrence(), recurrenceStartDate, tenantDateTime);
|
||||
} else {
|
||||
nextTriggerDate = smsCampaign.getRecurrenceStartDate();
|
||||
nextTriggerDate = recurrenceStartDate;
|
||||
}
|
||||
// to get time of tenant
|
||||
final LocalDateTime getTime = smsCampaign.getRecurrenceStartDateTime();
|
||||
|
||||
smsCampaign.setNextTriggerDate(nextTriggerDate);
|
||||
}
|
||||
this.smsCampaignRepository.saveAndFlush(smsCampaign);
|
||||
@@ -555,21 +544,7 @@ public class SmsCampaignWritePlatformServiceJpaImpl implements SmsCampaignWriteP
|
||||
}
|
||||
|
||||
private void handleDataIntegrityIssues(final JsonCommand command, final Throwable realCause) {
|
||||
|
||||
throw new PlatformDataIntegrityException("error.msg.sms.campaign.unknown.data.integrity.issue",
|
||||
"Unknown data integrity issue with resource: " + realCause.getMessage());
|
||||
}
|
||||
|
||||
private LocalDateTime tenantDateTime() {
|
||||
LocalDateTime today = LocalDateTime.now(DateUtils.getDateTimeZoneOfTenant());
|
||||
final FineractPlatformTenant tenant = ThreadLocalContextUtil.getTenant();
|
||||
|
||||
if (tenant != null) {
|
||||
final ZoneId zone = ZoneId.of(tenant.getTimezoneId());
|
||||
if (zone != null) {
|
||||
today = LocalDateTime.now(zone);
|
||||
}
|
||||
}
|
||||
return today;
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -61,7 +61,7 @@ public class CustomAuditingHandler extends AuditingHandler {
|
||||
|
||||
private DateTimeProvider fetchDateTimeProvider(Object bean) {
|
||||
if (bean instanceof AbstractAuditableWithUTCDateTimeCustom) {
|
||||
return CustomDateTimeProvider.TENANT;
|
||||
return CustomDateTimeProvider.UTC;
|
||||
} else {
|
||||
return CustomDateTimeProvider.INSTANCE;
|
||||
}
|
||||
|
||||
+4
-7
@@ -18,9 +18,6 @@
|
||||
*/
|
||||
package org.apache.fineract.infrastructure.core.auditing;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.OffsetDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.temporal.TemporalAccessor;
|
||||
import java.util.Optional;
|
||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||
@@ -29,7 +26,7 @@ import org.springframework.data.auditing.DateTimeProvider;
|
||||
|
||||
public enum CustomDateTimeProvider implements DateTimeProvider {
|
||||
|
||||
INSTANCE, TENANT;
|
||||
INSTANCE, UTC;
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
@@ -42,10 +39,10 @@ public enum CustomDateTimeProvider implements DateTimeProvider {
|
||||
|
||||
switch (this) {
|
||||
case INSTANCE -> {
|
||||
return Optional.of(LocalDateTime.now(ZoneId.systemDefault()));
|
||||
return Optional.of(DateUtils.getLocalDateTimeOfSystem());
|
||||
}
|
||||
case TENANT -> {
|
||||
return Optional.of(OffsetDateTime.now(DateUtils.getDateTimeZoneOfTenant()));
|
||||
case UTC -> {
|
||||
return Optional.of(DateUtils.getAuditOffsetDateTime());
|
||||
}
|
||||
}
|
||||
throw new UnsupportedOperationException(this + " is not supported!");
|
||||
|
||||
+3
-3
@@ -113,7 +113,7 @@ public class InteropAccountData extends CommandProcessingResult {
|
||||
|
||||
return new InteropAccountData(account.getExternalId().getValue(), product.getId().toString(), product.getName(),
|
||||
product.getShortName(), account.getCurrency().getCode(), account.getAccountBalance(), account.getWithdrawableBalance(),
|
||||
account.getStatus(), subStatus, account.getAccountType(), account.depositAccountType(), account.getActivationLocalDate(),
|
||||
account.getStatus(), subStatus, account.getAccountType(), account.depositAccountType(), account.getActivationDate(),
|
||||
calcStatusUpdateOn(account), account.getWithdrawnOnDate(), account.retrieveLastTransactionDate(), ids,
|
||||
account.getClient().getId());
|
||||
}
|
||||
@@ -125,8 +125,8 @@ public class InteropAccountData extends CommandProcessingResult {
|
||||
if (account.getWithdrawnOnDate() != null) {
|
||||
return account.getWithdrawnOnDate();
|
||||
}
|
||||
if (account.getActivationLocalDate() != null) {
|
||||
return account.getActivationLocalDate();
|
||||
if (account.getActivationDate() != null) {
|
||||
return account.getActivationDate();
|
||||
}
|
||||
if (account.getRejectedOnDate() != null) {
|
||||
return account.getRejectedOnDate();
|
||||
|
||||
+2
-2
@@ -112,8 +112,8 @@ public class InteropTransactionData extends CommandProcessingResult {
|
||||
String currency = savingsAccount.getCurrency().getCode();
|
||||
BigDecimal runningBalance = transaction.getRunningBalance(savingsAccount.getCurrency()).getAmount();
|
||||
|
||||
LocalDate bookingDateTime = transaction.getTransactionLocalDate();
|
||||
LocalDate endOfBalanceLocalDate = transaction.getEndOfBalanceLocalDate();
|
||||
LocalDate bookingDateTime = transaction.getTransactionDate();
|
||||
LocalDate endOfBalanceLocalDate = transaction.getEndOfBalanceDate();
|
||||
LocalDate valueDateTime = endOfBalanceLocalDate == null ? bookingDateTime : endOfBalanceLocalDate;
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
+5
-5
@@ -30,6 +30,7 @@ import jakarta.validation.constraints.NotNull;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Objects;
|
||||
import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom;
|
||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||
import org.apache.fineract.portfolio.savings.domain.SavingsAccount;
|
||||
|
||||
@Entity
|
||||
@@ -67,18 +68,17 @@ public class InteropIdentifier extends AbstractPersistableCustom {
|
||||
protected InteropIdentifier() {}
|
||||
|
||||
public InteropIdentifier(@NotNull SavingsAccount account, @NotNull InteropIdentifierType type, @NotNull String value, String subType,
|
||||
@NotNull String createdBy, @NotNull LocalDateTime createdOn) {
|
||||
@NotNull String createdBy) {
|
||||
this.account = account;
|
||||
this.type = type;
|
||||
this.value = value;
|
||||
this.subType = subType;
|
||||
this.createdBy = createdBy;
|
||||
this.createdOn = createdOn;
|
||||
this.createdOn = DateUtils.getAuditLocalDateTime();
|
||||
}
|
||||
|
||||
public InteropIdentifier(@NotNull SavingsAccount account, @NotNull InteropIdentifierType type, @NotNull String createdBy,
|
||||
@NotNull LocalDateTime createdOn) {
|
||||
this(account, type, null, null, createdBy, createdOn);
|
||||
public InteropIdentifier(@NotNull SavingsAccount account, @NotNull InteropIdentifierType type, @NotNull String createdBy) {
|
||||
this(account, type, null, null, createdBy);
|
||||
}
|
||||
|
||||
public SavingsAccount getAccount() {
|
||||
|
||||
+10
-17
@@ -243,7 +243,7 @@ public class InteropServiceImpl implements InteropService {
|
||||
return true;
|
||||
}
|
||||
|
||||
java.time.LocalDateTime transactionDate = t.getTransactionLocalDate().atStartOfDay(ZoneId.systemDefault()).toLocalDateTime();
|
||||
java.time.LocalDateTime transactionDate = t.getTransactionDate().atStartOfDay(ZoneId.systemDefault()).toLocalDateTime();
|
||||
return (transactionsTo == null || transactionsTo.compareTo(transactionDate) > 0) && (transactionsFrom == null
|
||||
|| transactionsFrom.compareTo(transactionDate.withHour(23).withMinute(59).withSecond(59)) <= 0);
|
||||
};
|
||||
@@ -276,16 +276,15 @@ public class InteropServiceImpl implements InteropService {
|
||||
@Override
|
||||
public InteropIdentifierAccountResponseData registerAccountIdentifier(@NotNull InteropIdentifierType idType, @NotNull String idValue,
|
||||
String subIdOrType, @NotNull JsonCommand command) {
|
||||
|
||||
InteropIdentifierRequestData request = dataValidator.validateAndParseCreateIdentifier(idType, idValue, subIdOrType, command);
|
||||
// TODO: error handling
|
||||
SavingsAccount savingsAccount = validateAndGetSavingAccount(request.getAccountId());
|
||||
|
||||
try {
|
||||
AppUser createdBy = getLoginUser();
|
||||
AppUser createdBy = securityContext.authenticatedUser();
|
||||
|
||||
InteropIdentifier identifier = new InteropIdentifier(savingsAccount, request.getIdType(), request.getIdValue(),
|
||||
request.getSubIdOrType(), createdBy.getUsername(), DateUtils.getLocalDateTimeOfTenant());
|
||||
request.getSubIdOrType(), createdBy.getUsername());
|
||||
|
||||
identifierRepository.saveAndFlush(identifier);
|
||||
|
||||
@@ -401,10 +400,9 @@ public class InteropServiceImpl implements InteropService {
|
||||
PaymentDetail paymentDetail = instance(findPaymentType(), savingsAccount.getExternalId().getValue(), null, getRoutingCode(),
|
||||
transferCode, null);
|
||||
SavingsAccountTransaction holdTransaction = SavingsAccountTransaction.holdAmount(savingsAccount, savingsAccount.office(),
|
||||
paymentDetail, transactionDate, Money.of(savingsAccount.getCurrency(), total), DateUtils.getLocalDateTimeOfTenant(),
|
||||
getLoginUser(), false);
|
||||
paymentDetail, transactionDate, Money.of(savingsAccount.getCurrency(), total), false);
|
||||
MonetaryCurrency accountCurrency = savingsAccount.getCurrency().copy();
|
||||
holdTransaction.updateRunningBalance(
|
||||
holdTransaction.setRunningBalance(
|
||||
Money.of(accountCurrency, savingsAccount.getWithdrawableBalance().subtract(holdTransaction.getAmount())));
|
||||
holdTransaction.updateCumulativeBalanceAndDates(accountCurrency, transactionDate);
|
||||
|
||||
@@ -454,8 +452,8 @@ public class InteropServiceImpl implements InteropService {
|
||||
}
|
||||
|
||||
if (holdTransaction.getReleaseIdOfHoldAmountTransaction() == null) {
|
||||
SavingsAccountTransaction releaseTransaction = savingsAccountTransactionRepository.saveAndFlush(
|
||||
releaseAmount(holdTransaction, transactionDate, DateUtils.getLocalDateTimeOfSystem(), getLoginUser()));
|
||||
SavingsAccountTransaction releaseTransaction = savingsAccountTransactionRepository
|
||||
.saveAndFlush(releaseAmount(holdTransaction, transactionDate));
|
||||
holdTransaction.updateReleaseId(releaseTransaction.getId());
|
||||
savingsAccount.releaseOnHoldAmount(holdTransaction.getAmount());
|
||||
savingsAccount.addTransaction(releaseTransaction);
|
||||
@@ -493,11 +491,10 @@ public class InteropServiceImpl implements InteropService {
|
||||
SavingsAccountTransaction holdTransaction = findTransaction(savingsAccount, request.getTransferCode(), AMOUNT_HOLD.getValue());
|
||||
|
||||
if (holdTransaction != null && holdTransaction.getReleaseIdOfHoldAmountTransaction() == null) {
|
||||
SavingsAccountTransaction releaseTransaction = releaseAmount(holdTransaction, transactionDate,
|
||||
DateUtils.getLocalDateTimeOfSystem(), getLoginUser());
|
||||
SavingsAccountTransaction releaseTransaction = releaseAmount(holdTransaction, transactionDate);
|
||||
MonetaryCurrency accountCurrency = savingsAccount.getCurrency().copy();
|
||||
releaseTransaction.updateRunningBalance(
|
||||
Money.of(accountCurrency, savingsAccount.getWithdrawableBalance().add(holdTransaction.getAmount())));
|
||||
releaseTransaction
|
||||
.setRunningBalance(Money.of(accountCurrency, savingsAccount.getWithdrawableBalance().add(holdTransaction.getAmount())));
|
||||
releaseTransaction.updateCumulativeBalanceAndDates(accountCurrency, transactionDate);
|
||||
releaseTransaction = savingsAccountTransactionRepository.saveAndFlush(releaseTransaction);
|
||||
holdTransaction.updateReleaseId(releaseTransaction.getId());
|
||||
@@ -652,10 +649,6 @@ public class InteropServiceImpl implements InteropService {
|
||||
return identifierRepository.findOneByTypeAndValueAndSubType(idType, idValue, subIdOrType);
|
||||
}
|
||||
|
||||
private AppUser getLoginUser() {
|
||||
return securityContext.getAuthenticatedUserIfPresent();
|
||||
}
|
||||
|
||||
/*
|
||||
* Guaranteed to throw an exception no matter what the data integrity issue is.
|
||||
*/
|
||||
|
||||
+4
-3
@@ -34,6 +34,7 @@ import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.apache.fineract.infrastructure.core.data.CommandProcessingResultBuilder;
|
||||
import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder;
|
||||
import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException;
|
||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||
import org.apache.fineract.portfolio.calendar.CalendarConstants.CalendarSupportedParameters;
|
||||
import org.apache.fineract.portfolio.calendar.domain.Calendar;
|
||||
import org.apache.fineract.portfolio.calendar.domain.CalendarEntityType;
|
||||
@@ -78,7 +79,7 @@ public class CalendarWritePlatformServiceJpaRepositoryImpl implements CalendarWr
|
||||
Group centerOrGroup = null;
|
||||
if (command.getGroupId() != null) {
|
||||
centerOrGroup = this.groupRepository.findOneWithNotFoundDetection(command.getGroupId());
|
||||
entityActivationDate = centerOrGroup.getActivationLocalDate();
|
||||
entityActivationDate = centerOrGroup.getActivationDate();
|
||||
entityType = centerOrGroup.isCenter() ? CalendarEntityType.CENTERS : CalendarEntityType.GROUPS;
|
||||
entityId = command.getGroupId();
|
||||
} else if (command.getLoanId() != null) {
|
||||
@@ -88,7 +89,7 @@ public class CalendarWritePlatformServiceJpaRepositoryImpl implements CalendarWr
|
||||
entityId = command.getLoanId();
|
||||
} else if (command.getClientId() != null) {
|
||||
final Client client = this.clientRepository.findOneWithNotFoundDetection(command.getClientId());
|
||||
entityActivationDate = client.getActivationLocalDate();
|
||||
entityActivationDate = client.getActivationDate();
|
||||
entityType = CalendarEntityType.CLIENTS;
|
||||
entityId = command.getClientId();
|
||||
}
|
||||
@@ -98,7 +99,7 @@ public class CalendarWritePlatformServiceJpaRepositoryImpl implements CalendarWr
|
||||
|
||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
|
||||
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("calendar");
|
||||
if (entityActivationDate == null || newCalendar.getStartDateLocalDate().isBefore(entityActivationDate)) {
|
||||
if (entityActivationDate == null || DateUtils.isBefore(newCalendar.getStartDateLocalDate(), entityActivationDate)) {
|
||||
final DateTimeFormatter formatter = DateTimeFormatter.ofPattern(command.dateFormat()).withLocale(command.extractLocale());
|
||||
String dateAsString = "";
|
||||
if (entityActivationDate != null) {
|
||||
|
||||
+5
-6
@@ -230,8 +230,7 @@ public class InterestRateChart extends AbstractPersistableCustom {
|
||||
if (!existingChart.equals(this)) {
|
||||
if (this.chartFields.isOverlapping(existingChart.chartFields)) {
|
||||
baseDataValidator.failWithCodeNoParameterAddedToErrorCode("chart.overlapping.from.and.end.dates",
|
||||
existingChart.getFromDateAsLocalDate(), existingChart.getEndDateAsLocalDate(), this.getFromDateAsLocalDate(),
|
||||
this.getEndDateAsLocalDate());
|
||||
existingChart.getFromDate(), existingChart.getEndDate(), this.getFromDate(), this.getEndDate());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -318,12 +317,12 @@ public class InterestRateChart extends AbstractPersistableCustom {
|
||||
return chartSlabs.remove(chartSlab);
|
||||
}
|
||||
|
||||
public LocalDate getFromDateAsLocalDate() {
|
||||
return this.chartFields.getFromDateAsLocalDate();
|
||||
public LocalDate getFromDate() {
|
||||
return this.chartFields.getFromDate();
|
||||
}
|
||||
|
||||
public LocalDate getEndDateAsLocalDate() {
|
||||
return this.chartFields.getEndDateAsLocalDate();
|
||||
public LocalDate getEndDate() {
|
||||
return this.chartFields.getEndDate();
|
||||
}
|
||||
|
||||
private void throwExceptionIfValidationWarningsExist(final List<ApiParameterError> dataValidationErrors) {
|
||||
|
||||
+12
-16
@@ -88,7 +88,7 @@ public class InterestRateChartFields {
|
||||
final String localeAsInput = command.locale();
|
||||
final String dateFormat = command.dateFormat();
|
||||
|
||||
if (command.isChangeInLocalDateParameterNamed(fromDateParamName, getFromDateAsLocalDate())) {
|
||||
if (command.isChangeInLocalDateParameterNamed(fromDateParamName, getFromDate())) {
|
||||
final String newValueAsString = command.stringValueOfParameterNamed(fromDateParamName);
|
||||
actualChanges.put(fromDateParamName, newValueAsString);
|
||||
actualChanges.put(localeParamName, localeAsInput);
|
||||
@@ -96,7 +96,7 @@ public class InterestRateChartFields {
|
||||
this.fromDate = command.localDateValueOfParameterNamed(fromDateParamName);
|
||||
}
|
||||
|
||||
if (command.isChangeInLocalDateParameterNamed(endDateParamName, getEndDateAsLocalDate())) {
|
||||
if (command.isChangeInLocalDateParameterNamed(endDateParamName, getEndDate())) {
|
||||
final String newValueAsString = command.stringValueOfParameterNamed(endDateParamName);
|
||||
actualChanges.put(endDateParamName, newValueAsString);
|
||||
actualChanges.put(localeParamName, localeAsInput);
|
||||
@@ -116,31 +116,27 @@ public class InterestRateChartFields {
|
||||
}
|
||||
|
||||
public boolean isFromDateAfterToDate() {
|
||||
return isFromDateAfter(getEndDateAsLocalDate());
|
||||
return isFromDateAfter(getEndDate());
|
||||
}
|
||||
|
||||
public boolean isFromDateAfter(LocalDate compare) {
|
||||
final LocalDate fromDate = getFromDateAsLocalDate();
|
||||
if (fromDate != null && compare != null) {
|
||||
return fromDate.isAfter(compare);
|
||||
}
|
||||
return false;
|
||||
return compare != null && DateUtils.isAfter(getFromDate(), compare);
|
||||
}
|
||||
|
||||
public LocalDate getFromDateAsLocalDate() {
|
||||
public LocalDate getFromDate() {
|
||||
return this.fromDate;
|
||||
}
|
||||
|
||||
public LocalDate getEndDateAsLocalDate() {
|
||||
public LocalDate getEndDate() {
|
||||
return this.endDate;
|
||||
}
|
||||
|
||||
public boolean isOverlapping(InterestRateChartFields that) {
|
||||
final LocalDate thisFromDate = this.getFromDateAsLocalDate();
|
||||
LocalDate thisEndDate = this.getEndDateAsLocalDate();
|
||||
final LocalDate thisFromDate = this.getFromDate();
|
||||
LocalDate thisEndDate = this.getEndDate();
|
||||
thisEndDate = thisEndDate == null ? DateUtils.getBusinessLocalDate() : thisEndDate;
|
||||
final LocalDate thatFromDate = that.getFromDateAsLocalDate();
|
||||
LocalDate thatEndDate = that.getEndDateAsLocalDate();
|
||||
final LocalDate thatFromDate = that.getFromDate();
|
||||
LocalDate thatEndDate = that.getEndDate();
|
||||
thatEndDate = thatEndDate == null ? DateUtils.getBusinessLocalDate() : thatEndDate;
|
||||
|
||||
final LocalDateInterval thisInterval = LocalDateInterval.create(thisFromDate, thisEndDate);
|
||||
@@ -153,8 +149,8 @@ public class InterestRateChartFields {
|
||||
}
|
||||
|
||||
public boolean isApplicableChartFor(final LocalDate target) {
|
||||
final LocalDate endDate = this.endDate == null ? DateUtils.getBusinessLocalDate() : this.getEndDateAsLocalDate();
|
||||
final LocalDateInterval interval = LocalDateInterval.create(getFromDateAsLocalDate(), endDate);
|
||||
final LocalDate endDate = this.endDate == null ? DateUtils.getBusinessLocalDate() : this.getEndDate();
|
||||
final LocalDateInterval interval = LocalDateInterval.create(getFromDate(), endDate);
|
||||
return interval.contains(target);
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -327,7 +327,7 @@ public class GuarantorDomainServiceImpl implements GuarantorDomainService {
|
||||
if (loan.isApproved() && !loan.isDisbursed()) {
|
||||
final List<SavingsAccountTransaction> transactions = new ArrayList<>();
|
||||
for (final SavingsAccountTransaction transaction : savingsAccount.getTransactions()) {
|
||||
if (!transaction.getTransactionLocalDate().isAfter(loan.getApprovedOnDate())) {
|
||||
if (!transaction.getTransactionDate().isAfter(loan.getApprovedOnDate())) {
|
||||
transactions.add(transaction);
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -187,12 +187,12 @@ public class GuarantorWritePlatformServiceJpaRepositoryIImpl implements Guaranto
|
||||
|
||||
private void validateGuarantorSavingsAccountActivationDateWithLoanSubmittedOnDate(final Loan loan,
|
||||
final SavingsAccount savingsAccount) {
|
||||
if (loan.getSubmittedOnDate().isBefore(savingsAccount.getActivationLocalDate())) {
|
||||
if (loan.getSubmittedOnDate().isBefore(savingsAccount.getActivationDate())) {
|
||||
throw new GeneralPlatformDomainRuleException(
|
||||
"error.msg.guarantor.saving.account.activation.date.is.on.or.before.loan.submitted.on.date",
|
||||
"Guarantor saving account activation date [" + savingsAccount.getActivationLocalDate()
|
||||
"Guarantor saving account activation date [" + savingsAccount.getActivationDate()
|
||||
+ "] is on or before the loan submitted on date [" + loan.getSubmittedOnDate() + "]",
|
||||
savingsAccount.getActivationLocalDate(), loan.getSubmittedOnDate());
|
||||
savingsAccount.getActivationDate(), loan.getSubmittedOnDate());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -23,6 +23,7 @@ import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import org.apache.fineract.infrastructure.codes.data.CodeValueData;
|
||||
import org.apache.fineract.infrastructure.core.data.EnumOptionData;
|
||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||
import org.apache.fineract.portfolio.interestratechart.data.InterestRateChartData;
|
||||
import org.apache.fineract.portfolio.interestratechart.data.InterestRateChartSlabData;
|
||||
|
||||
@@ -159,12 +160,11 @@ public final class DepositAccountInterestRateChartData {
|
||||
if (this.chartSlabs == null) {
|
||||
this.chartSlabs = new ArrayList<>();
|
||||
}
|
||||
|
||||
this.chartSlabs.add(chartSlab);
|
||||
}
|
||||
|
||||
public boolean isFromDateAfter(final LocalDate compareDate) {
|
||||
return (compareDate == null) ? false : this.fromDate.isAfter(compareDate);
|
||||
return compareDate != null && DateUtils.isAfter(this.fromDate, compareDate);
|
||||
}
|
||||
|
||||
public LocalDate endDate() {
|
||||
|
||||
+1
-30
@@ -20,10 +20,8 @@ package org.apache.fineract.portfolio.savings.data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import org.apache.fineract.portfolio.paymentdetail.domain.PaymentDetail;
|
||||
import org.apache.fineract.useradministration.domain.AppUser;
|
||||
|
||||
public class SavingsAccountTransactionDTO {
|
||||
|
||||
@@ -31,24 +29,9 @@ public class SavingsAccountTransactionDTO {
|
||||
private final LocalDate transactionDate;
|
||||
private final BigDecimal transactionAmount;
|
||||
private final PaymentDetail paymentDetail;
|
||||
private final LocalDateTime createdDate;
|
||||
private final Long savingsAccountId;
|
||||
private final AppUser appUser;
|
||||
private final Integer depositAccountType;
|
||||
|
||||
public SavingsAccountTransactionDTO(final DateTimeFormatter formatter, final LocalDate transactionDate,
|
||||
final BigDecimal transactionAmount, final PaymentDetail paymentDetail, final LocalDateTime createdDate, final AppUser appUser,
|
||||
final Integer depositAccountType) {
|
||||
this.formatter = formatter;
|
||||
this.transactionDate = transactionDate;
|
||||
this.transactionAmount = transactionAmount;
|
||||
this.paymentDetail = paymentDetail;
|
||||
this.createdDate = createdDate;
|
||||
this.savingsAccountId = null;
|
||||
this.appUser = appUser;
|
||||
this.depositAccountType = depositAccountType;
|
||||
}
|
||||
|
||||
/**
|
||||
* This constructor is used for bulk deposit transactions
|
||||
*
|
||||
@@ -56,19 +39,15 @@ public class SavingsAccountTransactionDTO {
|
||||
* @param transactionDate
|
||||
* @param transactionAmount
|
||||
* @param paymentDetail
|
||||
* @param createdDate
|
||||
* @param savingsAccountId
|
||||
*/
|
||||
public SavingsAccountTransactionDTO(DateTimeFormatter formatter, LocalDate transactionDate, BigDecimal transactionAmount,
|
||||
PaymentDetail paymentDetail, LocalDateTime createdDate, Long savingsAccountId, AppUser appUser,
|
||||
final Integer depositAccountType) {
|
||||
PaymentDetail paymentDetail, Long savingsAccountId, final Integer depositAccountType) {
|
||||
this.formatter = formatter;
|
||||
this.transactionDate = transactionDate;
|
||||
this.transactionAmount = transactionAmount;
|
||||
this.paymentDetail = paymentDetail;
|
||||
this.createdDate = createdDate;
|
||||
this.savingsAccountId = savingsAccountId;
|
||||
this.appUser = appUser;
|
||||
this.depositAccountType = depositAccountType;
|
||||
}
|
||||
|
||||
@@ -88,18 +67,10 @@ public class SavingsAccountTransactionDTO {
|
||||
return this.paymentDetail;
|
||||
}
|
||||
|
||||
public LocalDateTime getCreatedDate() {
|
||||
return this.createdDate;
|
||||
}
|
||||
|
||||
public Long getSavingsAccountId() {
|
||||
return this.savingsAccountId;
|
||||
}
|
||||
|
||||
public AppUser getAppUser() {
|
||||
return this.appUser;
|
||||
}
|
||||
|
||||
public Integer getAccountType() {
|
||||
return this.depositAccountType;
|
||||
}
|
||||
|
||||
+4
-10
@@ -37,7 +37,6 @@ import com.google.gson.reflect.TypeToken;
|
||||
import java.lang.reflect.Type;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
@@ -83,7 +82,6 @@ public class SavingsAccountTransactionDataValidator {
|
||||
}
|
||||
|
||||
public void validateTransactionWithPivotDate(final LocalDate transactionDate, final SavingsAccount savingsAccount) {
|
||||
|
||||
final boolean backdatedTxnsAllowedTill = this.configurationDomainService.retrievePivotDateConfig();
|
||||
final boolean isRelaxingDaysConfigOn = this.configurationDomainService.isRelaxingDaysConfigForPivotDateEnabled();
|
||||
|
||||
@@ -94,14 +92,13 @@ public class SavingsAccountTransactionDataValidator {
|
||||
if (isRelaxingDaysConfigOn) {
|
||||
pivotDate = pivotDate.minusDays(this.configurationDomainService.retrieveRelaxingDaysConfigForPivotDate());
|
||||
}
|
||||
if (pivotDate.isAfter(transactionDate)) {
|
||||
if (DateUtils.isAfter(pivotDate, transactionDate)) {
|
||||
throw new TransactionBeforePivotDateNotAllowed(transactionDate, pivotDate);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void validate(final JsonCommand command) {
|
||||
|
||||
final String json = command.json();
|
||||
|
||||
if (StringUtils.isBlank(json)) {
|
||||
@@ -296,7 +293,7 @@ public class SavingsAccountTransactionDataValidator {
|
||||
}
|
||||
|
||||
// compare two dates now
|
||||
if (lastTransactionDate != null && transactionDate.isBefore(lastTransactionDate)) {
|
||||
if (DateUtils.isBefore(transactionDate, lastTransactionDate)) {
|
||||
baseDataValidator.parameter(SavingsApiConstants.dateParamName).value(lastTransactionDate).failWithCode(
|
||||
"validation.msg.date.can.not.be.before.last.transaction.date", "Amount can be put on hold only after last transaction");
|
||||
}
|
||||
@@ -304,8 +301,7 @@ public class SavingsAccountTransactionDataValidator {
|
||||
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
||||
}
|
||||
|
||||
public SavingsAccountTransaction validateReleaseAmountAndAssembleForm(final SavingsAccountTransaction holdTransaction,
|
||||
final AppUser createdUser) {
|
||||
public SavingsAccountTransaction validateReleaseAmountAndAssembleForm(final SavingsAccountTransaction holdTransaction) {
|
||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
|
||||
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
|
||||
.resource(SAVINGS_ACCOUNT_RESOURCE_NAME);
|
||||
@@ -326,10 +322,8 @@ public class SavingsAccountTransactionDataValidator {
|
||||
}
|
||||
|
||||
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
||||
LocalDateTime createdDate = DateUtils.getLocalDateTimeOfSystem();
|
||||
LocalDate transactionDate = DateUtils.getBusinessLocalDate();
|
||||
SavingsAccountTransaction transaction = SavingsAccountTransaction.releaseAmount(holdTransaction, transactionDate, createdDate,
|
||||
createdUser);
|
||||
SavingsAccountTransaction transaction = SavingsAccountTransaction.releaseAmount(holdTransaction, transactionDate);
|
||||
return transaction;
|
||||
}
|
||||
|
||||
|
||||
+2
-13
@@ -69,7 +69,6 @@ import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||
import org.apache.fineract.infrastructure.core.exception.InvalidJsonException;
|
||||
import org.apache.fineract.infrastructure.core.exception.UnsupportedParameterException;
|
||||
import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
|
||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||
import org.apache.fineract.infrastructure.core.service.ExternalIdFactory;
|
||||
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
|
||||
import org.apache.fineract.organisation.staff.domain.Staff;
|
||||
@@ -358,7 +357,7 @@ public class DepositAccountAssembler {
|
||||
|
||||
if (account != null) {
|
||||
account.setHelpers(this.savingsAccountTransactionSummaryWrapper, this.savingsHelper);
|
||||
account.validateNewApplicationState(DateUtils.getBusinessLocalDate(), depositAccountType.resourceName());
|
||||
account.validateNewApplicationState(depositAccountType.resourceName());
|
||||
}
|
||||
|
||||
return account;
|
||||
@@ -448,7 +447,6 @@ public class DepositAccountAssembler {
|
||||
|
||||
public Collection<SavingsAccountTransactionDTO> assembleBulkMandatorySavingsAccountTransactionDTOs(final JsonCommand command,
|
||||
final PaymentDetail paymentDetail) {
|
||||
AppUser user = getAppUserIfPresent();
|
||||
final String json = command.json();
|
||||
if (StringUtils.isBlank(json)) {
|
||||
throw new InvalidJsonException();
|
||||
@@ -478,7 +476,7 @@ public class DepositAccountAssembler {
|
||||
detail = this.paymentDetailAssembler.fetchPaymentDetail(savingsTransactionElement);
|
||||
}
|
||||
final SavingsAccountTransactionDTO savingsAccountTransactionDTO = new SavingsAccountTransactionDTO(formatter,
|
||||
transactionDate, dueAmount, detail, DateUtils.getLocalDateTimeOfSystem(), savingsId, user, depositAccountType);
|
||||
transactionDate, dueAmount, detail, savingsId, depositAccountType);
|
||||
savingsAccountTransactions.add(savingsAccountTransactionDTO);
|
||||
}
|
||||
}
|
||||
@@ -486,13 +484,4 @@ public class DepositAccountAssembler {
|
||||
|
||||
return savingsAccountTransactions;
|
||||
}
|
||||
|
||||
private AppUser getAppUserIfPresent() {
|
||||
AppUser user = null;
|
||||
if (this.context != null) {
|
||||
user = this.context.getAuthenticatedUserIfPresent();
|
||||
}
|
||||
return user;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+7
-8
@@ -42,19 +42,18 @@ public interface DepositAccountDomainService {
|
||||
BigDecimal transactionAmount, PaymentDetail paymentDetail, boolean isRegularTransaction);
|
||||
|
||||
Long handleFDAccountClosure(FixedDepositAccount account, PaymentDetail paymentDetail, AppUser user, JsonCommand command,
|
||||
LocalDate tenantsTodayDate, Map<String, Object> changes);
|
||||
|
||||
@Transactional
|
||||
Long handleFDAccountMaturityClosure(FixedDepositAccount account, PaymentDetail paymentDetail, AppUser user, LocalDate tenantsTodayDate,
|
||||
DateTimeFormatter fmt, LocalDate closedDate, Integer onAccountClosureId, Long toSavingsId, String transferDescription,
|
||||
Map<String, Object> changes);
|
||||
|
||||
@Transactional
|
||||
Long handleFDAccountMaturityClosure(FixedDepositAccount account, PaymentDetail paymentDetail, AppUser user, DateTimeFormatter fmt,
|
||||
LocalDate closedDate, Integer onAccountClosureId, Long toSavingsId, String transferDescription, Map<String, Object> changes);
|
||||
|
||||
Long handleRDAccountClosure(RecurringDepositAccount account, PaymentDetail paymentDetail, AppUser user, JsonCommand command,
|
||||
LocalDate tenantsTodayDate, Map<String, Object> changes);
|
||||
Map<String, Object> changes);
|
||||
|
||||
Long handleFDAccountPreMatureClosure(FixedDepositAccount account, PaymentDetail paymentDetail, AppUser user, JsonCommand command,
|
||||
LocalDate tenantsTodayDate, Map<String, Object> changes);
|
||||
Map<String, Object> changes);
|
||||
|
||||
Long handleRDAccountPreMatureClosure(RecurringDepositAccount account, PaymentDetail paymentDetail, AppUser user, JsonCommand command,
|
||||
LocalDate tenantsTodayDate, Map<String, Object> changes);
|
||||
Map<String, Object> changes);
|
||||
}
|
||||
|
||||
+17
-41
@@ -40,8 +40,6 @@ import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||
import org.apache.fineract.infrastructure.core.domain.ExternalId;
|
||||
import org.apache.fineract.infrastructure.core.exception.GeneralPlatformDomainRuleException;
|
||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
|
||||
import org.apache.fineract.organisation.monetary.domain.ApplicationCurrencyRepositoryWrapper;
|
||||
import org.apache.fineract.portfolio.account.PortfolioAccountType;
|
||||
import org.apache.fineract.portfolio.account.data.AccountTransferDTO;
|
||||
import org.apache.fineract.portfolio.account.domain.AccountTransferType;
|
||||
@@ -69,9 +67,7 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
@Service
|
||||
public class DepositAccountDomainServiceJpa implements DepositAccountDomainService {
|
||||
|
||||
private final PlatformSecurityContext context;
|
||||
private final SavingsAccountRepositoryWrapper savingsAccountRepository;
|
||||
private final ApplicationCurrencyRepositoryWrapper applicationCurrencyRepositoryWrapper;
|
||||
private final JournalEntryWritePlatformService journalEntryWritePlatformService;
|
||||
private final AccountNumberGenerator accountNumberGenerator;
|
||||
private final DepositAccountAssembler depositAccountAssembler;
|
||||
@@ -82,18 +78,14 @@ public class DepositAccountDomainServiceJpa implements DepositAccountDomainServi
|
||||
private final CalendarInstanceRepository calendarInstanceRepository;
|
||||
|
||||
@Autowired
|
||||
public DepositAccountDomainServiceJpa(final PlatformSecurityContext context,
|
||||
final SavingsAccountRepositoryWrapper savingsAccountRepository,
|
||||
final ApplicationCurrencyRepositoryWrapper applicationCurrencyRepositoryWrapper,
|
||||
public DepositAccountDomainServiceJpa(final SavingsAccountRepositoryWrapper savingsAccountRepository,
|
||||
final JournalEntryWritePlatformService journalEntryWritePlatformService, final AccountNumberGenerator accountNumberGenerator,
|
||||
final DepositAccountAssembler depositAccountAssembler, final SavingsAccountDomainService savingsAccountDomainService,
|
||||
final AccountTransfersWritePlatformService accountTransfersWritePlatformService,
|
||||
final ConfigurationDomainService configurationDomainService,
|
||||
final AccountNumberFormatRepositoryWrapper accountNumberFormatRepository,
|
||||
final CalendarInstanceRepository calendarInstanceRepository) {
|
||||
this.context = context;
|
||||
this.savingsAccountRepository = savingsAccountRepository;
|
||||
this.applicationCurrencyRepositoryWrapper = applicationCurrencyRepositoryWrapper;
|
||||
this.journalEntryWritePlatformService = journalEntryWritePlatformService;
|
||||
this.accountNumberGenerator = accountNumberGenerator;
|
||||
this.depositAccountAssembler = depositAccountAssembler;
|
||||
@@ -135,7 +127,6 @@ public class DepositAccountDomainServiceJpa implements DepositAccountDomainServi
|
||||
public SavingsAccountTransaction handleRDDeposit(final RecurringDepositAccount account, final DateTimeFormatter fmt,
|
||||
final LocalDate transactionDate, final BigDecimal transactionAmount, final PaymentDetail paymentDetail,
|
||||
final boolean isRegularTransaction) {
|
||||
AppUser user = getAppUserIfPresent();
|
||||
final boolean isSavingsInterestPostingAtCurrentPeriodEnd = this.configurationDomainService
|
||||
.isSavingsInterestPostingAtCurrentPeriodEnd();
|
||||
final Integer financialYearBeginningMonth = this.configurationDomainService.retrieveFinancialYearBeginningMonth();
|
||||
@@ -151,7 +142,7 @@ public class DepositAccountDomainServiceJpa implements DepositAccountDomainServi
|
||||
final boolean isAnyActivationChargesDue = isAnyActivationChargesDue(account);
|
||||
if (isAnyActivationChargesDue) {
|
||||
updateExistingTransactionsDetails(account, existingTransactionIds, existingReversedTransactionIds);
|
||||
account.processAccountUponActivation(isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth, user);
|
||||
account.processAccountUponActivation(isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth);
|
||||
this.savingsAccountRepository.saveAndFlush(account);
|
||||
}
|
||||
account.handleScheduleInstallments(deposit);
|
||||
@@ -193,8 +184,7 @@ public class DepositAccountDomainServiceJpa implements DepositAccountDomainServi
|
||||
@Transactional
|
||||
@Override
|
||||
public Long handleFDAccountClosure(final FixedDepositAccount account, final PaymentDetail paymentDetail, final AppUser user,
|
||||
final JsonCommand command, final LocalDate tenantsTodayDate, final Map<String, Object> changes) {
|
||||
|
||||
final JsonCommand command, final Map<String, Object> changes) {
|
||||
final boolean isSavingsInterestPostingAtCurrentPeriodEnd = this.configurationDomainService
|
||||
.isSavingsInterestPostingAtCurrentPeriodEnd();
|
||||
final Integer financialYearBeginningMonth = this.configurationDomainService.retrieveFinancialYearBeginningMonth();
|
||||
@@ -204,9 +194,7 @@ public class DepositAccountDomainServiceJpa implements DepositAccountDomainServi
|
||||
final boolean isPreMatureClosure = false;
|
||||
final Set<Long> existingTransactionIds = new HashSet<>();
|
||||
final Set<Long> existingReversedTransactionIds = new HashSet<>();
|
||||
/***
|
||||
* Update account transactionIds for post journal entries.
|
||||
*/
|
||||
// Update account transactionIds for post journal entries.
|
||||
updateExistingTransactionsDetails(account, existingTransactionIds, existingReversedTransactionIds);
|
||||
/*
|
||||
* final SavingsAccountTransactionDTO transactionDTO = new SavingsAccountTransactionDTO(fmt, transactionDate,
|
||||
@@ -254,7 +242,7 @@ public class DepositAccountDomainServiceJpa implements DepositAccountDomainServi
|
||||
savingsTransactionId = withdrawal.getId();
|
||||
}
|
||||
|
||||
account.close(user, command, tenantsTodayDate, changes);
|
||||
account.close(user, command, changes);
|
||||
this.savingsAccountRepository.save(account);
|
||||
|
||||
return savingsTransactionId;
|
||||
@@ -263,8 +251,8 @@ public class DepositAccountDomainServiceJpa implements DepositAccountDomainServi
|
||||
@Transactional
|
||||
@Override
|
||||
public Long handleFDAccountMaturityClosure(final FixedDepositAccount account, final PaymentDetail paymentDetail, final AppUser user,
|
||||
final LocalDate tenantsTodayDate, final DateTimeFormatter fmt, final LocalDate closedDate, final Integer onAccountClosureId,
|
||||
final Long toSavingsId, final String transferDescription, Map<String, Object> changes) {
|
||||
final DateTimeFormatter fmt, final LocalDate closedDate, final Integer onAccountClosureId, final Long toSavingsId,
|
||||
final String transferDescription, Map<String, Object> changes) {
|
||||
|
||||
final boolean isSavingsInterestPostingAtCurrentPeriodEnd = this.configurationDomainService
|
||||
.isSavingsInterestPostingAtCurrentPeriodEnd();
|
||||
@@ -329,7 +317,7 @@ public class DepositAccountDomainServiceJpa implements DepositAccountDomainServi
|
||||
}
|
||||
|
||||
// if(!processMaturityInstructionOnly)
|
||||
// account.close(user, command, tenantsTodayDate, changes);
|
||||
// account.close(user, command, changes);
|
||||
|
||||
this.savingsAccountRepository.save(account);
|
||||
|
||||
@@ -341,7 +329,7 @@ public class DepositAccountDomainServiceJpa implements DepositAccountDomainServi
|
||||
@Transactional
|
||||
@Override
|
||||
public Long handleRDAccountClosure(final RecurringDepositAccount account, final PaymentDetail paymentDetail, final AppUser user,
|
||||
final JsonCommand command, final LocalDate tenantsTodayDate, final Map<String, Object> changes) {
|
||||
final JsonCommand command, final Map<String, Object> changes) {
|
||||
|
||||
final boolean isSavingsInterestPostingAtCurrentPeriodEnd = this.configurationDomainService
|
||||
.isSavingsInterestPostingAtCurrentPeriodEnd();
|
||||
@@ -352,9 +340,7 @@ public class DepositAccountDomainServiceJpa implements DepositAccountDomainServi
|
||||
final boolean isPreMatureClosure = false;
|
||||
final Set<Long> existingTransactionIds = new HashSet<>();
|
||||
final Set<Long> existingReversedTransactionIds = new HashSet<>();
|
||||
/***
|
||||
* Update account transactionIds for post journal entries.
|
||||
*/
|
||||
// Update account transactionIds for post journal entries.
|
||||
updateExistingTransactionsDetails(account, existingTransactionIds, existingReversedTransactionIds);
|
||||
|
||||
final MathContext mc = MathContext.DECIMAL64;
|
||||
@@ -383,7 +369,7 @@ public class DepositAccountDomainServiceJpa implements DepositAccountDomainServi
|
||||
Integer frequency = CalendarUtils.getInterval(calendar.getRecurrence());
|
||||
frequency = frequency == -1 ? 1 : frequency;
|
||||
reinvestedDeposit.generateSchedule(frequencyType, frequency, calendar);
|
||||
reinvestedDeposit.processAccountUponActivation(fmt, user, postReversals);
|
||||
reinvestedDeposit.processAccountUponActivation(fmt, postReversals);
|
||||
reinvestedDeposit.updateMaturityDateAndAmount(mc, isPreMatureClosure, isSavingsInterestPostingAtCurrentPeriodEnd,
|
||||
financialYearBeginningMonth);
|
||||
this.savingsAccountRepository.save(reinvestedDeposit);
|
||||
@@ -411,7 +397,7 @@ public class DepositAccountDomainServiceJpa implements DepositAccountDomainServi
|
||||
savingsTransactionId = withdrawal.getId();
|
||||
}
|
||||
|
||||
account.close(user, command, tenantsTodayDate, changes);
|
||||
account.close(user, command, changes);
|
||||
|
||||
this.savingsAccountRepository.save(account);
|
||||
|
||||
@@ -456,7 +442,7 @@ public class DepositAccountDomainServiceJpa implements DepositAccountDomainServi
|
||||
@Transactional
|
||||
@Override
|
||||
public Long handleFDAccountPreMatureClosure(final FixedDepositAccount account, final PaymentDetail paymentDetail, final AppUser user,
|
||||
final JsonCommand command, final LocalDate tenantsTodayDate, final Map<String, Object> changes) {
|
||||
final JsonCommand command, final Map<String, Object> changes) {
|
||||
|
||||
final boolean isSavingsInterestPostingAtCurrentPeriodEnd = this.configurationDomainService
|
||||
.isSavingsInterestPostingAtCurrentPeriodEnd();
|
||||
@@ -467,9 +453,7 @@ public class DepositAccountDomainServiceJpa implements DepositAccountDomainServi
|
||||
final boolean isPreMatureClosure = true;
|
||||
final Set<Long> existingTransactionIds = new HashSet<>();
|
||||
final Set<Long> existingReversedTransactionIds = new HashSet<>();
|
||||
/***
|
||||
* Update account transactionIds for post journal entries.
|
||||
*/
|
||||
// Update account transactionIds for post journal entries.
|
||||
updateExistingTransactionsDetails(account, existingTransactionIds, existingReversedTransactionIds);
|
||||
|
||||
final LocalDate closedDate = command.localDateValueOfParameterNamed(SavingsApiConstants.closedOnDateParamName);
|
||||
@@ -502,7 +486,7 @@ public class DepositAccountDomainServiceJpa implements DepositAccountDomainServi
|
||||
savingsTransactionId = withdrawal.getId();
|
||||
}
|
||||
|
||||
account.prematureClosure(user, command, tenantsTodayDate, changes);
|
||||
account.prematureClosure(user, command, changes);
|
||||
|
||||
this.savingsAccountRepository.save(account);
|
||||
|
||||
@@ -513,7 +497,7 @@ public class DepositAccountDomainServiceJpa implements DepositAccountDomainServi
|
||||
@Transactional
|
||||
@Override
|
||||
public Long handleRDAccountPreMatureClosure(final RecurringDepositAccount account, final PaymentDetail paymentDetail,
|
||||
final AppUser user, final JsonCommand command, final LocalDate tenantsTodayDate, final Map<String, Object> changes) {
|
||||
final AppUser user, final JsonCommand command, final Map<String, Object> changes) {
|
||||
|
||||
final boolean isSavingsInterestPostingAtCurrentPeriodEnd = this.configurationDomainService
|
||||
.isSavingsInterestPostingAtCurrentPeriodEnd();
|
||||
@@ -558,7 +542,7 @@ public class DepositAccountDomainServiceJpa implements DepositAccountDomainServi
|
||||
savingsTransactionId = withdrawal.getId();
|
||||
}
|
||||
|
||||
account.prematureClosure(user, command, tenantsTodayDate, changes);
|
||||
account.prematureClosure(user, command, changes);
|
||||
this.savingsAccountRepository.save(account);
|
||||
postJournalEntries(account, existingTransactionIds, existingReversedTransactionIds, isAccountTransfer);
|
||||
return savingsTransactionId;
|
||||
@@ -592,12 +576,4 @@ public class DepositAccountDomainServiceJpa implements DepositAccountDomainServi
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private AppUser getAppUserIfPresent() {
|
||||
AppUser user = null;
|
||||
if (this.context != null) {
|
||||
user = this.context.getAuthenticatedUserIfPresent();
|
||||
}
|
||||
return user;
|
||||
}
|
||||
}
|
||||
|
||||
+4
-4
@@ -103,12 +103,12 @@ public class DepositAccountInterestRateChart extends AbstractPersistableCustom {
|
||||
return null;
|
||||
}
|
||||
|
||||
public LocalDate getFromDateAsLocalDate() {
|
||||
return this.chartFields.getFromDateAsLocalDate();
|
||||
public LocalDate getFromDate() {
|
||||
return this.chartFields.getFromDate();
|
||||
}
|
||||
|
||||
public LocalDate getEndDateAsLocalDate() {
|
||||
return this.chartFields.getEndDateAsLocalDate();
|
||||
public LocalDate getEndDate() {
|
||||
return this.chartFields.getEndDate();
|
||||
}
|
||||
|
||||
public Long savingsAccountId() {
|
||||
|
||||
+32
-14
@@ -18,6 +18,8 @@
|
||||
*/
|
||||
package org.apache.fineract.portfolio.savings.domain;
|
||||
|
||||
import static org.apache.fineract.infrastructure.core.service.DateUtils.getSystemZoneId;
|
||||
|
||||
import jakarta.persistence.CascadeType;
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
@@ -28,8 +30,9 @@ import jakarta.persistence.Table;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom;
|
||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||
import java.time.OffsetDateTime;
|
||||
import java.util.Optional;
|
||||
import org.apache.fineract.infrastructure.core.domain.AbstractAuditableWithUTCDateTimeCustom;
|
||||
import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency;
|
||||
import org.apache.fineract.organisation.monetary.domain.Money;
|
||||
import org.apache.fineract.portfolio.loanaccount.guarantor.domain.GuarantorFundingTransaction;
|
||||
@@ -37,7 +40,7 @@ import org.apache.fineract.portfolio.savings.DepositAccountOnHoldTransactionType
|
||||
|
||||
@Entity
|
||||
@Table(name = "m_deposit_account_on_hold_transaction")
|
||||
public class DepositAccountOnHoldTransaction extends AbstractPersistableCustom {
|
||||
public class DepositAccountOnHoldTransaction extends AbstractAuditableWithUTCDateTimeCustom {
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "savings_account_id", nullable = true)
|
||||
@@ -55,8 +58,9 @@ public class DepositAccountOnHoldTransaction extends AbstractPersistableCustom {
|
||||
@Column(name = "is_reversed", nullable = false)
|
||||
private boolean reversed;
|
||||
|
||||
@Column(name = "created_date", nullable = false)
|
||||
private LocalDateTime createdDate;
|
||||
@Deprecated
|
||||
@Column(name = "created_date", nullable = true)
|
||||
private LocalDateTime createdDateToRemove;
|
||||
|
||||
@OneToOne(cascade = CascadeType.ALL, mappedBy = "depositAccountOnHoldTransaction", optional = true, orphanRemoval = true)
|
||||
private GuarantorFundingTransaction guarantorFundingTransaction;
|
||||
@@ -69,7 +73,7 @@ public class DepositAccountOnHoldTransaction extends AbstractPersistableCustom {
|
||||
this.amount = amount;
|
||||
this.transactionType = transactionType.getValue();
|
||||
this.transactionDate = transactionDate;
|
||||
this.createdDate = DateUtils.getLocalDateTimeOfSystem();
|
||||
this.createdDateToRemove = null; // #audit backward compatibility deprecated
|
||||
this.reversed = reversed;
|
||||
}
|
||||
|
||||
@@ -87,14 +91,30 @@ public class DepositAccountOnHoldTransaction extends AbstractPersistableCustom {
|
||||
reversed);
|
||||
}
|
||||
|
||||
public SavingsAccount getSavingsAccount() {
|
||||
return savingsAccount;
|
||||
}
|
||||
|
||||
public BigDecimal getAmount() {
|
||||
return this.amount;
|
||||
}
|
||||
|
||||
public Money getAmountMoney(final MonetaryCurrency currency) {
|
||||
public Money getAmount(final MonetaryCurrency currency) {
|
||||
return Money.of(currency, this.amount);
|
||||
}
|
||||
|
||||
public DepositAccountOnHoldTransactionType getTransactionType() {
|
||||
return DepositAccountOnHoldTransactionType.fromInt(this.transactionType);
|
||||
}
|
||||
|
||||
public LocalDate getTransactionDate() {
|
||||
return this.transactionDate;
|
||||
}
|
||||
|
||||
public MonetaryCurrency getCurrency() {
|
||||
return getSavingsAccount().getCurrency();
|
||||
}
|
||||
|
||||
public void reverseTransaction() {
|
||||
this.reversed = true;
|
||||
if (this.getTransactionType().isHold()) {
|
||||
@@ -104,12 +124,10 @@ public class DepositAccountOnHoldTransaction extends AbstractPersistableCustom {
|
||||
}
|
||||
}
|
||||
|
||||
public DepositAccountOnHoldTransactionType getTransactionType() {
|
||||
return DepositAccountOnHoldTransactionType.fromInt(this.transactionType);
|
||||
@Override
|
||||
public Optional<OffsetDateTime> getCreatedDate() {
|
||||
// #audit backward compatibility keep system datetime
|
||||
return Optional.ofNullable(super.getCreatedDate()
|
||||
.orElse(createdDateToRemove == null ? null : createdDateToRemove.atZone(getSystemZoneId()).toOffsetDateTime()));
|
||||
}
|
||||
|
||||
public LocalDate getTransactionDate() {
|
||||
return this.transactionDate;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+2
-2
@@ -224,7 +224,7 @@ public class DepositAccountTermAndPreClosure extends AbstractPersistableCustom {
|
||||
this.depositAmount = depositAmount;
|
||||
}
|
||||
|
||||
public LocalDate getMaturityLocalDate() {
|
||||
public LocalDate getMaturityDate() {
|
||||
return this.maturityDate;
|
||||
}
|
||||
|
||||
@@ -247,7 +247,7 @@ public class DepositAccountTermAndPreClosure extends AbstractPersistableCustom {
|
||||
}
|
||||
|
||||
Integer actualDepositPeriod = this.depositPeriod;
|
||||
if (depositFromDate == null || getMaturityLocalDate() == null || interestPostingUpToDate.isEqual(getMaturityLocalDate())) {
|
||||
if (depositFromDate == null || getMaturityDate() == null || DateUtils.isEqual(interestPostingUpToDate, getMaturityDate())) {
|
||||
return actualDepositPeriod;
|
||||
}
|
||||
|
||||
|
||||
+21
-38
@@ -197,18 +197,8 @@ public class FixedDepositAccount extends SavingsAccount {
|
||||
String refNo = null;
|
||||
final Money transactionAmountMoney = Money.of(getCurrency(), this.accountTermAndPreClosure.depositAmount());
|
||||
final SavingsAccountTransaction transaction = SavingsAccountTransaction.deposit(null, office(), null,
|
||||
this.accountSubmittedOrActivationDate(), transactionAmountMoney, DateUtils.getLocalDateTimeOfSystem(), null, refNo); // TODO:
|
||||
// verify
|
||||
// if
|
||||
// it
|
||||
// is
|
||||
// ok
|
||||
// to
|
||||
// pass
|
||||
// null
|
||||
// for
|
||||
// AppUser
|
||||
transaction.updateRunningBalance(transactionAmountMoney);
|
||||
this.accountSubmittedOrActivationDate(), transactionAmountMoney, refNo);
|
||||
transaction.setRunningBalance(transactionAmountMoney);
|
||||
transaction.updateCumulativeBalanceAndDates(this.getCurrency(), interestCalculatedUpto());
|
||||
allTransactions.add(transaction);
|
||||
updateMaturityDateAndAmount(mc, allTransactions, isPreMatureClosure, isSavingsInterestPostingAtCurrentPeriodEnd,
|
||||
@@ -260,8 +250,7 @@ public class FixedDepositAccount extends SavingsAccount {
|
||||
}
|
||||
}
|
||||
|
||||
final LocalDate todayDate = DateUtils.getBusinessLocalDate();
|
||||
if (!this.maturityDate().isAfter(todayDate)) {
|
||||
if (!DateUtils.isDateInTheFuture(maturityDate())) {
|
||||
// update account status
|
||||
this.status = SavingsAccountStatusType.MATURED.getValue();
|
||||
postMaturityInterest(isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth);
|
||||
@@ -338,14 +327,12 @@ public class FixedDepositAccount extends SavingsAccount {
|
||||
}
|
||||
|
||||
this.summary.updateFromInterestPeriodSummaries(this.currency, allPostingPeriods);
|
||||
this.savingsHelper.calculateInterestForAllPostingPeriods(this.currency, allPostingPeriods, this.getLockedInUntilLocalDate(),
|
||||
this.savingsHelper.calculateInterestForAllPostingPeriods(this.currency, allPostingPeriods, getLockedInUntilDate(),
|
||||
isTransferInterestToOtherAccount());
|
||||
return allPostingPeriods;
|
||||
}
|
||||
|
||||
public void prematureClosure(final AppUser currentUser, final JsonCommand command, final LocalDate tenantsTodayDate,
|
||||
final Map<String, Object> actualChanges) {
|
||||
|
||||
public void prematureClosure(final AppUser currentUser, final JsonCommand command, final Map<String, Object> actualChanges) {
|
||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
|
||||
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
|
||||
.resource(FIXED_DEPOSIT_ACCOUNT_RESOURCE_NAME + DepositsApiConstants.preMatureCloseAction);
|
||||
@@ -362,14 +349,13 @@ public class FixedDepositAccount extends SavingsAccount {
|
||||
final DateTimeFormatter fmt = DateTimeFormatter.ofPattern(command.dateFormat()).withLocale(locale);
|
||||
final LocalDate closedDate = command.localDateValueOfParameterNamed(SavingsApiConstants.closedOnDateParamName);
|
||||
|
||||
if (closedDate.isBefore(getActivationLocalDate())) {
|
||||
if (DateUtils.isBefore(closedDate, getActivationDate())) {
|
||||
baseDataValidator.reset().parameter(SavingsApiConstants.closedOnDateParamName).value(closedDate)
|
||||
.failWithCode("must.be.after.activation.date");
|
||||
if (!dataValidationErrors.isEmpty()) {
|
||||
throw new PlatformApiDataValidationException(dataValidationErrors);
|
||||
}
|
||||
}
|
||||
|
||||
if (isAccountLocked(closedDate)) {
|
||||
baseDataValidator.reset().parameter(SavingsApiConstants.closedOnDateParamName).value(closedDate)
|
||||
.failWithCode("must.be.after.lockin.period");
|
||||
@@ -377,16 +363,14 @@ public class FixedDepositAccount extends SavingsAccount {
|
||||
throw new PlatformApiDataValidationException(dataValidationErrors);
|
||||
}
|
||||
}
|
||||
|
||||
if (closedDate.isAfter(maturityDate())) {
|
||||
if (maturityDate() != null && DateUtils.isAfter(closedDate, maturityDate())) {
|
||||
baseDataValidator.reset().parameter(SavingsApiConstants.closedOnDateParamName).value(closedDate)
|
||||
.failWithCode("must.be.before.maturity.date");
|
||||
if (!dataValidationErrors.isEmpty()) {
|
||||
throw new PlatformApiDataValidationException(dataValidationErrors);
|
||||
}
|
||||
}
|
||||
|
||||
if (closedDate.isAfter(tenantsTodayDate)) {
|
||||
if (DateUtils.isAfterBusinessDate(closedDate)) {
|
||||
baseDataValidator.reset().parameter(SavingsApiConstants.closedOnDateParamName).value(closedDate)
|
||||
.failWithCode("cannot.be.a.future.date");
|
||||
if (!dataValidationErrors.isEmpty()) {
|
||||
@@ -437,9 +421,7 @@ public class FixedDepositAccount extends SavingsAccount {
|
||||
return Money.of(this.currency, this.accountTermAndPreClosure.depositAmount());
|
||||
}
|
||||
|
||||
public void close(final AppUser currentUser, final JsonCommand command, final LocalDate tenantsTodayDate,
|
||||
final Map<String, Object> actualChanges) {
|
||||
|
||||
public void close(final AppUser currentUser, final JsonCommand command, final Map<String, Object> actualChanges) {
|
||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
|
||||
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
|
||||
.resource(FIXED_DEPOSIT_ACCOUNT_RESOURCE_NAME + SavingsApiConstants.closeAction);
|
||||
@@ -456,21 +438,21 @@ public class FixedDepositAccount extends SavingsAccount {
|
||||
final DateTimeFormatter fmt = DateTimeFormatter.ofPattern(command.dateFormat()).withLocale(locale);
|
||||
final LocalDate closedDate = command.localDateValueOfParameterNamed(SavingsApiConstants.closedOnDateParamName);
|
||||
|
||||
if (closedDate.isBefore(getActivationLocalDate())) {
|
||||
if (DateUtils.isBefore(closedDate, getActivationDate())) {
|
||||
baseDataValidator.reset().parameter(SavingsApiConstants.closedOnDateParamName).value(closedDate)
|
||||
.failWithCode("must.be.after.activation.date");
|
||||
if (!dataValidationErrors.isEmpty()) {
|
||||
throw new PlatformApiDataValidationException(dataValidationErrors);
|
||||
}
|
||||
}
|
||||
if (closedDate.isBefore(maturityDate())) {
|
||||
if (DateUtils.isBefore(closedDate, maturityDate())) {
|
||||
baseDataValidator.reset().parameter(SavingsApiConstants.closedOnDateParamName).value(closedDate)
|
||||
.failWithCode("must.be.after.account.maturity.date");
|
||||
if (!dataValidationErrors.isEmpty()) {
|
||||
throw new PlatformApiDataValidationException(dataValidationErrors);
|
||||
}
|
||||
}
|
||||
if (closedDate.isAfter(tenantsTodayDate)) {
|
||||
if (DateUtils.isAfterBusinessDate(closedDate)) {
|
||||
baseDataValidator.reset().parameter(SavingsApiConstants.closedOnDateParamName).value(closedDate)
|
||||
.failWithCode("cannot.be.a.future.date");
|
||||
if (!dataValidationErrors.isEmpty()) {
|
||||
@@ -548,7 +530,8 @@ public class FixedDepositAccount extends SavingsAccount {
|
||||
|
||||
LocalDate interestPostingTransactionDate = interestPostingPeriod.dateOfPostingTransaction();
|
||||
|
||||
interestPostingTransactionDate = interestPostingTransactionDate.isAfter(interestPostingUpToDate) ? interestPostingUpToDate
|
||||
interestPostingTransactionDate = DateUtils.isAfter(interestPostingTransactionDate, interestPostingUpToDate)
|
||||
? interestPostingUpToDate
|
||||
: interestPostingTransactionDate;
|
||||
|
||||
final Money interestEarnedToBePostedForPeriod = interestPostingPeriod.getInterestEarned();
|
||||
@@ -669,14 +652,14 @@ public class FixedDepositAccount extends SavingsAccount {
|
||||
private LocalDate interestPostingUpToDate(final LocalDate interestPostingDate) {
|
||||
LocalDate interestPostingUpToDate = interestPostingDate;
|
||||
final LocalDate uptoMaturityDate = interestCalculatedUpto();
|
||||
if (uptoMaturityDate != null && uptoMaturityDate.isBefore(interestPostingDate)) {
|
||||
if (uptoMaturityDate != null && DateUtils.isBefore(uptoMaturityDate, interestPostingDate)) {
|
||||
interestPostingUpToDate = uptoMaturityDate;
|
||||
}
|
||||
return interestPostingUpToDate;
|
||||
}
|
||||
|
||||
public LocalDate maturityDate() {
|
||||
return this.accountTermAndPreClosure.getMaturityLocalDate();
|
||||
return this.accountTermAndPreClosure.getMaturityDate();
|
||||
}
|
||||
|
||||
public BigDecimal maturityAmount() {
|
||||
@@ -695,8 +678,8 @@ public class FixedDepositAccount extends SavingsAccount {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> activate(final AppUser currentUser, final JsonCommand command, final LocalDate tenantsTodayDate) {
|
||||
final Map<String, Object> actualChanges = super.activate(currentUser, command, tenantsTodayDate);
|
||||
public Map<String, Object> activate(final AppUser currentUser, final JsonCommand command) {
|
||||
final Map<String, Object> actualChanges = super.activate(currentUser, command);
|
||||
|
||||
// if (isAccountLocked(calculateMaturityDate())) {
|
||||
// final List<ApiParameterError> dataValidationErrors = new
|
||||
@@ -770,8 +753,8 @@ public class FixedDepositAccount extends SavingsAccount {
|
||||
}
|
||||
|
||||
if (this.chart != null) {
|
||||
final LocalDate chartFromDate = this.chart.getFromDateAsLocalDate();
|
||||
LocalDate chartEndDate = this.chart.getEndDateAsLocalDate();
|
||||
final LocalDate chartFromDate = this.chart.getFromDate();
|
||||
LocalDate chartEndDate = this.chart.getEndDate();
|
||||
chartEndDate = chartEndDate == null ? DateUtils.getBusinessLocalDate() : chartEndDate;
|
||||
|
||||
final LocalDateInterval chartInterval = LocalDateInterval.create(chartFromDate, chartEndDate);
|
||||
@@ -783,7 +766,7 @@ public class FixedDepositAccount extends SavingsAccount {
|
||||
BigDecimal applicableInterestRate = this.chart.getApplicableInterestRate(depositAmount, depositStartDate(),
|
||||
calculateMaturityDate(), this.client);
|
||||
|
||||
if (applicableInterestRate.compareTo(BigDecimal.ZERO) == 0 ? Boolean.TRUE : Boolean.FALSE) {
|
||||
if (applicableInterestRate.compareTo(BigDecimal.ZERO) == 0) {
|
||||
baseDataValidator.reset()
|
||||
.failWithCodeNoParameterAddedToErrorCode("no.applicable.interest.rate.is.found.based.on.amount.and.deposit.period");
|
||||
}
|
||||
|
||||
+2
-2
@@ -258,8 +258,8 @@ public class FixedDepositProduct extends SavingsProduct {
|
||||
if (!existingChart.equals(comparingChart)) {
|
||||
if (existingChart.chartFields().isOverlapping(comparingChart.chartFields())) {
|
||||
baseDataValidator.failWithCodeNoParameterAddedToErrorCode("chart.overlapping.from.and.end.dates",
|
||||
existingChart.getFromDateAsLocalDate(), existingChart.getEndDateAsLocalDate(),
|
||||
comparingChart.getFromDateAsLocalDate(), comparingChart.getEndDateAsLocalDate());
|
||||
existingChart.getFromDate(), existingChart.getEndDate(), comparingChart.getFromDate(),
|
||||
comparingChart.getEndDate());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+43
-61
@@ -286,7 +286,7 @@ public class RecurringDepositAccount extends SavingsAccount {
|
||||
}
|
||||
|
||||
final LocalDate todayDate = DateUtils.getBusinessLocalDate();
|
||||
if (!this.maturityDate().isAfter(todayDate)) {
|
||||
if (!DateUtils.isAfter(this.maturityDate(), todayDate)) {
|
||||
// update account status
|
||||
this.status = SavingsAccountStatusType.MATURED.getValue();
|
||||
postMaturityInterest(isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth, todayDate, postReversals);
|
||||
@@ -368,7 +368,7 @@ public class RecurringDepositAccount extends SavingsAccount {
|
||||
allPostingPeriods.add(postingPeriod);
|
||||
}
|
||||
|
||||
this.savingsHelper.calculateInterestForAllPostingPeriods(this.currency, allPostingPeriods, this.getLockedInUntilLocalDate(),
|
||||
this.savingsHelper.calculateInterestForAllPostingPeriods(this.currency, allPostingPeriods, this.getLockedInUntilDate(),
|
||||
isTransferInterestToOtherAccount());
|
||||
// this.summary.updateFromInterestPeriodSummaries(this.currency,
|
||||
// allPostingPeriods);
|
||||
@@ -381,8 +381,8 @@ public class RecurringDepositAccount extends SavingsAccount {
|
||||
allTransactions.addAll(retreiveOrderedNonInterestPostingTransactions());
|
||||
LocalDate latestTransactionDate = null;
|
||||
for (final SavingsAccountTransaction installment : allTransactions) {
|
||||
if (latestTransactionDate == null || latestTransactionDate.isBefore(installment.getTransactionLocalDate())) {
|
||||
latestTransactionDate = installment.getTransactionLocalDate();
|
||||
if (latestTransactionDate == null || DateUtils.isBefore(latestTransactionDate, installment.getTransactionDate())) {
|
||||
latestTransactionDate = installment.getTransactionDate();
|
||||
}
|
||||
}
|
||||
String refNo = null;
|
||||
@@ -390,11 +390,11 @@ public class RecurringDepositAccount extends SavingsAccount {
|
||||
for (RecurringDepositScheduleInstallment installment : depositScheduleInstallments()) {
|
||||
if (installment.isPrincipalNotCompleted(getCurrency())) {
|
||||
LocalDate dueDate = installment.dueDate();
|
||||
if (latestTransactionDate != null && dueDate.isBefore(latestTransactionDate)) {
|
||||
if (DateUtils.isBefore(dueDate, latestTransactionDate)) {
|
||||
dueDate = latestTransactionDate;
|
||||
}
|
||||
final SavingsAccountTransaction transaction = SavingsAccountTransaction.deposit(null, office(), null, dueDate,
|
||||
installment.getDepositAmountOutstanding(getCurrency()), DateUtils.getLocalDateTimeOfSystem(), null, refNo);
|
||||
installment.getDepositAmountOutstanding(getCurrency()), refNo);
|
||||
allTransactions.add(transaction);
|
||||
}
|
||||
}
|
||||
@@ -414,7 +414,7 @@ public class RecurringDepositAccount extends SavingsAccount {
|
||||
}
|
||||
|
||||
runningBalance = runningBalance.plus(transactionAmount);
|
||||
transaction.updateRunningBalance(runningBalance);
|
||||
transaction.setRunningBalance(runningBalance);
|
||||
}
|
||||
}
|
||||
// loop over transactions in reverse
|
||||
@@ -423,7 +423,7 @@ public class RecurringDepositAccount extends SavingsAccount {
|
||||
final SavingsAccountTransaction transaction = allTransactions.get(i);
|
||||
if (transaction.isNotReversed() && !transaction.isInterestPostingAndNotReversed()) {
|
||||
transaction.updateCumulativeBalanceAndDates(this.currency, endOfBalanceDate);
|
||||
endOfBalanceDate = transaction.transactionLocalDate().minusDays(1);
|
||||
endOfBalanceDate = transaction.getTransactionDate().minusDays(1);
|
||||
}
|
||||
}
|
||||
return allTransactions;
|
||||
@@ -437,9 +437,7 @@ public class RecurringDepositAccount extends SavingsAccount {
|
||||
return depositStartDate;
|
||||
}
|
||||
|
||||
public void prematureClosure(final AppUser currentUser, final JsonCommand command, final LocalDate tenantsTodayDate,
|
||||
final Map<String, Object> actualChanges) {
|
||||
|
||||
public void prematureClosure(final AppUser currentUser, final JsonCommand command, final Map<String, Object> actualChanges) {
|
||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
|
||||
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
|
||||
.resource(RECURRING_DEPOSIT_ACCOUNT_RESOURCE_NAME + DepositsApiConstants.preMatureCloseAction);
|
||||
@@ -456,14 +454,13 @@ public class RecurringDepositAccount extends SavingsAccount {
|
||||
final DateTimeFormatter fmt = DateTimeFormatter.ofPattern(command.dateFormat()).withLocale(locale);
|
||||
final LocalDate closedDate = command.localDateValueOfParameterNamed(SavingsApiConstants.closedOnDateParamName);
|
||||
|
||||
if (closedDate.isBefore(getActivationLocalDate())) {
|
||||
if (DateUtils.isBefore(closedDate, getActivationDate())) {
|
||||
baseDataValidator.reset().parameter(SavingsApiConstants.closedOnDateParamName).value(closedDate)
|
||||
.failWithCode("must.be.after.activation.date");
|
||||
if (!dataValidationErrors.isEmpty()) {
|
||||
throw new PlatformApiDataValidationException(dataValidationErrors);
|
||||
}
|
||||
}
|
||||
|
||||
if (isAccountLocked(closedDate)) {
|
||||
baseDataValidator.reset().parameter(SavingsApiConstants.closedOnDateParamName).value(closedDate)
|
||||
.failWithCode("must.be.after.lockin.period");
|
||||
@@ -471,16 +468,14 @@ public class RecurringDepositAccount extends SavingsAccount {
|
||||
throw new PlatformApiDataValidationException(dataValidationErrors);
|
||||
}
|
||||
}
|
||||
|
||||
if (closedDate.isAfter(maturityDate())) {
|
||||
if (maturityDate() != null && DateUtils.isAfter(closedDate, maturityDate())) {
|
||||
baseDataValidator.reset().parameter(SavingsApiConstants.closedOnDateParamName).value(closedDate)
|
||||
.failWithCode("must.be.before.maturity.date");
|
||||
if (!dataValidationErrors.isEmpty()) {
|
||||
throw new PlatformApiDataValidationException(dataValidationErrors);
|
||||
}
|
||||
}
|
||||
|
||||
if (closedDate.isAfter(tenantsTodayDate)) {
|
||||
if (DateUtils.isAfterBusinessDate(closedDate)) {
|
||||
baseDataValidator.reset().parameter(SavingsApiConstants.closedOnDateParamName).value(closedDate)
|
||||
.failWithCode("cannot.be.a.future.date");
|
||||
if (!dataValidationErrors.isEmpty()) {
|
||||
@@ -541,14 +536,14 @@ public class RecurringDepositAccount extends SavingsAccount {
|
||||
return Money.of(this.currency, this.minRequiredOpeningBalance);
|
||||
}
|
||||
|
||||
protected void processAccountUponActivation(final DateTimeFormatter fmt, final AppUser user, final boolean postReversals) {
|
||||
protected void processAccountUponActivation(final DateTimeFormatter fmt, final boolean postReversals) {
|
||||
final Money minRequiredOpeningBalance = Money.of(this.currency, this.minRequiredOpeningBalance);
|
||||
final boolean backdatedTxnsAllowedTill = false;
|
||||
String refNo = null;
|
||||
final Long relaxingDaysConfigForPivotDate = this.configurationDomainService.retrieveRelaxingDaysConfigForPivotDate();
|
||||
if (minRequiredOpeningBalance.isGreaterThanZero()) {
|
||||
final SavingsAccountTransactionDTO transactionDTO = new SavingsAccountTransactionDTO(fmt, getActivationLocalDate(),
|
||||
minRequiredOpeningBalance.getAmount(), null, DateUtils.getLocalDateTimeOfSystem(), user, accountType);
|
||||
final SavingsAccountTransactionDTO transactionDTO = new SavingsAccountTransactionDTO(fmt, getActivationDate(),
|
||||
minRequiredOpeningBalance.getAmount(), null, null, accountType);
|
||||
deposit(transactionDTO, backdatedTxnsAllowedTill, relaxingDaysConfigForPivotDate, refNo);
|
||||
|
||||
// update existing transactions so derived balance fields are
|
||||
@@ -557,9 +552,7 @@ public class RecurringDepositAccount extends SavingsAccount {
|
||||
}
|
||||
}
|
||||
|
||||
public void close(final AppUser currentUser, final JsonCommand command, final LocalDate tenantsTodayDate,
|
||||
final Map<String, Object> actualChanges) {
|
||||
|
||||
public void close(final AppUser currentUser, final JsonCommand command, final Map<String, Object> actualChanges) {
|
||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
|
||||
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
|
||||
.resource(RECURRING_DEPOSIT_ACCOUNT_RESOURCE_NAME + SavingsApiConstants.closeAction);
|
||||
@@ -576,21 +569,21 @@ public class RecurringDepositAccount extends SavingsAccount {
|
||||
final DateTimeFormatter fmt = DateTimeFormatter.ofPattern(command.dateFormat()).withLocale(locale);
|
||||
final LocalDate closedDate = command.localDateValueOfParameterNamed(SavingsApiConstants.closedOnDateParamName);
|
||||
|
||||
if (closedDate.isBefore(getActivationLocalDate())) {
|
||||
if (DateUtils.isBefore(closedDate, getActivationDate())) {
|
||||
baseDataValidator.reset().parameter(SavingsApiConstants.closedOnDateParamName).value(closedDate)
|
||||
.failWithCode("must.be.after.activation.date");
|
||||
if (!dataValidationErrors.isEmpty()) {
|
||||
throw new PlatformApiDataValidationException(dataValidationErrors);
|
||||
}
|
||||
}
|
||||
if (maturityDate() != null && closedDate.isBefore(maturityDate())) {
|
||||
if (maturityDate() != null && DateUtils.isBefore(closedDate, maturityDate())) {
|
||||
baseDataValidator.reset().parameter(SavingsApiConstants.closedOnDateParamName).value(closedDate)
|
||||
.failWithCode("must.be.after.account.maturity.date");
|
||||
if (!dataValidationErrors.isEmpty()) {
|
||||
throw new PlatformApiDataValidationException(dataValidationErrors);
|
||||
}
|
||||
}
|
||||
if (closedDate.isAfter(tenantsTodayDate)) {
|
||||
if (DateUtils.isAfterBusinessDate(closedDate)) {
|
||||
baseDataValidator.reset().parameter(SavingsApiConstants.closedOnDateParamName).value(closedDate)
|
||||
.failWithCode("cannot.be.a.future.date");
|
||||
if (!dataValidationErrors.isEmpty()) {
|
||||
@@ -659,7 +652,8 @@ public class RecurringDepositAccount extends SavingsAccount {
|
||||
for (final PostingPeriod interestPostingPeriod : postingPeriods) {
|
||||
|
||||
LocalDate interestPostingTransactionDate = interestPostingPeriod.dateOfPostingTransaction();
|
||||
interestPostingTransactionDate = interestPostingTransactionDate.isAfter(interestPostingUpToDate) ? interestPostingUpToDate
|
||||
interestPostingTransactionDate = DateUtils.isAfter(interestPostingTransactionDate, interestPostingUpToDate)
|
||||
? interestPostingUpToDate
|
||||
: interestPostingTransactionDate;
|
||||
final Money interestEarnedToBePostedForPeriod = interestPostingPeriod.getInterestEarned();
|
||||
|
||||
@@ -777,14 +771,14 @@ public class RecurringDepositAccount extends SavingsAccount {
|
||||
private LocalDate interestPostingUpToDate(final LocalDate interestPostingDate) {
|
||||
LocalDate interestPostingUpToDate = interestPostingDate;
|
||||
final LocalDate uptoMaturityDate = interestCalculatedUpto();
|
||||
if (uptoMaturityDate != null && uptoMaturityDate.isBefore(interestPostingDate)) {
|
||||
if (uptoMaturityDate != null && DateUtils.isBefore(uptoMaturityDate, interestPostingDate)) {
|
||||
interestPostingUpToDate = uptoMaturityDate;
|
||||
}
|
||||
return interestPostingUpToDate;
|
||||
}
|
||||
|
||||
public LocalDate maturityDate() {
|
||||
return this.accountTermAndPreClosure.getMaturityLocalDate();
|
||||
return this.accountTermAndPreClosure.getMaturityDate();
|
||||
}
|
||||
|
||||
public BigDecimal maturityAmount() {
|
||||
@@ -813,11 +807,10 @@ public class RecurringDepositAccount extends SavingsAccount {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> activate(final AppUser currentUser, final JsonCommand command, final LocalDate tenantsTodayDate) {
|
||||
public Map<String, Object> activate(final AppUser currentUser, final JsonCommand command) {
|
||||
final Map<String, Object> actualChanges = super.activate(currentUser, command);
|
||||
|
||||
final Map<String, Object> actualChanges = super.activate(currentUser, command, tenantsTodayDate);
|
||||
|
||||
if (accountTermAndPreClosure.isAfterExpectedFirstDepositDate(getActivationLocalDate())) {
|
||||
if (accountTermAndPreClosure.isAfterExpectedFirstDepositDate(getActivationDate())) {
|
||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
|
||||
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
|
||||
.resource(RECURRING_DEPOSIT_ACCOUNT_RESOURCE_NAME);
|
||||
@@ -889,13 +882,12 @@ public class RecurringDepositAccount extends SavingsAccount {
|
||||
}
|
||||
|
||||
public void handleScheduleInstallments(final SavingsAccountTransaction transaction) {
|
||||
|
||||
final LocalDate transactionDate = transaction.transactionLocalDate();
|
||||
final LocalDate transactionDate = transaction.getTransactionDate();
|
||||
Money transactionAmountUnprocessed = transaction.getAmount(getCurrency());
|
||||
|
||||
for (RecurringDepositScheduleInstallment currentInstallment : depositScheduleInstallments()) {
|
||||
if (currentInstallment.isNotFullyPaidOff() && transactionAmountUnprocessed.isGreaterThanZero()) {
|
||||
if (!this.adjustAdvanceTowardsFuturePayments() && currentInstallment.dueDate().isAfter(transactionDate)) {
|
||||
if (!this.adjustAdvanceTowardsFuturePayments() && DateUtils.isBefore(transactionDate, currentInstallment.dueDate())) {
|
||||
transactionAmountUnprocessed = Money.zero(getCurrency());
|
||||
}
|
||||
transactionAmountUnprocessed = handleInstallmentTransaction(currentInstallment, transactionAmountUnprocessed,
|
||||
@@ -906,7 +898,6 @@ public class RecurringDepositAccount extends SavingsAccount {
|
||||
}
|
||||
|
||||
public void updateScheduleInstallments() {
|
||||
|
||||
// reset all installments to process from the beginning
|
||||
for (RecurringDepositScheduleInstallment currentInstallment : depositScheduleInstallments()) {
|
||||
currentInstallment.resetDerivedFields();
|
||||
@@ -923,8 +914,7 @@ public class RecurringDepositAccount extends SavingsAccount {
|
||||
// reset all installments to process from the beginning, also update
|
||||
// deposit amount as necessary
|
||||
for (RecurringDepositScheduleInstallment currentInstallment : depositScheduleInstallments()) {
|
||||
if (currentInstallment.dueDate().isAfter(depositAmountupdatedFromDate)
|
||||
|| currentInstallment.dueDate().isEqual(depositAmountupdatedFromDate)) {
|
||||
if (!DateUtils.isAfter(depositAmountupdatedFromDate, currentInstallment.dueDate())) {
|
||||
currentInstallment.updateDepositAmountAndResetDerivedFields(newDepositAmount);
|
||||
} else {
|
||||
currentInstallment.resetDerivedFields();
|
||||
@@ -959,19 +949,14 @@ public class RecurringDepositAccount extends SavingsAccount {
|
||||
*/
|
||||
protected boolean isTransactionInAdvanceOfInstallment(final int currentInstallmentIndex,
|
||||
final List<RecurringDepositScheduleInstallment> installments, final LocalDate transactionDate) {
|
||||
|
||||
final RecurringDepositScheduleInstallment currentInstallment = installments.get(currentInstallmentIndex);
|
||||
|
||||
return transactionDate.isBefore(currentInstallment.dueDate());
|
||||
return DateUtils.isBefore(transactionDate, currentInstallment.dueDate());
|
||||
}
|
||||
|
||||
private Money handleInstallmentTransaction(final RecurringDepositScheduleInstallment currentInstallment,
|
||||
final Money transactionAmountUnprocessed, final LocalDate transactionDate) {
|
||||
|
||||
Money transactionAmountRemaining = transactionAmountUnprocessed;
|
||||
Money depositAmountPortion = Money.zero(transactionAmountRemaining.getCurrency());
|
||||
|
||||
depositAmountPortion = currentInstallment.payInstallment(transactionDate, transactionAmountRemaining);
|
||||
Money depositAmountPortion = currentInstallment.payInstallment(transactionDate, transactionAmountRemaining);
|
||||
transactionAmountRemaining = transactionAmountRemaining.minus(depositAmountPortion);
|
||||
|
||||
return transactionAmountRemaining;
|
||||
@@ -984,11 +969,11 @@ public class RecurringDepositAccount extends SavingsAccount {
|
||||
|
||||
private boolean isBeforeMaturityDate(final LocalDate compareDate) {
|
||||
final LocalDate maturityDate = this.maturityDate();
|
||||
return maturityDate == null ? true : compareDate.isBefore(maturityDate);
|
||||
return maturityDate == null || DateUtils.isBefore(compareDate, maturityDate);
|
||||
}
|
||||
|
||||
private boolean isBeforeDepositStartDate(LocalDate compareDate) {
|
||||
return compareDate.isBefore(depositStartDate());
|
||||
return DateUtils.isBefore(compareDate, depositStartDate());
|
||||
}
|
||||
|
||||
public void validateDomainRules() {
|
||||
@@ -1003,7 +988,6 @@ public class RecurringDepositAccount extends SavingsAccount {
|
||||
}
|
||||
|
||||
private void validateDomainRules(final DataValidatorBuilder baseDataValidator) {
|
||||
|
||||
final boolean isMinTermGreaterThanMax = this.accountTermAndPreClosure.depositTermDetail()
|
||||
.isMinDepositTermGreaterThanMaxDepositTerm();
|
||||
// deposit period should be within min and max deposit term
|
||||
@@ -1063,8 +1047,8 @@ public class RecurringDepositAccount extends SavingsAccount {
|
||||
.resource(RECURRING_DEPOSIT_ACCOUNT_RESOURCE_NAME);
|
||||
LocalDate maturityDate = calculateMaturityDate();
|
||||
if (this.chart != null) {
|
||||
final LocalDate chartFromDate = this.chart.getFromDateAsLocalDate();
|
||||
LocalDate chartEndDate = this.chart.getEndDateAsLocalDate();
|
||||
final LocalDate chartFromDate = this.chart.getFromDate();
|
||||
LocalDate chartEndDate = this.chart.getEndDate();
|
||||
chartEndDate = chartEndDate == null ? DateUtils.getBusinessLocalDate() : chartEndDate;
|
||||
|
||||
final LocalDateInterval chartInterval = LocalDateInterval.create(chartFromDate, chartEndDate);
|
||||
@@ -1080,7 +1064,7 @@ public class RecurringDepositAccount extends SavingsAccount {
|
||||
BigDecimal applicableInterestRate = this.chart.getApplicableInterestRate(maturityAmount, depositStartDate(), maturityDate,
|
||||
this.client);
|
||||
|
||||
if (applicableInterestRate.compareTo(BigDecimal.ZERO) == 0 ? Boolean.TRUE : Boolean.FALSE) {
|
||||
if (applicableInterestRate.compareTo(BigDecimal.ZERO) == 0) {
|
||||
baseDataValidator.reset()
|
||||
.failWithCodeNoParameterAddedToErrorCode("no.applicable.interest.rate.is.found.based.on.amount.and.deposit.period");
|
||||
}
|
||||
@@ -1092,13 +1076,13 @@ public class RecurringDepositAccount extends SavingsAccount {
|
||||
if (!dataValidationErrors.isEmpty()) {
|
||||
throw new PlatformApiDataValidationException(dataValidationErrors);
|
||||
}
|
||||
/**
|
||||
/*
|
||||
* final boolean recurringFrequencyBeforeDepositPeriod = recurringFrequencyBeforeDepositPeriod();
|
||||
*
|
||||
* if (!recurringFrequencyBeforeDepositPeriod) {
|
||||
* baseDataValidator.reset().failWithCodeNoParameterAddedToErrorCode(
|
||||
* "recurring.frequency.not.before.deposit.period"); }
|
||||
**/
|
||||
*/
|
||||
}
|
||||
|
||||
public boolean isReinvestOnClosure() {
|
||||
@@ -1151,10 +1135,8 @@ public class RecurringDepositAccount extends SavingsAccount {
|
||||
|
||||
private boolean firstDepositDateBeforeAccountSubmittedOrActivationDate() {
|
||||
final LocalDate expectedFirstDepositLocalDate = accountTermAndPreClosure.getExpectedFirstDepositOnDate();
|
||||
if (expectedFirstDepositLocalDate == null) {
|
||||
return false;
|
||||
}
|
||||
return expectedFirstDepositLocalDate.isBefore(accountSubmittedOrActivationDate());
|
||||
return expectedFirstDepositLocalDate != null
|
||||
&& DateUtils.isBefore(expectedFirstDepositLocalDate, accountSubmittedOrActivationDate());
|
||||
}
|
||||
|
||||
public void setDatesFrom(final LocalDate now) {
|
||||
@@ -1192,7 +1174,7 @@ public class RecurringDepositAccount extends SavingsAccount {
|
||||
int installmentNumber = 1;
|
||||
final LocalDate maturityDate = calcualteScheduleTillDate(frequency, recurringEvery);
|
||||
final BigDecimal depositAmount = this.recurringDetail.mandatoryRecommendedDepositAmount();
|
||||
while (maturityDate.isAfter(installmentDate)) {
|
||||
while (DateUtils.isBefore(installmentDate, maturityDate)) {
|
||||
final RecurringDepositScheduleInstallment installment = RecurringDepositScheduleInstallment.installment(this, installmentNumber,
|
||||
installmentDate, depositAmount);
|
||||
addDepositScheduleInstallment(installment);
|
||||
@@ -1226,7 +1208,7 @@ public class RecurringDepositAccount extends SavingsAccount {
|
||||
|
||||
public void updateOverduePayments(final LocalDate todayDate) {
|
||||
LocalDate overdueUptoDate = this.maturityDate();
|
||||
if (overdueUptoDate == null || overdueUptoDate.isAfter(todayDate)) {
|
||||
if (overdueUptoDate == null || DateUtils.isAfter(overdueUptoDate, todayDate)) {
|
||||
overdueUptoDate = todayDate;
|
||||
}
|
||||
|
||||
@@ -1234,7 +1216,7 @@ public class RecurringDepositAccount extends SavingsAccount {
|
||||
int noOfOverdueInstallments = 0;
|
||||
Money totalOverdueAmount = Money.zero(getCurrency());
|
||||
for (RecurringDepositScheduleInstallment installment : installments) {
|
||||
if (installment.isNotFullyPaidOff() && overdueUptoDate.isAfter(installment.dueDate())) {
|
||||
if (installment.isNotFullyPaidOff() && DateUtils.isAfter(overdueUptoDate, installment.dueDate())) {
|
||||
noOfOverdueInstallments++;
|
||||
totalOverdueAmount = totalOverdueAmount.plus(installment.getDepositAmountOutstanding(getCurrency()));
|
||||
}
|
||||
|
||||
+37
-14
@@ -18,6 +18,8 @@
|
||||
*/
|
||||
package org.apache.fineract.portfolio.savings.domain;
|
||||
|
||||
import static org.apache.fineract.infrastructure.core.service.DateUtils.getSystemZoneId;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.JoinColumn;
|
||||
@@ -25,13 +27,17 @@ import jakarta.persistence.ManyToOne;
|
||||
import jakarta.persistence.Table;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import org.apache.fineract.infrastructure.core.domain.AbstractAuditableCustom;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.OffsetDateTime;
|
||||
import java.util.Optional;
|
||||
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;
|
||||
|
||||
@Entity
|
||||
@Table(name = "m_mandatory_savings_schedule")
|
||||
public class RecurringDepositScheduleInstallment extends AbstractAuditableCustom {
|
||||
public class RecurringDepositScheduleInstallment extends AbstractAuditableWithUTCDateTimeCustom {
|
||||
|
||||
@ManyToOne(optional = false)
|
||||
@JoinColumn(name = "savings_account_id")
|
||||
@@ -64,15 +70,18 @@ public class RecurringDepositScheduleInstallment extends AbstractAuditableCustom
|
||||
@Column(name = "obligations_met_on_date")
|
||||
private LocalDate obligationsMetOnDate;
|
||||
|
||||
@Deprecated
|
||||
@Column(name = "created_date")
|
||||
private LocalDateTime createdDateToRemove;
|
||||
|
||||
@Deprecated
|
||||
@Column(name = "lastmodified_date")
|
||||
private LocalDateTime lastModifiedDateToRemove;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
protected RecurringDepositScheduleInstallment() {
|
||||
this.installmentNumber = null;
|
||||
this.fromDate = null;
|
||||
this.dueDate = null;
|
||||
this.obligationsMet = false;
|
||||
}
|
||||
protected RecurringDepositScheduleInstallment() {}
|
||||
|
||||
/**
|
||||
* @param account
|
||||
@@ -165,6 +174,24 @@ public class RecurringDepositScheduleInstallment extends AbstractAuditableCustom
|
||||
return this.dueDate;
|
||||
}
|
||||
|
||||
public Integer installmentNumber() {
|
||||
return this.installmentNumber;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<OffsetDateTime> getCreatedDate() {
|
||||
// #audit backward compatibility keep system datetime
|
||||
return Optional.ofNullable(super.getCreatedDate()
|
||||
.orElse(createdDateToRemove == null ? null : createdDateToRemove.atZone(getSystemZoneId()).toOffsetDateTime()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<OffsetDateTime> getLastModifiedDate() {
|
||||
// #audit backward compatibility keep system datetime
|
||||
return Optional.ofNullable(super.getLastModifiedDate()
|
||||
.orElse(lastModifiedDateToRemove == null ? null : lastModifiedDateToRemove.atZone(getSystemZoneId()).toOffsetDateTime()));
|
||||
}
|
||||
|
||||
public Money payInstallment(final LocalDate transactionDate, final Money transactionAmountRemaining) {
|
||||
|
||||
final MonetaryCurrency currency = transactionAmountRemaining.getCurrency();
|
||||
@@ -209,11 +236,11 @@ public class RecurringDepositScheduleInstallment extends AbstractAuditableCustom
|
||||
}
|
||||
|
||||
private boolean isInAdvance(final LocalDate transactionDate) {
|
||||
return transactionDate.isBefore(dueDate());
|
||||
return DateUtils.isBefore(transactionDate, dueDate());
|
||||
}
|
||||
|
||||
private boolean isLatePayment(final LocalDate transactionDate) {
|
||||
return transactionDate.isAfter(dueDate());
|
||||
return DateUtils.isAfter(transactionDate, dueDate());
|
||||
}
|
||||
|
||||
private Money asMoney(final BigDecimal decimal, final MonetaryCurrency currency) {
|
||||
@@ -232,8 +259,4 @@ public class RecurringDepositScheduleInstallment extends AbstractAuditableCustom
|
||||
this.depositAmount = newDepositAmount;
|
||||
this.resetDerivedFields();
|
||||
}
|
||||
|
||||
public Integer installmentNumber() {
|
||||
return this.installmentNumber;
|
||||
}
|
||||
}
|
||||
|
||||
+166
-259
File diff suppressed because it is too large
Load Diff
+3
-4
@@ -56,7 +56,6 @@ import org.apache.fineract.infrastructure.configuration.domain.ConfigurationDoma
|
||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||
import org.apache.fineract.infrastructure.core.exception.UnsupportedParameterException;
|
||||
import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
|
||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||
import org.apache.fineract.infrastructure.core.service.ExternalIdFactory;
|
||||
import org.apache.fineract.organisation.staff.domain.Staff;
|
||||
import org.apache.fineract.organisation.staff.domain.StaffRepositoryWrapper;
|
||||
@@ -333,7 +332,7 @@ public class SavingsAccountAssembler {
|
||||
nominalAnnualInterestRateOverdraft, minOverdraftForInterestCalculation, withHoldTax);
|
||||
account.setHelpers(this.savingsAccountTransactionSummaryWrapper, this.savingsHelper);
|
||||
|
||||
account.validateNewApplicationState(DateUtils.getBusinessLocalDate(), SAVINGS_ACCOUNT_RESOURCE_NAME);
|
||||
account.validateNewApplicationState(SAVINGS_ACCOUNT_RESOURCE_NAME);
|
||||
|
||||
account.validateAccountValuesWithProduct();
|
||||
|
||||
@@ -349,7 +348,7 @@ public class SavingsAccountAssembler {
|
||||
List<SavingsAccountTransaction> savingsAccountTransactions = null;
|
||||
if (backdatedTxnsAllowedTill) {
|
||||
LocalDate pivotDate = account.getSummary().getInterestPostedTillDate();
|
||||
boolean isNotPresent = pivotDate == null ? true : false;
|
||||
boolean isNotPresent = pivotDate == null;
|
||||
if (!isNotPresent) {
|
||||
// Get savings account transactions
|
||||
if (isRelaxingDaysConfigForPivotDateEnabled()) {
|
||||
@@ -468,7 +467,7 @@ public class SavingsAccountAssembler {
|
||||
product.withHoldTax());
|
||||
account.setHelpers(this.savingsAccountTransactionSummaryWrapper, this.savingsHelper);
|
||||
|
||||
account.validateNewApplicationState(DateUtils.getBusinessLocalDate(), SAVINGS_ACCOUNT_RESOURCE_NAME);
|
||||
account.validateNewApplicationState(SAVINGS_ACCOUNT_RESOURCE_NAME);
|
||||
|
||||
account.validateAccountValuesWithProduct();
|
||||
|
||||
|
||||
+18
-21
@@ -41,7 +41,9 @@ import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
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.service.DateUtils;
|
||||
import org.apache.fineract.infrastructure.core.service.MathUtil;
|
||||
import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency;
|
||||
import org.apache.fineract.organisation.monetary.domain.Money;
|
||||
import org.apache.fineract.organisation.monetary.domain.MoneyHelper;
|
||||
@@ -58,7 +60,7 @@ import org.slf4j.LoggerFactory;
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "m_savings_account_charge")
|
||||
public class SavingsAccountCharge extends AbstractPersistableCustom {
|
||||
public class SavingsAccountCharge extends AbstractAuditableWithUTCDateTimeCustom {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(SavingsAccountCharge.class);
|
||||
|
||||
@@ -448,7 +450,7 @@ public class SavingsAccountCharge extends AbstractPersistableCustom {
|
||||
final String dateFormatAsInput = command.dateFormat();
|
||||
final String localeAsInput = command.locale();
|
||||
|
||||
if (command.isChangeInLocalDateParameterNamed(dueAsOfDateParamName, getDueLocalDate())) {
|
||||
if (command.isChangeInLocalDateParameterNamed(dueAsOfDateParamName, getDueDate())) {
|
||||
final String valueAsInput = command.stringValueOfParameterNamed(dueAsOfDateParamName);
|
||||
actualChanges.put(dueAsOfDateParamName, valueAsInput);
|
||||
actualChanges.put(dateFormatParamName, dateFormatAsInput);
|
||||
@@ -521,7 +523,7 @@ public class SavingsAccountCharge extends AbstractPersistableCustom {
|
||||
return value.compareTo(BigDecimal.ZERO) > 0;
|
||||
}
|
||||
|
||||
public LocalDate getDueLocalDate() {
|
||||
public LocalDate getDueDate() {
|
||||
return this.dueDate;
|
||||
}
|
||||
|
||||
@@ -754,17 +756,13 @@ public class SavingsAccountCharge extends AbstractPersistableCustom {
|
||||
SavingsAccountCharge that = (SavingsAccountCharge) o;
|
||||
return (penaltyCharge == that.penaltyCharge) && (paid == that.paid) && (waived == that.waived) && (status == that.status)
|
||||
&& Objects.equals(savingsAccount, that.savingsAccount) && Objects.equals(charge, that.charge)
|
||||
&& Objects.equals(chargeTime, that.chargeTime) && dueDate.compareTo(that.dueDate) == 0
|
||||
? Boolean.TRUE
|
||||
: Boolean.FALSE && Objects.equals(feeOnMonth, that.feeOnMonth) && Objects.equals(feeOnDay, that.feeOnDay)
|
||||
&& Objects.equals(feeInterval, that.feeInterval)
|
||||
&& Objects.equals(chargeCalculation, that.chargeCalculation) && Objects.equals(percentage, that.percentage)
|
||||
&& Objects.equals(amountPercentageAppliedTo, that.amountPercentageAppliedTo)
|
||||
&& Objects.equals(amount, that.amount) && Objects.equals(amountPaid, that.amountPaid)
|
||||
&& Objects.equals(amountWaived, that.amountWaived)
|
||||
&& Objects.equals(amountWrittenOff, that.amountWrittenOff)
|
||||
&& Objects.equals(amountOutstanding, that.amountOutstanding)
|
||||
&& inactivationDate.compareTo(that.inactivationDate) == 0 ? Boolean.TRUE : Boolean.FALSE;
|
||||
&& Objects.equals(chargeTime, that.chargeTime) && DateUtils.isEqual(dueDate, that.dueDate)
|
||||
&& Objects.equals(feeOnMonth, that.feeOnMonth) && Objects.equals(feeOnDay, that.feeOnDay)
|
||||
&& Objects.equals(feeInterval, that.feeInterval) && Objects.equals(chargeCalculation, that.chargeCalculation)
|
||||
&& Objects.equals(percentage, that.percentage) && Objects.equals(amountPercentageAppliedTo, that.amountPercentageAppliedTo)
|
||||
&& Objects.equals(amount, that.amount) && Objects.equals(amountPaid, that.amountPaid)
|
||||
&& Objects.equals(amountWaived, that.amountWaived) && Objects.equals(amountWrittenOff, that.amountWrittenOff)
|
||||
&& Objects.equals(amountOutstanding, that.amountOutstanding) && DateUtils.isEqual(inactivationDate, that.inactivationDate);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -803,12 +801,12 @@ public class SavingsAccountCharge extends AbstractPersistableCustom {
|
||||
if (isAnnualFee() || isMonthlyFee()) {
|
||||
nextDueLocalDate = startingDate.withMonth(this.feeOnMonth);
|
||||
nextDueLocalDate = setDayOfMonth(nextDueLocalDate);
|
||||
while (startingDate.isAfter(nextDueLocalDate)) {
|
||||
while (DateUtils.isBefore(nextDueLocalDate, startingDate)) {
|
||||
nextDueLocalDate = calculateNextDueDate(nextDueLocalDate);
|
||||
}
|
||||
} else if (isWeeklyFee()) {
|
||||
nextDueLocalDate = getDueLocalDate();
|
||||
while (startingDate.isAfter(nextDueLocalDate)) {
|
||||
nextDueLocalDate = getDueDate();
|
||||
while (DateUtils.isBefore(nextDueLocalDate, startingDate)) {
|
||||
nextDueLocalDate = calculateNextDueDate(nextDueLocalDate);
|
||||
}
|
||||
} else {
|
||||
@@ -883,12 +881,11 @@ public class SavingsAccountCharge extends AbstractPersistableCustom {
|
||||
}
|
||||
|
||||
public boolean isChargeIsDue(final LocalDate nextDueDate) {
|
||||
return this.getDueLocalDate().isBefore(nextDueDate);
|
||||
return DateUtils.isBefore(getDueDate(), nextDueDate);
|
||||
}
|
||||
|
||||
public boolean isChargeIsOverPaid(final LocalDate nextDueDate) {
|
||||
final BigDecimal amountPaid = this.amountPaid == null ? BigDecimal.ZERO : amountPaid();
|
||||
return this.getDueLocalDate().isAfter(nextDueDate) && amountPaid.compareTo(BigDecimal.ZERO) > 0;
|
||||
return DateUtils.isAfter(getDueDate(), nextDueDate) && MathUtil.isGreaterThanZero(amountPaid());
|
||||
}
|
||||
|
||||
private BigDecimal amountPaid() {
|
||||
|
||||
+1
-3
@@ -25,7 +25,6 @@ import java.util.List;
|
||||
import java.util.Set;
|
||||
import org.apache.fineract.portfolio.paymentdetail.domain.PaymentDetail;
|
||||
import org.apache.fineract.portfolio.savings.SavingsTransactionBooleanValues;
|
||||
import org.apache.fineract.useradministration.domain.AppUser;
|
||||
|
||||
public interface SavingsAccountDomainService {
|
||||
|
||||
@@ -46,6 +45,5 @@ public interface SavingsAccountDomainService {
|
||||
SavingsAccountTransaction handleReversal(SavingsAccount account, List<SavingsAccountTransaction> savingsAccountTransactions,
|
||||
boolean backdatedTxnsAllowedTill);
|
||||
|
||||
SavingsAccountTransaction handleHold(SavingsAccount account, AppUser createdUser, BigDecimal amount, LocalDate transactionDate,
|
||||
Boolean lienAllowed);
|
||||
SavingsAccountTransaction handleHold(SavingsAccount account, BigDecimal amount, LocalDate transactionDate, Boolean lienAllowed);
|
||||
}
|
||||
|
||||
+10
-23
@@ -43,7 +43,6 @@ import org.apache.fineract.portfolio.savings.SavingsAccountTransactionType;
|
||||
import org.apache.fineract.portfolio.savings.SavingsTransactionBooleanValues;
|
||||
import org.apache.fineract.portfolio.savings.data.SavingsAccountTransactionDTO;
|
||||
import org.apache.fineract.portfolio.savings.exception.DepositAccountTransactionNotAllowedException;
|
||||
import org.apache.fineract.useradministration.domain.AppUser;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
@@ -83,8 +82,7 @@ public class SavingsAccountDomainServiceJpa implements SavingsAccountDomainServi
|
||||
public SavingsAccountTransaction handleWithdrawal(final SavingsAccount account, final DateTimeFormatter fmt,
|
||||
final LocalDate transactionDate, final BigDecimal transactionAmount, final PaymentDetail paymentDetail,
|
||||
final SavingsTransactionBooleanValues transactionBooleanValues, final boolean backdatedTxnsAllowedTill) {
|
||||
|
||||
AppUser user = getAppUserIfPresent();
|
||||
context.authenticatedUser();
|
||||
account.validateForAccountBlock();
|
||||
account.validateForDebitBlock();
|
||||
final boolean isSavingsInterestPostingAtCurrentPeriodEnd = this.configurationDomainService
|
||||
@@ -107,7 +105,7 @@ public class SavingsAccountDomainServiceJpa implements SavingsAccountDomainServi
|
||||
|
||||
Integer accountType = null;
|
||||
final SavingsAccountTransactionDTO transactionDTO = new SavingsAccountTransactionDTO(fmt, transactionDate, transactionAmount,
|
||||
paymentDetail, DateUtils.getLocalDateTimeOfSystem(), user, accountType);
|
||||
paymentDetail, null, accountType);
|
||||
UUID refNo = UUID.randomUUID();
|
||||
final SavingsAccountTransaction withdrawal = account.withdraw(transactionDTO, transactionBooleanValues.isApplyWithdrawFee(),
|
||||
backdatedTxnsAllowedTill, relaxingDaysConfigForPivotDate, refNo.toString());
|
||||
@@ -147,14 +145,6 @@ public class SavingsAccountDomainServiceJpa implements SavingsAccountDomainServi
|
||||
return withdrawal;
|
||||
}
|
||||
|
||||
private AppUser getAppUserIfPresent() {
|
||||
AppUser user = null;
|
||||
if (this.context != null) {
|
||||
user = this.context.getAuthenticatedUserIfPresent();
|
||||
}
|
||||
return user;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public SavingsAccountTransaction handleDeposit(final SavingsAccount account, final DateTimeFormatter fmt,
|
||||
@@ -169,7 +159,7 @@ public class SavingsAccountDomainServiceJpa implements SavingsAccountDomainServi
|
||||
final LocalDate transactionDate, final BigDecimal transactionAmount, final PaymentDetail paymentDetail,
|
||||
final boolean isAccountTransfer, final boolean isRegularTransaction,
|
||||
final SavingsAccountTransactionType savingsAccountTransactionType, final boolean backdatedTxnsAllowedTill) {
|
||||
AppUser user = getAppUserIfPresent();
|
||||
context.authenticatedUser();
|
||||
account.validateForAccountBlock();
|
||||
account.validateForCreditBlock();
|
||||
|
||||
@@ -193,7 +183,7 @@ public class SavingsAccountDomainServiceJpa implements SavingsAccountDomainServi
|
||||
|
||||
Integer accountType = null;
|
||||
final SavingsAccountTransactionDTO transactionDTO = new SavingsAccountTransactionDTO(fmt, transactionDate, transactionAmount,
|
||||
paymentDetail, DateUtils.getLocalDateTimeOfSystem(), user, accountType);
|
||||
paymentDetail, null, accountType);
|
||||
UUID refNo = UUID.randomUUID();
|
||||
final SavingsAccountTransaction deposit = account.deposit(transactionDTO, savingsAccountTransactionType, backdatedTxnsAllowedTill,
|
||||
relaxingDaysConfigForPivotDate, refNo.toString());
|
||||
@@ -226,13 +216,10 @@ public class SavingsAccountDomainServiceJpa implements SavingsAccountDomainServi
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public SavingsAccountTransaction handleHold(final SavingsAccount account, final AppUser createdUser, BigDecimal amount,
|
||||
LocalDate transactionDate, Boolean lienAllowed) {
|
||||
final PaymentDetail paymentDetails = null;
|
||||
|
||||
SavingsAccountTransaction transaction = SavingsAccountTransaction.holdAmount(account, account.office(), paymentDetails,
|
||||
transactionDate, Money.of(account.getCurrency(), amount), DateUtils.getLocalDateTimeOfSystem(), createdUser, lienAllowed);
|
||||
return transaction;
|
||||
public SavingsAccountTransaction handleHold(final SavingsAccount account, BigDecimal amount, LocalDate transactionDate,
|
||||
Boolean lienAllowed) {
|
||||
return SavingsAccountTransaction.holdAmount(account, account.office(), null, transactionDate,
|
||||
Money.of(account.getCurrency(), amount), lienAllowed);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -322,7 +309,7 @@ public class SavingsAccountDomainServiceJpa implements SavingsAccountDomainServi
|
||||
final MathContext mc = new MathContext(15, MoneyHelper.getRoundingMode());
|
||||
for (SavingsAccountTransaction savingsAccountTransaction : savingsAccountTransactions) {
|
||||
if (savingsAccountTransaction.isPostInterestCalculationRequired()
|
||||
&& account.isBeforeLastPostingPeriod(savingsAccountTransaction.transactionLocalDate(), backdatedTxnsAllowedTill)) {
|
||||
&& account.isBeforeLastPostingPeriod(savingsAccountTransaction.getTransactionDate(), backdatedTxnsAllowedTill)) {
|
||||
|
||||
account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth,
|
||||
postInterestOnDate, backdatedTxnsAllowedTill, postReversals);
|
||||
@@ -330,7 +317,7 @@ public class SavingsAccountDomainServiceJpa implements SavingsAccountDomainServi
|
||||
account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
|
||||
financialYearBeginningMonth, postInterestOnDate, backdatedTxnsAllowedTill, postReversals);
|
||||
}
|
||||
account.validatePivotDateTransaction(savingsAccountTransaction.getLastTransactionDate(), backdatedTxnsAllowedTill,
|
||||
account.validatePivotDateTransaction(savingsAccountTransaction.getTransactionDate(), backdatedTxnsAllowedTill,
|
||||
relaxingDaysConfigForPivotDate, "savingsaccount");
|
||||
account.validateAccountBalanceDoesNotBecomeNegativeMinimal(savingsAccountTransaction.getAmount(), false);
|
||||
account.activateAccountBasedOnBalance();
|
||||
|
||||
+2
-2
@@ -216,7 +216,7 @@ public final class SavingsAccountSummary {
|
||||
final SavingsAccountTransaction savingsAccountTransaction = savingsAccountTransactions.get(i);
|
||||
if (savingsAccountTransaction.isInterestPostingAndNotReversed() && !savingsAccountTransaction.isReversalTransaction()
|
||||
&& !isUpdated) {
|
||||
setInterestPostedTillDate(savingsAccountTransaction.getLastTransactionDate());
|
||||
setInterestPostedTillDate(savingsAccountTransaction.getTransactionDate());
|
||||
isUpdated = true;
|
||||
if (!backdatedTxnsAllowedTill) {
|
||||
break;
|
||||
@@ -224,7 +224,7 @@ public final class SavingsAccountSummary {
|
||||
}
|
||||
if (savingsAccountTransaction.isOverdraftInterestAndNotReversed() && !savingsAccountTransaction.isReversalTransaction()
|
||||
&& !isUpdated) {
|
||||
setInterestPostedTillDate(savingsAccountTransaction.getLastTransactionDate());
|
||||
setInterestPostedTillDate(savingsAccountTransaction.getTransactionDate());
|
||||
isUpdated = true;
|
||||
if (!backdatedTxnsAllowedTill) {
|
||||
break;
|
||||
|
||||
+239
-265
@@ -18,6 +18,8 @@
|
||||
*/
|
||||
package org.apache.fineract.portfolio.savings.domain;
|
||||
|
||||
import static org.apache.fineract.infrastructure.core.service.DateUtils.getSystemZoneId;
|
||||
|
||||
import jakarta.persistence.CascadeType;
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
@@ -29,14 +31,16 @@ import jakarta.persistence.Table;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.OffsetDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom;
|
||||
import org.apache.fineract.infrastructure.core.domain.AbstractAuditableWithUTCDateTimeCustom;
|
||||
import org.apache.fineract.infrastructure.core.domain.LocalDateInterval;
|
||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||
import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency;
|
||||
@@ -50,7 +54,6 @@ import org.apache.fineract.portfolio.savings.domain.interest.EndOfDayBalance;
|
||||
import org.apache.fineract.portfolio.savings.domain.interest.SavingsAccountTransactionDetailsForPostingPeriod;
|
||||
import org.apache.fineract.portfolio.savings.service.SavingsEnumerations;
|
||||
import org.apache.fineract.portfolio.tax.domain.TaxComponent;
|
||||
import org.apache.fineract.useradministration.domain.AppUser;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
/**
|
||||
@@ -58,7 +61,7 @@ import org.springframework.util.CollectionUtils;
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "m_savings_account_transaction")
|
||||
public final class SavingsAccountTransaction extends AbstractPersistableCustom {
|
||||
public final class SavingsAccountTransaction extends AbstractAuditableWithUTCDateTimeCustom {
|
||||
|
||||
@ManyToOne(optional = false)
|
||||
@JoinColumn(name = "savings_account_id", referencedColumnName = "id", nullable = false)
|
||||
@@ -102,16 +105,13 @@ public final class SavingsAccountTransaction extends AbstractPersistableCustom {
|
||||
@Column(name = "overdraft_amount_derived", scale = 6, precision = 19, nullable = true)
|
||||
private BigDecimal overdraftAmount;
|
||||
|
||||
@Column(name = "created_date", nullable = false)
|
||||
private LocalDateTime createdDate;
|
||||
@Deprecated
|
||||
@Column(name = "created_date", nullable = true)
|
||||
private LocalDateTime createdDateToRemove;
|
||||
|
||||
@Column(name = "submitted_on_date", nullable = false)
|
||||
private LocalDate submittedOnDate;
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "appuser_id", nullable = true)
|
||||
private AppUser appUser;
|
||||
|
||||
@Column(name = "is_manual", length = 1, nullable = true)
|
||||
private boolean isManualTransaction;
|
||||
|
||||
@@ -143,16 +143,11 @@ public final class SavingsAccountTransaction extends AbstractPersistableCustom {
|
||||
@Column(name = "ref_no", nullable = true)
|
||||
private String refNo;
|
||||
|
||||
SavingsAccountTransaction() {
|
||||
this.dateOf = null;
|
||||
this.typeOf = null;
|
||||
this.createdDate = null;
|
||||
}
|
||||
SavingsAccountTransaction() {}
|
||||
|
||||
private SavingsAccountTransaction(final SavingsAccount savingsAccount, final Office office, final PaymentDetail paymentDetail,
|
||||
final Integer typeOf, final LocalDate transactionLocalDate, final LocalDateTime createdDate, final BigDecimal amount,
|
||||
final boolean isReversed, final AppUser appUser, final boolean isManualTransaction, final Boolean lienTransaction,
|
||||
final String refNo) {
|
||||
final Integer typeOf, final LocalDate transactionLocalDate, final BigDecimal amount, final boolean isReversed,
|
||||
final boolean isManualTransaction, final Boolean lienTransaction, final String refNo) {
|
||||
this.savingsAccount = savingsAccount;
|
||||
this.office = office;
|
||||
this.typeOf = typeOf;
|
||||
@@ -160,42 +155,52 @@ public final class SavingsAccountTransaction extends AbstractPersistableCustom {
|
||||
this.amount = amount;
|
||||
this.reversed = isReversed;
|
||||
this.paymentDetail = paymentDetail;
|
||||
this.createdDate = createdDate;
|
||||
this.createdDateToRemove = null; // #audit backward compatibility deprecated
|
||||
this.submittedOnDate = DateUtils.getBusinessLocalDate();
|
||||
this.appUser = appUser;
|
||||
this.isManualTransaction = isManualTransaction;
|
||||
this.lienTransaction = lienTransaction;
|
||||
this.refNo = refNo;
|
||||
}
|
||||
|
||||
private SavingsAccountTransaction(final SavingsAccount savingsAccount, final Office office, final Integer typeOf,
|
||||
final LocalDate transactionLocalDate, final Money amount, final boolean isReversed, final boolean isManualTransaction,
|
||||
final Boolean lienTransaction, final String refNo) {
|
||||
this(savingsAccount, office, null, typeOf, transactionLocalDate, amount, isReversed, isManualTransaction, lienTransaction, refNo);
|
||||
}
|
||||
|
||||
private SavingsAccountTransaction(final SavingsAccount savingsAccount, final Office office, final PaymentDetail paymentDetail,
|
||||
final Integer typeOf, final LocalDate transactionLocalDate, final Money amount, final boolean isReversed,
|
||||
final boolean isManualTransaction, final Boolean lienTransaction, final String refNo) {
|
||||
this(savingsAccount, office, paymentDetail, typeOf, transactionLocalDate, amount.getAmount(), isReversed, isManualTransaction,
|
||||
lienTransaction, refNo);
|
||||
}
|
||||
|
||||
public static SavingsAccountTransaction deposit(final SavingsAccount savingsAccount, final Office office,
|
||||
final PaymentDetail paymentDetail, final LocalDate date, final Money amount, LocalDateTime createdDate, final AppUser appUser,
|
||||
final String refNo) {
|
||||
final PaymentDetail paymentDetail, final LocalDate date, final Money amount, final String refNo) {
|
||||
final boolean isReversed = false;
|
||||
final boolean isManualTransaction = false;
|
||||
final Boolean lienTransaction = false;
|
||||
return new SavingsAccountTransaction(savingsAccount, office, paymentDetail, SavingsAccountTransactionType.DEPOSIT.getValue(), date,
|
||||
createdDate, amount, isReversed, appUser, isManualTransaction, lienTransaction, refNo);
|
||||
amount, isReversed, isManualTransaction, lienTransaction, refNo);
|
||||
}
|
||||
|
||||
public static SavingsAccountTransaction deposit(final SavingsAccount savingsAccount, final Office office,
|
||||
final PaymentDetail paymentDetail, final LocalDate date, final Money amount, LocalDateTime createdDate, final AppUser appUser,
|
||||
final PaymentDetail paymentDetail, final LocalDate date, final Money amount,
|
||||
final SavingsAccountTransactionType savingsAccountTransactionType, final String refNo) {
|
||||
final boolean isReversed = false;
|
||||
final boolean isManualTransaction = false;
|
||||
final Boolean lienTransaction = false;
|
||||
return new SavingsAccountTransaction(savingsAccount, office, paymentDetail, savingsAccountTransactionType.getValue(), date,
|
||||
createdDate, amount, isReversed, appUser, isManualTransaction, lienTransaction, refNo);
|
||||
return new SavingsAccountTransaction(savingsAccount, office, paymentDetail, savingsAccountTransactionType.getValue(), date, amount,
|
||||
isReversed, isManualTransaction, lienTransaction, refNo);
|
||||
}
|
||||
|
||||
public static SavingsAccountTransaction withdrawal(final SavingsAccount savingsAccount, final Office office,
|
||||
final PaymentDetail paymentDetail, final LocalDate date, final Money amount, LocalDateTime createdDate, final AppUser appUser,
|
||||
final String refNo) {
|
||||
final PaymentDetail paymentDetail, final LocalDate date, final Money amount, final String refNo) {
|
||||
final boolean isReversed = false;
|
||||
final boolean isManualTransaction = false;
|
||||
final Boolean lienTransaction = false;
|
||||
return new SavingsAccountTransaction(savingsAccount, office, paymentDetail, SavingsAccountTransactionType.WITHDRAWAL.getValue(),
|
||||
date, createdDate, amount, isReversed, appUser, isManualTransaction, lienTransaction, refNo);
|
||||
date, amount, isReversed, isManualTransaction, lienTransaction, refNo);
|
||||
}
|
||||
|
||||
public static SavingsAccountTransaction interestPosting(final SavingsAccount savingsAccount, final Office office, final LocalDate date,
|
||||
@@ -204,7 +209,7 @@ public final class SavingsAccountTransaction extends AbstractPersistableCustom {
|
||||
final Boolean lienTransaction = false;
|
||||
final String refNo = null;
|
||||
return new SavingsAccountTransaction(savingsAccount, office, SavingsAccountTransactionType.INTEREST_POSTING.getValue(), date,
|
||||
amount, isReversed, null, isManualTransaction, lienTransaction, refNo);
|
||||
amount, isReversed, isManualTransaction, lienTransaction, refNo);
|
||||
}
|
||||
|
||||
public static SavingsAccountTransaction overdraftInterest(final SavingsAccount savingsAccount, final Office office,
|
||||
@@ -213,82 +218,82 @@ public final class SavingsAccountTransaction extends AbstractPersistableCustom {
|
||||
final Boolean lienTransaction = false;
|
||||
final String refNo = null;
|
||||
return new SavingsAccountTransaction(savingsAccount, office, SavingsAccountTransactionType.OVERDRAFT_INTEREST.getValue(), date,
|
||||
amount, isReversed, null, isManualTransaction, lienTransaction, refNo);
|
||||
amount, isReversed, isManualTransaction, lienTransaction, refNo);
|
||||
}
|
||||
|
||||
public static SavingsAccountTransaction withdrawalFee(final SavingsAccount savingsAccount, final Office office, final LocalDate date,
|
||||
final Money amount, final AppUser appUser, final String refNo) {
|
||||
final Money amount, final String refNo) {
|
||||
final boolean isReversed = false;
|
||||
final boolean isManualTransaction = false;
|
||||
final Boolean lienTransaction = false;
|
||||
return new SavingsAccountTransaction(savingsAccount, office, SavingsAccountTransactionType.WITHDRAWAL_FEE.getValue(), date, amount,
|
||||
isReversed, appUser, isManualTransaction, lienTransaction, refNo);
|
||||
isReversed, isManualTransaction, lienTransaction, refNo);
|
||||
}
|
||||
|
||||
public static SavingsAccountTransaction annualFee(final SavingsAccount savingsAccount, final Office office, final LocalDate date,
|
||||
final Money amount, final AppUser appUser) {
|
||||
final Money amount) {
|
||||
final boolean isReversed = false;
|
||||
final boolean isManualTransaction = false;
|
||||
final Boolean lienTransaction = false;
|
||||
final String refNo = null;
|
||||
return new SavingsAccountTransaction(savingsAccount, office, SavingsAccountTransactionType.ANNUAL_FEE.getValue(), date, amount,
|
||||
isReversed, appUser, isManualTransaction, lienTransaction, refNo);
|
||||
isReversed, isManualTransaction, lienTransaction, refNo);
|
||||
}
|
||||
|
||||
public static SavingsAccountTransaction charge(final SavingsAccount savingsAccount, final Office office, final LocalDate date,
|
||||
final Money amount, final AppUser appUser) {
|
||||
final Money amount) {
|
||||
final boolean isReversed = false;
|
||||
final boolean isManualTransaction = false;
|
||||
final Boolean lienTransaction = false;
|
||||
final String refNo = null;
|
||||
return new SavingsAccountTransaction(savingsAccount, office, SavingsAccountTransactionType.PAY_CHARGE.getValue(), date, amount,
|
||||
isReversed, appUser, isManualTransaction, lienTransaction, refNo);
|
||||
isReversed, isManualTransaction, lienTransaction, refNo);
|
||||
}
|
||||
|
||||
public static SavingsAccountTransaction waiver(final SavingsAccount savingsAccount, final Office office, final LocalDate date,
|
||||
final Money amount, final AppUser appUser) {
|
||||
final Money amount) {
|
||||
final boolean isReversed = false;
|
||||
final boolean isManualTransaction = false;
|
||||
final Boolean lienTransaction = false;
|
||||
final String refNo = null;
|
||||
return new SavingsAccountTransaction(savingsAccount, office, SavingsAccountTransactionType.WAIVE_CHARGES.getValue(), date, amount,
|
||||
isReversed, appUser, isManualTransaction, lienTransaction, refNo);
|
||||
isReversed, isManualTransaction, lienTransaction, refNo);
|
||||
}
|
||||
|
||||
public static SavingsAccountTransaction initiateTransfer(final SavingsAccount savingsAccount, final Office office, final LocalDate date,
|
||||
final AppUser appUser) {
|
||||
public static SavingsAccountTransaction initiateTransfer(final SavingsAccount savingsAccount, final Office office,
|
||||
final LocalDate date) {
|
||||
final boolean isReversed = false;
|
||||
final boolean isManualTransaction = false;
|
||||
final PaymentDetail paymentDetail = null;
|
||||
final Boolean lienTransaction = false;
|
||||
final String refNo = null;
|
||||
return new SavingsAccountTransaction(savingsAccount, office, paymentDetail,
|
||||
SavingsAccountTransactionType.INITIATE_TRANSFER.getValue(), date, DateUtils.getLocalDateTimeOfSystem(),
|
||||
savingsAccount.getSummary().getAccountBalance(), isReversed, appUser, isManualTransaction, lienTransaction, refNo);
|
||||
SavingsAccountTransactionType.INITIATE_TRANSFER.getValue(), date, savingsAccount.getSummary().getAccountBalance(),
|
||||
isReversed, isManualTransaction, lienTransaction, refNo);
|
||||
}
|
||||
|
||||
public static SavingsAccountTransaction approveTransfer(final SavingsAccount savingsAccount, final Office office, final LocalDate date,
|
||||
final AppUser appUser) {
|
||||
public static SavingsAccountTransaction approveTransfer(final SavingsAccount savingsAccount, final Office office,
|
||||
final LocalDate date) {
|
||||
final boolean isReversed = false;
|
||||
final boolean isManualTransaction = false;
|
||||
final PaymentDetail paymentDetail = null;
|
||||
final Boolean lienTransaction = false;
|
||||
final String refNo = null;
|
||||
return new SavingsAccountTransaction(savingsAccount, office, paymentDetail,
|
||||
SavingsAccountTransactionType.APPROVE_TRANSFER.getValue(), date, DateUtils.getLocalDateTimeOfSystem(),
|
||||
savingsAccount.getSummary().getAccountBalance(), isReversed, appUser, isManualTransaction, lienTransaction, refNo);
|
||||
SavingsAccountTransactionType.APPROVE_TRANSFER.getValue(), date, savingsAccount.getSummary().getAccountBalance(),
|
||||
isReversed, isManualTransaction, lienTransaction, refNo);
|
||||
}
|
||||
|
||||
public static SavingsAccountTransaction withdrawTransfer(final SavingsAccount savingsAccount, final Office office, final LocalDate date,
|
||||
final AppUser appUser) {
|
||||
public static SavingsAccountTransaction withdrawTransfer(final SavingsAccount savingsAccount, final Office office,
|
||||
final LocalDate date) {
|
||||
final boolean isReversed = false;
|
||||
final boolean isManualTransaction = false;
|
||||
final PaymentDetail paymentDetail = null;
|
||||
final Boolean lienTransaction = false;
|
||||
final String refNo = null;
|
||||
return new SavingsAccountTransaction(savingsAccount, office, paymentDetail,
|
||||
SavingsAccountTransactionType.WITHDRAW_TRANSFER.getValue(), date, DateUtils.getLocalDateTimeOfSystem(),
|
||||
savingsAccount.getSummary().getAccountBalance(), isReversed, appUser, isManualTransaction, lienTransaction, refNo);
|
||||
SavingsAccountTransactionType.WITHDRAW_TRANSFER.getValue(), date, savingsAccount.getSummary().getAccountBalance(),
|
||||
isReversed, isManualTransaction, lienTransaction, refNo);
|
||||
}
|
||||
|
||||
public static SavingsAccountTransaction withHoldTax(final SavingsAccount savingsAccount, final Office office, final LocalDate date,
|
||||
@@ -298,21 +303,51 @@ public final class SavingsAccountTransaction extends AbstractPersistableCustom {
|
||||
final Boolean lienTransaction = false;
|
||||
final String refNo = null;
|
||||
SavingsAccountTransaction accountTransaction = new SavingsAccountTransaction(savingsAccount, office,
|
||||
SavingsAccountTransactionType.WITHHOLD_TAX.getValue(), date, amount, isReversed, null, isManualTransaction, lienTransaction,
|
||||
SavingsAccountTransactionType.WITHHOLD_TAX.getValue(), date, amount, isReversed, isManualTransaction, lienTransaction,
|
||||
refNo);
|
||||
updateTaxDetails(taxDetails, accountTransaction);
|
||||
return accountTransaction;
|
||||
}
|
||||
|
||||
public static SavingsAccountTransaction escheat(final SavingsAccount savingsAccount, final LocalDate date, final AppUser appUser,
|
||||
public static SavingsAccountTransaction escheat(final SavingsAccount savingsAccount, final LocalDate date,
|
||||
final boolean accountTransaction) {
|
||||
final boolean isReversed = false;
|
||||
final PaymentDetail paymentDetail = null;
|
||||
final Boolean lienTransaction = false;
|
||||
final String refNo = null;
|
||||
return new SavingsAccountTransaction(savingsAccount, savingsAccount.office(), paymentDetail,
|
||||
SavingsAccountTransactionType.ESCHEAT.getValue(), date, DateUtils.getLocalDateTimeOfSystem(),
|
||||
savingsAccount.getSummary().getAccountBalance(), isReversed, appUser, accountTransaction, lienTransaction, refNo);
|
||||
SavingsAccountTransactionType.ESCHEAT.getValue(), date, savingsAccount.getSummary().getAccountBalance(), isReversed,
|
||||
accountTransaction, lienTransaction, refNo);
|
||||
}
|
||||
|
||||
public static SavingsAccountTransaction copyTransaction(SavingsAccountTransaction accountTransaction) {
|
||||
return new SavingsAccountTransaction(accountTransaction.savingsAccount, accountTransaction.office, accountTransaction.paymentDetail,
|
||||
accountTransaction.typeOf, accountTransaction.getTransactionDate(), accountTransaction.amount, accountTransaction.reversed,
|
||||
accountTransaction.isManualTransaction, accountTransaction.lienTransaction, accountTransaction.refNo);
|
||||
}
|
||||
|
||||
public static SavingsAccountTransaction holdAmount(final SavingsAccount savingsAccount, final Office office,
|
||||
final PaymentDetail paymentDetail, final LocalDate date, final Money amount, final Boolean lienTransaction) {
|
||||
final boolean isReversed = false;
|
||||
final boolean isManualTransaction = false;
|
||||
final String refNo = null;
|
||||
return new SavingsAccountTransaction(savingsAccount, office, paymentDetail, SavingsAccountTransactionType.AMOUNT_HOLD.getValue(),
|
||||
date, amount, isReversed, isManualTransaction, lienTransaction, refNo);
|
||||
}
|
||||
|
||||
public static SavingsAccountTransaction releaseAmount(SavingsAccountTransaction accountTransaction, LocalDate transactionDate) {
|
||||
return new SavingsAccountTransaction(accountTransaction.savingsAccount, accountTransaction.office, accountTransaction.paymentDetail,
|
||||
SavingsAccountTransactionType.AMOUNT_RELEASE.getValue(), transactionDate, accountTransaction.amount,
|
||||
accountTransaction.reversed, accountTransaction.isManualTransaction, accountTransaction.lienTransaction,
|
||||
accountTransaction.refNo);
|
||||
}
|
||||
|
||||
public static SavingsAccountTransaction reversal(SavingsAccountTransaction accountTransaction) {
|
||||
SavingsAccountTransaction sat = copyTransaction(accountTransaction);
|
||||
sat.reversed = false;
|
||||
sat.setReversalTransaction(true);
|
||||
sat.originalTxnId = accountTransaction.getId();
|
||||
return sat;
|
||||
}
|
||||
|
||||
public static void updateTaxDetails(final Map<TaxComponent, BigDecimal> taxDetails,
|
||||
@@ -325,71 +360,142 @@ public final class SavingsAccountTransaction extends AbstractPersistableCustom {
|
||||
}
|
||||
}
|
||||
|
||||
public static SavingsAccountTransaction copyTransaction(SavingsAccountTransaction accountTransaction) {
|
||||
return new SavingsAccountTransaction(accountTransaction.savingsAccount, accountTransaction.office, accountTransaction.paymentDetail,
|
||||
accountTransaction.typeOf, accountTransaction.transactionLocalDate(), DateUtils.getLocalDateTimeOfSystem(),
|
||||
accountTransaction.amount, accountTransaction.reversed, accountTransaction.appUser, accountTransaction.isManualTransaction,
|
||||
accountTransaction.lienTransaction, accountTransaction.refNo);
|
||||
public SavingsAccount getSavingsAccount() {
|
||||
return this.savingsAccount;
|
||||
}
|
||||
|
||||
private SavingsAccountTransaction(final SavingsAccount savingsAccount, final Office office, final Integer typeOf,
|
||||
final LocalDate transactionLocalDate, final Money amount, final boolean isReversed, final AppUser appUser,
|
||||
final boolean isManualTransaction, final Boolean lienTransaction, final String refNo) {
|
||||
this(savingsAccount, office, null, typeOf, transactionLocalDate, DateUtils.getLocalDateTimeOfSystem(), amount, isReversed, appUser,
|
||||
isManualTransaction, lienTransaction, refNo);
|
||||
}
|
||||
|
||||
private SavingsAccountTransaction(final SavingsAccount savingsAccount, final Office office, final PaymentDetail paymentDetail,
|
||||
final Integer typeOf, final LocalDate transactionLocalDate, final LocalDateTime createdDate, final Money amount,
|
||||
final boolean isReversed, final AppUser appUser, final boolean isManualTransaction, final Boolean lienTransaction,
|
||||
final String refNo) {
|
||||
this(savingsAccount, office, paymentDetail, typeOf, transactionLocalDate, createdDate, amount.getAmount(), isReversed, appUser,
|
||||
isManualTransaction, lienTransaction, refNo);
|
||||
}
|
||||
|
||||
public static SavingsAccountTransaction holdAmount(final SavingsAccount savingsAccount, final Office office,
|
||||
final PaymentDetail paymentDetail, final LocalDate date, final Money amount, LocalDateTime createdDate, final AppUser appUser,
|
||||
final Boolean lienTransaction) {
|
||||
final boolean isReversed = false;
|
||||
final boolean isManualTransaction = false;
|
||||
final String refNo = null;
|
||||
return new SavingsAccountTransaction(savingsAccount, office, paymentDetail, SavingsAccountTransactionType.AMOUNT_HOLD.getValue(),
|
||||
date, createdDate, amount, isReversed, appUser, isManualTransaction, lienTransaction, refNo);
|
||||
}
|
||||
|
||||
public static SavingsAccountTransaction releaseAmount(SavingsAccountTransaction accountTransaction, LocalDate transactionDate,
|
||||
LocalDateTime createdDate, final AppUser appUser) {
|
||||
return new SavingsAccountTransaction(accountTransaction.savingsAccount, accountTransaction.office, accountTransaction.paymentDetail,
|
||||
SavingsAccountTransactionType.AMOUNT_RELEASE.getValue(), transactionDate, createdDate, accountTransaction.amount,
|
||||
accountTransaction.reversed, appUser, accountTransaction.isManualTransaction, accountTransaction.lienTransaction,
|
||||
accountTransaction.refNo);
|
||||
}
|
||||
|
||||
public static SavingsAccountTransaction reversal(SavingsAccountTransaction accountTransaction) {
|
||||
SavingsAccountTransaction sat = copyTransaction(accountTransaction);
|
||||
sat.reversed = false;
|
||||
sat.setReversalTransaction(true);
|
||||
sat.originalTxnId = accountTransaction.getId();
|
||||
return sat;
|
||||
|
||||
}
|
||||
|
||||
public LocalDate transactionLocalDate() {
|
||||
public LocalDate getTransactionDate() {
|
||||
return this.dateOf;
|
||||
}
|
||||
|
||||
public LocalDate getEndOfBalanceDate() {
|
||||
return balanceEndDate;
|
||||
}
|
||||
|
||||
public boolean isReversed() {
|
||||
return this.reversed;
|
||||
}
|
||||
|
||||
public void reverse() {
|
||||
this.reversed = true;
|
||||
}
|
||||
|
||||
public BigDecimal getAmount() {
|
||||
return this.amount;
|
||||
}
|
||||
|
||||
public Money getAmount(final MonetaryCurrency currency) {
|
||||
return Money.of(currency, this.amount);
|
||||
}
|
||||
|
||||
public void setAmount(final Money amount) {
|
||||
this.amount = amount == null ? null : amount.getAmount();
|
||||
}
|
||||
|
||||
public BigDecimal getRunningBalance() {
|
||||
return this.runningBalance;
|
||||
}
|
||||
|
||||
public Money getRunningBalance(final MonetaryCurrency currency) {
|
||||
return Money.of(currency, this.runningBalance);
|
||||
}
|
||||
|
||||
public void setRunningBalance(Money balance) {
|
||||
this.runningBalance = balance == null ? null : balance.getAmount();
|
||||
}
|
||||
|
||||
public boolean isManualTransaction() {
|
||||
return this.isManualTransaction;
|
||||
}
|
||||
|
||||
public Set<SavingsAccountChargePaidBy> getSavingsAccountChargesPaid() {
|
||||
return this.savingsAccountChargesPaid;
|
||||
}
|
||||
|
||||
public BigDecimal getOverdraftAmount() {
|
||||
return this.overdraftAmount;
|
||||
}
|
||||
|
||||
public Money getOverdraftAmount(final MonetaryCurrency currency) {
|
||||
return Money.of(currency, this.overdraftAmount);
|
||||
}
|
||||
|
||||
void setOverdraftAmount(Money overdraftAmount) {
|
||||
this.overdraftAmount = overdraftAmount == null ? null : overdraftAmount.getAmount();
|
||||
}
|
||||
|
||||
public List<SavingsAccountTransactionTaxDetails> getTaxDetails() {
|
||||
return this.taxDetails;
|
||||
}
|
||||
|
||||
public List<Note> getNotes() {
|
||||
return notes;
|
||||
}
|
||||
|
||||
public Integer getTypeOf() {
|
||||
return this.typeOf;
|
||||
}
|
||||
|
||||
public SavingsAccountTransactionType getTransactionType() {
|
||||
return SavingsAccountTransactionType.fromInt(this.typeOf);
|
||||
}
|
||||
|
||||
public LocalDate getDateOf() {
|
||||
return this.dateOf;
|
||||
}
|
||||
|
||||
public String getRefNo() {
|
||||
return this.refNo;
|
||||
}
|
||||
|
||||
public PaymentDetail getPaymentDetail() {
|
||||
return this.paymentDetail;
|
||||
}
|
||||
|
||||
public void updateReleaseId(Long releaseId) {
|
||||
this.releaseIdOfHoldAmountTransaction = releaseId;
|
||||
}
|
||||
|
||||
public void updateReason(String reasonForBlock) {
|
||||
this.reasonForBlock = reasonForBlock;
|
||||
}
|
||||
|
||||
public Long getReleaseIdOfHoldAmountTransaction() {
|
||||
return this.releaseIdOfHoldAmountTransaction;
|
||||
}
|
||||
|
||||
public MonetaryCurrency getCurrency() {
|
||||
return savingsAccount == null ? null : savingsAccount.getCurrency();
|
||||
}
|
||||
|
||||
public Long getOfficeId() {
|
||||
return this.office.getId();
|
||||
}
|
||||
|
||||
public LocalDate getBalanceEndDate() {
|
||||
return this.balanceEndDate;
|
||||
}
|
||||
|
||||
public BigDecimal getCumulativeBalance() {
|
||||
return this.cumulativeBalance;
|
||||
}
|
||||
|
||||
public Integer getBalanceNumberOfDays() {
|
||||
return this.balanceNumberOfDays;
|
||||
}
|
||||
|
||||
public LocalDate getSubmittedOnDate() {
|
||||
return submittedOnDate;
|
||||
}
|
||||
|
||||
public boolean isReversalTransaction() {
|
||||
return reversalTransaction;
|
||||
}
|
||||
|
||||
void setReversalTransaction(boolean reversalTransaction) {
|
||||
this.reversalTransaction = reversalTransaction;
|
||||
}
|
||||
|
||||
public boolean isDeposit() {
|
||||
return getTransactionType().isDeposit();
|
||||
}
|
||||
@@ -442,10 +548,6 @@ public final class SavingsAccountTransaction extends AbstractPersistableCustom {
|
||||
return !isReversed();
|
||||
}
|
||||
|
||||
public boolean isReversed() {
|
||||
return this.reversed;
|
||||
}
|
||||
|
||||
public boolean isTransferInitiation() {
|
||||
return getTransactionType().isTransferInitiation();
|
||||
}
|
||||
@@ -466,14 +568,6 @@ public final class SavingsAccountTransaction extends AbstractPersistableCustom {
|
||||
return isTransferInitiation() || isTransferApproval() || isTransferRejection() || isTransferWithdrawal();
|
||||
}
|
||||
|
||||
public boolean occursOn(final LocalDate occursOnDate) {
|
||||
return getTransactionLocalDate().isEqual(occursOnDate);
|
||||
}
|
||||
|
||||
public void setLoanDisbursement(boolean isLoanDisbursement) {
|
||||
this.isLoanDisbursement = isLoanDisbursement;
|
||||
}
|
||||
|
||||
public void zeroBalanceFields() {
|
||||
this.runningBalance = null;
|
||||
this.cumulativeBalance = null;
|
||||
@@ -481,35 +575,19 @@ public final class SavingsAccountTransaction extends AbstractPersistableCustom {
|
||||
this.balanceNumberOfDays = null;
|
||||
}
|
||||
|
||||
public void updateRunningBalance(final Money balance) {
|
||||
this.runningBalance = balance.getAmount();
|
||||
}
|
||||
|
||||
public void updateCumulativeBalanceAndDates(final MonetaryCurrency currency, final LocalDate endOfBalanceDate) {
|
||||
// balance end date should not be before transaction date
|
||||
if (endOfBalanceDate != null && endOfBalanceDate.isBefore(this.transactionLocalDate())) {
|
||||
this.balanceEndDate = this.transactionLocalDate();
|
||||
if (endOfBalanceDate != null && DateUtils.isBefore(endOfBalanceDate, this.getTransactionDate())) {
|
||||
this.balanceEndDate = this.getTransactionDate();
|
||||
} else {
|
||||
this.balanceEndDate = endOfBalanceDate;
|
||||
}
|
||||
this.balanceNumberOfDays = LocalDateInterval.create(getTransactionLocalDate(), endOfBalanceDate).daysInPeriodInclusiveOfEndDate();
|
||||
this.balanceNumberOfDays = LocalDateInterval.create(getTransactionDate(), endOfBalanceDate).daysInPeriodInclusiveOfEndDate();
|
||||
this.cumulativeBalance = Money.of(currency, this.runningBalance).multipliedBy(this.balanceNumberOfDays).getAmount();
|
||||
}
|
||||
|
||||
public LocalDate getTransactionLocalDate() {
|
||||
return this.dateOf;
|
||||
}
|
||||
|
||||
public LocalDate getLastTransactionDate() {
|
||||
return this.dateOf;
|
||||
}
|
||||
|
||||
public LocalDate getEndOfBalanceLocalDate() {
|
||||
return balanceEndDate;
|
||||
}
|
||||
|
||||
public boolean isAcceptableForDailyBalance(final LocalDateInterval interestPeriodInterval) {
|
||||
return isNotReversed() && interestPeriodInterval.contains(getTransactionLocalDate()) && isABalanceForAtLeastOneDay();
|
||||
return isNotReversed() && interestPeriodInterval.contains(getTransactionDate()) && isABalanceForAtLeastOneDay();
|
||||
}
|
||||
|
||||
private boolean isABalanceForAtLeastOneDay() {
|
||||
@@ -530,7 +608,7 @@ public final class SavingsAccountTransaction extends AbstractPersistableCustom {
|
||||
thisTransactionData.put("officeId", this.office.getId());
|
||||
thisTransactionData.put("type", transactionType);
|
||||
thisTransactionData.put("reversed", isReversed());
|
||||
thisTransactionData.put("date", getTransactionLocalDate());
|
||||
thisTransactionData.put("date", getTransactionDate());
|
||||
thisTransactionData.put("currencyCode", currencyCode);
|
||||
thisTransactionData.put("amount", this.amount);
|
||||
thisTransactionData.put("overdraftAmount", this.overdraftAmount);
|
||||
@@ -573,29 +651,28 @@ public final class SavingsAccountTransaction extends AbstractPersistableCustom {
|
||||
return thisTransactionData;
|
||||
}
|
||||
|
||||
public boolean isAfter(final LocalDate transactionDate) {
|
||||
return getTransactionLocalDate().isAfter(transactionDate);
|
||||
public boolean isBefore(final LocalDate date) {
|
||||
return DateUtils.isBefore(getTransactionDate(), date);
|
||||
}
|
||||
|
||||
public boolean isManualTransaction() {
|
||||
return this.isManualTransaction;
|
||||
public boolean isAfter(final LocalDate date) {
|
||||
return DateUtils.isAfter(getTransactionDate(), date);
|
||||
}
|
||||
|
||||
public void setPostInterestAsOn(boolean isManualTransaction) {
|
||||
this.isManualTransaction = isManualTransaction;
|
||||
public boolean occursOn(final LocalDate date) {
|
||||
return DateUtils.isEqual(getTransactionDate(), date);
|
||||
}
|
||||
|
||||
public EndOfDayBalance toEndOfDayBalance(final LocalDateInterval periodInterval, final MonetaryCurrency currency) {
|
||||
|
||||
final Money endOfDayBalance = Money.of(currency, this.runningBalance);
|
||||
final Money openingBalance = endOfDayBalance;
|
||||
|
||||
LocalDate balanceDate = periodInterval.startDate();
|
||||
|
||||
int numberOfDays = periodInterval.daysInPeriodInclusiveOfEndDate();
|
||||
if (periodInterval.contains(getTransactionLocalDate())) {
|
||||
balanceDate = getTransactionLocalDate();
|
||||
final LocalDateInterval newInterval = LocalDateInterval.create(getTransactionLocalDate(), periodInterval.endDate());
|
||||
if (periodInterval.contains(getTransactionDate())) {
|
||||
balanceDate = getTransactionDate();
|
||||
final LocalDateInterval newInterval = LocalDateInterval.create(getTransactionDate(), periodInterval.endDate());
|
||||
numberOfDays = newInterval.daysInPeriodInclusiveOfEndDate();
|
||||
}
|
||||
|
||||
@@ -603,7 +680,6 @@ public final class SavingsAccountTransaction extends AbstractPersistableCustom {
|
||||
}
|
||||
|
||||
public EndOfDayBalance toEndOfDayBalance(final Money openingBalance, final LocalDate nextTransactionDate) {
|
||||
|
||||
final MonetaryCurrency currency = openingBalance.getCurrency();
|
||||
Money endOfDayBalance = openingBalance.copy();
|
||||
if (isDeposit() || isDividendPayoutAndNotReversed()) {
|
||||
@@ -612,11 +688,11 @@ public final class SavingsAccountTransaction extends AbstractPersistableCustom {
|
||||
endOfDayBalance = openingBalance.minus(getAmount(currency));
|
||||
}
|
||||
|
||||
int numberOfDays = LocalDateInterval.create(getTransactionLocalDate(), nextTransactionDate).daysInPeriodInclusiveOfEndDate();
|
||||
int numberOfDays = LocalDateInterval.create(getTransactionDate(), nextTransactionDate).daysInPeriodInclusiveOfEndDate();
|
||||
if (!openingBalance.isEqualTo(endOfDayBalance) && numberOfDays > 1) {
|
||||
numberOfDays = numberOfDays - 1;
|
||||
}
|
||||
return EndOfDayBalance.from(getTransactionLocalDate(), openingBalance, endOfDayBalance, numberOfDays);
|
||||
return EndOfDayBalance.from(getTransactionDate(), openingBalance, endOfDayBalance, numberOfDays);
|
||||
}
|
||||
|
||||
public EndOfDayBalance toEndOfDayBalance(final Money openingBalance) {
|
||||
@@ -629,24 +705,23 @@ public final class SavingsAccountTransaction extends AbstractPersistableCustom {
|
||||
if (openingBalance.isGreaterThanZero() || this.savingsAccount.allowOverdraft()) {
|
||||
endOfDayBalance = openingBalance.minus(getAmount(currency));
|
||||
} else {
|
||||
endOfDayBalance = Money.of(currency, this.runningBalance);
|
||||
endOfDayBalance = getRunningBalance(currency);
|
||||
}
|
||||
}
|
||||
|
||||
return EndOfDayBalance.from(getTransactionLocalDate(), openingBalance, endOfDayBalance, this.balanceNumberOfDays);
|
||||
return EndOfDayBalance.from(getTransactionDate(), openingBalance, endOfDayBalance, this.balanceNumberOfDays);
|
||||
}
|
||||
|
||||
public EndOfDayBalance toEndOfDayBalanceBoundedBy(final Money openingBalance, final LocalDateInterval boundedBy) {
|
||||
|
||||
final MonetaryCurrency currency = openingBalance.getCurrency();
|
||||
Money endOfDayBalance = openingBalance.copy();
|
||||
|
||||
int numberOfDaysOfBalance = this.balanceNumberOfDays;
|
||||
|
||||
LocalDate balanceStartDate = getTransactionLocalDate();
|
||||
LocalDate balanceEndDate = getEndOfBalanceLocalDate();
|
||||
LocalDate balanceStartDate = getTransactionDate();
|
||||
LocalDate balanceEndDate = getEndOfBalanceDate();
|
||||
|
||||
if (boundedBy.startDate().isAfter(balanceStartDate)) {
|
||||
if (DateUtils.isBefore(balanceStartDate, boundedBy.startDate())) {
|
||||
balanceStartDate = boundedBy.startDate();
|
||||
final LocalDateInterval spanOfBalance = LocalDateInterval.create(balanceStartDate, balanceEndDate);
|
||||
numberOfDaysOfBalance = spanOfBalance.daysInPeriodInclusiveOfEndDate();
|
||||
@@ -661,12 +736,12 @@ public final class SavingsAccountTransaction extends AbstractPersistableCustom {
|
||||
if (endOfDayBalance.isGreaterThanZero() || this.savingsAccount.allowOverdraft()) {
|
||||
endOfDayBalance = endOfDayBalance.minus(getAmount(currency));
|
||||
} else {
|
||||
endOfDayBalance = Money.of(currency, this.runningBalance);
|
||||
endOfDayBalance = getRunningBalance(currency);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (balanceEndDate.isAfter(boundedBy.endDate())) {
|
||||
if (DateUtils.isAfter(balanceEndDate, boundedBy.endDate())) {
|
||||
balanceEndDate = boundedBy.endDate();
|
||||
final LocalDateInterval spanOfBalance = LocalDateInterval.create(balanceStartDate, balanceEndDate);
|
||||
numberOfDaysOfBalance = spanOfBalance.daysInPeriodInclusiveOfEndDate();
|
||||
@@ -676,16 +751,16 @@ public final class SavingsAccountTransaction extends AbstractPersistableCustom {
|
||||
}
|
||||
|
||||
public boolean isBalanceInExistencesForOneDayOrMore() {
|
||||
return this.balanceNumberOfDays != null && this.balanceNumberOfDays.intValue() >= 1;
|
||||
return this.balanceNumberOfDays != null && this.balanceNumberOfDays >= 1;
|
||||
}
|
||||
|
||||
public boolean fallsWithin(final LocalDateInterval periodInterval) {
|
||||
final LocalDateInterval balanceInterval = LocalDateInterval.create(getTransactionLocalDate(), getEndOfBalanceLocalDate());
|
||||
final LocalDateInterval balanceInterval = LocalDateInterval.create(getTransactionDate(), getEndOfBalanceDate());
|
||||
return periodInterval.contains(balanceInterval);
|
||||
}
|
||||
|
||||
public boolean spansAnyPortionOf(final LocalDateInterval periodInterval) {
|
||||
final LocalDateInterval balanceInterval = LocalDateInterval.create(getTransactionLocalDate(), getEndOfBalanceLocalDate());
|
||||
final LocalDateInterval balanceInterval = LocalDateInterval.create(getTransactionDate(), getEndOfBalanceDate());
|
||||
return balanceInterval.containsPortionOf(periodInterval);
|
||||
}
|
||||
|
||||
@@ -793,123 +868,22 @@ public final class SavingsAccountTransaction extends AbstractPersistableCustom {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Set<SavingsAccountChargePaidBy> getSavingsAccountChargesPaid() {
|
||||
return this.savingsAccountChargesPaid;
|
||||
}
|
||||
|
||||
public void updateOverdraftAmount(BigDecimal overdraftAmount) {
|
||||
this.overdraftAmount = overdraftAmount;
|
||||
}
|
||||
|
||||
public Money getOverdraftAmount(final MonetaryCurrency currency) {
|
||||
return Money.of(currency, this.overdraftAmount);
|
||||
}
|
||||
|
||||
public boolean isPaymentForCurrentCharge(final SavingsAccountCharge savingsAccountCharge) {
|
||||
final SavingsAccountChargePaidBy chargePaidBy = getSavingsAccountChargePaidBy();
|
||||
return chargePaidBy != null && chargePaidBy.getSavingsAccountCharge().equals(savingsAccountCharge);
|
||||
}
|
||||
|
||||
public BigDecimal getAmount() {
|
||||
return this.amount;
|
||||
}
|
||||
|
||||
public List<SavingsAccountTransactionTaxDetails> getTaxDetails() {
|
||||
return this.taxDetails;
|
||||
}
|
||||
|
||||
public List<Note> getNotes() {
|
||||
return notes;
|
||||
}
|
||||
|
||||
public void updateAmount(final Money amount) {
|
||||
this.amount = amount.getAmount();
|
||||
}
|
||||
|
||||
public Integer getTypeOf() {
|
||||
return this.typeOf;
|
||||
}
|
||||
|
||||
public SavingsAccountTransactionType getTransactionType() {
|
||||
return SavingsAccountTransactionType.fromInt(this.typeOf);
|
||||
}
|
||||
|
||||
public SavingsAccount getSavingsAccount() {
|
||||
return this.savingsAccount;
|
||||
}
|
||||
|
||||
public void setSavingsAccount(SavingsAccount savingsAccount) {
|
||||
this.savingsAccount = savingsAccount;
|
||||
}
|
||||
|
||||
public LocalDate getDateOf() {
|
||||
return this.dateOf;
|
||||
}
|
||||
|
||||
public String getRefNo() {
|
||||
return this.refNo;
|
||||
}
|
||||
|
||||
public PaymentDetail getPaymentDetail() {
|
||||
return this.paymentDetail;
|
||||
}
|
||||
|
||||
public void updateReleaseId(Long releaseId) {
|
||||
this.releaseIdOfHoldAmountTransaction = releaseId;
|
||||
}
|
||||
|
||||
public void updateReason(String reasonForBlock) {
|
||||
this.reasonForBlock = reasonForBlock;
|
||||
}
|
||||
|
||||
public Long getReleaseIdOfHoldAmountTransaction() {
|
||||
return this.releaseIdOfHoldAmountTransaction;
|
||||
@Override
|
||||
public Optional<OffsetDateTime> getCreatedDate() {
|
||||
// #audit backward compatibility keep system datetime
|
||||
return Optional.ofNullable(super.getCreatedDate()
|
||||
.orElse(createdDateToRemove == null ? null : createdDateToRemove.atZone(getSystemZoneId()).toOffsetDateTime()));
|
||||
}
|
||||
|
||||
public boolean isAmountOnHoldNotReleased() {
|
||||
return (isAmountOnHold() && getReleaseIdOfHoldAmountTransaction() == null);
|
||||
}
|
||||
|
||||
public Long getOfficeId() {
|
||||
return this.office.getId();
|
||||
}
|
||||
|
||||
public LocalDate getBalanceEndDate() {
|
||||
return this.balanceEndDate;
|
||||
}
|
||||
|
||||
public BigDecimal getCumulativeBalance() {
|
||||
return this.cumulativeBalance;
|
||||
}
|
||||
|
||||
public Integer getBalanceNumberOfDays() {
|
||||
return this.balanceNumberOfDays;
|
||||
}
|
||||
|
||||
public Long getAppUserId() {
|
||||
return this.appUser.getId();
|
||||
}
|
||||
|
||||
public LocalDateTime getCreatedDate() {
|
||||
return this.createdDate;
|
||||
}
|
||||
|
||||
public LocalDate getSubmittedOnDate() {
|
||||
return submittedOnDate;
|
||||
}
|
||||
|
||||
public boolean getIsManualTransaction() {
|
||||
return this.isManualTransaction;
|
||||
}
|
||||
|
||||
public void setReversalTransaction(boolean reversalTransaction) {
|
||||
this.reversalTransaction = reversalTransaction;
|
||||
}
|
||||
|
||||
public boolean isReversalTransaction() {
|
||||
return reversalTransaction;
|
||||
}
|
||||
|
||||
public SavingsAccountTransactionDetailsForPostingPeriod toSavingsAccountTransactionDetailsForPostingPeriod(MonetaryCurrency currency,
|
||||
boolean isAllowOverDraft) {
|
||||
return new SavingsAccountTransactionDetailsForPostingPeriod(getId(), this.dateOf, this.balanceEndDate, this.runningBalance,
|
||||
|
||||
+12
-12
@@ -19,6 +19,7 @@
|
||||
package org.apache.fineract.portfolio.savings.domain;
|
||||
|
||||
import java.util.Comparator;
|
||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||
|
||||
/**
|
||||
* Sort savings account transactions by transaction date and transaction type placing
|
||||
@@ -27,18 +28,17 @@ public class SavingsAccountTransactionComparator implements Comparator<SavingsAc
|
||||
|
||||
@Override
|
||||
public int compare(final SavingsAccountTransaction o1, final SavingsAccountTransaction o2) {
|
||||
int compareResult = 0;
|
||||
final int comparsion = o1.transactionLocalDate().compareTo(o2.transactionLocalDate());
|
||||
if (comparsion == 0) {
|
||||
compareResult = o1.getCreatedDate().compareTo(o2.getCreatedDate());
|
||||
if (compareResult == 0 && o1.getId() != null && o2.getId() != null) {
|
||||
compareResult = o1.getId().compareTo(o2.getId());
|
||||
} else {
|
||||
compareResult = comparsion;
|
||||
}
|
||||
} else {
|
||||
compareResult = comparsion;
|
||||
int result = DateUtils.compare(o1.getTransactionDate(), o2.getTransactionDate());
|
||||
if (result != 0) {
|
||||
return result;
|
||||
}
|
||||
return compareResult;
|
||||
result = DateUtils.compare(o1.getCreatedDateTime(), o2.getCreatedDateTime());
|
||||
if (result != 0) {
|
||||
return result;
|
||||
}
|
||||
if (o1.getId() != null && o2.getId() != null) {
|
||||
return o1.getId().compareTo(o2.getId());
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
+12
-13
@@ -19,26 +19,25 @@
|
||||
package org.apache.fineract.portfolio.savings.domain;
|
||||
|
||||
import java.util.Comparator;
|
||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||
import org.apache.fineract.portfolio.savings.data.SavingsAccountTransactionData;
|
||||
|
||||
public class SavingsAccountTransactionDataComparator implements Comparator<SavingsAccountTransactionData> {
|
||||
|
||||
@Override
|
||||
public int compare(final SavingsAccountTransactionData o1, final SavingsAccountTransactionData o2) {
|
||||
int compareResult = 0;
|
||||
|
||||
final int comparsion = o1.getTransactionDate().compareTo(o2.getTransactionDate());
|
||||
if (comparsion == 0) {
|
||||
compareResult = o1.getSubmittedOnDate().compareTo(o2.getSubmittedOnDate());
|
||||
if (compareResult == 0 && o1.getId() != null && o2.getId() != null) {
|
||||
compareResult = o1.getId().compareTo(o2.getId());
|
||||
} else {
|
||||
compareResult = comparsion;
|
||||
}
|
||||
} else {
|
||||
compareResult = comparsion;
|
||||
int result = DateUtils.compare(o1.getTransactionDate(), o2.getTransactionDate());
|
||||
if (result != 0) {
|
||||
return result;
|
||||
}
|
||||
return compareResult;
|
||||
result = DateUtils.compare(o1.getSubmittedOnDate(), o2.getSubmittedOnDate());
|
||||
if (result != 0) {
|
||||
return result;
|
||||
}
|
||||
if (o1.getId() != null && o2.getId() != null) {
|
||||
return o1.getId().compareTo(o2.getId());
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+54
-27
@@ -18,18 +18,24 @@
|
||||
*/
|
||||
package org.apache.fineract.portfolio.savings.domain;
|
||||
|
||||
import static org.apache.fineract.infrastructure.core.service.DateUtils.getSystemZoneId;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.JoinColumn;
|
||||
import jakarta.persistence.ManyToOne;
|
||||
import jakarta.persistence.Table;
|
||||
import java.time.LocalDate;
|
||||
import org.apache.fineract.infrastructure.core.domain.AbstractAuditableCustom;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.OffsetDateTime;
|
||||
import java.util.Optional;
|
||||
import org.apache.fineract.infrastructure.core.domain.AbstractAuditableWithUTCDateTimeCustom;
|
||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||
import org.apache.fineract.organisation.staff.domain.Staff;
|
||||
|
||||
@Entity
|
||||
@Table(name = "m_savings_officer_assignment_history")
|
||||
public class SavingsOfficerAssignmentHistory extends AbstractAuditableCustom {
|
||||
public class SavingsOfficerAssignmentHistory extends AbstractAuditableWithUTCDateTimeCustom {
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "account_id", nullable = false)
|
||||
@@ -45,10 +51,13 @@ public class SavingsOfficerAssignmentHistory extends AbstractAuditableCustom {
|
||||
@Column(name = "end_date")
|
||||
private LocalDate endDate;
|
||||
|
||||
public static SavingsOfficerAssignmentHistory createNew(final SavingsAccount account, final Staff savingsOfficer,
|
||||
final LocalDate assignmentDate) {
|
||||
return new SavingsOfficerAssignmentHistory(account, savingsOfficer, assignmentDate, null);
|
||||
}
|
||||
@Deprecated
|
||||
@Column(name = "created_date")
|
||||
private LocalDateTime createdDateToRemove;
|
||||
|
||||
@Deprecated
|
||||
@Column(name = "lastmodified_date")
|
||||
private LocalDateTime lastModifiedDateToRemove;
|
||||
|
||||
protected SavingsOfficerAssignmentHistory() {
|
||||
//
|
||||
@@ -62,7 +71,12 @@ public class SavingsOfficerAssignmentHistory extends AbstractAuditableCustom {
|
||||
this.endDate = endDate;
|
||||
}
|
||||
|
||||
public void updateSavingsOfficer(final Staff savingsOfficer) {
|
||||
public static SavingsOfficerAssignmentHistory createNew(final SavingsAccount account, final Staff savingsOfficer,
|
||||
final LocalDate startDate) {
|
||||
return new SavingsOfficerAssignmentHistory(account, savingsOfficer, startDate, null);
|
||||
}
|
||||
|
||||
public void setSavingsOfficer(final Staff savingsOfficer) {
|
||||
this.savingsOfficer = savingsOfficer;
|
||||
}
|
||||
|
||||
@@ -70,28 +84,28 @@ public class SavingsOfficerAssignmentHistory extends AbstractAuditableCustom {
|
||||
return this.savingsOfficer.identifiedBy(staff);
|
||||
}
|
||||
|
||||
public void updateStartDate(final LocalDate startDate) {
|
||||
this.startDate = startDate;
|
||||
}
|
||||
|
||||
public void updateEndDate(final LocalDate endDate) {
|
||||
this.endDate = endDate;
|
||||
}
|
||||
|
||||
public boolean matchesStartDateOf(final LocalDate matchingDate) {
|
||||
return getStartDate().isEqual(matchingDate);
|
||||
}
|
||||
|
||||
public LocalDate getStartDate() {
|
||||
return this.startDate;
|
||||
}
|
||||
|
||||
public boolean hasStartDateBefore(final LocalDate matchingDate) {
|
||||
return matchingDate.isBefore(getStartDate());
|
||||
public void setStartDate(final LocalDate startDate) {
|
||||
this.startDate = startDate;
|
||||
}
|
||||
|
||||
public boolean isCurrentRecord() {
|
||||
return this.endDate == null;
|
||||
public LocalDate getEndDate() {
|
||||
return this.endDate;
|
||||
}
|
||||
|
||||
public void setEndDate(final LocalDate endDate) {
|
||||
this.endDate = endDate;
|
||||
}
|
||||
|
||||
public boolean matchesStartDateOf(final LocalDate matchingDate) {
|
||||
return DateUtils.isEqual(matchingDate, getStartDate());
|
||||
}
|
||||
|
||||
public boolean isBeforeStartDate(final LocalDate matchingDate) {
|
||||
return DateUtils.isBefore(matchingDate, getStartDate());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -100,12 +114,25 @@ public class SavingsOfficerAssignmentHistory extends AbstractAuditableCustom {
|
||||
* @param compareDate
|
||||
* @return
|
||||
*/
|
||||
public boolean isEndDateAfter(final LocalDate compareDate) {
|
||||
return this.endDate != null && this.endDate.isAfter(compareDate);
|
||||
public boolean isBeforeEndDate(final LocalDate compareDate) {
|
||||
return DateUtils.isBefore(compareDate, this.endDate);
|
||||
}
|
||||
|
||||
public LocalDate getEndDate() {
|
||||
return this.endDate;
|
||||
public boolean isCurrentRecord() {
|
||||
return this.endDate == null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<OffsetDateTime> getCreatedDate() {
|
||||
// #audit backward compatibility keep system datetime
|
||||
return Optional.ofNullable(super.getCreatedDate()
|
||||
.orElse(createdDateToRemove == null ? null : createdDateToRemove.atZone(getSystemZoneId()).toOffsetDateTime()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<OffsetDateTime> getLastModifiedDate() {
|
||||
// #audit backward compatibility keep system datetime
|
||||
return Optional.ofNullable(super.getLastModifiedDate()
|
||||
.orElse(lastModifiedDateToRemove == null ? null : lastModifiedDateToRemove.atZone(getSystemZoneId()).toOffsetDateTime()));
|
||||
}
|
||||
}
|
||||
|
||||
+4
-1
@@ -20,6 +20,7 @@ package org.apache.fineract.portfolio.savings.jobs.generaterdschedule;
|
||||
|
||||
import org.apache.fineract.infrastructure.core.service.database.RoutingDataSourceServiceFactory;
|
||||
import org.apache.fineract.infrastructure.jobs.service.JobName;
|
||||
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
|
||||
import org.apache.fineract.portfolio.savings.service.DepositAccountReadPlatformService;
|
||||
import org.springframework.batch.core.Job;
|
||||
import org.springframework.batch.core.Step;
|
||||
@@ -43,6 +44,8 @@ public class GenerateRdScheduleConfig {
|
||||
private RoutingDataSourceServiceFactory dataSourceServiceFactory;
|
||||
@Autowired
|
||||
private DepositAccountReadPlatformService depositAccountReadPlatformService;
|
||||
@Autowired
|
||||
private PlatformSecurityContext securityContext;
|
||||
|
||||
@Bean
|
||||
protected Step generateRdScheduleStep() {
|
||||
@@ -58,6 +61,6 @@ public class GenerateRdScheduleConfig {
|
||||
|
||||
@Bean
|
||||
public GenerateRdScheduleTasklet generateRdScheduleTasklet() {
|
||||
return new GenerateRdScheduleTasklet(dataSourceServiceFactory, depositAccountReadPlatformService);
|
||||
return new GenerateRdScheduleTasklet(dataSourceServiceFactory, depositAccountReadPlatformService, securityContext);
|
||||
}
|
||||
}
|
||||
|
||||
+26
-31
@@ -18,15 +18,23 @@
|
||||
*/
|
||||
package org.apache.fineract.portfolio.savings.jobs.generaterdschedule;
|
||||
|
||||
import static org.apache.fineract.infrastructure.core.domain.AuditableFieldsConstants.CREATED_BY_DB_FIELD;
|
||||
import static org.apache.fineract.infrastructure.core.domain.AuditableFieldsConstants.CREATED_DATE_DB_FIELD;
|
||||
import static org.apache.fineract.infrastructure.core.domain.AuditableFieldsConstants.LAST_MODIFIED_BY_DB_FIELD;
|
||||
import static org.apache.fineract.infrastructure.core.domain.AuditableFieldsConstants.LAST_MODIFIED_DATE_DB_FIELD;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.OffsetDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||
import org.apache.fineract.infrastructure.core.service.database.RoutingDataSourceServiceFactory;
|
||||
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
|
||||
import org.apache.fineract.portfolio.savings.DepositAccountUtils;
|
||||
import org.apache.fineract.portfolio.savings.service.DepositAccountReadPlatformService;
|
||||
import org.springframework.batch.core.StepContribution;
|
||||
@@ -41,19 +49,20 @@ public class GenerateRdScheduleTasklet implements Tasklet {
|
||||
|
||||
private final RoutingDataSourceServiceFactory dataSourceServiceFactory;
|
||||
private final DepositAccountReadPlatformService depositAccountReadPlatformService;
|
||||
private final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
|
||||
private final DateTimeFormatter formatterWithTime = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
||||
private final PlatformSecurityContext securityContext;
|
||||
|
||||
@Override
|
||||
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
|
||||
final JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSourceServiceFactory.determineDataSourceService().retrieveDataSource());
|
||||
final Collection<Map<String, Object>> scheduleDetails = depositAccountReadPlatformService.retriveDataForRDScheduleCreation();
|
||||
String insertSql = "INSERT INTO m_mandatory_savings_schedule (savings_account_id, duedate, installment, deposit_amount, completed_derived, created_date, lastmodified_date) VALUES ";
|
||||
StringBuilder sb = new StringBuilder();
|
||||
String currentDate = DateUtils.getLocalDateTimeOfTenant().format(DateUtils.DEFAULT_DATETIME_FORMATTER);
|
||||
String insertSql = "INSERT INTO m_mandatory_savings_schedule (savings_account_id, duedate, installment, deposit_amount, completed_derived, "
|
||||
+ CREATED_DATE_DB_FIELD + ", " + CREATED_BY_DB_FIELD + ", " + LAST_MODIFIED_DATE_DB_FIELD + ", " + LAST_MODIFIED_BY_DB_FIELD
|
||||
+ ") " + "VALUES (?, ?, ?, ?, ?, ?, ?)";
|
||||
List<Object[]> params = new ArrayList<>();
|
||||
Long userId = securityContext.authenticatedUser().getId();
|
||||
int iterations = 0;
|
||||
for (Map<String, Object> details : scheduleDetails) {
|
||||
Long count = (Long) details.get("futureInstallemts");
|
||||
Long count = (Long) details.get("futureInstallments");
|
||||
if (count == null) {
|
||||
count = 0L;
|
||||
}
|
||||
@@ -66,34 +75,20 @@ public class GenerateRdScheduleTasklet implements Tasklet {
|
||||
count++;
|
||||
installmentNumber++;
|
||||
lastDepositDate = DepositAccountUtils.calculateNextDepositDate(lastDepositDate, recurrence);
|
||||
|
||||
if (sb.length() > 0) {
|
||||
sb.append(", ");
|
||||
}
|
||||
sb.append("(");
|
||||
sb.append(savingsId);
|
||||
sb.append(",'");
|
||||
sb.append(formatter.format(lastDepositDate));
|
||||
sb.append("',");
|
||||
sb.append(installmentNumber);
|
||||
sb.append(",");
|
||||
sb.append(amount);
|
||||
sb.append(", b'0','");
|
||||
sb.append(currentDate);
|
||||
sb.append("','");
|
||||
sb.append(currentDate);
|
||||
sb.append("')");
|
||||
OffsetDateTime auditTime = DateUtils.getAuditOffsetDateTime();
|
||||
params.add(new Object[] { savingsId, lastDepositDate, installmentNumber, amount, false, auditTime, userId, auditTime,
|
||||
userId });
|
||||
iterations++;
|
||||
if (iterations > 200) {
|
||||
jdbcTemplate.update(insertSql + sb); // NOSONAR
|
||||
sb = new StringBuilder();
|
||||
}
|
||||
|
||||
}
|
||||
if (iterations > 200) {
|
||||
jdbcTemplate.batchUpdate(insertSql, params);
|
||||
params.clear();
|
||||
iterations = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (sb.length() > 0) {
|
||||
jdbcTemplate.update(insertSql + sb); // NOSONAR
|
||||
if (!params.isEmpty()) {
|
||||
jdbcTemplate.batchUpdate(insertSql, params);
|
||||
}
|
||||
return RepeatStatus.FINISHED;
|
||||
}
|
||||
|
||||
+4
-2
@@ -18,6 +18,8 @@
|
||||
*/
|
||||
package org.apache.fineract.portfolio.savings.service;
|
||||
|
||||
import static org.apache.fineract.infrastructure.core.domain.AuditableFieldsConstants.CREATED_BY_DB_FIELD;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
@@ -524,7 +526,7 @@ public class DepositAccountReadPlatformServiceImpl implements DepositAccountRead
|
||||
sb.append(" select rd.savings_account_id savingsId, rd.mandatory_recommended_deposit_amount as amount,");
|
||||
sb.append(" mc.recurrence as recurrence ,");
|
||||
sb.append(" max(ms.duedate) as dueDate , max(ms.installment) as installment,");
|
||||
sb.append(" count(ms.installment) as futureInstallemts");
|
||||
sb.append(" count(ms.installment) as futureInstallments");
|
||||
sb.append(" from m_deposit_account_term_and_preclosure dat ");
|
||||
sb.append(" inner join m_savings_account sa on sa.id = dat.savings_account_id and sa.status_enum = ?");
|
||||
sb.append(" inner join m_deposit_account_recurring_detail rd on rd.savings_account_id = dat.savings_account_id ");
|
||||
@@ -1163,7 +1165,7 @@ public class DepositAccountReadPlatformServiceImpl implements DepositAccountRead
|
||||
sqlBuilder.append("left join m_account_transfer_transaction totran on totran.to_savings_transaction_id = tr.id ");
|
||||
sqlBuilder.append("left join m_payment_detail pd on tr.payment_detail_id = pd.id ");
|
||||
sqlBuilder.append("left join m_payment_type pt on pd.payment_type_id = pt.id ");
|
||||
sqlBuilder.append("left join m_appuser au on au.id=tr.appuser_id ");
|
||||
sqlBuilder.append("left join m_appuser au on au.id = tr." + CREATED_BY_DB_FIELD);
|
||||
this.schemaSql = sqlBuilder.toString();
|
||||
}
|
||||
|
||||
|
||||
+51
-64
@@ -144,7 +144,7 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult activateFDAccount(final Long savingsId, final JsonCommand command) {
|
||||
final AppUser user = this.context.authenticatedUser();
|
||||
final AppUser user = context.authenticatedUser();
|
||||
|
||||
final boolean isSavingsInterestPostingAtCurrentPeriodEnd = this.configurationDomainService
|
||||
.isSavingsInterestPostingAtCurrentPeriodEnd();
|
||||
@@ -160,7 +160,7 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
final Set<Long> existingReversedTransactionIds = new HashSet<>();
|
||||
updateExistingTransactionsDetails(account, existingTransactionIds, existingReversedTransactionIds);
|
||||
|
||||
final Map<String, Object> changes = account.activate(user, command, DateUtils.getBusinessLocalDate());
|
||||
final Map<String, Object> changes = account.activate(user, command);
|
||||
Money activationChargeAmount = getActivationCharge(account);
|
||||
if (!changes.isEmpty()) {
|
||||
final Locale locale = command.extractLocale();
|
||||
@@ -172,13 +172,13 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
|
||||
if (portfolioAccountData == null) {
|
||||
final PaymentDetail paymentDetail = null;
|
||||
this.depositAccountDomainService.handleFDDeposit(account, fmt, account.getActivationLocalDate(),
|
||||
this.depositAccountDomainService.handleFDDeposit(account, fmt, account.getActivationDate(),
|
||||
amountForDeposit.getAmount(), paymentDetail);
|
||||
} else {
|
||||
final SavingsAccount fromSavingsAccount = null;
|
||||
boolean isRegularTransaction = false;
|
||||
final boolean isExceptionForBalanceCheck = false;
|
||||
final AccountTransferDTO accountTransferDTO = new AccountTransferDTO(account.getActivationLocalDate(),
|
||||
final AccountTransferDTO accountTransferDTO = new AccountTransferDTO(account.getActivationDate(),
|
||||
amountForDeposit.getAmount(), PortfolioAccountType.SAVINGS, PortfolioAccountType.SAVINGS,
|
||||
portfolioAccountData.getId(), account.getId(), "Account Transfer", locale, fmt, null, null, null, null, null,
|
||||
AccountTransferType.ACCOUNT_TRANSFER.getValue(), null, null, ExternalId.empty(), null, account,
|
||||
@@ -188,9 +188,9 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
final boolean isInterestTransfer = false;
|
||||
final LocalDate postInterestOnDate = null;
|
||||
if (activationChargeAmount.isGreaterThanZero()) {
|
||||
payActivationCharge(account, user);
|
||||
payActivationCharge(account);
|
||||
}
|
||||
if (account.isBeforeLastPostingPeriod(account.getActivationLocalDate(), false)) {
|
||||
if (account.isBeforeLastPostingPeriod(account.getActivationDate(), false)) {
|
||||
final LocalDate today = DateUtils.getBusinessLocalDate();
|
||||
account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
|
||||
financialYearBeginningMonth, postInterestOnDate, false);
|
||||
@@ -237,11 +237,11 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
return activationChargeAmount;
|
||||
}
|
||||
|
||||
private void payActivationCharge(final FixedDepositAccount account, AppUser user) {
|
||||
private void payActivationCharge(final FixedDepositAccount account) {
|
||||
for (SavingsAccountCharge savingsAccountCharge : account.charges()) {
|
||||
if (savingsAccountCharge.isSavingsActivation()) {
|
||||
account.payCharge(savingsAccountCharge, savingsAccountCharge.getAmount(account.getCurrency()),
|
||||
account.getActivationLocalDate(), user, false, null);
|
||||
account.payCharge(savingsAccountCharge, savingsAccountCharge.getAmount(account.getCurrency()), account.getActivationDate(),
|
||||
false, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -267,7 +267,7 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
final Set<Long> existingReversedTransactionIds = new HashSet<>();
|
||||
updateExistingTransactionsDetails(account, existingTransactionIds, existingReversedTransactionIds);
|
||||
|
||||
final Map<String, Object> changes = account.activate(user, command, DateUtils.getBusinessLocalDate());
|
||||
final Map<String, Object> changes = account.activate(user, command);
|
||||
|
||||
if (!changes.isEmpty()) {
|
||||
final Locale locale = command.extractLocale();
|
||||
@@ -277,12 +277,12 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
final PortfolioAccountData portfolioAccountData = this.accountAssociationsReadPlatformService
|
||||
.retriveSavingsLinkedAssociation(savingsId);
|
||||
if (portfolioAccountData == null) {
|
||||
this.depositAccountDomainService.handleRDDeposit(account, fmt, account.getActivationLocalDate(),
|
||||
this.depositAccountDomainService.handleRDDeposit(account, fmt, account.getActivationDate(),
|
||||
amountForDeposit.getAmount(), null, isRegularTransaction);
|
||||
} else {
|
||||
final boolean isExceptionForBalanceCheck = false;
|
||||
final SavingsAccount fromSavingsAccount = null;
|
||||
final AccountTransferDTO accountTransferDTO = new AccountTransferDTO(account.getActivationLocalDate(),
|
||||
final AccountTransferDTO accountTransferDTO = new AccountTransferDTO(account.getActivationDate(),
|
||||
amountForDeposit.getAmount(), PortfolioAccountType.SAVINGS, PortfolioAccountType.SAVINGS,
|
||||
portfolioAccountData.getId(), account.getId(), "Account Transfer", locale, fmt, null, null, null, null, null,
|
||||
AccountTransferType.ACCOUNT_TRANSFER.getValue(), null, null, ExternalId.empty(), null, account,
|
||||
@@ -314,7 +314,7 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
account.updateOverduePayments(overdueUptoDate);
|
||||
final boolean isInterestTransfer = false;
|
||||
final LocalDate postInterestOnDate = null;
|
||||
if (account.isBeforeLastPostingPeriod(account.getActivationLocalDate(), false)) {
|
||||
if (account.isBeforeLastPostingPeriod(account.getActivationDate(), false)) {
|
||||
final LocalDate today = DateUtils.getBusinessLocalDate();
|
||||
account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth,
|
||||
postInterestOnDate, false, postReversals);
|
||||
@@ -571,7 +571,7 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
checkClientOrGroupActive(account);
|
||||
final boolean postReversals = false;
|
||||
if (savingsAccountTransaction.isPostInterestCalculationRequired()
|
||||
&& account.isBeforeLastPostingPeriod(savingsAccountTransaction.transactionLocalDate(), false)) {
|
||||
&& account.isBeforeLastPostingPeriod(savingsAccountTransaction.getTransactionDate(), false)) {
|
||||
account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth,
|
||||
postInterestOnDate, false, postReversals);
|
||||
} else {
|
||||
@@ -620,7 +620,7 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
|
||||
@Override
|
||||
public CommandProcessingResult adjustRDTransaction(final Long savingsId, final Long transactionId, final JsonCommand command) {
|
||||
AppUser user = getAppUserIfPresent();
|
||||
context.authenticatedUser();
|
||||
|
||||
final boolean isSavingsInterestPostingAtCurrentPeriodEnd = this.configurationDomainService
|
||||
.isSavingsInterestPostingAtCurrentPeriodEnd();
|
||||
@@ -671,11 +671,11 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
UUID refNo = UUID.randomUUID();
|
||||
if (savingsAccountTransaction.isDeposit()) {
|
||||
final SavingsAccountTransactionDTO transactionDTO = new SavingsAccountTransactionDTO(fmt, transactionDate, transactionAmount,
|
||||
paymentDetail, savingsAccountTransaction.getCreatedDate(), user, accountType);
|
||||
paymentDetail, null, accountType);
|
||||
transaction = account.deposit(transactionDTO, false, relaxingDaysConfigForPivotDate, refNo.toString());
|
||||
} else {
|
||||
final SavingsAccountTransactionDTO transactionDTO = new SavingsAccountTransactionDTO(fmt, transactionDate, transactionAmount,
|
||||
paymentDetail, savingsAccountTransaction.getCreatedDate(), user, accountType);
|
||||
paymentDetail, null, accountType);
|
||||
transaction = account.withdraw(transactionDTO, true, false, relaxingDaysConfigForPivotDate, refNo.toString());
|
||||
}
|
||||
final Long newtransactionId = saveTransactionToGenerateTransactionId(transaction);
|
||||
@@ -683,7 +683,7 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
final LocalDate postInterestOnDate = null;
|
||||
final boolean postReversals = false;
|
||||
if (account.isBeforeLastPostingPeriod(transactionDate, false)
|
||||
|| account.isBeforeLastPostingPeriod(savingsAccountTransaction.transactionLocalDate(), false)) {
|
||||
|| account.isBeforeLastPostingPeriod(savingsAccountTransaction.getTransactionDate(), false)) {
|
||||
account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth,
|
||||
postInterestOnDate, false, postReversals);
|
||||
} else {
|
||||
@@ -757,8 +757,7 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
DepositAccountType.FIXED_DEPOSIT);
|
||||
checkClientOrGroupActive(account);
|
||||
|
||||
this.depositAccountDomainService.handleFDAccountClosure(account, paymentDetail, user, command, DateUtils.getBusinessLocalDate(),
|
||||
changes);
|
||||
this.depositAccountDomainService.handleFDAccountClosure(account, paymentDetail, user, command, changes);
|
||||
|
||||
final String noteText = command.stringValueOfParameterNamed("note");
|
||||
if (StringUtils.isNotBlank(noteText)) {
|
||||
@@ -791,8 +790,7 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
DepositAccountType.RECURRING_DEPOSIT);
|
||||
checkClientOrGroupActive(account);
|
||||
|
||||
this.depositAccountDomainService.handleRDAccountClosure(account, paymentDetail, user, command, DateUtils.getBusinessLocalDate(),
|
||||
changes);
|
||||
this.depositAccountDomainService.handleRDAccountClosure(account, paymentDetail, user, command, changes);
|
||||
|
||||
final String noteText = command.stringValueOfParameterNamed("note");
|
||||
if (StringUtils.isNotBlank(noteText)) {
|
||||
@@ -825,8 +823,7 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
DepositAccountType.FIXED_DEPOSIT);
|
||||
checkClientOrGroupActive(account);
|
||||
|
||||
this.depositAccountDomainService.handleFDAccountPreMatureClosure(account, paymentDetail, user, command,
|
||||
DateUtils.getBusinessLocalDate(), changes);
|
||||
this.depositAccountDomainService.handleFDAccountPreMatureClosure(account, paymentDetail, user, command, changes);
|
||||
|
||||
final String noteText = command.stringValueOfParameterNamed("note");
|
||||
if (StringUtils.isNotBlank(noteText)) {
|
||||
@@ -868,8 +865,7 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
}
|
||||
}
|
||||
|
||||
this.depositAccountDomainService.handleRDAccountPreMatureClosure(account, paymentDetail, user, command,
|
||||
DateUtils.getBusinessLocalDate(), changes);
|
||||
this.depositAccountDomainService.handleRDAccountPreMatureClosure(account, paymentDetail, user, command, changes);
|
||||
|
||||
final String noteText = command.stringValueOfParameterNamed("note");
|
||||
if (StringUtils.isNotBlank(noteText)) {
|
||||
@@ -892,7 +888,7 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
@Override
|
||||
public SavingsAccountTransaction initiateSavingsTransfer(final Long accountId, final LocalDate transferDate,
|
||||
final DepositAccountType depositAccountType) {
|
||||
AppUser user = getAppUserIfPresent();
|
||||
context.authenticatedUser();
|
||||
final boolean isSavingsInterestPostingAtCurrentPeriodEnd = this.configurationDomainService
|
||||
.isSavingsInterestPostingAtCurrentPeriodEnd();
|
||||
final Integer financialYearBeginningMonth = this.configurationDomainService.retrieveFinancialYearBeginningMonth();
|
||||
@@ -904,7 +900,7 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
updateExistingTransactionsDetails(savingsAccount, existingTransactionIds, existingReversedTransactionIds);
|
||||
|
||||
final SavingsAccountTransaction newTransferTransaction = SavingsAccountTransaction.initiateTransfer(savingsAccount,
|
||||
savingsAccount.office(), transferDate, user);
|
||||
savingsAccount.office(), transferDate);
|
||||
savingsAccount.addTransaction(newTransferTransaction);
|
||||
savingsAccount.setStatus(SavingsAccountStatusType.TRANSFER_IN_PROGRESS.getValue());
|
||||
final MathContext mc = MathContext.DECIMAL64;
|
||||
@@ -924,7 +920,7 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
@Override
|
||||
public SavingsAccountTransaction withdrawSavingsTransfer(final Long accountId, final LocalDate transferDate,
|
||||
final DepositAccountType depositAccountType) {
|
||||
AppUser user = getAppUserIfPresent();
|
||||
context.authenticatedUser();
|
||||
|
||||
final boolean isSavingsInterestPostingAtCurrentPeriodEnd = this.configurationDomainService
|
||||
.isSavingsInterestPostingAtCurrentPeriodEnd();
|
||||
@@ -937,7 +933,7 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
updateExistingTransactionsDetails(savingsAccount, existingTransactionIds, existingReversedTransactionIds);
|
||||
|
||||
final SavingsAccountTransaction withdrawtransferTransaction = SavingsAccountTransaction.withdrawTransfer(savingsAccount,
|
||||
savingsAccount.office(), transferDate, user);
|
||||
savingsAccount.office(), transferDate);
|
||||
savingsAccount.addTransaction(withdrawtransferTransaction);
|
||||
savingsAccount.setStatus(SavingsAccountStatusType.ACTIVE.getValue());
|
||||
final boolean postReversals = false;
|
||||
@@ -965,7 +961,7 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
@Override
|
||||
public SavingsAccountTransaction acceptSavingsTransfer(final Long accountId, final LocalDate transferDate,
|
||||
final Office acceptedInOffice, final Staff fieldOfficer, final DepositAccountType depositAccountType) {
|
||||
AppUser user = getAppUserIfPresent();
|
||||
context.authenticatedUser();
|
||||
|
||||
final boolean isSavingsInterestPostingAtCurrentPeriodEnd = this.configurationDomainService
|
||||
.isSavingsInterestPostingAtCurrentPeriodEnd();
|
||||
@@ -978,7 +974,7 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
updateExistingTransactionsDetails(savingsAccount, existingTransactionIds, existingReversedTransactionIds);
|
||||
|
||||
final SavingsAccountTransaction acceptTransferTransaction = SavingsAccountTransaction.approveTransfer(savingsAccount,
|
||||
acceptedInOffice, transferDate, user);
|
||||
acceptedInOffice, transferDate);
|
||||
savingsAccount.addTransaction(acceptTransferTransaction);
|
||||
savingsAccount.setStatus(SavingsAccountStatusType.ACTIVE.getValue());
|
||||
if (fieldOfficer != null) {
|
||||
@@ -1024,11 +1020,11 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
|
||||
final SavingsAccountCharge savingsAccountCharge = SavingsAccountCharge.createNewFromJson(savingsAccount, chargeDefinition, command);
|
||||
|
||||
if (savingsAccountCharge.getDueLocalDate() != null) {
|
||||
if (savingsAccountCharge.getDueDate() != null) {
|
||||
// transaction date should not be on a holiday or non working day
|
||||
if (!this.configurationDomainService.allowTransactionsOnHolidayEnabled()
|
||||
&& this.holidayRepository.isHoliday(savingsAccount.officeId(), savingsAccountCharge.getDueLocalDate())) {
|
||||
baseDataValidator.reset().parameter(dueAsOfDateParamName).value(savingsAccountCharge.getDueLocalDate().format(fmt))
|
||||
&& this.holidayRepository.isHoliday(savingsAccount.officeId(), savingsAccountCharge.getDueDate())) {
|
||||
baseDataValidator.reset().parameter(dueAsOfDateParamName).value(savingsAccountCharge.getDueDate().format(fmt))
|
||||
.failWithCodeNoParameterAddedToErrorCode("charge.due.date.is.on.holiday");
|
||||
if (!dataValidationErrors.isEmpty()) {
|
||||
throw new PlatformApiDataValidationException(dataValidationErrors);
|
||||
@@ -1036,8 +1032,8 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
}
|
||||
|
||||
if (!this.configurationDomainService.allowTransactionsOnNonWorkingDayEnabled()
|
||||
&& !this.workingDaysRepository.isWorkingDay(savingsAccountCharge.getDueLocalDate())) {
|
||||
baseDataValidator.reset().parameter(dueAsOfDateParamName).value(savingsAccountCharge.getDueLocalDate().format(fmt))
|
||||
&& !this.workingDaysRepository.isWorkingDay(savingsAccountCharge.getDueDate())) {
|
||||
baseDataValidator.reset().parameter(dueAsOfDateParamName).value(savingsAccountCharge.getDueDate().format(fmt))
|
||||
.failWithCodeNoParameterAddedToErrorCode("charge.due.date.is.a.nonworking.day");
|
||||
if (!dataValidationErrors.isEmpty()) {
|
||||
throw new PlatformApiDataValidationException(dataValidationErrors);
|
||||
@@ -1080,14 +1076,14 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
|
||||
final Map<String, Object> changes = savingsAccountCharge.update(command);
|
||||
|
||||
if (savingsAccountCharge.getDueLocalDate() != null) {
|
||||
if (savingsAccountCharge.getDueDate() != null) {
|
||||
final Locale locale = command.extractLocale();
|
||||
final DateTimeFormatter fmt = DateTimeFormatter.ofPattern(command.dateFormat()).withLocale(locale);
|
||||
|
||||
// transaction date should not be on a holiday or non working day
|
||||
if (!this.configurationDomainService.allowTransactionsOnHolidayEnabled()
|
||||
&& this.holidayRepository.isHoliday(savingsAccount.officeId(), savingsAccountCharge.getDueLocalDate())) {
|
||||
baseDataValidator.reset().parameter(dueAsOfDateParamName).value(savingsAccountCharge.getDueLocalDate().format(fmt))
|
||||
&& this.holidayRepository.isHoliday(savingsAccount.officeId(), savingsAccountCharge.getDueDate())) {
|
||||
baseDataValidator.reset().parameter(dueAsOfDateParamName).value(savingsAccountCharge.getDueDate().format(fmt))
|
||||
.failWithCodeNoParameterAddedToErrorCode("charge.due.date.is.on.holiday");
|
||||
if (!dataValidationErrors.isEmpty()) {
|
||||
throw new PlatformApiDataValidationException(dataValidationErrors);
|
||||
@@ -1095,8 +1091,8 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
}
|
||||
|
||||
if (!this.configurationDomainService.allowTransactionsOnNonWorkingDayEnabled()
|
||||
&& !this.workingDaysRepository.isWorkingDay(savingsAccountCharge.getDueLocalDate())) {
|
||||
baseDataValidator.reset().parameter(dueAsOfDateParamName).value(savingsAccountCharge.getDueLocalDate().format(fmt))
|
||||
&& !this.workingDaysRepository.isWorkingDay(savingsAccountCharge.getDueDate())) {
|
||||
baseDataValidator.reset().parameter(dueAsOfDateParamName).value(savingsAccountCharge.getDueDate().format(fmt))
|
||||
.failWithCodeNoParameterAddedToErrorCode("charge.due.date.is.a.nonworking.day");
|
||||
if (!dataValidationErrors.isEmpty()) {
|
||||
throw new PlatformApiDataValidationException(dataValidationErrors);
|
||||
@@ -1120,7 +1116,7 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
@Override
|
||||
public CommandProcessingResult waiveCharge(final Long savingsAccountId, final Long savingsAccountChargeId,
|
||||
@SuppressWarnings("unused") final DepositAccountType depositAccountType) {
|
||||
AppUser user = getAppUserIfPresent();
|
||||
context.authenticatedUser();
|
||||
|
||||
final boolean isSavingsInterestPostingAtCurrentPeriodEnd = this.configurationDomainService
|
||||
.isSavingsInterestPostingAtCurrentPeriodEnd();
|
||||
@@ -1137,12 +1133,12 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
final Set<Long> existingReversedTransactionIds = new HashSet<>();
|
||||
updateExistingTransactionsDetails(account, existingTransactionIds, existingReversedTransactionIds);
|
||||
|
||||
account.waiveCharge(savingsAccountChargeId, user, false);
|
||||
account.waiveCharge(savingsAccountChargeId, false);
|
||||
boolean isInterestTransfer = false;
|
||||
LocalDate postInterestOnDate = null;
|
||||
final MathContext mc = MathContext.DECIMAL64;
|
||||
final boolean postReversals = false;
|
||||
if (account.isBeforeLastPostingPeriod(savingsAccountCharge.getDueLocalDate(), false)) {
|
||||
if (account.isBeforeLastPostingPeriod(savingsAccountCharge.getDueDate(), false)) {
|
||||
final LocalDate today = DateUtils.getBusinessLocalDate();
|
||||
account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth,
|
||||
postInterestOnDate, false, postReversals);
|
||||
@@ -1249,13 +1245,13 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
@Override
|
||||
public void applyChargeDue(final Long savingsAccountChargeId, final Long accountId,
|
||||
@SuppressWarnings("unused") final DepositAccountType depositAccountType) {
|
||||
// always use current date as transaction date for batch job
|
||||
final LocalDate transactionDate = DateUtils.getBusinessLocalDate();
|
||||
final SavingsAccountCharge savingsAccountCharge = this.savingsAccountChargeRepository
|
||||
.findOneWithNotFoundDetection(savingsAccountChargeId, accountId);
|
||||
|
||||
// always use current date as transaction date for batch job
|
||||
final LocalDate transactionDate = DateUtils.getBusinessLocalDate();
|
||||
final DateTimeFormatter fmt = DateTimeFormatter.ofPattern("dd MM yyyy");
|
||||
while (transactionDate.isAfter(savingsAccountCharge.getDueLocalDate())) {
|
||||
|
||||
while (DateUtils.isBefore(savingsAccountCharge.getDueDate(), transactionDate)) {
|
||||
payCharge(savingsAccountCharge, transactionDate, savingsAccountCharge.amoutOutstanding(), fmt);
|
||||
}
|
||||
}
|
||||
@@ -1263,7 +1259,7 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
@Transactional
|
||||
private void payCharge(final SavingsAccountCharge savingsAccountCharge, final LocalDate transactionDate, final BigDecimal amountPaid,
|
||||
final DateTimeFormatter formatter) {
|
||||
AppUser user = getAppUserIfPresent();
|
||||
context.authenticatedUser();
|
||||
|
||||
final boolean isSavingsInterestPostingAtCurrentPeriodEnd = this.configurationDomainService
|
||||
.isSavingsInterestPostingAtCurrentPeriodEnd();
|
||||
@@ -1275,7 +1271,7 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
final Set<Long> existingTransactionIds = new HashSet<>();
|
||||
final Set<Long> existingReversedTransactionIds = new HashSet<>();
|
||||
updateExistingTransactionsDetails(account, existingTransactionIds, existingReversedTransactionIds);
|
||||
account.payCharge(savingsAccountCharge, amountPaid, transactionDate, formatter, user, false, null);
|
||||
account.payCharge(savingsAccountCharge, amountPaid, transactionDate, formatter, false, null);
|
||||
boolean isInterestTransfer = false;
|
||||
LocalDate postInterestOnDate = null;
|
||||
final MathContext mc = MathContext.DECIMAL64;
|
||||
@@ -1323,10 +1319,10 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
if (fdAccount.isMatured() && (fdAccount.isReinvestOnClosure() || fdAccount.isTransferToSavingsOnClosure())) {
|
||||
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd");
|
||||
Map<String, Object> changes = new HashMap<>();
|
||||
AppUser user = context.authenticatedUser();
|
||||
final AppUser user = context.authenticatedUser();
|
||||
Long toSavingsId = fdAccount.getTransferToSavingsAccountId();
|
||||
this.depositAccountDomainService.handleFDAccountMaturityClosure(fdAccount, null, user, fdAccount.maturityDate(), fmt,
|
||||
fdAccount.maturityDate(), fdAccount.getOnAccountClosureId(), toSavingsId, "Apply maturity instructions", changes);
|
||||
this.depositAccountDomainService.handleFDAccountMaturityClosure(fdAccount, null, user, fmt, fdAccount.maturityDate(),
|
||||
fdAccount.getOnAccountClosureId(), toSavingsId, "Apply maturity instructions", changes);
|
||||
|
||||
if (changes.get("reinvestedDepositId") != null) {
|
||||
Long reinvestedDepositId = (Long) changes.get("reinvestedDepositId");
|
||||
@@ -1335,7 +1331,7 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
.assembleFrom(reinvestedDepositId, DepositAccountType.FIXED_DEPOSIT);
|
||||
Money activationChargeAmount = getActivationCharge(reinvestAccount);
|
||||
if (activationChargeAmount.isGreaterThanZero()) {
|
||||
payActivationCharge(reinvestAccount, user);
|
||||
payActivationCharge(reinvestAccount);
|
||||
amountForDeposit = amountForDeposit.plus(activationChargeAmount);
|
||||
}
|
||||
this.depositAccountDomainService.handleFDDeposit(reinvestAccount, fmt, fdAccount.maturityDate(),
|
||||
@@ -1393,13 +1389,4 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
isRegularTransaction);
|
||||
|
||||
}
|
||||
|
||||
private AppUser getAppUserIfPresent() {
|
||||
AppUser user = null;
|
||||
if (this.context != null) {
|
||||
user = this.context.getAuthenticatedUserIfPresent();
|
||||
}
|
||||
return user;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+5
-7
@@ -47,7 +47,6 @@ import org.apache.fineract.infrastructure.core.exception.GeneralPlatformDomainRu
|
||||
import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException;
|
||||
import org.apache.fineract.infrastructure.core.exception.PlatformDataIntegrityException;
|
||||
import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
|
||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||
import org.apache.fineract.infrastructure.event.business.domain.deposit.FixedDepositAccountCreateBusinessEvent;
|
||||
import org.apache.fineract.infrastructure.event.business.domain.deposit.RecurringDepositAccountCreateBusinessEvent;
|
||||
import org.apache.fineract.infrastructure.event.business.service.BusinessEventNotifierService;
|
||||
@@ -384,7 +383,7 @@ public class DepositApplicationProcessWritePlatformServiceJpaRepositoryImpl impl
|
||||
DepositAccountType.FIXED_DEPOSIT);
|
||||
checkClientOrGroupActive(account);
|
||||
account.modifyApplication(command, changes);
|
||||
account.validateNewApplicationState(DateUtils.getBusinessLocalDate(), DepositAccountType.FIXED_DEPOSIT.resourceName());
|
||||
account.validateNewApplicationState(DepositAccountType.FIXED_DEPOSIT.resourceName());
|
||||
|
||||
if (!changes.isEmpty()) {
|
||||
updateFDAndRDCommonChanges(changes, command, account);
|
||||
@@ -474,7 +473,7 @@ public class DepositApplicationProcessWritePlatformServiceJpaRepositoryImpl impl
|
||||
DepositAccountType.RECURRING_DEPOSIT);
|
||||
checkClientOrGroupActive(account);
|
||||
account.modifyApplication(command, changes);
|
||||
account.validateNewApplicationState(DateUtils.getBusinessLocalDate(), DepositAccountType.RECURRING_DEPOSIT.resourceName());
|
||||
account.validateNewApplicationState(DepositAccountType.RECURRING_DEPOSIT.resourceName());
|
||||
|
||||
if (!changes.isEmpty()) {
|
||||
updateFDAndRDCommonChanges(changes, command, account);
|
||||
@@ -638,7 +637,7 @@ public class DepositApplicationProcessWritePlatformServiceJpaRepositoryImpl impl
|
||||
final SavingsAccount savingsAccount = this.depositAccountAssembler.assembleFrom(savingsId, depositAccountType);
|
||||
checkClientOrGroupActive(savingsAccount);
|
||||
|
||||
final Map<String, Object> changes = savingsAccount.approveApplication(currentUser, command, DateUtils.getBusinessLocalDate());
|
||||
final Map<String, Object> changes = savingsAccount.approveApplication(currentUser, command);
|
||||
if (!changes.isEmpty()) {
|
||||
this.savingAccountRepository.save(savingsAccount);
|
||||
|
||||
@@ -708,7 +707,7 @@ public class DepositApplicationProcessWritePlatformServiceJpaRepositoryImpl impl
|
||||
final SavingsAccount savingsAccount = this.depositAccountAssembler.assembleFrom(savingsId, depositAccountType);
|
||||
checkClientOrGroupActive(savingsAccount);
|
||||
|
||||
final Map<String, Object> changes = savingsAccount.rejectApplication(currentUser, command, DateUtils.getBusinessLocalDate());
|
||||
final Map<String, Object> changes = savingsAccount.rejectApplication(currentUser, command);
|
||||
if (!changes.isEmpty()) {
|
||||
this.savingAccountRepository.save(savingsAccount);
|
||||
|
||||
@@ -742,8 +741,7 @@ public class DepositApplicationProcessWritePlatformServiceJpaRepositoryImpl impl
|
||||
final SavingsAccount savingsAccount = this.depositAccountAssembler.assembleFrom(savingsId, depositAccountType);
|
||||
checkClientOrGroupActive(savingsAccount);
|
||||
|
||||
final Map<String, Object> changes = savingsAccount.applicantWithdrawsFromApplication(currentUser, command,
|
||||
DateUtils.getBusinessLocalDate());
|
||||
final Map<String, Object> changes = savingsAccount.applicantWithdrawsFromApplication(currentUser, command);
|
||||
if (!changes.isEmpty()) {
|
||||
this.savingAccountRepository.save(savingsAccount);
|
||||
|
||||
|
||||
-1
@@ -94,7 +94,6 @@ public class SavingsAccountChargeReadPlatformServiceImpl implements SavingsAccou
|
||||
|
||||
@Override
|
||||
public SavingsAccountChargeData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {
|
||||
|
||||
final Long id = rs.getLong("id");
|
||||
final Long chargeId = rs.getLong("chargeId");
|
||||
final Long accountId = rs.getLong("accountId");
|
||||
|
||||
+15
-24
@@ -18,6 +18,7 @@
|
||||
*/
|
||||
package org.apache.fineract.portfolio.savings.service;
|
||||
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.MathContext;
|
||||
import java.time.LocalDate;
|
||||
@@ -30,6 +31,7 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import org.apache.fineract.infrastructure.core.domain.LocalDateInterval;
|
||||
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.portfolio.savings.DepositAccountType;
|
||||
@@ -62,7 +64,6 @@ public class SavingsAccountInterestPostingServiceImpl implements SavingsAccountI
|
||||
public SavingsAccountData postInterest(final MathContext mc, final LocalDate interestPostingUpToDate, final boolean isInterestTransfer,
|
||||
final boolean isSavingsInterestPostingAtCurrentPeriodEnd, final Integer financialYearBeginningMonth,
|
||||
final LocalDate postInterestOnDate, final boolean backdatedTxnsAllowedTill, final SavingsAccountData savingsAccountData) {
|
||||
|
||||
Money interestPostedToDate = Money.zero(savingsAccountData.getCurrency());
|
||||
LocalDate startInterestDate = getStartInterestCalculationDate(savingsAccountData);
|
||||
|
||||
@@ -84,13 +85,11 @@ public class SavingsAccountInterestPostingServiceImpl implements SavingsAccountI
|
||||
withholdTransactions.addAll(findWithHoldSavingsTransactionsWithPivotConfig(savingsAccountData));
|
||||
|
||||
for (final PostingPeriod interestPostingPeriod : postingPeriods) {
|
||||
|
||||
final LocalDate interestPostingTransactionDate = interestPostingPeriod.dateOfPostingTransaction();
|
||||
final Money interestEarnedToBePostedForPeriod = interestPostingPeriod.getInterestEarned();
|
||||
|
||||
if (!interestPostingTransactionDate.isAfter(interestPostingUpToDate)) {
|
||||
if (!DateUtils.isAfter(interestPostingTransactionDate, interestPostingUpToDate)) {
|
||||
interestPostedToDate = interestPostedToDate.plus(interestEarnedToBePostedForPeriod);
|
||||
|
||||
final SavingsAccountTransactionData postingTransaction = findInterestPostingTransactionFor(interestPostingTransactionDate,
|
||||
savingsAccountData);
|
||||
|
||||
@@ -245,7 +244,7 @@ public class SavingsAccountInterestPostingServiceImpl implements SavingsAccountI
|
||||
Money periodStartingBalance;
|
||||
if (savingsAccountData.getStartInterestCalculationDate() != null
|
||||
&& !savingsAccountData.getStartInterestCalculationDate().equals(savingsAccountData.getActivationLocalDate())) {
|
||||
final SavingsAccountTransactionData transaction = retrieveLastTransactions(savingsAccountData);
|
||||
final SavingsAccountTransactionData transaction = retrieveLastTransaction(savingsAccountData);
|
||||
|
||||
if (transaction == null) {
|
||||
periodStartingBalance = Money.zero(savingsAccountData.getCurrency());
|
||||
@@ -329,13 +328,8 @@ public class SavingsAccountInterestPostingServiceImpl implements SavingsAccountI
|
||||
}
|
||||
|
||||
protected LocalDate getLockedInUntilLocalDate(final SavingsAccountData savingsAccount) {
|
||||
LocalDate lockedInUntilLocalDate = null;
|
||||
if (savingsAccount.getLockedInUntilDate() != null) {
|
||||
lockedInUntilLocalDate = savingsAccount.getActivationLocalDate();
|
||||
// lockedInUntilLocalDate = LocalDate.ofInstant(this.lockedInUntilDate.toInstant(),
|
||||
// DateUtils.getDateTimeZoneOfTenant());
|
||||
}
|
||||
return lockedInUntilLocalDate;
|
||||
LocalDate lockedInUntilLocalDate = savingsAccount.getLockedInUntilDate();
|
||||
return lockedInUntilLocalDate == null ? savingsAccount.getActivationLocalDate() : lockedInUntilLocalDate;
|
||||
}
|
||||
|
||||
private BigDecimal minBalanceForInterestCalculation(final SavingsAccountData savingsAccountData) {
|
||||
@@ -358,20 +352,17 @@ public class SavingsAccountInterestPostingServiceImpl implements SavingsAccountI
|
||||
return savingsAccountData.getSavingsAccountTransactionData();
|
||||
}
|
||||
|
||||
private SavingsAccountTransactionData retrieveLastTransactions(final SavingsAccountData savingsAccountData) {
|
||||
if (savingsAccountData.getSavingsAccountTransactionData() != null
|
||||
&& savingsAccountData.getSavingsAccountTransactionData().size() == 1) {
|
||||
return savingsAccountData.getSavingsAccountTransactionData().get(0);
|
||||
private SavingsAccountTransactionData retrieveLastTransaction(@NotNull SavingsAccountData savingsAccountData) {
|
||||
List<SavingsAccountTransactionData> transactions = savingsAccountData.getSavingsAccountTransactionData();
|
||||
if (transactions == null || transactions.isEmpty()) {
|
||||
return savingsAccountData.getLastSavingsAccountTransaction(); // what is this?
|
||||
}
|
||||
final List<SavingsAccountTransactionData> listOfTransactionsSorted = new ArrayList<>();
|
||||
listOfTransactionsSorted.addAll(savingsAccountData.getSavingsAccountTransactionData());
|
||||
if (!listOfTransactionsSorted.isEmpty()) {
|
||||
final SavingsAccountTransactionDataComparator transactionComparator = new SavingsAccountTransactionDataComparator();
|
||||
Collections.sort(listOfTransactionsSorted, transactionComparator);
|
||||
} else {
|
||||
listOfTransactionsSorted.add(savingsAccountData.getLastSavingsAccountTransaction());
|
||||
if (transactions.size() == 1) {
|
||||
return transactions.get(0);
|
||||
}
|
||||
return listOfTransactionsSorted.get(0);
|
||||
final List<SavingsAccountTransactionData> listOfTransactionsSorted = new ArrayList<>(transactions);
|
||||
listOfTransactionsSorted.sort(new SavingsAccountTransactionDataComparator());
|
||||
return listOfTransactionsSorted.get(0); // this is the first transaction, not the last
|
||||
}
|
||||
|
||||
public LocalDate getStartInterestCalculationDate(final SavingsAccountData savingsAccountData) {
|
||||
|
||||
+19
-15
@@ -18,6 +18,9 @@
|
||||
*/
|
||||
package org.apache.fineract.portfolio.savings.service;
|
||||
|
||||
import static org.apache.fineract.infrastructure.core.domain.AuditableFieldsConstants.CREATED_BY_DB_FIELD;
|
||||
import static org.apache.fineract.infrastructure.core.domain.AuditableFieldsConstants.CREATED_DATE_DB_FIELD;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
@@ -278,7 +281,8 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
|
||||
}
|
||||
|
||||
sql = sql + " and (sa.interest_posted_till_date is null or sa.interest_posted_till_date <= ? ) ";
|
||||
sql = sql + " order by sa.id, tr.transaction_date, tr.created_date, tr.id";
|
||||
// #audit backward compatibility
|
||||
sql = sql + " order by sa.id, tr.transaction_date, tr." + CREATED_DATE_DB_FIELD + ", tr.created_date, tr.id";
|
||||
|
||||
List<SavingsAccountData> savingsAccountDataList = this.jdbcTemplate.query(sql, this.savingAccountMapperForInterestPosting, // NOSONAR
|
||||
new Object[] { maxSavingsId, status, pageSize, yesterday });
|
||||
@@ -459,19 +463,19 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
|
||||
Integer daysToDormancy = null;
|
||||
Integer daysToEscheat = null;
|
||||
|
||||
LocalDate localTenantDate = DateUtils.getBusinessLocalDate();
|
||||
LocalDate currentDate = DateUtils.getBusinessLocalDate();
|
||||
if (isDormancyTrackingActive && statusEnum.equals(SavingsAccountStatusType.ACTIVE.getValue())) {
|
||||
if (subStatusEnum < SavingsAccountSubStatusEnum.ESCHEAT.getValue()) {
|
||||
daysToEscheat = Math.toIntExact(
|
||||
ChronoUnit.DAYS.between(localTenantDate, lastActiveTransactionDate.plusDays(numDaysToEscheat)));
|
||||
daysToEscheat = Math
|
||||
.toIntExact(ChronoUnit.DAYS.between(currentDate, lastActiveTransactionDate.plusDays(numDaysToEscheat)));
|
||||
}
|
||||
if (subStatusEnum < SavingsAccountSubStatusEnum.DORMANT.getValue()) {
|
||||
daysToDormancy = Math.toIntExact(
|
||||
ChronoUnit.DAYS.between(localTenantDate, lastActiveTransactionDate.plusDays(numDaysToDormancy)));
|
||||
ChronoUnit.DAYS.between(currentDate, lastActiveTransactionDate.plusDays(numDaysToDormancy)));
|
||||
}
|
||||
if (subStatusEnum < SavingsAccountSubStatusEnum.INACTIVE.getValue()) {
|
||||
daysToInactive = Math.toIntExact(
|
||||
ChronoUnit.DAYS.between(localTenantDate, lastActiveTransactionDate.plusDays(numDaysToInactive)));
|
||||
ChronoUnit.DAYS.between(currentDate, lastActiveTransactionDate.plusDays(numDaysToInactive)));
|
||||
}
|
||||
}
|
||||
final LocalDate approvedOnDate = JdbcSupport.getLocalDate(rs, "approvedOnDate");
|
||||
@@ -896,19 +900,19 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
|
||||
Integer daysToDormancy = null;
|
||||
Integer daysToEscheat = null;
|
||||
|
||||
LocalDate localTenantDate = DateUtils.getBusinessLocalDate();
|
||||
LocalDate currentDate = DateUtils.getBusinessLocalDate();
|
||||
if (isDormancyTrackingActive && statusEnum.equals(SavingsAccountStatusType.ACTIVE.getValue())) {
|
||||
if (subStatusEnum < SavingsAccountSubStatusEnum.ESCHEAT.getValue()) {
|
||||
daysToEscheat = Math
|
||||
.toIntExact(ChronoUnit.DAYS.between(localTenantDate, lastActiveTransactionDate.plusDays(numDaysToEscheat)));
|
||||
.toIntExact(ChronoUnit.DAYS.between(currentDate, lastActiveTransactionDate.plusDays(numDaysToEscheat)));
|
||||
}
|
||||
if (subStatusEnum < SavingsAccountSubStatusEnum.DORMANT.getValue()) {
|
||||
daysToDormancy = Math
|
||||
.toIntExact(ChronoUnit.DAYS.between(localTenantDate, lastActiveTransactionDate.plusDays(numDaysToDormancy)));
|
||||
.toIntExact(ChronoUnit.DAYS.between(currentDate, lastActiveTransactionDate.plusDays(numDaysToDormancy)));
|
||||
}
|
||||
if (subStatusEnum < SavingsAccountSubStatusEnum.INACTIVE.getValue()) {
|
||||
daysToInactive = Math
|
||||
.toIntExact(ChronoUnit.DAYS.between(localTenantDate, lastActiveTransactionDate.plusDays(numDaysToInactive)));
|
||||
.toIntExact(ChronoUnit.DAYS.between(currentDate, lastActiveTransactionDate.plusDays(numDaysToInactive)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1266,10 +1270,10 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
|
||||
|
||||
@Override
|
||||
public Collection<SavingsAccountTransactionData> retrieveAllTransactions(final Long savingsId, DepositAccountType depositAccountType) {
|
||||
|
||||
// #audit backward compatibility
|
||||
final String sql = "select " + this.transactionsMapper.schema()
|
||||
+ " where sa.id = ? and sa.deposit_type_enum = ? order by tr.transaction_date DESC, tr.created_date DESC, tr.id DESC";
|
||||
|
||||
+ " where sa.id = ? and sa.deposit_type_enum = ? order by tr.transaction_date DESC," + " tr." + CREATED_DATE_DB_FIELD
|
||||
+ " DESC, tr.created_date DESC, tr.id DESC";
|
||||
return this.jdbcTemplate.query(sql, this.transactionsMapper, new Object[] { savingsId, depositAccountType.getValue() }); // NOSONAR
|
||||
}
|
||||
|
||||
@@ -1352,8 +1356,8 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
|
||||
+ "left join m_account_transfer_transaction fromtran on fromtran.from_savings_transaction_id = tr.id "
|
||||
+ "left join m_account_transfer_transaction totran on totran.to_savings_transaction_id = tr.id "
|
||||
+ "left join m_payment_detail pd on tr.payment_detail_id = pd.id "
|
||||
+ "left join m_payment_type pt on pd.payment_type_id = pt.id left join m_appuser au on au.id=tr.appuser_id "
|
||||
+ "left join m_note nt ON nt.savings_account_transaction_id=tr.id ";
|
||||
+ "left join m_payment_type pt on pd.payment_type_id = pt.id left join m_appuser au on au.id= tr." + CREATED_BY_DB_FIELD
|
||||
+ " left join m_note nt ON nt.savings_account_transaction_id=tr.id ";
|
||||
}
|
||||
|
||||
public String schema() {
|
||||
|
||||
+52
-56
@@ -207,7 +207,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
|
||||
updateExistingTransactionsDetails(account, existingTransactionIds, existingReversedTransactionIds);
|
||||
|
||||
final Map<String, Object> changes = account.activate(user, command, DateUtils.getBusinessLocalDate());
|
||||
final Map<String, Object> changes = account.activate(user, command);
|
||||
|
||||
entityDatatableChecksWritePlatformService.runTheCheckForProduct(savingsId, EntityTables.SAVINGS.getName(),
|
||||
StatusEnum.ACTIVATE.getCode().longValue(), EntityTables.SAVINGS.getForeignKeyColumnNameOnDatatable(), account.productId());
|
||||
@@ -235,7 +235,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
@Override
|
||||
public void processPostActiveActions(final SavingsAccount account, final DateTimeFormatter fmt, final Set<Long> existingTransactionIds,
|
||||
final Set<Long> existingReversedTransactionIds) {
|
||||
AppUser user = getAppUserIfPresent();
|
||||
getAppUserIfPresent();
|
||||
|
||||
final boolean isSavingsInterestPostingAtCurrentPeriodEnd = this.configurationDomainService
|
||||
.isSavingsInterestPostingAtCurrentPeriodEnd();
|
||||
@@ -245,13 +245,13 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
boolean isRegularTransaction = false;
|
||||
if (amountForDeposit.isGreaterThanZero()) {
|
||||
boolean isAccountTransfer = false;
|
||||
this.savingsAccountDomainService.handleDeposit(account, fmt, account.getActivationLocalDate(), amountForDeposit.getAmount(),
|
||||
null, isAccountTransfer, isRegularTransaction, false);
|
||||
this.savingsAccountDomainService.handleDeposit(account, fmt, account.getActivationDate(), amountForDeposit.getAmount(), null,
|
||||
isAccountTransfer, isRegularTransaction, false);
|
||||
|
||||
updateExistingTransactionsDetails(account, existingTransactionIds, existingReversedTransactionIds);
|
||||
}
|
||||
|
||||
account.processAccountUponActivation(isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth, user);
|
||||
account.processAccountUponActivation(isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth);
|
||||
List<DepositAccountOnHoldTransaction> depositAccountOnHoldTransactions = null;
|
||||
if (account.getOnHoldFunds().compareTo(BigDecimal.ZERO) > 0) {
|
||||
depositAccountOnHoldTransactions = this.depositAccountOnHoldTransactionRepository
|
||||
@@ -417,16 +417,16 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult applyAnnualFee(final Long savingsAccountChargeId, final Long accountId) {
|
||||
AppUser user = getAppUserIfPresent();
|
||||
getAppUserIfPresent();
|
||||
|
||||
final SavingsAccountCharge savingsAccountCharge = this.savingsAccountChargeRepository
|
||||
.findOneWithNotFoundDetection(savingsAccountChargeId, accountId);
|
||||
|
||||
final LocalDate todaysDate = DateUtils.getBusinessLocalDate();
|
||||
final LocalDate currentDate = DateUtils.getBusinessLocalDate();
|
||||
final DateTimeFormatter fmt = DateTimeFormatter.ofPattern("dd MM yyyy").withZone(DateUtils.getDateTimeZoneOfTenant());
|
||||
|
||||
while (todaysDate.isAfter(savingsAccountCharge.getDueLocalDate())) {
|
||||
this.payCharge(savingsAccountCharge, savingsAccountCharge.getDueLocalDate(), savingsAccountCharge.amount(), fmt, user, false);
|
||||
while (DateUtils.isBefore(savingsAccountCharge.getDueDate(), currentDate)) {
|
||||
this.payCharge(savingsAccountCharge, savingsAccountCharge.getDueDate(), savingsAccountCharge.amount(), fmt, false);
|
||||
}
|
||||
|
||||
return new CommandProcessingResultBuilder() //
|
||||
@@ -681,7 +681,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
throw new SavingsAccountTransactionNotFoundException(savingsId, transactionId);
|
||||
}
|
||||
|
||||
this.savingsAccountTransactionDataValidator.validateTransactionWithPivotDate(savingsAccountTransaction.getTransactionLocalDate(),
|
||||
this.savingsAccountTransactionDataValidator.validateTransactionWithPivotDate(savingsAccountTransaction.getTransactionDate(),
|
||||
account);
|
||||
|
||||
if (!allowAccountTransferModification
|
||||
@@ -718,7 +718,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
boolean postReversals = false;
|
||||
checkClientOrGroupActive(account);
|
||||
if (savingsAccountTransaction.isPostInterestCalculationRequired()
|
||||
&& account.isBeforeLastPostingPeriod(savingsAccountTransaction.transactionLocalDate(), false)) {
|
||||
&& account.isBeforeLastPostingPeriod(savingsAccountTransaction.getTransactionDate(), false)) {
|
||||
account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth,
|
||||
postInterestOnDate, false, postReversals);
|
||||
} else {
|
||||
@@ -746,7 +746,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
|
||||
@Override
|
||||
public CommandProcessingResult adjustSavingsTransaction(final Long savingsId, final Long transactionId, final JsonCommand command) {
|
||||
AppUser user = getAppUserIfPresent();
|
||||
context.authenticatedUser();
|
||||
|
||||
final boolean isSavingsInterestPostingAtCurrentPeriodEnd = this.configurationDomainService
|
||||
.isSavingsInterestPostingAtCurrentPeriodEnd();
|
||||
@@ -808,7 +808,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
boolean isInterestTransfer = false;
|
||||
Integer accountType = null;
|
||||
final SavingsAccountTransactionDTO transactionDTO = new SavingsAccountTransactionDTO(fmt, transactionDate, transactionAmount,
|
||||
paymentDetail, savingsAccountTransaction.getCreatedDate(), user, accountType);
|
||||
paymentDetail, null, accountType);
|
||||
UUID refNo = UUID.randomUUID();
|
||||
if (savingsAccountTransaction.isDeposit()) {
|
||||
transaction = account.deposit(transactionDTO, false, relaxingDaysConfigForPivotDate, refNo.toString());
|
||||
@@ -819,7 +819,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
final LocalDate postInterestOnDate = null;
|
||||
boolean postReversals = false;
|
||||
if (account.isBeforeLastPostingPeriod(transactionDate, false)
|
||||
|| account.isBeforeLastPostingPeriod(savingsAccountTransaction.transactionLocalDate(), false)) {
|
||||
|| account.isBeforeLastPostingPeriod(savingsAccountTransaction.getTransactionDate(), false)) {
|
||||
account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth,
|
||||
postInterestOnDate, false, postReversals);
|
||||
} else {
|
||||
@@ -927,7 +927,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
List<SavingsAccountTransaction> savingTransactions = account.getTransactions();
|
||||
for (SavingsAccountTransaction savingTransaction : savingTransactions) {
|
||||
if (savingTransaction.isInterestPosting() && savingTransaction.isNotReversed()
|
||||
&& DateUtils.isEqual(closedDate, savingTransaction.getTransactionLocalDate())) {
|
||||
&& DateUtils.isEqual(closedDate, savingTransaction.getTransactionDate())) {
|
||||
postInterestOnClosingDate = true;
|
||||
break;
|
||||
}
|
||||
@@ -957,7 +957,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
|
||||
}
|
||||
|
||||
final Map<String, Object> accountChanges = account.close(user, command, DateUtils.getBusinessLocalDate());
|
||||
final Map<String, Object> accountChanges = account.close(user, command);
|
||||
changes.putAll(accountChanges);
|
||||
if (!changes.isEmpty()) {
|
||||
this.savingAccountRepositoryWrapper.save(account);
|
||||
@@ -985,7 +985,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
|
||||
@Override
|
||||
public SavingsAccountTransaction initiateSavingsTransfer(final SavingsAccount savingsAccount, final LocalDate transferDate) {
|
||||
AppUser user = getAppUserIfPresent();
|
||||
getAppUserIfPresent();
|
||||
|
||||
final boolean isSavingsInterestPostingAtCurrentPeriodEnd = this.configurationDomainService
|
||||
.isSavingsInterestPostingAtCurrentPeriodEnd();
|
||||
@@ -999,7 +999,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
updateExistingTransactionsDetails(savingsAccount, existingTransactionIds, existingReversedTransactionIds);
|
||||
|
||||
final SavingsAccountTransaction newTransferTransaction = SavingsAccountTransaction.initiateTransfer(savingsAccount,
|
||||
savingsAccount.office(), transferDate, user);
|
||||
savingsAccount.office(), transferDate);
|
||||
savingsAccount.addTransaction(newTransferTransaction);
|
||||
savingsAccount.setStatus(SavingsAccountStatusType.TRANSFER_IN_PROGRESS.getValue());
|
||||
final MathContext mc = MathContext.DECIMAL64;
|
||||
@@ -1019,7 +1019,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
|
||||
@Override
|
||||
public SavingsAccountTransaction withdrawSavingsTransfer(final SavingsAccount savingsAccount, final LocalDate transferDate) {
|
||||
AppUser user = getAppUserIfPresent();
|
||||
getAppUserIfPresent();
|
||||
|
||||
final boolean isSavingsInterestPostingAtCurrentPeriodEnd = this.configurationDomainService
|
||||
.isSavingsInterestPostingAtCurrentPeriodEnd();
|
||||
@@ -1030,7 +1030,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
updateExistingTransactionsDetails(savingsAccount, existingTransactionIds, existingReversedTransactionIds);
|
||||
|
||||
final SavingsAccountTransaction withdrawtransferTransaction = SavingsAccountTransaction.withdrawTransfer(savingsAccount,
|
||||
savingsAccount.office(), transferDate, user);
|
||||
savingsAccount.office(), transferDate);
|
||||
savingsAccount.addTransaction(withdrawtransferTransaction);
|
||||
savingsAccount.setStatus(SavingsAccountStatusType.ACTIVE.getValue());
|
||||
final MathContext mc = MathContext.DECIMAL64;
|
||||
@@ -1058,7 +1058,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
@Override
|
||||
public SavingsAccountTransaction acceptSavingsTransfer(final SavingsAccount savingsAccount, final LocalDate transferDate,
|
||||
final Office acceptedInOffice, final Staff fieldOfficer) {
|
||||
AppUser user = getAppUserIfPresent();
|
||||
getAppUserIfPresent();
|
||||
|
||||
final boolean isSavingsInterestPostingAtCurrentPeriodEnd = this.configurationDomainService
|
||||
.isSavingsInterestPostingAtCurrentPeriodEnd();
|
||||
@@ -1069,7 +1069,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
updateExistingTransactionsDetails(savingsAccount, existingTransactionIds, existingReversedTransactionIds);
|
||||
|
||||
final SavingsAccountTransaction acceptTransferTransaction = SavingsAccountTransaction.approveTransfer(savingsAccount,
|
||||
acceptedInOffice, transferDate, user);
|
||||
acceptedInOffice, transferDate);
|
||||
savingsAccount.addTransaction(acceptTransferTransaction);
|
||||
savingsAccount.setStatus(SavingsAccountStatusType.ACTIVE.getValue());
|
||||
if (fieldOfficer != null) {
|
||||
@@ -1126,17 +1126,17 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
savingsAccountCharge.setFreeWithdrawalCount(0);
|
||||
}
|
||||
|
||||
if (savingsAccountCharge.getDueLocalDate() != null) {
|
||||
if (savingsAccountCharge.getDueDate() != null) {
|
||||
// transaction date should not be on a holiday or non working day
|
||||
if (!this.configurationDomainService.allowTransactionsOnHolidayEnabled()
|
||||
&& this.holidayRepository.isHoliday(savingsAccount.officeId(), savingsAccountCharge.getDueLocalDate())) {
|
||||
baseDataValidator.reset().parameter(dueAsOfDateParamName).value(savingsAccountCharge.getDueLocalDate().format(fmt))
|
||||
&& this.holidayRepository.isHoliday(savingsAccount.officeId(), savingsAccountCharge.getDueDate())) {
|
||||
baseDataValidator.reset().parameter(dueAsOfDateParamName).value(savingsAccountCharge.getDueDate().format(fmt))
|
||||
.failWithCodeNoParameterAddedToErrorCode("charge.due.date.is.on.holiday");
|
||||
}
|
||||
|
||||
if (!this.configurationDomainService.allowTransactionsOnNonWorkingDayEnabled()
|
||||
&& !this.workingDaysRepository.isWorkingDay(savingsAccountCharge.getDueLocalDate())) {
|
||||
baseDataValidator.reset().parameter(dueAsOfDateParamName).value(savingsAccountCharge.getDueLocalDate().format(fmt))
|
||||
&& !this.workingDaysRepository.isWorkingDay(savingsAccountCharge.getDueDate())) {
|
||||
baseDataValidator.reset().parameter(dueAsOfDateParamName).value(savingsAccountCharge.getDueDate().format(fmt))
|
||||
.failWithCodeNoParameterAddedToErrorCode("charge.due.date.is.a.nonworking.day");
|
||||
}
|
||||
}
|
||||
@@ -1178,14 +1178,14 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
|
||||
final Map<String, Object> changes = savingsAccountCharge.update(command);
|
||||
|
||||
if (savingsAccountCharge.getDueLocalDate() != null) {
|
||||
if (savingsAccountCharge.getDueDate() != null) {
|
||||
final Locale locale = command.extractLocale();
|
||||
final DateTimeFormatter fmt = DateTimeFormatter.ofPattern(command.dateFormat()).withLocale(locale);
|
||||
|
||||
// transaction date should not be on a holiday or non working day
|
||||
if (!this.configurationDomainService.allowTransactionsOnHolidayEnabled()
|
||||
&& this.holidayRepository.isHoliday(savingsAccount.officeId(), savingsAccountCharge.getDueLocalDate())) {
|
||||
baseDataValidator.reset().parameter(dueAsOfDateParamName).value(savingsAccountCharge.getDueLocalDate().format(fmt))
|
||||
&& this.holidayRepository.isHoliday(savingsAccount.officeId(), savingsAccountCharge.getDueDate())) {
|
||||
baseDataValidator.reset().parameter(dueAsOfDateParamName).value(savingsAccountCharge.getDueDate().format(fmt))
|
||||
.failWithCodeNoParameterAddedToErrorCode("charge.due.date.is.on.holiday");
|
||||
if (!dataValidationErrors.isEmpty()) {
|
||||
throw new PlatformApiDataValidationException(dataValidationErrors);
|
||||
@@ -1193,8 +1193,8 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
}
|
||||
|
||||
if (!this.configurationDomainService.allowTransactionsOnNonWorkingDayEnabled()
|
||||
&& !this.workingDaysRepository.isWorkingDay(savingsAccountCharge.getDueLocalDate())) {
|
||||
baseDataValidator.reset().parameter(dueAsOfDateParamName).value(savingsAccountCharge.getDueLocalDate().format(fmt))
|
||||
&& !this.workingDaysRepository.isWorkingDay(savingsAccountCharge.getDueDate())) {
|
||||
baseDataValidator.reset().parameter(dueAsOfDateParamName).value(savingsAccountCharge.getDueDate().format(fmt))
|
||||
.failWithCodeNoParameterAddedToErrorCode("charge.due.date.is.a.nonworking.day");
|
||||
if (!dataValidationErrors.isEmpty()) {
|
||||
throw new PlatformApiDataValidationException(dataValidationErrors);
|
||||
@@ -1217,7 +1217,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult waiveCharge(final Long savingsAccountId, final Long savingsAccountChargeId) {
|
||||
AppUser user = getAppUserIfPresent();
|
||||
context.authenticatedUser();
|
||||
|
||||
final boolean isSavingsInterestPostingAtCurrentPeriodEnd = this.configurationDomainService
|
||||
.isSavingsInterestPostingAtCurrentPeriodEnd();
|
||||
@@ -1242,13 +1242,13 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
updateExistingTransactionsDetails(account, existingTransactionIds, existingReversedTransactionIds);
|
||||
}
|
||||
|
||||
account.waiveCharge(savingsAccountChargeId, user, backdatedTxnsAllowedTill);
|
||||
account.waiveCharge(savingsAccountChargeId, backdatedTxnsAllowedTill);
|
||||
|
||||
boolean isInterestTransfer = false;
|
||||
LocalDate postInterestOnDate = null;
|
||||
final MathContext mc = MathContext.DECIMAL64;
|
||||
boolean postReversals = false;
|
||||
if (account.isBeforeLastPostingPeriod(savingsAccountCharge.getDueLocalDate(), backdatedTxnsAllowedTill)) {
|
||||
if (account.isBeforeLastPostingPeriod(savingsAccountCharge.getDueDate(), backdatedTxnsAllowedTill)) {
|
||||
final LocalDate today = DateUtils.getBusinessLocalDate();
|
||||
account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth,
|
||||
postInterestOnDate, backdatedTxnsAllowedTill, postReversals);
|
||||
@@ -1308,7 +1308,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
|
||||
@Override
|
||||
public CommandProcessingResult payCharge(final Long savingsAccountId, final Long savingsAccountChargeId, final JsonCommand command) {
|
||||
AppUser user = getAppUserIfPresent();
|
||||
context.authenticatedUser();
|
||||
|
||||
this.savingsAccountChargeDataValidator.validatePayCharge(command.json());
|
||||
final Locale locale = command.extractLocale();
|
||||
@@ -1344,7 +1344,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
|
||||
final boolean backdatedTxnsAllowedTill = false;
|
||||
|
||||
SavingsAccountTransaction chargeTransaction = this.payCharge(savingsAccountCharge, transactionDate, amountPaid, fmt, user,
|
||||
SavingsAccountTransaction chargeTransaction = this.payCharge(savingsAccountCharge, transactionDate, amountPaid, fmt,
|
||||
backdatedTxnsAllowedTill);
|
||||
|
||||
final String noteText = command.stringValueOfParameterNamed("note");
|
||||
@@ -1367,16 +1367,14 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
@Override
|
||||
public void applyChargeDue(final Long savingsAccountChargeId, final Long accountId) {
|
||||
// always use current date as transaction date for batch job
|
||||
AppUser user = null;
|
||||
|
||||
final LocalDate transactionDate = DateUtils.getBusinessLocalDate();
|
||||
final SavingsAccountCharge savingsAccountCharge = this.savingsAccountChargeRepository
|
||||
.findOneWithNotFoundDetection(savingsAccountChargeId, accountId);
|
||||
|
||||
final DateTimeFormatter fmt = DateTimeFormatter.ofPattern("dd MM yyyy").withZone(DateUtils.getDateTimeZoneOfTenant());
|
||||
|
||||
while (savingsAccountCharge.isNotFullyPaid() && DateUtils.isBeforeBusinessDate(savingsAccountCharge.getDueLocalDate())) {
|
||||
payCharge(savingsAccountCharge, transactionDate, savingsAccountCharge.amoutOutstanding(), fmt, user, false);
|
||||
while (savingsAccountCharge.isNotFullyPaid() && DateUtils.isBefore(savingsAccountCharge.getDueDate(), transactionDate)) {
|
||||
payCharge(savingsAccountCharge, transactionDate, savingsAccountCharge.amoutOutstanding(), fmt, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1390,8 +1388,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
|
||||
@Transactional
|
||||
private SavingsAccountTransaction payCharge(final SavingsAccountCharge savingsAccountCharge, final LocalDate transactionDate,
|
||||
final BigDecimal amountPaid, final DateTimeFormatter formatter, final AppUser user, final boolean backdatedTxnsAllowedTill) {
|
||||
|
||||
final BigDecimal amountPaid, final DateTimeFormatter formatter, final boolean backdatedTxnsAllowedTill) {
|
||||
final boolean isSavingsInterestPostingAtCurrentPeriodEnd = this.configurationDomainService
|
||||
.isSavingsInterestPostingAtCurrentPeriodEnd();
|
||||
final Integer financialYearBeginningMonth = this.configurationDomainService.retrieveFinancialYearBeginningMonth();
|
||||
@@ -1409,7 +1406,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
account.validateAccountBalanceDoesNotViolateOverdraft(savingsAccountTransaction, amountPaid);
|
||||
|
||||
updateExistingTransactionsDetails(account, existingTransactionIds, existingReversedTransactionIds);
|
||||
SavingsAccountTransaction chargeTransaction = account.payCharge(savingsAccountCharge, amountPaid, transactionDate, formatter, user,
|
||||
SavingsAccountTransaction chargeTransaction = account.payCharge(savingsAccountCharge, amountPaid, transactionDate, formatter,
|
||||
backdatedTxnsAllowedTill, null);
|
||||
boolean isInterestTransfer = false;
|
||||
LocalDate postInterestOnDate = null;
|
||||
@@ -1649,7 +1646,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
final Set<Long> existingTransactionIds = new HashSet<>();
|
||||
final Set<Long> existingReversedTransactionIds = new HashSet<>();
|
||||
updateExistingTransactionsDetails(account, existingTransactionIds, existingReversedTransactionIds);
|
||||
account.setSubStatusInactive(appuserRepository.fetchSystemUser(), false);
|
||||
account.setSubStatusInactive(false);
|
||||
this.savingAccountRepositoryWrapper.saveAndFlush(account);
|
||||
postJournalEntries(account, existingTransactionIds, existingReversedTransactionIds, false);
|
||||
}
|
||||
@@ -1767,16 +1764,15 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
|
||||
this.savingsAccountTransactionDataValidator.validateHoldAndAssembleForm(command.json(), account, submittedBy,
|
||||
backdatedTxnsAllowedTill);
|
||||
SavingsAccountTransaction transaction = this.savingsAccountDomainService.handleHold(account, getAppUserIfPresent(), amount,
|
||||
transactionDate, lienAllowed);
|
||||
SavingsAccountTransaction transaction = this.savingsAccountDomainService.handleHold(account, amount, transactionDate, lienAllowed);
|
||||
account.holdAmount(amount);
|
||||
transaction.updateRunningBalance(runningBalance);
|
||||
transaction.setRunningBalance(runningBalance);
|
||||
|
||||
final String reasonForBlock = command.stringValueOfParameterNamed(SavingsApiConstants.reasonForBlockParamName);
|
||||
transaction.updateReason(reasonForBlock);
|
||||
|
||||
account.getAccountBalance();
|
||||
this.savingsAccountTransactionDataValidator.validateTransactionWithPivotDate(transaction.getTransactionLocalDate(), account);
|
||||
this.savingsAccountTransactionDataValidator.validateTransactionWithPivotDate(transaction.getTransactionDate(), account);
|
||||
|
||||
this.savingsAccountTransactionRepository.saveAndFlush(transaction);
|
||||
|
||||
@@ -1794,14 +1790,14 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult releaseAmount(final Long savingsId, final Long savingsTransactionId) {
|
||||
final AppUser submittedBy = this.context.authenticatedUser();
|
||||
context.authenticatedUser();
|
||||
SavingsAccountTransaction holdTransaction = this.savingsAccountTransactionRepository
|
||||
.findOneByIdAndSavingsAccountId(savingsTransactionId, savingsId);
|
||||
|
||||
holdTransaction.updateReason(null);
|
||||
|
||||
final SavingsAccountTransaction transaction = this.savingsAccountTransactionDataValidator
|
||||
.validateReleaseAmountAndAssembleForm(holdTransaction, submittedBy);
|
||||
.validateReleaseAmountAndAssembleForm(holdTransaction);
|
||||
|
||||
final boolean backdatedTxnsAllowedTill = this.savingAccountAssembler.getPivotConfigStatus();
|
||||
final SavingsAccount account = this.savingAccountAssembler.assembleFrom(savingsId, backdatedTxnsAllowedTill);
|
||||
@@ -1814,9 +1810,9 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
runningBalance = runningBalance.minus(savingsOnHold);
|
||||
|
||||
runningBalance = runningBalance.plus(transaction.getAmount());
|
||||
transaction.updateRunningBalance(runningBalance);
|
||||
transaction.setRunningBalance(runningBalance);
|
||||
|
||||
this.savingsAccountTransactionDataValidator.validateTransactionWithPivotDate(transaction.getTransactionLocalDate(), account);
|
||||
this.savingsAccountTransactionDataValidator.validateTransactionWithPivotDate(transaction.getTransactionDate(), account);
|
||||
account.releaseOnHoldAmount(transaction.getAmount());
|
||||
|
||||
this.savingsAccountTransactionRepository.saveAndFlush(transaction);
|
||||
@@ -1914,11 +1910,11 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
|
||||
private void validateTransactionsForTransfer(final SavingsAccount savingsAccount, final LocalDate transferDate) {
|
||||
for (SavingsAccountTransaction transaction : savingsAccount.getTransactions()) {
|
||||
if ((DateUtils.isEqual(transferDate, transaction.getTransactionLocalDate())
|
||||
if ((DateUtils.isEqual(transferDate, transaction.getTransactionDate())
|
||||
&& DateUtils.isEqual(transferDate, transaction.getSubmittedOnDate()))
|
||||
|| DateUtils.isBefore(transferDate, transaction.getTransactionLocalDate())) {
|
||||
|| DateUtils.isBefore(transferDate, transaction.getTransactionDate())) {
|
||||
throw new GeneralPlatformDomainRuleException(TransferApiConstants.transferClientSavingsException,
|
||||
TransferApiConstants.transferClientSavingsException, transaction.getCreatedDate(), transferDate);
|
||||
TransferApiConstants.transferClientSavingsException, transaction.getCreatedDateTime(), transferDate);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+4
-6
@@ -47,7 +47,6 @@ import org.apache.fineract.infrastructure.core.data.CommandProcessingResultBuild
|
||||
import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder;
|
||||
import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException;
|
||||
import org.apache.fineract.infrastructure.core.exception.PlatformDataIntegrityException;
|
||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||
import org.apache.fineract.infrastructure.dataqueries.data.EntityTables;
|
||||
import org.apache.fineract.infrastructure.dataqueries.data.StatusEnum;
|
||||
import org.apache.fineract.infrastructure.dataqueries.service.EntityDatatableChecksWritePlatformService;
|
||||
@@ -320,7 +319,7 @@ public class SavingsApplicationProcessWritePlatformServiceJpaRepositoryImpl impl
|
||||
final SavingsAccount account = this.savingAccountAssembler.assembleFrom(savingsId, false);
|
||||
checkClientOrGroupActive(account);
|
||||
account.modifyApplication(command, changes);
|
||||
account.validateNewApplicationState(DateUtils.getBusinessLocalDate(), SAVINGS_ACCOUNT_RESOURCE_NAME);
|
||||
account.validateNewApplicationState(SAVINGS_ACCOUNT_RESOURCE_NAME);
|
||||
account.validateAccountValuesWithProduct();
|
||||
|
||||
if (!changes.isEmpty()) {
|
||||
@@ -480,7 +479,7 @@ public class SavingsApplicationProcessWritePlatformServiceJpaRepositoryImpl impl
|
||||
StatusEnum.APPROVE.getCode().longValue(), EntityTables.SAVINGS.getForeignKeyColumnNameOnDatatable(),
|
||||
savingsAccount.productId());
|
||||
|
||||
final Map<String, Object> changes = savingsAccount.approveApplication(currentUser, command, DateUtils.getBusinessLocalDate());
|
||||
final Map<String, Object> changes = savingsAccount.approveApplication(currentUser, command);
|
||||
if (!changes.isEmpty()) {
|
||||
this.savingAccountRepository.save(savingsAccount);
|
||||
|
||||
@@ -603,7 +602,7 @@ public class SavingsApplicationProcessWritePlatformServiceJpaRepositoryImpl impl
|
||||
StatusEnum.REJECTED.getCode().longValue(), EntityTables.SAVINGS.getForeignKeyColumnNameOnDatatable(),
|
||||
savingsAccount.productId());
|
||||
|
||||
final Map<String, Object> changes = savingsAccount.rejectApplication(currentUser, command, DateUtils.getBusinessLocalDate());
|
||||
final Map<String, Object> changes = savingsAccount.rejectApplication(currentUser, command);
|
||||
if (!changes.isEmpty()) {
|
||||
this.savingAccountRepository.save(savingsAccount);
|
||||
|
||||
@@ -640,8 +639,7 @@ public class SavingsApplicationProcessWritePlatformServiceJpaRepositoryImpl impl
|
||||
StatusEnum.WITHDRAWN.getCode().longValue(), EntityTables.SAVINGS.getForeignKeyColumnNameOnDatatable(),
|
||||
savingsAccount.productId());
|
||||
|
||||
final Map<String, Object> changes = savingsAccount.applicantWithdrawsFromApplication(currentUser, command,
|
||||
DateUtils.getBusinessLocalDate());
|
||||
final Map<String, Object> changes = savingsAccount.applicantWithdrawsFromApplication(currentUser, command);
|
||||
if (!changes.isEmpty()) {
|
||||
this.savingAccountRepository.save(savingsAccount);
|
||||
|
||||
|
||||
+44
-64
@@ -18,12 +18,16 @@
|
||||
*/
|
||||
package org.apache.fineract.portfolio.savings.service;
|
||||
|
||||
import static org.apache.fineract.infrastructure.core.domain.AuditableFieldsConstants.CREATED_BY_DB_FIELD;
|
||||
import static org.apache.fineract.infrastructure.core.domain.AuditableFieldsConstants.CREATED_DATE_DB_FIELD;
|
||||
import static org.apache.fineract.infrastructure.core.domain.AuditableFieldsConstants.LAST_MODIFIED_BY_DB_FIELD;
|
||||
import static org.apache.fineract.infrastructure.core.domain.AuditableFieldsConstants.LAST_MODIFIED_DATE_DB_FIELD;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.OffsetDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
@@ -64,7 +68,6 @@ public class SavingsSchedularInterestPoster {
|
||||
|
||||
@Transactional(isolation = Isolation.READ_UNCOMMITTED, rollbackFor = Exception.class)
|
||||
public void postInterest() throws JobExecutionException {
|
||||
|
||||
if (!savingAccounts.isEmpty()) {
|
||||
List<Throwable> errors = new ArrayList<>();
|
||||
for (SavingsAccountData savingsAccountData : savingAccounts) {
|
||||
@@ -114,14 +117,14 @@ public class SavingsSchedularInterestPoster {
|
||||
savingsAccountTransactionData.setId(dataFromFetch.getId());
|
||||
if (savingsAccountData.getGlAccountIdForSavingsControl() != 0
|
||||
&& savingsAccountData.getGlAccountIdForInterestOnSavings() != 0) {
|
||||
OffsetDateTime auditDatetime = DateUtils.getAuditOffsetDateTime();
|
||||
paramsForGLInsertion.add(new Object[] { savingsAccountData.getGlAccountIdForSavingsControl(),
|
||||
savingsAccountData.getOfficeId(), null, currencyCode,
|
||||
SAVINGS_TRANSACTION_IDENTIFIER + savingsAccountTransactionData.getId().toString(),
|
||||
savingsAccountTransactionData.getId(), null, false, null, false,
|
||||
savingsAccountTransactionData.getTransactionDate(), JournalEntryType.CREDIT.getValue().longValue(),
|
||||
savingsAccountTransactionData.getAmount(), null, JournalEntryType.CREDIT.getValue().longValue(),
|
||||
savingsAccountData.getId(), DateUtils.getOffsetDateTimeOfTenantWithMostPrecision(),
|
||||
DateUtils.getOffsetDateTimeOfTenantWithMostPrecision(), false, BigDecimal.ZERO, BigDecimal.ZERO, null,
|
||||
savingsAccountData.getId(), auditDatetime, auditDatetime, false, BigDecimal.ZERO, BigDecimal.ZERO, null,
|
||||
savingsAccountTransactionData.getTransactionDate(), null, userId, userId,
|
||||
DateUtils.getBusinessLocalDate() });
|
||||
|
||||
@@ -131,8 +134,7 @@ public class SavingsSchedularInterestPoster {
|
||||
savingsAccountTransactionData.getId(), null, false, null, false,
|
||||
savingsAccountTransactionData.getTransactionDate(), JournalEntryType.DEBIT.getValue().longValue(),
|
||||
savingsAccountTransactionData.getAmount(), null, JournalEntryType.DEBIT.getValue().longValue(),
|
||||
savingsAccountData.getId(), DateUtils.getOffsetDateTimeOfTenantWithMostPrecision(),
|
||||
DateUtils.getOffsetDateTimeOfTenantWithMostPrecision(), false, BigDecimal.ZERO, BigDecimal.ZERO, null,
|
||||
savingsAccountData.getId(), auditDatetime, auditDatetime, false, BigDecimal.ZERO, BigDecimal.ZERO, null,
|
||||
savingsAccountTransactionData.getTransactionDate(), null, userId, userId,
|
||||
DateUtils.getBusinessLocalDate() });
|
||||
}
|
||||
@@ -147,16 +149,12 @@ public class SavingsSchedularInterestPoster {
|
||||
}
|
||||
|
||||
private String batchQueryForJournalEntries() {
|
||||
StringBuilder query = new StringBuilder(100);
|
||||
|
||||
query.append("INSERT INTO acc_gl_journal_entry(account_id,office_id,reversal_id,currency_code,transaction_id,");
|
||||
query.append("savings_transaction_id,client_transaction_id,reversed,ref_num,manual_entry,entry_date,type_enum,");
|
||||
query.append("amount,description,entity_type_enum,entity_id,created_on_utc,");
|
||||
query.append("last_modified_on_utc,is_running_balance_calculated,office_running_balance,organization_running_balance,");
|
||||
query.append("payment_details_id,transaction_date,share_transaction_id, created_by, last_modified_by, submitted_on_date) ");
|
||||
query.append("VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
|
||||
|
||||
return query.toString();
|
||||
return "INSERT INTO acc_gl_journal_entry(account_id,office_id,reversal_id,currency_code,transaction_id,"
|
||||
+ "savings_transaction_id,client_transaction_id,reversed,ref_num,manual_entry,entry_date,type_enum,"
|
||||
+ "amount,description,entity_type_enum,entity_id,created_on_utc,"
|
||||
+ "last_modified_on_utc,is_running_balance_calculated,office_running_balance,organization_running_balance,"
|
||||
+ "payment_details_id,transaction_date,share_transaction_id, created_by, last_modified_by, submitted_on_date) "
|
||||
+ "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
|
||||
}
|
||||
|
||||
private List<SavingsAccountTransactionData> fetchTransactionsFromIds(final List<String> refNo) throws DataAccessException {
|
||||
@@ -172,7 +170,10 @@ public class SavingsSchedularInterestPoster {
|
||||
List<Object[]> paramsForSavingsSummary = new ArrayList<>();
|
||||
List<Object[]> paramsForTransactionUpdate = new ArrayList<>();
|
||||
List<String> transRefNo = new ArrayList<>();
|
||||
LocalDate currentDate = DateUtils.getBusinessLocalDate();
|
||||
Long userId = platformSecurityContext.authenticatedUser().getId();
|
||||
for (SavingsAccountData savingsAccountData : savingsAccountDataList) {
|
||||
OffsetDateTime auditTime = DateUtils.getAuditOffsetDateTime();
|
||||
SavingsAccountSummaryData savingsAccountSummaryData = savingsAccountData.getSummary();
|
||||
paramsForSavingsSummary.add(new Object[] { savingsAccountSummaryData.getTotalDeposits(),
|
||||
savingsAccountSummaryData.getTotalWithdrawals(), savingsAccountSummaryData.getTotalInterestEarned(),
|
||||
@@ -180,39 +181,30 @@ public class SavingsSchedularInterestPoster {
|
||||
savingsAccountSummaryData.getTotalFeeCharge(), savingsAccountSummaryData.getTotalPenaltyCharge(),
|
||||
savingsAccountSummaryData.getTotalAnnualFees(), savingsAccountSummaryData.getAccountBalance(),
|
||||
savingsAccountSummaryData.getTotalOverdraftInterestDerived(), savingsAccountSummaryData.getTotalWithholdTax(),
|
||||
Date.from(savingsAccountSummaryData.getLastInterestCalculationDate().atStartOfDay(DateUtils.getDateTimeZoneOfTenant())
|
||||
.toInstant()),
|
||||
savingsAccountSummaryData.getInterestPostedTillDate() != null
|
||||
? Date.from(savingsAccountSummaryData.getInterestPostedTillDate()
|
||||
.atStartOfDay(DateUtils.getDateTimeZoneOfTenant()).toInstant())
|
||||
: Date.from(savingsAccountSummaryData.getLastInterestCalculationDate()
|
||||
.atStartOfDay(DateUtils.getDateTimeZoneOfTenant()).toInstant()),
|
||||
savingsAccountData.getId() });
|
||||
savingsAccountSummaryData.getLastInterestCalculationDate(),
|
||||
savingsAccountSummaryData.getInterestPostedTillDate() != null ? savingsAccountSummaryData.getInterestPostedTillDate()
|
||||
: savingsAccountSummaryData.getLastInterestCalculationDate(),
|
||||
auditTime, userId, savingsAccountData.getId() });
|
||||
List<SavingsAccountTransactionData> savingsAccountTransactionDataList = savingsAccountData.getSavingsAccountTransactionData();
|
||||
LocalDateTime currentDate = DateUtils.getLocalDateTimeOfTenant();
|
||||
for (SavingsAccountTransactionData savingsAccountTransactionData : savingsAccountTransactionDataList) {
|
||||
Date balanceEndDate = null;
|
||||
if (savingsAccountTransactionData.getBalanceEndDate() != null) {
|
||||
balanceEndDate = Date.from(savingsAccountTransactionData.getBalanceEndDate()
|
||||
.atStartOfDay(DateUtils.getDateTimeZoneOfTenant()).toInstant());
|
||||
}
|
||||
if (savingsAccountTransactionData.getId() == null) {
|
||||
UUID uuid = UUID.randomUUID();
|
||||
savingsAccountTransactionData.setRefNo(uuid.toString());
|
||||
transRefNo.add(uuid.toString());
|
||||
paramsForTransactionInsertion.add(new Object[] { savingsAccountData.getId(), savingsAccountData.getOfficeId(),
|
||||
savingsAccountTransactionData.isReversed(), savingsAccountTransactionData.getTransactionType().getId(),
|
||||
savingsAccountTransactionData.getTransactionDate(), savingsAccountTransactionData.getAmount(), balanceEndDate,
|
||||
savingsAccountTransactionData.getBalanceNumberOfDays(), savingsAccountTransactionData.getRunningBalance(),
|
||||
savingsAccountTransactionData.getCumulativeBalance(), currentDate, 1,
|
||||
savingsAccountTransactionData.isManualTransaction(), savingsAccountTransactionData.getRefNo(),
|
||||
savingsAccountTransactionData.isReversalTransaction(), savingsAccountTransactionData.getOverdraftAmount(),
|
||||
DateUtils.getBusinessLocalDate() });
|
||||
savingsAccountTransactionData.getTransactionDate(), savingsAccountTransactionData.getAmount(),
|
||||
savingsAccountTransactionData.getBalanceEndDate(), savingsAccountTransactionData.getBalanceNumberOfDays(),
|
||||
savingsAccountTransactionData.getRunningBalance(), savingsAccountTransactionData.getCumulativeBalance(),
|
||||
auditTime, userId, auditTime, userId, savingsAccountTransactionData.isManualTransaction(),
|
||||
savingsAccountTransactionData.getRefNo(), savingsAccountTransactionData.isReversalTransaction(),
|
||||
savingsAccountTransactionData.getOverdraftAmount(), currentDate });
|
||||
} else {
|
||||
paramsForTransactionUpdate.add(new Object[] { savingsAccountTransactionData.isReversed(),
|
||||
savingsAccountTransactionData.getAmount(), savingsAccountTransactionData.getOverdraftAmount(), balanceEndDate,
|
||||
savingsAccountTransactionData.getBalanceNumberOfDays(), savingsAccountTransactionData.getRunningBalance(),
|
||||
savingsAccountTransactionData.getCumulativeBalance(), savingsAccountTransactionData.isReversalTransaction(),
|
||||
savingsAccountTransactionData.getAmount(), savingsAccountTransactionData.getOverdraftAmount(),
|
||||
savingsAccountTransactionData.getBalanceEndDate(), savingsAccountTransactionData.getBalanceNumberOfDays(),
|
||||
savingsAccountTransactionData.getRunningBalance(), savingsAccountTransactionData.getCumulativeBalance(),
|
||||
savingsAccountTransactionData.isReversalTransaction(), auditTime, userId,
|
||||
savingsAccountTransactionData.getId() });
|
||||
}
|
||||
}
|
||||
@@ -240,35 +232,23 @@ public class SavingsSchedularInterestPoster {
|
||||
}
|
||||
|
||||
private String batchQueryForTransactionInsertion() {
|
||||
StringBuilder query = new StringBuilder(100);
|
||||
query.append("INSERT INTO m_savings_account_transaction (savings_account_id, office_id, is_reversed, ");
|
||||
query.append("transaction_type_enum, transaction_date, amount, balance_end_date_derived, ");
|
||||
query.append("balance_number_of_days_derived, running_balance_derived, cumulative_balance_derived, ");
|
||||
query.append("created_date, appuser_id, is_manual, ref_no, is_reversal, ");
|
||||
query.append("overdraft_amount_derived, submitted_on_date) VALUES ");
|
||||
query.append("(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
|
||||
return query.toString();
|
||||
|
||||
return "INSERT INTO m_savings_account_transaction (savings_account_id, office_id, is_reversed, transaction_type_enum, transaction_date, amount, balance_end_date_derived, "
|
||||
+ "balance_number_of_days_derived, running_balance_derived, cumulative_balance_derived, " + CREATED_DATE_DB_FIELD + ", "
|
||||
+ CREATED_BY_DB_FIELD + ", " + LAST_MODIFIED_DATE_DB_FIELD + ", " + LAST_MODIFIED_BY_DB_FIELD
|
||||
+ ", is_manual, ref_no, is_reversal, "
|
||||
+ "overdraft_amount_derived, submitted_on_date) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
|
||||
}
|
||||
|
||||
private String batchQueryForSavingsSummaryUpdate() {
|
||||
StringBuilder query = new StringBuilder(100);
|
||||
query.append("update m_savings_account set total_deposits_derived=?, total_withdrawals_derived=?, ");
|
||||
query.append("total_interest_earned_derived=?, total_interest_posted_derived=?, total_withdrawal_fees_derived=?, ");
|
||||
query.append("total_fees_charge_derived=?, total_penalty_charge_derived=?, total_annual_fees_derived=?, ");
|
||||
query.append("account_balance_derived=?, total_overdraft_interest_derived=?, total_withhold_tax_derived=?, ");
|
||||
query.append("last_interest_calculation_date=?, interest_posted_till_date=? where id=? ");
|
||||
return query.toString();
|
||||
return "update m_savings_account set total_deposits_derived=?, total_withdrawals_derived=?, total_interest_earned_derived=?, total_interest_posted_derived=?, total_withdrawal_fees_derived=?, "
|
||||
+ "total_fees_charge_derived=?, total_penalty_charge_derived=?, total_annual_fees_derived=?, account_balance_derived=?, total_overdraft_interest_derived=?, total_withhold_tax_derived=?, "
|
||||
+ "last_interest_calculation_date=?, interest_posted_till_date=?, " + LAST_MODIFIED_DATE_DB_FIELD + " = ?, "
|
||||
+ LAST_MODIFIED_BY_DB_FIELD + " = ? WHERE id=? ";
|
||||
}
|
||||
|
||||
private String batchQueryForTransactionsUpdate() {
|
||||
StringBuilder query = new StringBuilder(100);
|
||||
query.append("UPDATE m_savings_account_transaction ");
|
||||
query.append("SET is_reversed=?, ");
|
||||
query.append("amount=?, overdraft_amount_derived=?, balance_end_date_derived=?, ");
|
||||
query.append("balance_number_of_days_derived=?, running_balance_derived=?, cumulative_balance_derived=?, ");
|
||||
query.append("is_reversal=? ");
|
||||
query.append("WHERE id=?");
|
||||
return query.toString();
|
||||
return "UPDATE m_savings_account_transaction "
|
||||
+ "SET is_reversed=?, amount=?, overdraft_amount_derived=?, balance_end_date_derived=?, balance_number_of_days_derived=?, running_balance_derived=?, cumulative_balance_derived=?, is_reversal=?, "
|
||||
+ LAST_MODIFIED_DATE_DB_FIELD + " = ?, " + LAST_MODIFIED_BY_DB_FIELD + " = ? " + "WHERE id=?";
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -18,6 +18,7 @@
|
||||
*/
|
||||
package org.apache.fineract.portfolio.savings.service.search;
|
||||
|
||||
import static org.apache.fineract.infrastructure.core.domain.AuditableFieldsConstants.CREATED_DATE_DB_FIELD;
|
||||
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.SAVINGS_ACCOUNT_RESOURCE_NAME;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
@@ -87,7 +88,7 @@ public class SavingsAccountTransactionsSearchServiceImpl implements SavingsAccou
|
||||
sortPageable = pageable.withSort(Sort.by(orders.stream()
|
||||
.map(e -> e.withProperty(SearchUtil.validateToJdbcColumnName(e.getProperty(), headersByName, false))).toList()));
|
||||
} else {
|
||||
pageable = pageable.withSort(Sort.Direction.DESC, "transaction_date", "created_date", "id");
|
||||
pageable = pageable.withSort(Sort.Direction.DESC, "transaction_date", CREATED_DATE_DB_FIELD, "id");
|
||||
sortPageable = pageable;
|
||||
}
|
||||
|
||||
|
||||
@@ -147,4 +147,5 @@
|
||||
<include file="parts/0125_transaction_summary_with_asset_owner_report_chargeoff_reason.xml" relativeToChangelogFile="true" />
|
||||
<include file="parts/0126_add_loan_product_installment_level_delinquency.xml" relativeToChangelogFile="true" />
|
||||
<include file="parts/0127_client_name_length.xml" relativeToChangelogFile="true" />
|
||||
<include file="parts/0128_savings_audit.xml" relativeToChangelogFile="true" />
|
||||
</databaseChangeLog>
|
||||
|
||||
+266
@@ -0,0 +1,266 @@
|
||||
<?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">
|
||||
<!-- add audit fields -->
|
||||
<changeSet id="1" author="fineract">
|
||||
<addColumn tableName="m_savings_account">
|
||||
<column name="created_by" type="BIGINT" valueComputed="submittedon_userid"/>
|
||||
<column name="last_modified_by" type="BIGINT"/>
|
||||
</addColumn>
|
||||
<renameColumn tableName="m_savings_account_transaction" oldColumnName="appuser_id" newColumnName="created_by" columnDataType="BIGINT"/>
|
||||
<addColumn tableName="m_savings_account_transaction">
|
||||
<column name="last_modified_by" type="BIGINT"/>
|
||||
</addColumn>
|
||||
<addColumn tableName="m_deposit_account_on_hold_transaction">
|
||||
<column name="created_by" type="BIGINT"/>
|
||||
<column name="last_modified_by" type="BIGINT"/>
|
||||
</addColumn>
|
||||
<addColumn tableName="m_savings_account_charge">
|
||||
<column name="created_by" type="BIGINT"/>
|
||||
<column name="last_modified_by" type="BIGINT"/>
|
||||
</addColumn>
|
||||
<renameColumn tableName="m_savings_officer_assignment_history" oldColumnName="createdby_id" newColumnName="created_by" columnDataType="BIGINT"/>
|
||||
<renameColumn tableName="m_savings_officer_assignment_history" oldColumnName="lastmodifiedby_id" newColumnName="last_modified_by" columnDataType="BIGINT"/>
|
||||
<renameColumn tableName="m_mandatory_savings_schedule" oldColumnName="createdby_id" newColumnName="created_by" columnDataType="BIGINT"/>
|
||||
<renameColumn tableName="m_mandatory_savings_schedule" oldColumnName="lastmodifiedby_id" newColumnName="last_modified_by" columnDataType="BIGINT"/>
|
||||
</changeSet>
|
||||
<changeSet id="2" author="fineract" context="mysql">
|
||||
<addColumn tableName="m_savings_account">
|
||||
<column name="created_on_utc" type="DATETIME(6)"/>
|
||||
<column name="last_modified_on_utc" type="DATETIME(6)"/>
|
||||
</addColumn>
|
||||
<addColumn tableName="m_savings_account_transaction">
|
||||
<column name="created_on_utc" type="DATETIME(6)"/>
|
||||
<column name="last_modified_on_utc" type="DATETIME(6)"/>
|
||||
</addColumn>
|
||||
<addColumn tableName="m_deposit_account_on_hold_transaction">
|
||||
<column name="created_on_utc" type="DATETIME(6)"/>
|
||||
<column name="last_modified_on_utc" type="DATETIME(6)"/>
|
||||
</addColumn>
|
||||
<addColumn tableName="m_savings_account_charge">
|
||||
<column name="created_on_utc" type="DATETIME(6)"/>
|
||||
<column name="last_modified_on_utc" type="DATETIME(6)"/>
|
||||
</addColumn>
|
||||
<addColumn tableName="m_savings_officer_assignment_history">
|
||||
<column name="created_on_utc" type="DATETIME(6)"/>
|
||||
<column name="last_modified_on_utc" type="DATETIME(6)"/>
|
||||
</addColumn>
|
||||
<addColumn tableName="m_mandatory_savings_schedule">
|
||||
<column name="created_on_utc" type="DATETIME(6)"/>
|
||||
<column name="last_modified_on_utc" type="DATETIME(6)"/>
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
<changeSet id="2" author="fineract" context="postgresql">
|
||||
<addColumn tableName="m_savings_account">
|
||||
<column name="created_on_utc" type="TIMESTAMP WITH TIME ZONE"/>
|
||||
<column name="last_modified_on_utc" type="TIMESTAMP WITH TIME ZONE"/>
|
||||
</addColumn>
|
||||
<addColumn tableName="m_savings_account_transaction">
|
||||
<column name="created_on_utc" type="TIMESTAMP WITH TIME ZONE"/>
|
||||
<column name="last_modified_on_utc" type="TIMESTAMP WITH TIME ZONE"/>
|
||||
</addColumn>
|
||||
<addColumn tableName="m_deposit_account_on_hold_transaction">
|
||||
<column name="created_on_utc" type="TIMESTAMP WITH TIME ZONE"/>
|
||||
<column name="last_modified_on_utc" type="TIMESTAMP WITH TIME ZONE"/>
|
||||
</addColumn>
|
||||
<addColumn tableName="m_savings_account_charge">
|
||||
<column name="created_on_utc" type="TIMESTAMP WITH TIME ZONE"/>
|
||||
<column name="last_modified_on_utc" type="TIMESTAMP WITH TIME ZONE"/>
|
||||
</addColumn>
|
||||
<addColumn tableName="m_savings_officer_assignment_history">
|
||||
<column name="created_on_utc" type="TIMESTAMP WITH TIME ZONE"/>
|
||||
<column name="last_modified_on_utc" type="TIMESTAMP WITH TIME ZONE"/>
|
||||
</addColumn>
|
||||
<addColumn tableName="m_mandatory_savings_schedule">
|
||||
<column name="created_on_utc" type="TIMESTAMP WITH TIME ZONE"/>
|
||||
<column name="last_modified_on_utc" type="TIMESTAMP WITH TIME ZONE"/>
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
|
||||
<!-- add audit constraints -->
|
||||
<changeSet id="3" author="fineract" context="mysql">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<sqlCheck expectedResult="0">select count(*) from m_savings_account</sqlCheck>
|
||||
</preConditions>
|
||||
<addNotNullConstraint tableName="m_savings_account" columnName="created_by" columnDataType="BIGINT"/>
|
||||
<addNotNullConstraint tableName="m_savings_account" columnName="last_modified_by" columnDataType="BIGINT"/>
|
||||
<addNotNullConstraint tableName="m_savings_account" columnName="created_on_utc" columnDataType="DATETIME(6)"/>
|
||||
<addNotNullConstraint tableName="m_savings_account" columnName="last_modified_on_utc" columnDataType="DATETIME(6)"/>
|
||||
</changeSet>
|
||||
<changeSet id="3" author="fineract" context="postgresql">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<sqlCheck expectedResult="0">select count(*) from m_savings_account</sqlCheck>
|
||||
</preConditions>
|
||||
<addNotNullConstraint tableName="m_savings_account" columnName="created_by"/>
|
||||
<addNotNullConstraint tableName="m_savings_account" columnName="last_modified_by"/>
|
||||
<addNotNullConstraint tableName="m_savings_account" columnName="created_on_utc"/>
|
||||
<addNotNullConstraint tableName="m_savings_account" columnName="last_modified_on_utc"/>
|
||||
</changeSet>
|
||||
<changeSet id="4" author="fineract" context="mysql">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<sqlCheck expectedResult="0">select count(*) from m_savings_account_transaction</sqlCheck>
|
||||
</preConditions>
|
||||
<addNotNullConstraint tableName="m_savings_account_transaction" columnName="created_by" columnDataType="BIGINT"/>
|
||||
<addNotNullConstraint tableName="m_savings_account_transaction" columnName="last_modified_by" columnDataType="BIGINT"/>
|
||||
<addNotNullConstraint tableName="m_savings_account_transaction" columnName="created_on_utc" columnDataType="DATETIME(6)"/>
|
||||
<addNotNullConstraint tableName="m_savings_account_transaction" columnName="last_modified_on_utc" columnDataType="DATETIME(6)"/>
|
||||
</changeSet>
|
||||
<changeSet id="4" author="fineract" context="postgresql">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<sqlCheck expectedResult="0">select count(*) from m_savings_account_transaction</sqlCheck>
|
||||
</preConditions>
|
||||
<addNotNullConstraint tableName="m_savings_account_transaction" columnName="created_by"/>
|
||||
<addNotNullConstraint tableName="m_savings_account_transaction" columnName="last_modified_by"/>
|
||||
<addNotNullConstraint tableName="m_savings_account_transaction" columnName="created_on_utc"/>
|
||||
<addNotNullConstraint tableName="m_savings_account_transaction" columnName="last_modified_on_utc"/>
|
||||
</changeSet>
|
||||
<changeSet id="5" author="fineract" context="mysql">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<sqlCheck expectedResult="0">select count(*) from m_deposit_account_on_hold_transaction</sqlCheck>
|
||||
</preConditions>
|
||||
<addNotNullConstraint tableName="m_deposit_account_on_hold_transaction" columnName="created_by" columnDataType="BIGINT"/>
|
||||
<addNotNullConstraint tableName="m_deposit_account_on_hold_transaction" columnName="last_modified_by" columnDataType="BIGINT"/>
|
||||
<addNotNullConstraint tableName="m_deposit_account_on_hold_transaction" columnName="created_on_utc" columnDataType="DATETIME(6)"/>
|
||||
<addNotNullConstraint tableName="m_deposit_account_on_hold_transaction" columnName="last_modified_on_utc" columnDataType="DATETIME(6)"/>
|
||||
</changeSet>
|
||||
<changeSet id="5" author="fineract" context="postgresql">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<sqlCheck expectedResult="0">select count(*) from m_deposit_account_on_hold_transaction</sqlCheck>
|
||||
</preConditions>
|
||||
<addNotNullConstraint tableName="m_deposit_account_on_hold_transaction" columnName="created_by"/>
|
||||
<addNotNullConstraint tableName="m_deposit_account_on_hold_transaction" columnName="last_modified_by"/>
|
||||
<addNotNullConstraint tableName="m_deposit_account_on_hold_transaction" columnName="created_on_utc"/>
|
||||
<addNotNullConstraint tableName="m_deposit_account_on_hold_transaction" columnName="last_modified_on_utc"/>
|
||||
</changeSet>
|
||||
<changeSet id="6" author="fineract" context="mysql">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<sqlCheck expectedResult="0">select count(*) from m_savings_account_charge</sqlCheck>
|
||||
</preConditions>
|
||||
<addNotNullConstraint tableName="m_savings_account_charge" columnName="created_by" columnDataType="BIGINT"/>
|
||||
<addNotNullConstraint tableName="m_savings_account_charge" columnName="last_modified_by" columnDataType="BIGINT"/>
|
||||
<addNotNullConstraint tableName="m_savings_account_charge" columnName="created_on_utc" columnDataType="DATETIME(6)"/>
|
||||
<addNotNullConstraint tableName="m_savings_account_charge" columnName="last_modified_on_utc" columnDataType="DATETIME(6)"/>
|
||||
</changeSet>
|
||||
<changeSet id="6" author="fineract" context="postgresql">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<sqlCheck expectedResult="0">select count(*) from m_savings_account_charge</sqlCheck>
|
||||
</preConditions>
|
||||
<addNotNullConstraint tableName="m_savings_account_charge" columnName="created_by"/>
|
||||
<addNotNullConstraint tableName="m_savings_account_charge" columnName="last_modified_by"/>
|
||||
<addNotNullConstraint tableName="m_savings_account_charge" columnName="created_on_utc"/>
|
||||
<addNotNullConstraint tableName="m_savings_account_charge" columnName="last_modified_on_utc"/>
|
||||
</changeSet>
|
||||
<changeSet id="7" author="fineract" context="mysql">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<sqlCheck expectedResult="0">select count(*) from m_savings_officer_assignment_history</sqlCheck>
|
||||
</preConditions>
|
||||
<addNotNullConstraint tableName="m_savings_officer_assignment_history" columnName="created_by" columnDataType="BIGINT"/>
|
||||
<addNotNullConstraint tableName="m_savings_officer_assignment_history" columnName="last_modified_by" columnDataType="BIGINT"/>
|
||||
<addNotNullConstraint tableName="m_savings_officer_assignment_history" columnName="created_on_utc" columnDataType="DATETIME(6)"/>
|
||||
<addNotNullConstraint tableName="m_savings_officer_assignment_history" columnName="last_modified_on_utc" columnDataType="DATETIME(6)"/>
|
||||
</changeSet>
|
||||
<changeSet id="7" author="fineract" context="postgresql">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<sqlCheck expectedResult="0">select count(*) from m_savings_officer_assignment_history</sqlCheck>
|
||||
</preConditions>
|
||||
<addNotNullConstraint tableName="m_savings_officer_assignment_history" columnName="created_by"/>
|
||||
<addNotNullConstraint tableName="m_savings_officer_assignment_history" columnName="last_modified_by"/>
|
||||
<addNotNullConstraint tableName="m_savings_officer_assignment_history" columnName="created_on_utc"/>
|
||||
<addNotNullConstraint tableName="m_savings_officer_assignment_history" columnName="last_modified_on_utc"/>
|
||||
</changeSet>
|
||||
<changeSet id="8" author="fineract" context="mysql">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<sqlCheck expectedResult="0">select count(*) from m_mandatory_savings_schedule</sqlCheck>
|
||||
</preConditions>
|
||||
<addNotNullConstraint tableName="m_mandatory_savings_schedule" columnName="created_by" columnDataType="BIGINT"/>
|
||||
<addNotNullConstraint tableName="m_mandatory_savings_schedule" columnName="last_modified_by" columnDataType="BIGINT"/>
|
||||
<addNotNullConstraint tableName="m_mandatory_savings_schedule" columnName="created_on_utc" columnDataType="DATETIME(6)"/>
|
||||
<addNotNullConstraint tableName="m_mandatory_savings_schedule" columnName="last_modified_on_utc" columnDataType="DATETIME(6)"/>
|
||||
</changeSet>
|
||||
<changeSet id="8" author="fineract" context="postgresql">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<sqlCheck expectedResult="0">select count(*) from m_mandatory_savings_schedule</sqlCheck>
|
||||
</preConditions>
|
||||
<addNotNullConstraint tableName="m_mandatory_savings_schedule" columnName="created_by"/>
|
||||
<addNotNullConstraint tableName="m_mandatory_savings_schedule" columnName="last_modified_by"/>
|
||||
<addNotNullConstraint tableName="m_mandatory_savings_schedule" columnName="created_on_utc"/>
|
||||
<addNotNullConstraint tableName="m_mandatory_savings_schedule" columnName="last_modified_on_utc"/>
|
||||
</changeSet>
|
||||
<changeSet id="9" author="fineract">
|
||||
<addForeignKeyConstraint baseColumnNames="created_by" baseTableName="m_savings_account"
|
||||
constraintName="FK_savings_account_created_by" deferrable="false" initiallyDeferred="false"
|
||||
onDelete="RESTRICT" onUpdate="RESTRICT" referencedColumnNames="id"
|
||||
referencedTableName="m_appuser" validate="true"/>
|
||||
<addForeignKeyConstraint baseColumnNames="last_modified_by" baseTableName="m_savings_account"
|
||||
constraintName="FK_savings_account_last_modified_by" deferrable="false" initiallyDeferred="false"
|
||||
onDelete="RESTRICT" onUpdate="RESTRICT" referencedColumnNames="id"
|
||||
referencedTableName="m_appuser" validate="true"/>
|
||||
<addForeignKeyConstraint baseColumnNames="created_by" baseTableName="m_savings_account_transaction"
|
||||
constraintName="FK_savings_account_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_savings_account_transaction"
|
||||
constraintName="FK_savings_account_transaction_last_modified_by" deferrable="false" initiallyDeferred="false"
|
||||
onDelete="RESTRICT" onUpdate="RESTRICT" referencedColumnNames="id"
|
||||
referencedTableName="m_appuser" validate="true"/>
|
||||
<addForeignKeyConstraint baseColumnNames="created_by" baseTableName="m_deposit_account_on_hold_transaction"
|
||||
constraintName="FK_deposit_account_on_hold_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_deposit_account_on_hold_transaction"
|
||||
constraintName="FK_deposit_account_on_hold_transaction_last_modified_by" deferrable="false" initiallyDeferred="false"
|
||||
onDelete="RESTRICT" onUpdate="RESTRICT" referencedColumnNames="id"
|
||||
referencedTableName="m_appuser" validate="true"/>
|
||||
<addForeignKeyConstraint baseColumnNames="created_by" baseTableName="m_savings_account_charge"
|
||||
constraintName="FK_savings_account_charge_created_by" deferrable="false" initiallyDeferred="false"
|
||||
onDelete="RESTRICT" onUpdate="RESTRICT" referencedColumnNames="id"
|
||||
referencedTableName="m_appuser" validate="true"/>
|
||||
<addForeignKeyConstraint baseColumnNames="last_modified_by" baseTableName="m_savings_account_charge"
|
||||
constraintName="FK_savings_account_charge_last_modified_by" deferrable="false" initiallyDeferred="false"
|
||||
onDelete="RESTRICT" onUpdate="RESTRICT" referencedColumnNames="id"
|
||||
referencedTableName="m_appuser" validate="true"/>
|
||||
<addForeignKeyConstraint baseColumnNames="created_by" baseTableName="m_savings_officer_assignment_history"
|
||||
constraintName="FK_savings_officer_assignment_history_created_by" deferrable="false" initiallyDeferred="false"
|
||||
onDelete="RESTRICT" onUpdate="RESTRICT" referencedColumnNames="id"
|
||||
referencedTableName="m_appuser" validate="true"/>
|
||||
<addForeignKeyConstraint baseColumnNames="last_modified_by" baseTableName="m_savings_officer_assignment_history"
|
||||
constraintName="FK_savings_officer_assignment_history_last_modified_by" deferrable="false" initiallyDeferred="false"
|
||||
onDelete="RESTRICT" onUpdate="RESTRICT" referencedColumnNames="id"
|
||||
referencedTableName="m_appuser" validate="true"/>
|
||||
<addForeignKeyConstraint baseColumnNames="created_by" baseTableName="m_mandatory_savings_schedule"
|
||||
constraintName="FK_mandatory_savings_schedule_created_by" deferrable="false" initiallyDeferred="false"
|
||||
onDelete="RESTRICT" onUpdate="RESTRICT" referencedColumnNames="id"
|
||||
referencedTableName="m_appuser" validate="true"/>
|
||||
<addForeignKeyConstraint baseColumnNames="last_modified_by" baseTableName="m_mandatory_savings_schedule"
|
||||
constraintName="FK_mandatory_savings_schedule_last_modified_by" deferrable="false" initiallyDeferred="false"
|
||||
onDelete="RESTRICT" onUpdate="RESTRICT" referencedColumnNames="id"
|
||||
referencedTableName="m_appuser" validate="true"/>
|
||||
</changeSet>
|
||||
|
||||
<!-- old fields -->
|
||||
<changeSet id="10" author="fineract">
|
||||
<dropNotNullConstraint tableName="m_savings_account_transaction" columnName="created_date" columnDataType="DATETIME"/>
|
||||
<dropNotNullConstraint tableName="m_deposit_account_on_hold_transaction" columnName="created_date" columnDataType="DATETIME"/>
|
||||
</changeSet>
|
||||
</databaseChangeLog>
|
||||
+4
-4
@@ -54,7 +54,7 @@ public class CustomAuditingHandlerTest {
|
||||
CustomAuditingHandler testInstance = new CustomAuditingHandler(PersistentEntities.of(mappingContext));
|
||||
AbstractAuditableWithUTCDateTimeCustom targetObject = Mockito.spy(AbstractAuditableWithUTCDateTimeCustom.class);
|
||||
targetObject = testInstance.markCreated(targetObject);
|
||||
OffsetDateTime now = OffsetDateTime.now(DateUtils.getDateTimeZoneOfTenant());
|
||||
OffsetDateTime now = DateUtils.getAuditOffsetDateTime();
|
||||
|
||||
assertTrue(targetObject.getCreatedDate().isPresent());
|
||||
assertEquals(now.getYear(), targetObject.getCreatedDate().get().getYear());
|
||||
@@ -70,7 +70,7 @@ public class CustomAuditingHandlerTest {
|
||||
CustomAuditingHandler testInstance = new CustomAuditingHandler(PersistentEntities.of(mappingContext));
|
||||
AbstractAuditableWithUTCDateTimeCustom targetObject = Mockito.spy(AbstractAuditableWithUTCDateTimeCustom.class);
|
||||
targetObject = testInstance.markModified(targetObject);
|
||||
OffsetDateTime now = OffsetDateTime.now(DateUtils.getDateTimeZoneOfTenant());
|
||||
OffsetDateTime now = DateUtils.getAuditOffsetDateTime();
|
||||
|
||||
assertTrue(targetObject.getLastModifiedDate().isPresent());
|
||||
assertEquals(now.getYear(), targetObject.getLastModifiedDate().get().getYear());
|
||||
@@ -86,7 +86,7 @@ public class CustomAuditingHandlerTest {
|
||||
CustomAuditingHandler testInstance = new CustomAuditingHandler(PersistentEntities.of(mappingContext));
|
||||
AbstractAuditableCustom targetObject = Mockito.spy(AbstractAuditableCustom.class);
|
||||
targetObject = testInstance.markModified(targetObject);
|
||||
LocalDateTime now = LocalDateTime.now(ZoneId.systemDefault());
|
||||
LocalDateTime now = DateUtils.getLocalDateTimeOfSystem();
|
||||
|
||||
assertTrue(targetObject.getLastModifiedDate().isPresent());
|
||||
assertEquals(now.getYear(), targetObject.getLastModifiedDate().get().getYear());
|
||||
@@ -102,7 +102,7 @@ public class CustomAuditingHandlerTest {
|
||||
CustomAuditingHandler testInstance = new CustomAuditingHandler(PersistentEntities.of(mappingContext));
|
||||
AbstractAuditableCustom targetObject = Mockito.spy(AbstractAuditableCustom.class);
|
||||
targetObject = testInstance.markCreated(targetObject);
|
||||
LocalDateTime now = LocalDateTime.now(ZoneId.systemDefault());
|
||||
LocalDateTime now = DateUtils.getLocalDateTimeOfSystem();
|
||||
|
||||
assertTrue(targetObject.getCreatedDate().isPresent());
|
||||
assertEquals(now.getYear(), targetObject.getCreatedDate().get().getYear());
|
||||
|
||||
+3
-5
@@ -23,7 +23,6 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.OffsetDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.temporal.TemporalAccessor;
|
||||
import java.util.Optional;
|
||||
import org.apache.fineract.infrastructure.core.domain.FineractPlatformTenant;
|
||||
@@ -36,14 +35,13 @@ public class CustomDateTimeProviderTest {
|
||||
|
||||
@BeforeEach
|
||||
public void init() {
|
||||
|
||||
ThreadLocalContextUtil.setTenant(new FineractPlatformTenant(1L, "default", "Default", "Asia/Kolkata", null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void instanceDateProvider() {
|
||||
Optional<TemporalAccessor> dateTimeProvider = CustomDateTimeProvider.INSTANCE.getNow();
|
||||
LocalDateTime now = LocalDateTime.now(ZoneId.systemDefault());
|
||||
LocalDateTime now = DateUtils.getLocalDateTimeOfSystem();
|
||||
assertTrue(dateTimeProvider.isPresent());
|
||||
assertTrue(dateTimeProvider.get() instanceof LocalDateTime);
|
||||
|
||||
@@ -56,8 +54,8 @@ public class CustomDateTimeProviderTest {
|
||||
|
||||
@Test
|
||||
public void tenantDateProvider() {
|
||||
Optional<TemporalAccessor> dateTimeProvider = CustomDateTimeProvider.TENANT.getNow();
|
||||
OffsetDateTime now = OffsetDateTime.now(DateUtils.getDateTimeZoneOfTenant());
|
||||
Optional<TemporalAccessor> dateTimeProvider = CustomDateTimeProvider.UTC.getNow();
|
||||
OffsetDateTime now = DateUtils.getAuditOffsetDateTime();
|
||||
assertTrue(dateTimeProvider.isPresent());
|
||||
assertTrue(dateTimeProvider.get() instanceof OffsetDateTime);
|
||||
|
||||
|
||||
+5
-5
@@ -56,22 +56,22 @@ public class DateUtilsTest {
|
||||
|
||||
@Test
|
||||
public void getLocalDateOfTenant() {
|
||||
assertEquals(LocalDate.now(ZoneId.of("Asia/Kolkata")), DateUtils.getLocalDateOfTenant());
|
||||
assertTrue(DateUtils.isEqualTenantDate(LocalDate.now(ZoneId.of("Asia/Kolkata"))));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getLocalDateTimeOfTenant() {
|
||||
assertEquals(LocalDateTime.now(ZoneId.of("Asia/Kolkata")).truncatedTo(ChronoUnit.SECONDS), DateUtils.getLocalDateTimeOfTenant());
|
||||
assertTrue(DateUtils.isEqualTenantDateTime(LocalDateTime.now(ZoneId.of("Asia/Kolkata")), ChronoUnit.SECONDS));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getOffsetDateTimeOfTenant() {
|
||||
assertEquals(OffsetDateTime.now(ZoneId.of("Asia/Kolkata")).truncatedTo(ChronoUnit.SECONDS), DateUtils.getOffsetDateTimeOfTenant());
|
||||
assertTrue(DateUtils.isEqualTenantDateTime(OffsetDateTime.now(ZoneId.of("Asia/Kolkata")), ChronoUnit.SECONDS));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getLocalDateTimeOfSystem() {
|
||||
assertEquals(LocalDateTime.now(ZoneId.systemDefault()).truncatedTo(ChronoUnit.SECONDS), DateUtils.getLocalDateTimeOfSystem());
|
||||
assertTrue(DateUtils.isEqualSystemDateTime(LocalDateTime.now(ZoneId.systemDefault()), ChronoUnit.SECONDS));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -83,6 +83,6 @@ public class DateUtilsTest {
|
||||
|
||||
@Test
|
||||
public void getBusinesLocalDate() {
|
||||
assertEquals(LocalDate.of(2022, 6, 12), DateUtils.getBusinessLocalDate());
|
||||
assertTrue(DateUtils.isEqualBusinessDate(LocalDate.of(2022, 6, 12)));
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -3008,7 +3008,7 @@ public class ClientSavingsIntegrationTest {
|
||||
this.savingsProductHelper = new SavingsProductHelper();
|
||||
this.scheduleJobHelper = new SchedulerJobHelper(requestSpec);
|
||||
configurationForBackdatedTransaction();
|
||||
LocalDate transactionDate = LocalDate.now(Utils.getZoneIdOfTenant()).minusDays(5);
|
||||
LocalDate transactionDate = Utils.getLocalDateOfTenant().minusDays(5);
|
||||
final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd MMMM yyyy");
|
||||
String startDate = formatter.format(transactionDate);
|
||||
String secondTrx = formatter.format(transactionDate.plusDays(1));
|
||||
|
||||
+1
-2
@@ -30,7 +30,6 @@ import io.restassured.specification.RequestSpecification;
|
||||
import io.restassured.specification.ResponseSpecification;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.time.ZoneId;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
@@ -162,7 +161,7 @@ public class SavingsAccountTransactionsSearchIntegrationTest {
|
||||
|
||||
@Test
|
||||
public void testSavingsTransactionsSearchSubmittedDateFromTo() throws JsonProcessingException {
|
||||
LocalDate businessDate = LocalDate.now(ZoneId.systemDefault());
|
||||
LocalDate businessDate = Utils.getLocalDateOfTenant();
|
||||
final Integer clientID = ClientHelper.createClient(this.requestSpec, this.responseSpec, startDate);
|
||||
Assertions.assertNotNull(clientID);
|
||||
final Integer savingsId = createSavingsAccountDailyPosting(clientID, startDate);
|
||||
|
||||
+4
-4
@@ -18,13 +18,13 @@
|
||||
*/
|
||||
package org.apache.fineract.integrationtests;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import org.apache.fineract.client.models.PostSavingsAccountsAccountIdRequest;
|
||||
import org.apache.fineract.client.models.PostSavingsAccountsAccountIdResponse;
|
||||
import org.apache.fineract.client.models.PostSavingsAccountsRequest;
|
||||
import org.apache.fineract.client.models.PostSavingsAccountsResponse;
|
||||
import org.apache.fineract.integrationtests.client.IntegrationTest;
|
||||
import org.apache.fineract.integrationtests.common.Utils;
|
||||
import org.junit.jupiter.api.Order;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.slf4j.Logger;
|
||||
@@ -42,8 +42,8 @@ public class SavingsAccountsTest extends IntegrationTest {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(SavingsAccountsTest.class);
|
||||
private final String dateFormat = "dd MMMM yyyy";
|
||||
private final String locale = "en";
|
||||
private final SimpleDateFormat simpleDateFormat = new SimpleDateFormat(dateFormat);
|
||||
private final String formattedDate = simpleDateFormat.format(new Date());
|
||||
private final DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern(dateFormat);
|
||||
private final String formattedDate = dateFormatter.format(Utils.getLocalDateOfTenant());
|
||||
private int savingId = 1;
|
||||
|
||||
@Test
|
||||
|
||||
+3
-3
@@ -27,13 +27,13 @@ import io.restassured.http.ContentType;
|
||||
import io.restassured.specification.RequestSpecification;
|
||||
import io.restassured.specification.ResponseSpecification;
|
||||
import java.time.LocalDate;
|
||||
import java.time.ZoneId;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType;
|
||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||
import org.apache.fineract.integrationtests.common.BusinessDateHelper;
|
||||
import org.apache.fineract.integrationtests.common.ClientHelper;
|
||||
import org.apache.fineract.integrationtests.common.CommonConstants;
|
||||
@@ -72,7 +72,7 @@ public class SavingsInterestPostingIntegrationTest {
|
||||
|
||||
@Test
|
||||
public void testSavingsDailyInterestPosting() {
|
||||
LocalDate today = LocalDate.now(ZoneId.systemDefault());
|
||||
LocalDate today = Utils.getLocalDateOfTenant();
|
||||
try {
|
||||
GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec, responseSpec, true);
|
||||
BusinessDateHelper.updateBusinessDate(requestSpec, responseSpec, BusinessDateType.BUSINESS_DATE, today);
|
||||
@@ -100,7 +100,7 @@ public class SavingsInterestPostingIntegrationTest {
|
||||
List<Integer> submittedOnDateStringList = (List<Integer>) interestPostingTransaction.get("submittedOnDate");
|
||||
LocalDate submittedOnDate = submittedOnDateStringList.stream().collect(
|
||||
Collectors.collectingAndThen(Collectors.toList(), list -> LocalDate.of(list.get(0), list.get(1), list.get(2))));
|
||||
assertTrue(submittedOnDate.compareTo(today) == 0, "Submitted On Date check for Interest Posting transaction");
|
||||
assertTrue(DateUtils.isEqual(submittedOnDate, today), "Submitted On Date check for Interest Posting transaction");
|
||||
} finally {
|
||||
GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec, responseSpec, false);
|
||||
}
|
||||
|
||||
+4
-6
@@ -27,13 +27,13 @@ import io.restassured.http.ContentType;
|
||||
import io.restassured.specification.RequestSpecification;
|
||||
import io.restassured.specification.ResponseSpecification;
|
||||
import java.time.LocalDate;
|
||||
import java.time.ZoneId;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType;
|
||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||
import org.apache.fineract.integrationtests.common.BusinessDateHelper;
|
||||
import org.apache.fineract.integrationtests.common.ClientHelper;
|
||||
import org.apache.fineract.integrationtests.common.CommonConstants;
|
||||
@@ -149,7 +149,7 @@ public class SavingsInterestPostingJobIntegrationTest {
|
||||
|
||||
@Test
|
||||
public void testSavingsDailyInterestPostingJob() {
|
||||
LocalDate today = LocalDate.now(ZoneId.systemDefault());
|
||||
LocalDate today = Utils.getLocalDateOfTenant();
|
||||
try {
|
||||
GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec, responseSpec, true);
|
||||
BusinessDateHelper.updateBusinessDate(requestSpec, responseSpec, BusinessDateType.BUSINESS_DATE, today);
|
||||
@@ -179,7 +179,7 @@ public class SavingsInterestPostingJobIntegrationTest {
|
||||
List<Integer> submittedOnDateStringList = (List<Integer>) interestPostingTransaction.get("submittedOnDate");
|
||||
LocalDate submittedOnDate = submittedOnDateStringList.stream().collect(
|
||||
Collectors.collectingAndThen(Collectors.toList(), list -> LocalDate.of(list.get(0), list.get(1), list.get(2))));
|
||||
assertTrue(submittedOnDate.compareTo(today) == 0, "Submitted On Date check for Interest Posting transaction");
|
||||
assertTrue(DateUtils.isEqual(submittedOnDate, today), "Submitted On Date check for Interest Posting transaction");
|
||||
} finally {
|
||||
GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec, responseSpec, false);
|
||||
}
|
||||
@@ -198,9 +198,7 @@ public class SavingsInterestPostingJobIntegrationTest {
|
||||
|
||||
this.savingsAccountHelper.withdrawalFromSavingsAccount(savingsId, "10000", startDate, CommonConstants.RESPONSE_RESOURCE_ID);
|
||||
|
||||
/***
|
||||
* Runs Post interest posting job and verify the new account created with Overdraft is posting negative interest
|
||||
*/
|
||||
// Runs Post interest posting job and verify the new account created with Overdraft is posting negative interest
|
||||
this.scheduleJobHelper.executeAndAwaitJob(jobName);
|
||||
Object transactionObj = this.savingsAccountHelper.getSavingsDetails(savingsId, "transactions");
|
||||
ArrayList<HashMap<String, Object>> transactions = (ArrayList<HashMap<String, Object>>) transactionObj;
|
||||
|
||||
+1
-2
@@ -37,7 +37,6 @@ import java.text.SimpleDateFormat;
|
||||
import java.time.Duration;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.format.DateTimeFormatterBuilder;
|
||||
@@ -179,7 +178,7 @@ public class SchedulerJobsTestResults {
|
||||
ArrayList<Integer> annualFeeDueDateAsArrayList = (ArrayList<Integer>) annualFeeDetails.get("dueDate");
|
||||
LocalDate nextDueDateForAnnualFee = LocalDate.of(annualFeeDueDateAsArrayList.get(0), annualFeeDueDateAsArrayList.get(1),
|
||||
annualFeeDueDateAsArrayList.get(2));
|
||||
LocalDate todaysDate = LocalDate.now(ZoneId.of("Asia/Kolkata"));
|
||||
LocalDate todaysDate = Utils.getLocalDateOfTenant();
|
||||
|
||||
Truth.assertWithMessage("Verifying that all due Annual Fees have been paid").that(nextDueDateForAnnualFee)
|
||||
.isGreaterThan(todaysDate);
|
||||
|
||||
+14
@@ -42,7 +42,9 @@ import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.OffsetDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZoneOffset;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.format.DateTimeFormatterBuilder;
|
||||
import java.time.temporal.ChronoField;
|
||||
@@ -374,6 +376,14 @@ public final class Utils {
|
||||
return dateFormat.format(dateToBeConvert.getTime());
|
||||
}
|
||||
|
||||
public static OffsetDateTime getAuditOffsetDateTime() {
|
||||
return OffsetDateTime.now(ZoneOffset.UTC);
|
||||
}
|
||||
|
||||
public static LocalDateTime getLocalDateTimeOfSystem() {
|
||||
return LocalDateTime.now(ZoneId.systemDefault());
|
||||
}
|
||||
|
||||
public static TimeZone getTimeZoneOfTenant() {
|
||||
return TimeZone.getTimeZone(TENANT_TIME_ZONE);
|
||||
}
|
||||
@@ -386,6 +396,10 @@ public final class Utils {
|
||||
return LocalDate.now(getZoneIdOfTenant());
|
||||
}
|
||||
|
||||
public static LocalDateTime getLocalDateTimeOfTenant() {
|
||||
return LocalDateTime.now(getZoneIdOfTenant());
|
||||
}
|
||||
|
||||
public static Date convertJsonElementAsDate(JsonElement jsonElement) {
|
||||
if (jsonElement.isJsonArray()) {
|
||||
JsonArray jsonArray = jsonElement.getAsJsonArray();
|
||||
|
||||
+2
-3
@@ -25,7 +25,6 @@ import com.google.gson.Gson;
|
||||
import io.restassured.path.json.JsonPath;
|
||||
import io.restassured.specification.RequestSpecification;
|
||||
import io.restassured.specification.ResponseSpecification;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
@@ -108,7 +107,7 @@ public class CampaignsHelper {
|
||||
map.put("triggerType", triggerType);
|
||||
if (2 == triggerType) {
|
||||
map.put("recurrenceStartDate",
|
||||
LocalDateTime.now(Utils.getZoneIdOfTenant()).plusMinutes(1).format(DateTimeFormatter.ofPattern(DATE_TIME_FORMAT)));
|
||||
Utils.getLocalDateTimeOfTenant().plusMinutes(1).format(DateTimeFormatter.ofPattern(DATE_TIME_FORMAT)));
|
||||
map.put("frequency", 1);
|
||||
map.put("interval", "1");
|
||||
}
|
||||
@@ -136,7 +135,7 @@ public class CampaignsHelper {
|
||||
map.put("triggerType", triggerType);
|
||||
if (2 == triggerType) {
|
||||
map.put("recurrenceStartDate",
|
||||
LocalDateTime.now(Utils.getZoneIdOfTenant()).plusMinutes(1).format(DateTimeFormatter.ofPattern(DATE_TIME_FORMAT)));
|
||||
Utils.getLocalDateTimeOfTenant().plusMinutes(1).format(DateTimeFormatter.ofPattern(DATE_TIME_FORMAT)));
|
||||
}
|
||||
map.put("campaignName", Utils.randomStringGenerator("Campaign_Name_", 5));
|
||||
map.put("campaignType", 1);
|
||||
|
||||
Reference in New Issue
Block a user