FINERACT-1983: Date handling improvements - general
This commit is contained in:
+3
-4
@@ -66,15 +66,14 @@ public class GLClosureWritePlatformServiceJpaRepositoryImpl implements GLClosure
|
||||
final Office office = this.officeRepositoryWrapper.findOneWithNotFoundDetection(officeId);
|
||||
// TODO: Get Tenant specific date
|
||||
// ensure closure date is not in the future
|
||||
final LocalDate todaysDate = DateUtils.getBusinessLocalDate();
|
||||
final LocalDate closureDate = command.localDateValueOfParameterNamed(GLClosureJsonInputParams.CLOSING_DATE.getValue());
|
||||
if (closureDate.isAfter(todaysDate)) {
|
||||
if (DateUtils.isDateInTheFuture(closureDate)) {
|
||||
throw new GLClosureInvalidException(GlClosureInvalidReason.FUTURE_DATE, closureDate);
|
||||
}
|
||||
// shouldn't be before an existing accounting closure
|
||||
final GLClosure latestGLClosure = this.glClosureRepository.getLatestGLClosureByBranch(officeId);
|
||||
if (latestGLClosure != null) {
|
||||
if (latestGLClosure.getClosingDate().isAfter(closureDate)) {
|
||||
if (DateUtils.isAfter(latestGLClosure.getClosingDate(), closureDate)) {
|
||||
throw new GLClosureInvalidException(GlClosureInvalidReason.ACCOUNTING_CLOSED, latestGLClosure.getClosingDate());
|
||||
}
|
||||
}
|
||||
@@ -122,7 +121,7 @@ public class GLClosureWritePlatformServiceJpaRepositoryImpl implements GLClosure
|
||||
**/
|
||||
final LocalDate closureDate = glClosure.getClosingDate();
|
||||
final GLClosure latestGLClosure = this.glClosureRepository.getLatestGLClosureByBranch(glClosure.getOffice().getId());
|
||||
if (latestGLClosure.getClosingDate().isAfter(closureDate)) {
|
||||
if (DateUtils.isAfter(latestGLClosure.getClosingDate(), closureDate)) {
|
||||
throw new GLClosureInvalidDeleteException(latestGLClosure.getOffice().getId(), latestGLClosure.getOffice().getName(),
|
||||
latestGLClosure.getClosingDate());
|
||||
}
|
||||
|
||||
+3
-3
@@ -30,6 +30,7 @@ import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import lombok.experimental.Accessors;
|
||||
import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom;
|
||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||
|
||||
@Entity
|
||||
@Table(name = "m_trial_balance")
|
||||
@@ -70,9 +71,8 @@ public class TrialBalance extends AbstractPersistableCustom {
|
||||
}
|
||||
TrialBalance other = (TrialBalance) obj;
|
||||
return Objects.equals(other.officeId, officeId) && Objects.equals(other.glAccountId, glAccountId)
|
||||
&& Objects.equals(other.amount, amount) && other.entryDate.compareTo(entryDate) == 0 ? Boolean.TRUE
|
||||
: Boolean.FALSE && other.transactionDate.compareTo(transactionDate) == 0 ? Boolean.TRUE
|
||||
: Boolean.FALSE && Objects.equals(other.closingBalance, closingBalance);
|
||||
&& Objects.equals(other.amount, amount) && DateUtils.isEqual(other.entryDate, entryDate)
|
||||
&& DateUtils.isEqual(other.transactionDate, transactionDate) && Objects.equals(other.closingBalance, closingBalance);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -133,7 +133,7 @@ public class CommandSource extends AbstractPersistableCustom {
|
||||
this.subResourceId = subResourceId;
|
||||
this.commandAsJson = commandSerializedAsJson;
|
||||
this.maker = maker;
|
||||
this.madeOnDate = DateUtils.getOffsetDateTimeOfTenantWithMostPrecision();
|
||||
this.madeOnDate = DateUtils.getAuditOffsetDateTime();
|
||||
this.status = status;
|
||||
this.idempotencyKey = idempotencyKey;
|
||||
}
|
||||
@@ -314,13 +314,13 @@ public class CommandSource extends AbstractPersistableCustom {
|
||||
|
||||
public void markAsChecked(final AppUser checker) {
|
||||
this.checker = checker;
|
||||
this.checkedOnDate = DateUtils.getOffsetDateTimeOfTenantWithMostPrecision();
|
||||
this.checkedOnDate = DateUtils.getAuditOffsetDateTime();
|
||||
this.status = CommandProcessingResultType.PROCESSED.getValue();
|
||||
}
|
||||
|
||||
public void markAsRejected(final AppUser checker) {
|
||||
this.checker = checker;
|
||||
this.checkedOnDate = DateUtils.getOffsetDateTimeOfTenantWithMostPrecision();
|
||||
this.checkedOnDate = DateUtils.getAuditOffsetDateTime();
|
||||
this.status = CommandProcessingResultType.REJECTED.getValue();
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -43,7 +43,7 @@ public class PurgeProcessedCommandsTasklet implements Tasklet {
|
||||
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) {
|
||||
try {
|
||||
Long numberOfDaysForPurgeCriteria = configurationDomainService.retrieveProcessedCommandsPurgeDaysCriteria();
|
||||
OffsetDateTime dateForPurgeCriteria = DateUtils.getOffsetDateTimeOfTenant().minusDays(numberOfDaysForPurgeCriteria);
|
||||
OffsetDateTime dateForPurgeCriteria = DateUtils.getAuditOffsetDateTime().minusDays(numberOfDaysForPurgeCriteria);
|
||||
repository.deleteOlderEventsWithStatus(CommandProcessingResultType.PROCESSED.getValue(), dateForPurgeCriteria);
|
||||
} catch (Exception e) {
|
||||
log.error("Error occurred while purging processed commands: ", e);
|
||||
|
||||
+1
-4
@@ -19,7 +19,6 @@
|
||||
package org.apache.fineract.infrastructure.businessdate.service;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.ZoneId;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
@@ -70,8 +69,7 @@ public class BusinessDateReadPlatformServiceImpl implements BusinessDateReadPlat
|
||||
@Override
|
||||
public HashMap<BusinessDateType, LocalDate> getBusinessDates() {
|
||||
HashMap<BusinessDateType, LocalDate> businessDateMap = new HashMap<>();
|
||||
ZoneId zone = DateUtils.getDateTimeZoneOfTenant();
|
||||
LocalDate tenantDate = LocalDate.now(zone);
|
||||
LocalDate tenantDate = DateUtils.getLocalDateOfTenant();
|
||||
businessDateMap.put(BusinessDateType.BUSINESS_DATE, tenantDate);
|
||||
businessDateMap.put(BusinessDateType.COB_DATE, tenantDate);
|
||||
if (configurationDomainService.isBusinessDateEnabled()) {
|
||||
@@ -80,7 +78,6 @@ public class BusinessDateReadPlatformServiceImpl implements BusinessDateReadPlat
|
||||
businessDateMap.put(BusinessDateType.valueOf(businessDateData.getType()), businessDateData.getDate());
|
||||
}
|
||||
}
|
||||
|
||||
return businessDateMap;
|
||||
}
|
||||
}
|
||||
|
||||
+1
-5
@@ -132,15 +132,11 @@ public class BusinessDateWritePlatformServiceImpl implements BusinessDateWritePl
|
||||
private void updateBusinessDate(BusinessDate businessDate, LocalDate newDate, Map<String, Object> changes) {
|
||||
LocalDate oldDate = businessDate.getDate();
|
||||
|
||||
if (!hasChange(oldDate, newDate)) {
|
||||
if (DateUtils.isEqual(oldDate, newDate)) {
|
||||
return;
|
||||
}
|
||||
businessDate.setDate(newDate);
|
||||
repository.save(businessDate);
|
||||
changes.put(businessDate.getType().name(), newDate);
|
||||
}
|
||||
|
||||
private boolean hasChange(@NotNull LocalDate oldDate, @NotNull LocalDate date) {
|
||||
return (date.isBefore(oldDate) || date.isAfter(oldDate));
|
||||
}
|
||||
}
|
||||
|
||||
+5
-4
@@ -32,6 +32,7 @@ import net.fortuna.ical4j.model.property.RRule;
|
||||
import net.fortuna.ical4j.validate.ValidationException;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException;
|
||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||
import org.quartz.CronExpression;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
@@ -1045,7 +1046,7 @@ public class DataValidatorBuilder {
|
||||
|
||||
if (this.value != null && date != null) {
|
||||
final LocalDate dateVal = (LocalDate) this.value;
|
||||
if (date.isAfter(dateVal)) {
|
||||
if (DateUtils.isAfter(date, dateVal)) {
|
||||
final StringBuilder validationErrorCode = new StringBuilder("validation.msg.").append(this.resource).append(".")
|
||||
.append(this.parameter).append(".is.less.than.date");
|
||||
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter `").append(this.parameter)
|
||||
@@ -1065,7 +1066,7 @@ public class DataValidatorBuilder {
|
||||
|
||||
if (this.value != null && date != null) {
|
||||
final LocalDate dateVal = (LocalDate) this.value;
|
||||
if (date.isBefore(dateVal)) {
|
||||
if (DateUtils.isBefore(date, dateVal)) {
|
||||
final StringBuilder validationErrorCode = new StringBuilder("validation.msg.").append(this.resource).append(".")
|
||||
.append(this.parameter).append(".is.greater.than.date");
|
||||
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter `").append(this.parameter)
|
||||
@@ -1085,7 +1086,7 @@ public class DataValidatorBuilder {
|
||||
|
||||
if (this.value != null && date != null) {
|
||||
final LocalDate dateVal = (LocalDate) this.value;
|
||||
if (dateVal.isAfter(date)) {
|
||||
if (DateUtils.isAfter(dateVal, date)) {
|
||||
final StringBuilder validationErrorCode = new StringBuilder("validation.msg.").append(this.resource).append(".")
|
||||
.append(this.parameter).append(".is.greater.than.date");
|
||||
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter `").append(this.parameter)
|
||||
@@ -1105,7 +1106,7 @@ public class DataValidatorBuilder {
|
||||
|
||||
if (this.value != null && date != null) {
|
||||
final LocalDate dateVal = (LocalDate) this.value;
|
||||
if (!dateVal.isEqual(date)) {
|
||||
if (!DateUtils.isEqual(dateVal, date)) {
|
||||
final StringBuilder validationErrorCode = new StringBuilder("validation.msg.").append(this.resource).append(".")
|
||||
.append(this.parameter).append(".is.not.equal.to.date");
|
||||
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter `").append(this.parameter)
|
||||
|
||||
+3
-2
@@ -22,6 +22,7 @@ import java.time.LocalDate;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||
|
||||
public class LocalDateInterval {
|
||||
|
||||
@@ -66,11 +67,11 @@ public class LocalDateInterval {
|
||||
}
|
||||
|
||||
private boolean isBetweenInclusive(final LocalDate start, final LocalDate end, final LocalDate target) {
|
||||
return !target.isBefore(start) && !target.isAfter(end);
|
||||
return !DateUtils.isBefore(target, start) && !DateUtils.isAfter(target, end);
|
||||
}
|
||||
|
||||
public boolean fallsBefore(final LocalDate dateToCheck) {
|
||||
return this.endDate.isBefore(dateToCheck);
|
||||
return DateUtils.isBefore(this.endDate, dateToCheck);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
-4
@@ -70,10 +70,6 @@ public final class DateUtils {
|
||||
return truncate == null ? now : now.truncatedTo(truncate);
|
||||
}
|
||||
|
||||
public static OffsetDateTime getOffsetDateTimeOfTenantWithMostPrecision() {
|
||||
return getOffsetDateTimeOfTenant(null);
|
||||
}
|
||||
|
||||
public static OffsetDateTime getOffsetDateTimeOfTenant() {
|
||||
return getOffsetDateTimeOfTenant(null);
|
||||
}
|
||||
|
||||
+2
-1
@@ -20,6 +20,7 @@ package org.apache.fineract.infrastructure.core.service.database;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import java.io.Serializable;
|
||||
import java.sql.JDBCType;
|
||||
import org.apache.fineract.infrastructure.core.exception.PlatformServiceUnavailableException;
|
||||
|
||||
@@ -272,7 +273,7 @@ public enum JdbcJavaType {
|
||||
}
|
||||
|
||||
@com.google.errorprone.annotations.Immutable
|
||||
private static final class DialectType {
|
||||
private static final class DialectType implements Serializable {
|
||||
|
||||
@NotNull
|
||||
private final JDBCType jdbcType;
|
||||
|
||||
+1
-1
@@ -99,7 +99,7 @@ public class SendAsynchronousEventsTasklet implements Tasklet {
|
||||
}
|
||||
|
||||
private void markEventsAsSent(List<Long> eventIds) {
|
||||
OffsetDateTime sentAt = DateUtils.getOffsetDateTimeOfTenantWithMostPrecision();
|
||||
OffsetDateTime sentAt = DateUtils.getAuditOffsetDateTime();
|
||||
|
||||
// Partitioning dataset to avoid exception: PreparedStatement can have at most 65,535 parameters
|
||||
List<List<Long>> partitions = Lists.partition(eventIds, 5_000);
|
||||
|
||||
+1
-1
@@ -80,7 +80,7 @@ public class ExternalEvent extends AbstractPersistableCustom {
|
||||
this.data = data;
|
||||
this.idempotencyKey = idempotencyKey;
|
||||
this.aggregateRootId = aggregateRootId;
|
||||
this.createdAt = DateUtils.getOffsetDateTimeOfTenantWithMostPrecision();
|
||||
this.createdAt = DateUtils.getAuditOffsetDateTime();
|
||||
this.status = ExternalEventStatus.TO_BE_SENT;
|
||||
this.businessDate = DateUtils.getBusinessLocalDate();
|
||||
}
|
||||
|
||||
+11
-28
@@ -20,6 +20,7 @@ package org.apache.fineract.organisation.holiday.service;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||
import org.apache.fineract.organisation.holiday.domain.Holiday;
|
||||
import org.apache.fineract.organisation.workingdays.data.AdjustedDateDetailsDTO;
|
||||
|
||||
@@ -30,47 +31,29 @@ public final class HolidayUtil {
|
||||
}
|
||||
|
||||
public static LocalDate getRepaymentRescheduleDateToIfHoliday(LocalDate repaymentDate, final List<Holiday> holidays) {
|
||||
|
||||
for (final Holiday holiday : holidays) {
|
||||
if (repaymentDate.equals(holiday.getFromDate()) || repaymentDate.equals(holiday.getToDate())
|
||||
|| (repaymentDate.isAfter(holiday.getFromDate()) && repaymentDate.isBefore(holiday.getToDate()))) {
|
||||
repaymentDate = getRepaymentRescheduleDateIfHoliday(repaymentDate, holidays);
|
||||
}
|
||||
}
|
||||
return repaymentDate;
|
||||
}
|
||||
|
||||
private static LocalDate getRepaymentRescheduleDateIfHoliday(final LocalDate repaymentDate, final List<Holiday> holidays) {
|
||||
|
||||
for (final Holiday holiday : holidays) {
|
||||
if (repaymentDate.equals(holiday.getFromDate()) || repaymentDate.equals(holiday.getToDate())
|
||||
|| (repaymentDate.isAfter(holiday.getFromDate()) && repaymentDate.isBefore(holiday.getToDate()))) {
|
||||
// should be take from holiday
|
||||
return holiday.getRepaymentsRescheduledTo();
|
||||
if (isHoliday(repaymentDate, holiday)) {
|
||||
repaymentDate = holiday.getRepaymentsRescheduledTo();
|
||||
}
|
||||
}
|
||||
return repaymentDate;
|
||||
}
|
||||
|
||||
public static boolean isHoliday(final LocalDate date, final List<Holiday> holidays) {
|
||||
for (final Holiday holiday : holidays) {
|
||||
if (date.isEqual(holiday.getFromDate()) || date.isEqual(holiday.getToDate())
|
||||
|| (date.isAfter(holiday.getFromDate()) && date.isBefore(holiday.getToDate()))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return getApplicableHoliday(date, holidays) != null;
|
||||
}
|
||||
|
||||
public static Holiday getApplicableHoliday(final LocalDate repaymentDate, final List<Holiday> holidays) {
|
||||
Holiday referedHoliday = null;
|
||||
for (final Holiday holiday : holidays) {
|
||||
if (!repaymentDate.isBefore(holiday.getFromDate()) && !repaymentDate.isAfter(holiday.getToDate())) {
|
||||
referedHoliday = holiday;
|
||||
if (isHoliday(repaymentDate, holiday)) {
|
||||
return holiday;
|
||||
}
|
||||
}
|
||||
return referedHoliday;
|
||||
return null;
|
||||
}
|
||||
|
||||
public static boolean isHoliday(LocalDate date, Holiday holiday) {
|
||||
return !DateUtils.isBefore(date, holiday.getFromDate()) && !DateUtils.isAfter(date, holiday.getToDate());
|
||||
}
|
||||
|
||||
public static void updateRepaymentRescheduleDateToWorkingDayIfItIsHoliday(final AdjustedDateDetailsDTO adjustedDateDetailsDTO,
|
||||
|
||||
+4
-3
@@ -39,6 +39,7 @@ import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||
import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom;
|
||||
import org.apache.fineract.infrastructure.core.domain.ExternalId;
|
||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||
import org.apache.fineract.infrastructure.core.service.ExternalIdFactory;
|
||||
import org.apache.fineract.organisation.office.exception.CannotUpdateOfficeWithParentOfficeSameAsSelf;
|
||||
import org.apache.fineract.organisation.office.exception.RootOfficeParentCannotBeUpdated;
|
||||
@@ -155,11 +156,11 @@ public class Office extends AbstractPersistableCustom implements Serializable {
|
||||
}
|
||||
|
||||
public boolean isOpeningDateBefore(final LocalDate baseDate) {
|
||||
return getOpeningLocalDate().isBefore(baseDate);
|
||||
return DateUtils.isBefore(getOpeningLocalDate(), baseDate);
|
||||
}
|
||||
|
||||
public boolean isOpeningDateAfter(final LocalDate activationLocalDate) {
|
||||
return getOpeningLocalDate().isAfter(activationLocalDate);
|
||||
public boolean isOpeningDateAfter(final LocalDate baseDate) {
|
||||
return DateUtils.isAfter(getOpeningLocalDate(), baseDate);
|
||||
}
|
||||
|
||||
public LocalDate getOpeningLocalDate() {
|
||||
|
||||
+3
-3
@@ -28,6 +28,7 @@ import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.Accessors;
|
||||
import org.apache.fineract.infrastructure.core.data.EnumOptionData;
|
||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||
import org.apache.fineract.portfolio.calendar.domain.CalendarFrequencyType;
|
||||
import org.apache.fineract.portfolio.calendar.domain.CalendarRemindBy;
|
||||
import org.apache.fineract.portfolio.calendar.domain.CalendarType;
|
||||
@@ -377,12 +378,11 @@ public final class CalendarData implements Serializable {
|
||||
}
|
||||
|
||||
public boolean isStartDateBeforeOrEqual(final LocalDate compareDate) {
|
||||
return this.startDate != null && compareDate != null
|
||||
&& (this.startDate.isBefore(compareDate) || this.startDate.equals(compareDate));
|
||||
return this.startDate != null && compareDate != null && !DateUtils.isAfter(this.startDate, compareDate);
|
||||
}
|
||||
|
||||
public boolean isEndDateAfterOrEqual(final LocalDate compareDate) {
|
||||
return this.endDate != null && compareDate != null && (this.endDate.isAfter(compareDate) || this.endDate.isEqual(compareDate));
|
||||
return this.endDate != null && compareDate != null && !DateUtils.isBefore(this.endDate, compareDate);
|
||||
}
|
||||
|
||||
public boolean isBetweenStartAndEndDate(final LocalDate compareDate) {
|
||||
|
||||
+4
-4
@@ -20,10 +20,10 @@ package org.apache.fineract.portfolio.calendar.data;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||
import org.apache.fineract.portfolio.calendar.domain.CalendarHistory;
|
||||
|
||||
public class CalendarHistoryDataWrapper {
|
||||
@@ -37,16 +37,16 @@ public class CalendarHistoryDataWrapper {
|
||||
|
||||
@Override
|
||||
public int compare(CalendarHistory calendarHistory1, CalendarHistory calendarHistory2) {
|
||||
return calendarHistory1.getEndDateLocalDate().compareTo(calendarHistory2.getEndDateLocalDate());
|
||||
return DateUtils.compare(calendarHistory1.getEndDate(), calendarHistory2.getEndDate());
|
||||
}
|
||||
};
|
||||
Collections.sort(this.calendarHistoryList, orderByDate);
|
||||
this.calendarHistoryList.sort(orderByDate);
|
||||
}
|
||||
|
||||
public CalendarHistory getCalendarHistory(final LocalDate dueRepaymentPeriodDate) {
|
||||
CalendarHistory calendarHistory = null;
|
||||
for (CalendarHistory history : this.calendarHistoryList) {
|
||||
if (history.getEndDateLocalDate().isAfter(dueRepaymentPeriodDate)) {
|
||||
if (DateUtils.isAfter(history.getEndDate(), dueRepaymentPeriodDate)) {
|
||||
calendarHistory = history;
|
||||
break;
|
||||
}
|
||||
|
||||
+9
-29
@@ -175,23 +175,19 @@ public class Calendar extends AbstractAuditableWithUTCDateTimeCustom {
|
||||
}
|
||||
|
||||
public Map<String, Object> updateStartDateAndDerivedFeilds(final LocalDate newMeetingStartDate) {
|
||||
|
||||
final Map<String, Object> actualChanges = new LinkedHashMap<>(9);
|
||||
|
||||
final LocalDate currentDate = DateUtils.getLocalDateOfTenant();
|
||||
|
||||
if (newMeetingStartDate.isBefore(currentDate)) {
|
||||
if (DateUtils.isBefore(newMeetingStartDate, currentDate)) {
|
||||
final String defaultUserMessage = "New meeting effective from date cannot be in past";
|
||||
throw new CalendarDateException("new.start.date.cannot.be.in.past", defaultUserMessage, newMeetingStartDate,
|
||||
getStartDateLocalDate());
|
||||
} else if (isStartDateAfter(newMeetingStartDate) && isStartDateBeforeOrEqual(currentDate)) {
|
||||
// new meeting date should be on or after start date or current
|
||||
// date
|
||||
// new meeting date should be on or after start date or current date
|
||||
final String defaultUserMessage = "New meeting effective from date cannot be a date before existing meeting start date";
|
||||
throw new CalendarDateException("new.start.date.before.existing.date", defaultUserMessage, newMeetingStartDate,
|
||||
getStartDateLocalDate());
|
||||
} else {
|
||||
|
||||
actualChanges.put(CalendarSupportedParameters.START_DATE.getValue(), newMeetingStartDate.toString());
|
||||
this.startDate = newMeetingStartDate;
|
||||
|
||||
@@ -200,33 +196,25 @@ public class Calendar extends AbstractAuditableWithUTCDateTimeCustom {
|
||||
* recurring day and update it if it is changed. For weekly type is weekday and for monthly type it is day
|
||||
* of the month
|
||||
*/
|
||||
|
||||
CalendarFrequencyType calendarFrequencyType = CalendarUtils.getFrequency(this.recurrence);
|
||||
Integer interval = CalendarUtils.getInterval(this.recurrence);
|
||||
Integer repeatsOnDay = null;
|
||||
|
||||
/*
|
||||
* Repeats on day, need to derive based on the start date
|
||||
*/
|
||||
|
||||
// Repeats on day, need to derive based on the start date
|
||||
if (calendarFrequencyType.isWeekly()) {
|
||||
repeatsOnDay = newMeetingStartDate.get(ChronoField.DAY_OF_WEEK);
|
||||
} else if (calendarFrequencyType.isMonthly()) {
|
||||
repeatsOnDay = newMeetingStartDate.getDayOfMonth();
|
||||
}
|
||||
|
||||
// TODO cover other recurrence also
|
||||
|
||||
this.recurrence = constructRecurrence(calendarFrequencyType, interval, repeatsOnDay, null);
|
||||
|
||||
}
|
||||
|
||||
return actualChanges;
|
||||
|
||||
}
|
||||
|
||||
public Map<String, Object> update(final JsonCommand command, final Boolean areActiveEntitiesSynced) {
|
||||
|
||||
final Map<String, Object> actualChanges = new LinkedHashMap<>(9);
|
||||
|
||||
if (command.isChangeInStringParameterNamed(CalendarSupportedParameters.TITLE.getValue(), this.title)) {
|
||||
@@ -234,13 +222,11 @@ public class Calendar extends AbstractAuditableWithUTCDateTimeCustom {
|
||||
actualChanges.put(CalendarSupportedParameters.TITLE.getValue(), newValue);
|
||||
this.title = StringUtils.defaultIfEmpty(newValue, null);
|
||||
}
|
||||
|
||||
if (command.isChangeInStringParameterNamed(CalendarSupportedParameters.DESCRIPTION.getValue(), this.description)) {
|
||||
final String newValue = command.stringValueOfParameterNamed(CalendarSupportedParameters.DESCRIPTION.getValue());
|
||||
actualChanges.put(CalendarSupportedParameters.DESCRIPTION.getValue(), newValue);
|
||||
this.description = StringUtils.defaultIfEmpty(newValue, null);
|
||||
}
|
||||
|
||||
if (command.isChangeInStringParameterNamed(CalendarSupportedParameters.LOCATION.getValue(), this.location)) {
|
||||
final String newValue = command.stringValueOfParameterNamed(CalendarSupportedParameters.LOCATION.getValue());
|
||||
actualChanges.put(CalendarSupportedParameters.LOCATION.getValue(), newValue);
|
||||
@@ -251,12 +237,11 @@ public class Calendar extends AbstractAuditableWithUTCDateTimeCustom {
|
||||
final String localeAsInput = command.locale();
|
||||
final String startDateParamName = CalendarSupportedParameters.START_DATE.getValue();
|
||||
if (command.isChangeInLocalDateParameterNamed(startDateParamName, getStartDateLocalDate())) {
|
||||
|
||||
final String valueAsInput = command.stringValueOfParameterNamed(startDateParamName);
|
||||
final LocalDate newValue = command.localDateValueOfParameterNamed(startDateParamName);
|
||||
final LocalDate currentDate = DateUtils.getLocalDateOfTenant();
|
||||
|
||||
if (newValue.isBefore(currentDate)) {
|
||||
if (DateUtils.isBefore(newValue, currentDate)) {
|
||||
final String defaultUserMessage = "New meeting effective from date cannot be in past";
|
||||
throw new CalendarDateException("new.start.date.cannot.be.in.past", defaultUserMessage, newValue, getStartDateLocalDate());
|
||||
} else if (isStartDateAfter(newValue) && isStartDateBeforeOrEqual(currentDate)) {
|
||||
@@ -472,24 +457,19 @@ public class Calendar extends AbstractAuditableWithUTCDateTimeCustom {
|
||||
}
|
||||
|
||||
public boolean isStartDateBefore(final LocalDate compareDate) {
|
||||
if (this.startDate != null && compareDate != null && getStartDateLocalDate().isBefore(compareDate)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return startDate != null && DateUtils.isBefore(startDate, compareDate);
|
||||
}
|
||||
|
||||
public boolean isStartDateBeforeOrEqual(final LocalDate compareDate) {
|
||||
return this.startDate != null && compareDate != null
|
||||
&& (getStartDateLocalDate().isBefore(compareDate) || getStartDateLocalDate().equals(compareDate));
|
||||
return startDate != null && !DateUtils.isAfter(startDate, compareDate);
|
||||
}
|
||||
|
||||
public boolean isStartDateAfter(final LocalDate compareDate) {
|
||||
return this.startDate != null && compareDate != null && getStartDateLocalDate().isAfter(compareDate);
|
||||
return compareDate != null && DateUtils.isAfter(startDate, compareDate);
|
||||
}
|
||||
|
||||
public boolean isEndDateAfterOrEqual(final LocalDate compareDate) {
|
||||
return this.endDate != null && compareDate != null
|
||||
&& (getEndDateLocalDate().isAfter(compareDate) || getEndDateLocalDate().isEqual(compareDate));
|
||||
return compareDate != null && !DateUtils.isBefore(endDate, compareDate);
|
||||
}
|
||||
|
||||
public boolean isBetweenStartAndEndDate(final LocalDate compareDate) {
|
||||
@@ -585,7 +565,7 @@ public class Calendar extends AbstractAuditableWithUTCDateTimeCustom {
|
||||
// validate with history details.
|
||||
for (CalendarHistory history : history()) {
|
||||
if (history.isBetweenStartAndEndDate(compareDate)) {
|
||||
return CalendarUtils.isValidRedurringDate(history.getRecurrence(), history.getStartDateLocalDate(), compareDate,
|
||||
return CalendarUtils.isValidRedurringDate(history.getRecurrence(), history.getStartDate(), compareDate,
|
||||
isSkipRepaymentOnFirstMonth, numberOfDays);
|
||||
}
|
||||
}
|
||||
|
||||
+24
-25
@@ -88,51 +88,63 @@ public enum CalendarEntityType {
|
||||
}
|
||||
|
||||
public static boolean isGroup(final Integer value) {
|
||||
return CalendarEntityType.GROUPS.value.equals(value) ? true : false;
|
||||
return CalendarEntityType.GROUPS.value.equals(value);
|
||||
}
|
||||
|
||||
public static boolean isGroup(final String name) {
|
||||
return CalendarEntityType.GROUPS.name().equalsIgnoreCase(name) ? true : false;
|
||||
return CalendarEntityType.GROUPS.name().equalsIgnoreCase(name);
|
||||
}
|
||||
|
||||
public static boolean isCenter(final Integer value) {
|
||||
return CalendarEntityType.CENTERS.value.equals(value) ? true : false;
|
||||
return CalendarEntityType.CENTERS.value.equals(value);
|
||||
}
|
||||
|
||||
public static boolean isCenter(final String name) {
|
||||
return CalendarEntityType.CENTERS.name().equalsIgnoreCase(name) ? true : false;
|
||||
return CalendarEntityType.CENTERS.name().equalsIgnoreCase(name);
|
||||
}
|
||||
|
||||
public static boolean isLoan(final Integer value) {
|
||||
return CalendarEntityType.LOANS.value.equals(value) ? true : false;
|
||||
return CalendarEntityType.LOANS.value.equals(value);
|
||||
}
|
||||
|
||||
public static boolean isLoan(final String name) {
|
||||
return CalendarEntityType.LOANS.name().equalsIgnoreCase(name) ? true : false;
|
||||
return CalendarEntityType.LOANS.name().equalsIgnoreCase(name);
|
||||
}
|
||||
|
||||
public static boolean isClient(final Integer value) {
|
||||
return CalendarEntityType.CLIENTS.value.equals(value) ? true : false;
|
||||
return CalendarEntityType.CLIENTS.value.equals(value);
|
||||
}
|
||||
|
||||
public static boolean isClient(final String name) {
|
||||
return CalendarEntityType.CLIENTS.name().equalsIgnoreCase(name) ? true : false;
|
||||
return CalendarEntityType.CLIENTS.name().equalsIgnoreCase(name);
|
||||
}
|
||||
|
||||
public static boolean isSavings(final Integer value) {
|
||||
return CalendarEntityType.SAVINGS.value.equals(value);
|
||||
}
|
||||
|
||||
public static boolean isSavings(final String name) {
|
||||
return CalendarEntityType.SAVINGS.name().equalsIgnoreCase(name);
|
||||
}
|
||||
|
||||
public boolean isCenter() {
|
||||
return this.value.equals(CalendarEntityType.CENTERS.getValue());
|
||||
return this == CENTERS;
|
||||
}
|
||||
|
||||
public boolean isGroup() {
|
||||
return this.value.equals(CalendarEntityType.GROUPS.getValue());
|
||||
return this == GROUPS;
|
||||
}
|
||||
|
||||
public boolean isLoan() {
|
||||
return this.value.equals(CalendarEntityType.LOANS.getValue());
|
||||
return this == LOANS;
|
||||
}
|
||||
|
||||
public boolean isClient() {
|
||||
return this.value.equals(CalendarEntityType.CLIENTS.getValue());
|
||||
return this == CLIENTS;
|
||||
}
|
||||
|
||||
public boolean isSavings() {
|
||||
return this == SAVINGS;
|
||||
}
|
||||
|
||||
private static final Map<String, CalendarEntityType> entityNameToEnumMap = new HashMap<>();
|
||||
@@ -146,17 +158,4 @@ public enum CalendarEntityType {
|
||||
public static CalendarEntityType getEntityType(String entityType) {
|
||||
return entityNameToEnumMap.get(entityType.toLowerCase());
|
||||
}
|
||||
|
||||
public static boolean isSavings(final Integer value) {
|
||||
return CalendarEntityType.SAVINGS.value.equals(value) ? true : false;
|
||||
}
|
||||
|
||||
public static boolean isSavings(final String name) {
|
||||
return CalendarEntityType.SAVINGS.name().equalsIgnoreCase(name) ? true : false;
|
||||
}
|
||||
|
||||
public boolean isSavings() {
|
||||
return this.value.equals(CalendarEntityType.SAVINGS.getValue());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+8
-9
@@ -25,6 +25,7 @@ import jakarta.persistence.ManyToOne;
|
||||
import jakarta.persistence.Table;
|
||||
import java.time.LocalDate;
|
||||
import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom;
|
||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||
|
||||
@Entity
|
||||
@Table(name = "m_calendar_history")
|
||||
@@ -95,26 +96,24 @@ public class CalendarHistory extends AbstractPersistableCustom {
|
||||
return this.recurrence;
|
||||
}
|
||||
|
||||
public LocalDate getStartDateLocalDate() {
|
||||
public LocalDate getStartDate() {
|
||||
return this.startDate;
|
||||
}
|
||||
|
||||
public LocalDate getEndDateLocalDate() {
|
||||
public LocalDate getEndDate() {
|
||||
return this.endDate;
|
||||
}
|
||||
|
||||
public boolean isEndDateAfterOrEqual(final LocalDate compareDate) {
|
||||
return this.endDate != null && compareDate != null
|
||||
&& (getEndDateLocalDate().isAfter(compareDate) || getEndDateLocalDate().isEqual(compareDate));
|
||||
public boolean isStartDateBeforeOrEqual(final LocalDate compareDate) {
|
||||
return this.startDate != null && compareDate != null && !DateUtils.isAfter(this.startDate, compareDate);
|
||||
}
|
||||
|
||||
public boolean isStartDateBeforeOrEqual(final LocalDate compareDate) {
|
||||
return this.startDate != null && compareDate != null
|
||||
&& (getStartDateLocalDate().isBefore(compareDate) || getStartDateLocalDate().equals(compareDate));
|
||||
public boolean isEndDateAfterOrEqual(final LocalDate compareDate) {
|
||||
return this.endDate != null && compareDate != null && !DateUtils.isBefore(this.endDate, compareDate);
|
||||
}
|
||||
|
||||
public boolean isBetweenStartAndEndDate(final LocalDate compareDate) {
|
||||
return isStartDateBeforeOrEqual(compareDate) && (getEndDateLocalDate() == null || isEndDateAfterOrEqual(compareDate));
|
||||
return isStartDateBeforeOrEqual(compareDate) && (getEndDate() == null || isEndDateAfterOrEqual(compareDate));
|
||||
}
|
||||
|
||||
public void updateEndDate(LocalDate historyCalEndDate) {
|
||||
|
||||
+6
-8
@@ -103,14 +103,14 @@ public final class CalendarUtils {
|
||||
final DateTime periodStart = new DateTime(java.util.Date.from(startDate.atZone(ZoneId.systemDefault()).toInstant()));
|
||||
final Date seed = convertToiCal4JCompatibleDate(seedDate);
|
||||
final Date nextRecDate = recur.getNextDate(seed, periodStart);
|
||||
return nextRecDate == null ? null : LocalDateTime.ofInstant(nextRecDate.toInstant(), DateUtils.getSystemZoneId());
|
||||
return nextRecDate == null ? null : LocalDateTime.ofInstant(nextRecDate.toInstant(), DateUtils.getDateTimeZoneOfTenant());
|
||||
}
|
||||
|
||||
private static LocalDate getNextRecurringDate(final Recur recur, final LocalDate seedDate, final LocalDate startDate) {
|
||||
final DateTime periodStart = new DateTime(java.util.Date.from(startDate.atStartOfDay(ZoneId.systemDefault()).toInstant()));
|
||||
final Date seed = convertToiCal4JCompatibleDate(seedDate.atStartOfDay());
|
||||
final Date nextRecDate = recur.getNextDate(seed, periodStart);
|
||||
return nextRecDate == null ? null : LocalDate.ofInstant(nextRecDate.toInstant(), DateUtils.getSystemZoneId());
|
||||
return nextRecDate == null ? null : LocalDate.ofInstant(nextRecDate.toInstant(), DateUtils.getDateTimeZoneOfTenant());
|
||||
}
|
||||
|
||||
private static Date convertToiCal4JCompatibleDate(final LocalDateTime inputDate) {
|
||||
@@ -125,16 +125,16 @@ public final class CalendarUtils {
|
||||
}
|
||||
|
||||
public static Collection<LocalDate> getRecurringDates(final String recurringRule, final LocalDate seedDate, final LocalDate endDate) {
|
||||
|
||||
final LocalDate periodStartDate = DateUtils.getLocalDateOfTenant();
|
||||
final LocalDate periodEndDate = (endDate == null) ? DateUtils.getLocalDateOfTenant().plusYears(5) : endDate;
|
||||
final LocalDate periodEndDate = endDate == null ? periodStartDate.plusYears(5) : endDate;
|
||||
return getRecurringDates(recurringRule, seedDate, periodStartDate, periodEndDate);
|
||||
}
|
||||
|
||||
public static Collection<LocalDate> getRecurringDatesFrom(final String recurringRule, final LocalDate seedDate,
|
||||
final LocalDate startDate) {
|
||||
final LocalDate periodStartDate = (startDate == null) ? DateUtils.getLocalDateOfTenant() : startDate;
|
||||
final LocalDate periodEndDate = DateUtils.getLocalDateOfTenant().plusYears(5);
|
||||
LocalDate currentDate = DateUtils.getLocalDateOfTenant();
|
||||
final LocalDate periodStartDate = startDate == null ? currentDate : startDate;
|
||||
final LocalDate periodEndDate = currentDate.plusYears(5);
|
||||
return getRecurringDates(recurringRule, seedDate, periodStartDate, periodEndDate);
|
||||
}
|
||||
|
||||
@@ -150,7 +150,6 @@ public final class CalendarUtils {
|
||||
public static Collection<LocalDate> getRecurringDates(final String recurringRule, final LocalDate seedDate,
|
||||
final LocalDate periodStartDate, final LocalDate periodEndDate, final int maxCount, boolean isSkippMeetingOnFirstDay,
|
||||
final Integer numberOfDays) {
|
||||
|
||||
final Recur recur = CalendarUtils.getICalRecur(recurringRule);
|
||||
|
||||
return getRecurringDates(recur, seedDate, periodStartDate, periodEndDate, maxCount, isSkippMeetingOnFirstDay, numberOfDays);
|
||||
@@ -173,7 +172,6 @@ public final class CalendarUtils {
|
||||
|
||||
private static Collection<LocalDate> convertToLocalDateList(final DateList dates, final LocalDate seedDate,
|
||||
final PeriodFrequencyType frequencyType, boolean isSkippMeetingOnFirstDay, final Integer numberOfDays) {
|
||||
|
||||
final Collection<LocalDate> recurringDates = new ArrayList<>();
|
||||
|
||||
for (@SuppressWarnings("rawtypes")
|
||||
|
||||
+9
-30
@@ -407,10 +407,6 @@ public class Client extends AbstractAuditableWithUTCDateTimeCustom {
|
||||
return ClientStatus.fromInt(this.status).isPending();
|
||||
}
|
||||
|
||||
private boolean isDateInTheFuture(final LocalDate localDate) {
|
||||
return localDate.isAfter(DateUtils.getBusinessLocalDate());
|
||||
}
|
||||
|
||||
public boolean isRejected() {
|
||||
return ClientStatus.fromInt(this.status).isRejected();
|
||||
}
|
||||
@@ -444,49 +440,40 @@ public class Client extends AbstractAuditableWithUTCDateTimeCustom {
|
||||
}
|
||||
|
||||
private void validateActivationDate(final List<ApiParameterError> dataValidationErrors) {
|
||||
|
||||
if (getSubmittedOnDate() != null && isDateInTheFuture(getSubmittedOnDate())) {
|
||||
|
||||
if (getSubmittedOnDate() != null && DateUtils.isDateInTheFuture(getSubmittedOnDate())) {
|
||||
final String defaultUserMessage = "submitted date cannot be in the future.";
|
||||
final ApiParameterError error = ApiParameterError.parameterError("error.msg.clients.submittedOnDate.in.the.future",
|
||||
defaultUserMessage, ClientApiConstants.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.clients.submittedOnDate.after.activation.date",
|
||||
defaultUserMessage, ClientApiConstants.submittedOnDateParamName, this.submittedOnDate);
|
||||
|
||||
dataValidationErrors.add(error);
|
||||
}
|
||||
|
||||
if (getReopenedDate() != null && getActivationLocalDate() != null && getReopenedDate().isAfter(getActivationLocalDate())) {
|
||||
|
||||
if (getActivationDate() != null && DateUtils.isAfter(getReopenedDate(), getActivationDate())) {
|
||||
final String defaultUserMessage = "reopened date cannot be after the submittedon date";
|
||||
final ApiParameterError error = ApiParameterError.parameterError("error.msg.clients.submittedOnDate.after.reopened.date",
|
||||
defaultUserMessage, ClientApiConstants.reopenedDateParamName, this.reopenedDate);
|
||||
|
||||
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.clients.activationDate.in.the.future",
|
||||
defaultUserMessage, ClientApiConstants.activationDateParamName, getActivationLocalDate());
|
||||
defaultUserMessage, ClientApiConstants.activationDateParamName, getActivationDate());
|
||||
|
||||
dataValidationErrors.add(error);
|
||||
}
|
||||
|
||||
if (getActivationLocalDate() != null) {
|
||||
if (this.office.isOpeningDateAfter(getActivationLocalDate())) {
|
||||
if (getActivationDate() != null) {
|
||||
if (this.office.isOpeningDateAfter(getActivationDate())) {
|
||||
final String defaultUserMessage = "Client activation date cannot be a date before the office opening date.";
|
||||
final ApiParameterError error = ApiParameterError.parameterError(
|
||||
"error.msg.clients.activationDate.cannot.be.before.office.activation.date", defaultUserMessage,
|
||||
ClientApiConstants.activationDateParamName, getActivationLocalDate());
|
||||
ClientApiConstants.activationDateParamName, getActivationDate());
|
||||
dataValidationErrors.add(error);
|
||||
}
|
||||
}
|
||||
@@ -518,14 +505,6 @@ public class Client extends AbstractAuditableWithUTCDateTimeCustom {
|
||||
}
|
||||
}
|
||||
|
||||
public LocalDate getActivationLocalDate() {
|
||||
return this.activationDate;
|
||||
}
|
||||
|
||||
public LocalDate getOfficeJoiningLocalDate() {
|
||||
return this.officeJoiningDate;
|
||||
}
|
||||
|
||||
public boolean isOfficeIdentifiedBy(final Long officeId) {
|
||||
return this.office.identifiedBy(officeId);
|
||||
}
|
||||
@@ -618,7 +597,7 @@ public class Client extends AbstractAuditableWithUTCDateTimeCustom {
|
||||
}
|
||||
|
||||
public boolean isActivatedAfter(final LocalDate submittedOn) {
|
||||
return getActivationLocalDate().isAfter(submittedOn);
|
||||
return DateUtils.isAfter(getActivationDate(), submittedOn);
|
||||
}
|
||||
|
||||
public boolean isChildOfGroup(final Long groupId) {
|
||||
|
||||
+2
-1
@@ -21,6 +21,7 @@ package org.apache.fineract.portfolio.floatingrates.data;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.util.Collection;
|
||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||
|
||||
public class FloatingRateDTO {
|
||||
|
||||
@@ -43,7 +44,7 @@ public class FloatingRateDTO {
|
||||
BigDecimal rate = null;
|
||||
for (FloatingRatePeriodData periodData : this.baseLendingRatePeriods) {
|
||||
final LocalDate periodFromDate = periodData.getFromDate();
|
||||
if (periodFromDate.isBefore(date) || periodFromDate.isEqual(date)) {
|
||||
if (!DateUtils.isAfter(periodFromDate, date)) {
|
||||
rate = periodData.getInterestRate();
|
||||
break;
|
||||
}
|
||||
|
||||
+5
-7
@@ -89,9 +89,8 @@ public class FloatingRate extends AbstractAuditableWithUTCDateTimeCustom {
|
||||
|
||||
final String name = command.stringValueOfParameterNamed("name");
|
||||
final boolean isBaseLendingRate = command.parameterExists("isBaseLendingRate")
|
||||
? command.booleanPrimitiveValueOfParameterNamed("isBaseLendingRate")
|
||||
: false;
|
||||
final boolean isActive = command.parameterExists("isActive") ? command.booleanPrimitiveValueOfParameterNamed("isActive") : true;
|
||||
&& command.booleanPrimitiveValueOfParameterNamed("isBaseLendingRate");
|
||||
final boolean isActive = !command.parameterExists("isActive") || command.booleanPrimitiveValueOfParameterNamed("isActive");
|
||||
final List<FloatingRatePeriod> floatingRatePeriods = getRatePeriods(command);
|
||||
|
||||
return new FloatingRate(name, isBaseLendingRate, isActive, floatingRatePeriods);
|
||||
@@ -109,8 +108,7 @@ public class FloatingRate extends AbstractAuditableWithUTCDateTimeCustom {
|
||||
final LocalDate fromDate = helper.extractLocalDateNamed("fromDate", ratePeriod, new HashSet<String>());
|
||||
final BigDecimal interestRate = ratePeriodObject.get("interestRate").getAsBigDecimal();
|
||||
final boolean isDifferentialToBaseLendingRate = helper.parameterExists("isDifferentialToBaseLendingRate", ratePeriod)
|
||||
? ratePeriodObject.get("isDifferentialToBaseLendingRate").getAsBoolean()
|
||||
: false;
|
||||
&& ratePeriodObject.get("isDifferentialToBaseLendingRate").getAsBoolean();
|
||||
final boolean isActive = true;
|
||||
ratePeriods.add(new FloatingRatePeriod(fromDate, interestRate, isDifferentialToBaseLendingRate, isActive));
|
||||
}
|
||||
@@ -170,7 +168,7 @@ public class FloatingRate extends AbstractAuditableWithUTCDateTimeCustom {
|
||||
if (this.floatingRatePeriods != null) {
|
||||
for (FloatingRatePeriod ratePeriod : this.floatingRatePeriods) {
|
||||
LocalDate fromDate = ratePeriod.getFromDate();
|
||||
if (fromDate.isAfter(today)) {
|
||||
if (DateUtils.isAfter(fromDate, today)) {
|
||||
ratePeriod.setActive(false);
|
||||
}
|
||||
}
|
||||
@@ -188,7 +186,7 @@ public class FloatingRate extends AbstractAuditableWithUTCDateTimeCustom {
|
||||
for (FloatingRatePeriod floatingRatePeriod : this.floatingRatePeriods) {
|
||||
if (floatingRatePeriod.isActive()) {
|
||||
// will enter
|
||||
if (applicableRates.isEmpty() && floatingRateDTO.getStartDate().isBefore(floatingRatePeriod.fetchFromDate())) {
|
||||
if (applicableRates.isEmpty() && DateUtils.isBefore(floatingRateDTO.getStartDate(), floatingRatePeriod.fetchFromDate())) {
|
||||
if (floatingRateDTO.isFloatingInterestRate()) {
|
||||
addPeriodData = true;
|
||||
}
|
||||
|
||||
+1
-1
@@ -340,7 +340,7 @@ public class GroupGeneralData implements Serializable {
|
||||
}
|
||||
|
||||
public boolean isChildGroup() {
|
||||
return this.centerId == null ? false : true;
|
||||
return this.centerId != null;
|
||||
}
|
||||
|
||||
public Long getParentId() {
|
||||
|
||||
+2
-1
@@ -25,6 +25,7 @@ import jakarta.persistence.ManyToOne;
|
||||
import jakarta.persistence.Table;
|
||||
import java.time.LocalDate;
|
||||
import org.apache.fineract.infrastructure.core.domain.AbstractAuditableCustom;
|
||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||
import org.apache.fineract.organisation.staff.domain.Staff;
|
||||
|
||||
@Entity
|
||||
@@ -73,7 +74,7 @@ public class StaffAssignmentHistory extends AbstractAuditableCustom {
|
||||
}
|
||||
|
||||
public boolean matchesStartDateOf(final LocalDate matchingDate) {
|
||||
return getStartDate().isEqual(matchingDate);
|
||||
return DateUtils.isEqual(matchingDate, getStartDate());
|
||||
}
|
||||
|
||||
public LocalDate getStartDate() {
|
||||
|
||||
+2
-1
@@ -27,6 +27,7 @@ import java.util.Map;
|
||||
import lombok.Getter;
|
||||
import org.apache.fineract.accounting.glaccount.data.GLAccountData;
|
||||
import org.apache.fineract.infrastructure.core.data.EnumOptionData;
|
||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||
|
||||
@Getter
|
||||
public final class TaxComponentData implements Serializable {
|
||||
@@ -136,7 +137,7 @@ public final class TaxComponentData implements Serializable {
|
||||
}
|
||||
|
||||
private boolean occursOnDayFrom(final LocalDate target) {
|
||||
return target != null && target.isAfter(startDate());
|
||||
return DateUtils.isAfter(target, startDate());
|
||||
}
|
||||
|
||||
public LocalDate startDate() {
|
||||
|
||||
+2
-4
@@ -21,6 +21,7 @@ package org.apache.fineract.portfolio.tax.data;
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||
|
||||
public class TaxComponentHistoryData implements Serializable {
|
||||
|
||||
@@ -38,10 +39,7 @@ public class TaxComponentHistoryData implements Serializable {
|
||||
}
|
||||
|
||||
public boolean occursOnDayFromAndUpToAndIncluding(final LocalDate target) {
|
||||
if (this.endDate == null) {
|
||||
return target != null && target.isAfter(startDate());
|
||||
}
|
||||
return target != null && target.isAfter(startDate()) && !target.isAfter(endDate());
|
||||
return DateUtils.isAfter(target, startDate()) && (endDate == null || !DateUtils.isAfter(target, endDate()));
|
||||
}
|
||||
|
||||
public LocalDate startDate() {
|
||||
|
||||
+2
-4
@@ -20,6 +20,7 @@ package org.apache.fineract.portfolio.tax.data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDate;
|
||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||
|
||||
public class TaxGroupMappingsData implements Serializable {
|
||||
|
||||
@@ -44,10 +45,7 @@ public class TaxGroupMappingsData implements Serializable {
|
||||
}
|
||||
|
||||
public boolean occursOnDayFromAndUpToAndIncluding(final LocalDate target) {
|
||||
if (this.endDate == null) {
|
||||
return target != null && target.isAfter(startDate());
|
||||
}
|
||||
return target != null && target.isAfter(startDate()) && !target.isAfter(endDate());
|
||||
return DateUtils.isAfter(target, startDate()) && (endDate == null || !DateUtils.isAfter(target, endDate()));
|
||||
}
|
||||
|
||||
public LocalDate startDate() {
|
||||
|
||||
+1
-1
@@ -167,7 +167,7 @@ public class TaxComponent extends AbstractAuditableCustom {
|
||||
}
|
||||
|
||||
private boolean occursOnDayFrom(final LocalDate target) {
|
||||
return target != null && target.isAfter(startDate());
|
||||
return DateUtils.isAfter(target, startDate());
|
||||
}
|
||||
|
||||
public Set<TaxComponentHistory> getTaxComponentHistories() {
|
||||
|
||||
+2
-4
@@ -24,6 +24,7 @@ import jakarta.persistence.Table;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import org.apache.fineract.infrastructure.core.domain.AbstractAuditableCustom;
|
||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||
|
||||
@Entity
|
||||
@Table(name = "m_tax_component_history")
|
||||
@@ -62,10 +63,7 @@ public class TaxComponentHistory extends AbstractAuditableCustom {
|
||||
}
|
||||
|
||||
public boolean occursOnDayFromAndUpToAndIncluding(final LocalDate target) {
|
||||
if (this.endDate == null) {
|
||||
return target != null && target.isAfter(startDate());
|
||||
}
|
||||
return target != null && target.isAfter(startDate()) && !target.isAfter(endDate());
|
||||
return DateUtils.isAfter(target, startDate()) && (endDate == null || !DateUtils.isAfter(target, endDate()));
|
||||
}
|
||||
|
||||
public BigDecimal getPercentage() {
|
||||
|
||||
+2
-4
@@ -28,6 +28,7 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.apache.fineract.infrastructure.core.domain.AbstractAuditableCustom;
|
||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||
import org.apache.fineract.portfolio.tax.api.TaxApiConstants;
|
||||
|
||||
@Entity
|
||||
@@ -81,10 +82,7 @@ public class TaxGroupMappings extends AbstractAuditableCustom {
|
||||
}
|
||||
|
||||
public boolean occursOnDayFromAndUpToAndIncluding(final LocalDate target) {
|
||||
if (this.endDate == null) {
|
||||
return target != null && target.isAfter(startDate());
|
||||
}
|
||||
return target != null && target.isAfter(startDate()) && !target.isAfter(endDate());
|
||||
return DateUtils.isAfter(target, startDate()) && (endDate == null || !DateUtils.isAfter(target, endDate()));
|
||||
}
|
||||
|
||||
public TaxComponent getTaxComponent() {
|
||||
|
||||
+2
@@ -30,4 +30,6 @@ public final class AppUserConstants {
|
||||
|
||||
// TODO: Remove hard coding of system user name and make this a configurable parameter
|
||||
public static final String SYSTEM_USER_NAME = "system";
|
||||
public static final Long ADMIN_USER_ID = 1L;
|
||||
public static final Long SYSTEM_USER_ID = 2L;
|
||||
}
|
||||
|
||||
+2
-1
@@ -37,6 +37,7 @@ import org.apache.fineract.accounting.producttoaccountmapping.domain.PortfolioPr
|
||||
import org.apache.fineract.accounting.producttoaccountmapping.domain.ProductToGLAccountMapping;
|
||||
import org.apache.fineract.accounting.producttoaccountmapping.domain.ProductToGLAccountMappingRepository;
|
||||
import org.apache.fineract.accounting.producttoaccountmapping.exception.ProductToGLAccountMappingNotFoundException;
|
||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||
import org.apache.fineract.organisation.office.domain.Office;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@@ -61,7 +62,7 @@ public class InvestorAccountingHelper {
|
||||
**/
|
||||
GLClosure gLClosure = getLatestClosureByBranch(officeId);
|
||||
if (gLClosure != null) {
|
||||
if (gLClosure.getClosingDate().isAfter(transactionDate) || gLClosure.getClosingDate().isEqual(transactionDate)) {
|
||||
if (!DateUtils.isAfter(transactionDate, gLClosure.getClosingDate())) {
|
||||
throw new JournalEntryInvalidException(GlJournalEntryInvalidReason.ACCOUNTING_CLOSED, gLClosure.getClosingDate(), null,
|
||||
null);
|
||||
}
|
||||
|
||||
+2
-2
@@ -170,7 +170,7 @@ public class ExternalAssetOwnersWriteServiceImpl implements ExternalAssetOwnersW
|
||||
throw new ExternalAssetOwnerInitiateTransferException(
|
||||
String.format("This loan cannot be bought back, effective transfer is not in right state: %s",
|
||||
effectiveTransfers.get(0).getStatus()));
|
||||
} else if (settlementDate.isBefore(effectiveTransfers.get(0).getSettlementDate())) {
|
||||
} else if (DateUtils.isBefore(settlementDate, effectiveTransfers.get(0).getSettlementDate())) {
|
||||
throw new ExternalAssetOwnerInitiateTransferException(
|
||||
String.format("This loan cannot be bought back, settlement date is earlier than effective transfer settlement date: %s",
|
||||
effectiveTransfers.get(0).getSettlementDate()));
|
||||
@@ -251,7 +251,7 @@ public class ExternalAssetOwnersWriteServiceImpl implements ExternalAssetOwnersW
|
||||
}
|
||||
|
||||
private void validateSettlementDate(LocalDate settlementDate) {
|
||||
if (settlementDate.isBefore(ThreadLocalContextUtil.getBusinessDate())) {
|
||||
if (DateUtils.isBeforeBusinessDate(settlementDate)) {
|
||||
throw new ExternalAssetOwnerInitiateTransferException("Settlement date cannot be in the past");
|
||||
}
|
||||
}
|
||||
|
||||
+4
-7
@@ -22,6 +22,7 @@ import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||
|
||||
/**
|
||||
* Immutable data object representing disbursement information.
|
||||
@@ -85,8 +86,7 @@ public final class DisbursementData implements Comparable<DisbursementData> {
|
||||
if (obj == null) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return obj.expectedDisbursementDate.compareTo(this.expectedDisbursementDate);
|
||||
return DateUtils.compare(obj.expectedDisbursementDate, this.expectedDisbursementDate);
|
||||
}
|
||||
|
||||
public boolean isDueForDisbursement(final LocalDate fromNotInclusive, final LocalDate upToAndInclusive) {
|
||||
@@ -96,14 +96,11 @@ public final class DisbursementData implements Comparable<DisbursementData> {
|
||||
|
||||
private boolean occursOnDayFromAndUpToAndIncluding(final LocalDate fromNotInclusive, final LocalDate upToAndInclusive,
|
||||
final LocalDate target) {
|
||||
return target != null && target.isAfter(fromNotInclusive) && !target.isAfter(upToAndInclusive);
|
||||
return DateUtils.isAfter(target, fromNotInclusive) && !DateUtils.isAfter(target, upToAndInclusive);
|
||||
}
|
||||
|
||||
public BigDecimal getWaivedChargeAmount() {
|
||||
if (this.waivedChargeAmount == null) {
|
||||
return BigDecimal.ZERO;
|
||||
}
|
||||
return this.waivedChargeAmount;
|
||||
return this.waivedChargeAmount == null ? BigDecimal.ZERO : this.waivedChargeAmount;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+4
-3
@@ -22,6 +22,7 @@ import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import lombok.Getter;
|
||||
import org.apache.fineract.infrastructure.core.data.EnumOptionData;
|
||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanTermVariationType;
|
||||
|
||||
@Getter
|
||||
@@ -64,7 +65,7 @@ public class LoanTermVariationsData implements Comparable<LoanTermVariationsData
|
||||
}
|
||||
|
||||
private boolean occursOnDayFromAndUpTo(final LocalDate fromNotInclusive, final LocalDate upToInclusive, final LocalDate target) {
|
||||
return target != null && target.isAfter(fromNotInclusive) && !target.isAfter(upToInclusive);
|
||||
return DateUtils.isAfter(target, fromNotInclusive) && !DateUtils.isAfter(target, upToInclusive);
|
||||
}
|
||||
|
||||
public boolean isApplicable(final LocalDate fromDate) {
|
||||
@@ -72,7 +73,7 @@ public class LoanTermVariationsData implements Comparable<LoanTermVariationsData
|
||||
}
|
||||
|
||||
private boolean occursBefore(final LocalDate date, final LocalDate target) {
|
||||
return target != null && !target.isAfter(date);
|
||||
return target != null && !DateUtils.isAfter(target, date);
|
||||
}
|
||||
|
||||
public boolean isSpecificToInstallment() {
|
||||
@@ -84,7 +85,7 @@ public class LoanTermVariationsData implements Comparable<LoanTermVariationsData
|
||||
}
|
||||
|
||||
public Boolean isProcessed() {
|
||||
return this.isProcessed == null ? false : this.isProcessed;
|
||||
return this.isProcessed != null && this.isProcessed;
|
||||
}
|
||||
|
||||
public void setProcessed(Boolean isProcessed) {
|
||||
|
||||
+3
-2
@@ -23,6 +23,7 @@ import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||
|
||||
public class LoanTermVariationsDataWrapper {
|
||||
|
||||
@@ -54,7 +55,7 @@ public class LoanTermVariationsDataWrapper {
|
||||
boolean hasVariation = false;
|
||||
if (iterator.hasNext()) {
|
||||
LoanTermVariationsData loanTermVariationsData = iterator.next();
|
||||
if (!loanTermVariationsData.getTermVariationApplicableFrom().isAfter(date)) {
|
||||
if (!DateUtils.isAfter(loanTermVariationsData.getTermVariationApplicableFrom(), date)) {
|
||||
hasVariation = true;
|
||||
}
|
||||
iterator.previous();
|
||||
@@ -123,7 +124,7 @@ public class LoanTermVariationsDataWrapper {
|
||||
public LoanTermVariationsData fetchLoanTermDueDateVariationsData(final LocalDate onDate) {
|
||||
LoanTermVariationsData data = null;
|
||||
for (LoanTermVariationsData termVariationsData : this.dueDateVariation) {
|
||||
if (onDate.isEqual(termVariationsData.getTermVariationApplicableFrom())) {
|
||||
if (DateUtils.isEqual(onDate, termVariationsData.getTermVariationApplicableFrom())) {
|
||||
data = termVariationsData;
|
||||
break;
|
||||
}
|
||||
|
||||
+8
-15
@@ -2352,8 +2352,7 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom {
|
||||
|
||||
final LocalDate submittalDate = this.submittedOnDate;
|
||||
if (DateUtils.isBefore(approvedOn, submittalDate)) {
|
||||
final String errorMessage = "The date on which a loan is approved cannot be before its submittal date: "
|
||||
+ submittalDate.toString();
|
||||
final String errorMessage = "The date on which a loan is approved cannot be before its submittal date: " + submittalDate;
|
||||
throw new InvalidLoanStateTransitionException("approval", "cannot.be.before.submittal.date", errorMessage,
|
||||
getApprovedOnDate(), submittalDate);
|
||||
}
|
||||
@@ -3394,8 +3393,7 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom {
|
||||
incomePostTransactions.add(transaction);
|
||||
}
|
||||
}
|
||||
final LoanTransactionComparator transactionComparator = new LoanTransactionComparator();
|
||||
Collections.sort(incomePostTransactions, transactionComparator);
|
||||
incomePostTransactions.sort(LoanTransactionComparator.INSTANCE);
|
||||
return incomePostTransactions;
|
||||
}
|
||||
|
||||
@@ -3408,8 +3406,7 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom {
|
||||
repaymentsOrWaivers.add(transaction);
|
||||
}
|
||||
}
|
||||
final LoanTransactionComparator transactionComparator = new LoanTransactionComparator();
|
||||
Collections.sort(repaymentsOrWaivers, transactionComparator);
|
||||
repaymentsOrWaivers.sort(LoanTransactionComparator.INSTANCE);
|
||||
return repaymentsOrWaivers;
|
||||
}
|
||||
|
||||
@@ -3422,8 +3419,7 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom {
|
||||
repaymentsOrWaivers.add(transaction);
|
||||
}
|
||||
}
|
||||
final LoanTransactionComparator transactionComparator = new LoanTransactionComparator();
|
||||
Collections.sort(repaymentsOrWaivers, transactionComparator);
|
||||
repaymentsOrWaivers.sort(LoanTransactionComparator.INSTANCE);
|
||||
return repaymentsOrWaivers;
|
||||
}
|
||||
|
||||
@@ -3434,8 +3430,7 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom {
|
||||
repaymentsOrWaivers.add(transaction);
|
||||
}
|
||||
}
|
||||
final LoanTransactionComparator transactionComparator = new LoanTransactionComparator();
|
||||
Collections.sort(repaymentsOrWaivers, transactionComparator);
|
||||
repaymentsOrWaivers.sort(LoanTransactionComparator.INSTANCE);
|
||||
return repaymentsOrWaivers;
|
||||
}
|
||||
|
||||
@@ -3446,8 +3441,7 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom {
|
||||
transactions.add(transaction);
|
||||
}
|
||||
}
|
||||
final LoanTransactionComparator transactionComparator = new LoanTransactionComparator();
|
||||
Collections.sort(transactions, transactionComparator);
|
||||
transactions.sort(LoanTransactionComparator.INSTANCE);
|
||||
return transactions;
|
||||
}
|
||||
|
||||
@@ -3458,8 +3452,7 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom {
|
||||
transactions.add(transaction);
|
||||
}
|
||||
}
|
||||
final LoanTransactionComparator transactionComparator = new LoanTransactionComparator();
|
||||
Collections.sort(transactions, transactionComparator);
|
||||
transactions.sort(LoanTransactionComparator.INSTANCE);
|
||||
return transactions;
|
||||
}
|
||||
|
||||
@@ -6670,7 +6663,7 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom {
|
||||
paidFromFutureInstallments = paidFromFutureInstallments.plus(balancesForCurrentPeroid[4])
|
||||
.minus(balancesForCurrentPeroid[2]);
|
||||
}
|
||||
} else if (installment.getDueDate().isAfter(paymentDate)) {
|
||||
} else {
|
||||
paidFromFutureInstallments = paidFromFutureInstallments.plus(installment.getInterestPaid(currency))
|
||||
.plus(installment.getPenaltyChargesPaid(currency)).plus(installment.getFeeChargesPaid(currency));
|
||||
}
|
||||
|
||||
+12
-13
@@ -363,13 +363,11 @@ public class LoanCharge extends AbstractAuditableWithUTCDateTimeCustom {
|
||||
if (this.loan != null) {
|
||||
switch (ChargeCalculationType.fromInt(this.chargeCalculation)) {
|
||||
case PERCENT_OF_AMOUNT:
|
||||
// If charge type is specified due date and loan is multi
|
||||
// disburment loan.
|
||||
// Then we need to get as of this loan charge due date how
|
||||
// much amount disbursed.
|
||||
// If charge type is specified due date and loan is multi disburment loan.
|
||||
// Then we need to get as of this loan charge due date how much amount disbursed.
|
||||
if (this.loan.isMultiDisburmentLoan() && this.isSpecifiedDueDate()) {
|
||||
for (final LoanDisbursementDetails loanDisbursementDetails : this.loan.getDisbursementDetails()) {
|
||||
if (!loanDisbursementDetails.expectedDisbursementDate().isAfter(this.getDueDate())) {
|
||||
if (!DateUtils.isAfter(loanDisbursementDetails.expectedDisbursementDate(), this.getDueDate())) {
|
||||
amountPercentageAppliedTo = amountPercentageAppliedTo.add(loanDisbursementDetails.principal());
|
||||
}
|
||||
}
|
||||
@@ -635,13 +633,12 @@ public class LoanCharge extends AbstractAuditableWithUTCDateTimeCustom {
|
||||
|
||||
private boolean occursOnDayFromExclusiveAndUpToAndIncluding(final LocalDate fromNotInclusive, final LocalDate upToAndInclusive,
|
||||
final LocalDate target) {
|
||||
return target != null && target.isAfter(fromNotInclusive) && !target.isAfter(upToAndInclusive);
|
||||
return DateUtils.isAfter(target, fromNotInclusive) && !DateUtils.isAfter(target, upToAndInclusive);
|
||||
}
|
||||
|
||||
private boolean occursOnDayFromAndUpToAndIncluding(final LocalDate fromAndInclusive, final LocalDate upToAndInclusive,
|
||||
final LocalDate target) {
|
||||
return target != null && (target.isEqual(fromAndInclusive) || target.isAfter(fromAndInclusive))
|
||||
&& !target.isAfter(upToAndInclusive);
|
||||
return target != null && !DateUtils.isBefore(target, fromAndInclusive) && !DateUtils.isAfter(target, upToAndInclusive);
|
||||
}
|
||||
|
||||
public boolean isFeeCharge() {
|
||||
@@ -792,8 +789,9 @@ public class LoanCharge extends AbstractAuditableWithUTCDateTimeCustom {
|
||||
public LoanInstallmentCharge getUnpaidInstallmentLoanCharge() {
|
||||
LoanInstallmentCharge unpaidChargePerInstallment = null;
|
||||
for (final LoanInstallmentCharge loanChargePerInstallment : this.loanInstallmentCharge) {
|
||||
if (loanChargePerInstallment.isPending() && (unpaidChargePerInstallment == null || unpaidChargePerInstallment
|
||||
.getRepaymentInstallment().getDueDate().isAfter(loanChargePerInstallment.getRepaymentInstallment().getDueDate()))) {
|
||||
if (loanChargePerInstallment.isPending() && (unpaidChargePerInstallment == null
|
||||
|| DateUtils.isAfter(unpaidChargePerInstallment.getRepaymentInstallment().getDueDate(),
|
||||
loanChargePerInstallment.getRepaymentInstallment().getDueDate()))) {
|
||||
unpaidChargePerInstallment = loanChargePerInstallment;
|
||||
}
|
||||
}
|
||||
@@ -802,7 +800,7 @@ public class LoanCharge extends AbstractAuditableWithUTCDateTimeCustom {
|
||||
|
||||
public LoanInstallmentCharge getInstallmentLoanCharge(final LocalDate periodDueDate) {
|
||||
for (final LoanInstallmentCharge loanChargePerInstallment : this.loanInstallmentCharge) {
|
||||
if (periodDueDate.isEqual(loanChargePerInstallment.getRepaymentInstallment().getDueDate())) {
|
||||
if (DateUtils.isEqual(periodDueDate, loanChargePerInstallment.getRepaymentInstallment().getDueDate())) {
|
||||
return loanChargePerInstallment;
|
||||
}
|
||||
}
|
||||
@@ -974,8 +972,9 @@ public class LoanCharge extends AbstractAuditableWithUTCDateTimeCustom {
|
||||
Money outstanding = Money.of(currency, loanChargePerInstallment.getAmountOutstanding());
|
||||
final boolean partiallyPaid = outstanding.isGreaterThanZero()
|
||||
&& outstanding.isLessThan(loanChargePerInstallment.getAmount(currency));
|
||||
if ((partiallyPaid || loanChargePerInstallment.isPaid()) && (paidChargePerInstallment == null || paidChargePerInstallment
|
||||
.getRepaymentInstallment().getDueDate().isBefore(loanChargePerInstallment.getRepaymentInstallment().getDueDate()))) {
|
||||
if ((partiallyPaid || loanChargePerInstallment.isPaid()) && (paidChargePerInstallment == null
|
||||
|| DateUtils.isBefore(paidChargePerInstallment.getRepaymentInstallment().getDueDate(),
|
||||
loanChargePerInstallment.getRepaymentInstallment().getDueDate()))) {
|
||||
paidChargePerInstallment = loanChargePerInstallment;
|
||||
}
|
||||
}
|
||||
|
||||
+4
-8
@@ -27,6 +27,7 @@ import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
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.loanaccount.data.DisbursementData;
|
||||
|
||||
@Entity
|
||||
@@ -71,16 +72,11 @@ public class LoanDisbursementDetails extends AbstractPersistableCustom {
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object obj) {
|
||||
if (!(obj instanceof LoanDisbursementDetails)) {
|
||||
if (!(obj instanceof LoanDisbursementDetails loanDisbursementDetails)) {
|
||||
return false;
|
||||
}
|
||||
final LoanDisbursementDetails loanDisbursementDetails = (LoanDisbursementDetails) obj;
|
||||
if (loanDisbursementDetails.principal.equals(this.principal)
|
||||
&& loanDisbursementDetails.expectedDisbursementDate.compareTo(this.expectedDisbursementDate) == 0 ? Boolean.TRUE
|
||||
: Boolean.FALSE) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return loanDisbursementDetails.principal.equals(this.principal)
|
||||
&& DateUtils.isEqual(loanDisbursementDetails.expectedDisbursementDate, this.expectedDisbursementDate);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+2
-1
@@ -22,6 +22,7 @@ import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||
import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency;
|
||||
import org.apache.fineract.organisation.monetary.domain.Money;
|
||||
|
||||
@@ -114,7 +115,7 @@ public class LoanRepaymentScheduleProcessingWrapper {
|
||||
if (loanCharge.getLoan() != null && loanCharge.isSpecifiedDueDate()
|
||||
&& loanCharge.getLoan().isMultiDisburmentLoan()) {
|
||||
for (final LoanDisbursementDetails loanDisbursementDetails : loanCharge.getLoan().getDisbursementDetails()) {
|
||||
if (!loanDisbursementDetails.expectedDisbursementDate().isAfter(loanCharge.getDueDate())) {
|
||||
if (!DateUtils.isAfter(loanDisbursementDetails.expectedDisbursementDate(), loanCharge.getDueDate())) {
|
||||
amount = amount.add(loanDisbursementDetails.principal());
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -21,6 +21,7 @@ package org.apache.fineract.portfolio.loanaccount.domain;
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
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.springframework.stereotype.Component;
|
||||
@@ -230,7 +231,7 @@ public final class LoanSummaryWrapper {
|
||||
if (totalOverdue.isGreaterThanZero()) {
|
||||
for (final LoanRepaymentScheduleInstallment installment : repaymentScheduleInstallments) {
|
||||
if (installment.isOverdueOn(from)) {
|
||||
if (overdueSince == null || overdueSince.isAfter(installment.getDueDate())) {
|
||||
if (overdueSince == null || DateUtils.isAfter(overdueSince, installment.getDueDate())) {
|
||||
overdueSince = installment.getDueDate();
|
||||
}
|
||||
}
|
||||
|
||||
+12
-24
@@ -29,7 +29,6 @@ import jakarta.persistence.Table;
|
||||
import jakarta.persistence.UniqueConstraint;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.time.OffsetDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
@@ -850,29 +849,6 @@ public class LoanTransaction extends AbstractAuditableWithUTCDateTimeCustom {
|
||||
this.manuallyAdjustedOrReversed = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public OffsetDateTime getCreatedDateTime() {
|
||||
return (this.getCreatedDate().isPresent() ? this.getCreatedDate().get() : DateUtils.getOffsetDateTimeOfTenantWithMostPrecision());
|
||||
}
|
||||
|
||||
public boolean isLastTransaction(final LoanTransaction loanTransaction) {
|
||||
boolean isLatest = false;
|
||||
if (loanTransaction != null) {
|
||||
isLatest = this.getTransactionDate().isBefore(loanTransaction.getTransactionDate())
|
||||
|| (this.getTransactionDate().isEqual(loanTransaction.getTransactionDate())
|
||||
&& this.getCreatedDateTime().isBefore(loanTransaction.getCreatedDateTime()));
|
||||
}
|
||||
return isLatest;
|
||||
}
|
||||
|
||||
public boolean isLatestTransaction(final LoanTransaction loanTransaction) {
|
||||
boolean isLatest = false;
|
||||
if (loanTransaction != null) {
|
||||
isLatest = this.getCreatedDateTime().isBefore(loanTransaction.getCreatedDateTime());
|
||||
}
|
||||
return isLatest;
|
||||
}
|
||||
|
||||
public void updateLoanTransactionToRepaymentScheduleMappings(final Collection<LoanTransactionToRepaymentScheduleMapping> mappings) {
|
||||
Collection<LoanTransactionToRepaymentScheduleMapping> retainMappings = new ArrayList<>();
|
||||
for (LoanTransactionToRepaymentScheduleMapping updatedrepaymentScheduleMapping : mappings) {
|
||||
@@ -963,6 +939,18 @@ public class LoanTransaction extends AbstractAuditableWithUTCDateTimeCustom {
|
||||
return amount;
|
||||
}
|
||||
|
||||
public boolean isBefore(final LocalDate date) {
|
||||
return DateUtils.isBefore(getTransactionDate(), date);
|
||||
}
|
||||
|
||||
public boolean isAfter(final LocalDate date) {
|
||||
return DateUtils.isAfter(getTransactionDate(), date);
|
||||
}
|
||||
|
||||
public boolean isOn(final LocalDate date) {
|
||||
return DateUtils.isEqual(getTransactionDate(), date);
|
||||
}
|
||||
|
||||
// TODO missing hashCode(), equals(Object obj), but probably OK as long as
|
||||
// this is never stored in a Collection.
|
||||
}
|
||||
|
||||
+26
-33
@@ -19,47 +19,40 @@
|
||||
package org.apache.fineract.portfolio.loanaccount.domain;
|
||||
|
||||
import java.util.Comparator;
|
||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||
|
||||
/**
|
||||
* Sort loan transactions by transaction date, created date and transaction type placing
|
||||
*/
|
||||
public class LoanTransactionComparator implements Comparator<LoanTransaction> {
|
||||
|
||||
public static final LoanTransactionComparator INSTANCE = new LoanTransactionComparator();
|
||||
|
||||
@Override
|
||||
public int compare(final LoanTransaction o1, final LoanTransaction o2) {
|
||||
int compareResult = 0;
|
||||
final int comparsion = o1.getTransactionDate().compareTo(o2.getTransactionDate());
|
||||
/**
|
||||
* For transactions bearing the same transaction date, we sort transactions based on created date (when
|
||||
* available) after which sorting for waivers takes place
|
||||
**/
|
||||
if (comparsion == 0) {
|
||||
int comparisonBasedOnCreatedDate = 0;
|
||||
if (o1.isIncomePosting() && o2.isNotIncomePosting()) {
|
||||
compareResult = -1;
|
||||
} else if (o1.isNotIncomePosting() && o2.isIncomePosting()) {
|
||||
compareResult = 1;
|
||||
} else {
|
||||
compareResult = 0;
|
||||
}
|
||||
if (o1.getCreatedDateTime() != null && o2.getCreatedDateTime() != null) {
|
||||
comparisonBasedOnCreatedDate = o1.getCreatedDateTime().compareTo(o2.getCreatedDateTime());
|
||||
}
|
||||
// equal transaction dates
|
||||
if (comparisonBasedOnCreatedDate == 0) {
|
||||
if (o1.isWaiver() && o2.isNotWaiver()) {
|
||||
compareResult = -1;
|
||||
} else if (o1.isNotWaiver() && o2.isWaiver()) {
|
||||
compareResult = 1;
|
||||
} else {
|
||||
compareResult = 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
compareResult = comparsion;
|
||||
int result = DateUtils.compare(o1.getTransactionDate(), o2.getTransactionDate());
|
||||
if (result != 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
return compareResult;
|
||||
// For transactions bearing the same transaction date, we sort transactions based on created date (when
|
||||
// available) after which sorting for waivers takes place
|
||||
result = o1.getCreatedDate().isPresent()
|
||||
? (o2.getCreatedDate().isPresent() ? DateUtils.compare(o1.getCreatedDateTime(), o2.getCreatedDateTime()) : -1)
|
||||
: (o2.getCreatedDate().isPresent() ? 1 : 0);
|
||||
if (result != 0) {
|
||||
return result;
|
||||
}
|
||||
// equal transaction dates
|
||||
if (o1.isIncomePosting() != o2.isIncomePosting()) {
|
||||
return o1.isIncomePosting() ? -1 : 1;
|
||||
}
|
||||
if (o1.isWaiver() != o2.isWaiver()) {
|
||||
return o1.isWaiver() ? -1 : 1;
|
||||
}
|
||||
result = o1.getId() != null ? (o2.getId() != null ? Long.compare(o1.getId(), o2.getId()) : -1) : (o2.getId() != null ? 1 : 0);
|
||||
if (result != 0) {
|
||||
return result;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+4
-23
@@ -200,11 +200,7 @@ public final class LoanSchedulePeriodData {
|
||||
this.totalOutstandingForPeriod = this.feeChargesOutstanding;
|
||||
this.totalActualCostOfLoanForPeriod = this.feeChargesDue;
|
||||
this.totalInstallmentAmountForPeriod = null;
|
||||
if (dueDate.isBefore(DateUtils.getBusinessLocalDate())) {
|
||||
this.totalOverdue = this.totalOutstandingForPeriod;
|
||||
} else {
|
||||
this.totalOverdue = null;
|
||||
}
|
||||
this.totalOverdue = DateUtils.isBeforeBusinessDate(dueDate) ? this.totalOutstandingForPeriod : null;
|
||||
this.totalCredits = BigDecimal.ZERO;
|
||||
this.downPaymentPeriod = false;
|
||||
}
|
||||
@@ -263,12 +259,7 @@ public final class LoanSchedulePeriodData {
|
||||
this.totalOutstandingForPeriod = totalDueForPeriod;
|
||||
this.totalActualCostOfLoanForPeriod = interestDueOnPrincipalOutstanding.add(feeChargesDueForPeriod);
|
||||
this.totalInstallmentAmountForPeriod = totalInstallmentAmountForPeriod;
|
||||
|
||||
if (dueDate.isBefore(DateUtils.getBusinessLocalDate())) {
|
||||
this.totalOverdue = this.totalOutstandingForPeriod;
|
||||
} else {
|
||||
this.totalOverdue = null;
|
||||
}
|
||||
this.totalOverdue = DateUtils.isBeforeBusinessDate(dueDate) ? this.totalOutstandingForPeriod : null;
|
||||
this.totalCredits = BigDecimal.ZERO;
|
||||
this.downPaymentPeriod = false;
|
||||
}
|
||||
@@ -322,12 +313,7 @@ public final class LoanSchedulePeriodData {
|
||||
this.totalOutstandingForPeriod = totalDueForPeriod;
|
||||
this.totalActualCostOfLoanForPeriod = null;
|
||||
this.totalInstallmentAmountForPeriod = totalDueForPeriod;
|
||||
|
||||
if (dueDate.isBefore(DateUtils.getBusinessLocalDate())) {
|
||||
this.totalOverdue = this.totalOutstandingForPeriod;
|
||||
} else {
|
||||
this.totalOverdue = null;
|
||||
}
|
||||
this.totalOverdue = DateUtils.isBeforeBusinessDate(dueDate) ? this.totalOutstandingForPeriod : null;
|
||||
this.totalCredits = BigDecimal.ZERO;
|
||||
this.downPaymentPeriod = true;
|
||||
}
|
||||
@@ -396,12 +382,7 @@ public final class LoanSchedulePeriodData {
|
||||
this.totalOutstandingForPeriod = totalOutstanding;
|
||||
this.totalActualCostOfLoanForPeriod = totalActualCostOfLoanForPeriod;
|
||||
this.totalInstallmentAmountForPeriod = totalInstallmentAmountForPeriod;
|
||||
|
||||
if (dueDate.isBefore(DateUtils.getBusinessLocalDate())) {
|
||||
this.totalOverdue = this.totalOutstandingForPeriod;
|
||||
} else {
|
||||
this.totalOverdue = null;
|
||||
}
|
||||
this.totalOverdue = DateUtils.isBeforeBusinessDate(dueDate) ? this.totalOutstandingForPeriod : null;
|
||||
this.totalCredits = totalCredits;
|
||||
this.downPaymentPeriod = isDownPayment;
|
||||
}
|
||||
|
||||
+6
-3
@@ -18,6 +18,7 @@
|
||||
*/
|
||||
package org.apache.fineract.portfolio.loanaccount.loanschedule.domain;
|
||||
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.MathContext;
|
||||
import java.time.LocalDate;
|
||||
@@ -26,6 +27,7 @@ import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||
import org.apache.fineract.organisation.monetary.domain.ApplicationCurrency;
|
||||
import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency;
|
||||
import org.apache.fineract.organisation.monetary.domain.Money;
|
||||
@@ -716,7 +718,7 @@ public final class LoanApplicationTerms {
|
||||
// number of days from 'ideal disbursement' to final date
|
||||
|
||||
LocalDate loanStartDate = getExpectedDisbursementDate();
|
||||
if (getInterestChargedFromDate() != null && loanStartDate.isBefore(getInterestChargedFromLocalDate())) {
|
||||
if (DateUtils.isBefore(loanStartDate, getInterestChargedFromLocalDate())) {
|
||||
loanStartDate = getInterestChargedFromLocalDate();
|
||||
}
|
||||
|
||||
@@ -773,7 +775,7 @@ public final class LoanApplicationTerms {
|
||||
CalendarUtils.getMeetingFrequencyFromPeriodFrequencyType(getLoanTermPeriodFrequencyType()),
|
||||
this.holidayDetailDTO.getWorkingDays(), isSkipRepaymentOnFirstDayOfMonth, numberOfDays);
|
||||
}
|
||||
if (!expectedStartDate.isEqual(startDate)) {
|
||||
if (!DateUtils.isEqual(expectedStartDate, startDate)) {
|
||||
diffDays = Math.toIntExact(ChronoUnit.DAYS.between(startDate, expectedStartDate));
|
||||
}
|
||||
if (numberOfMonths == 0) {
|
||||
@@ -1368,6 +1370,7 @@ public final class LoanApplicationTerms {
|
||||
return this.multiDisburseLoan;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Money getMaxOutstandingBalance() {
|
||||
return Money.of(getCurrency(), this.maxOutstandingBalance);
|
||||
}
|
||||
@@ -1440,7 +1443,7 @@ public final class LoanApplicationTerms {
|
||||
|
||||
int months = getPeriodsBetween(fromDate, toDate);
|
||||
fromDate = fromDate.plusMonths(months);
|
||||
isSameAsRepaymentPeriod = fromDate.isEqual(toDate);
|
||||
isSameAsRepaymentPeriod = DateUtils.isEqual(fromDate, toDate);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
+3
-5
@@ -59,6 +59,7 @@ import org.apache.fineract.accounting.producttoaccountmapping.domain.ProductToGL
|
||||
import org.apache.fineract.accounting.producttoaccountmapping.exception.ProductToGLAccountMappingNotFoundException;
|
||||
import org.apache.fineract.infrastructure.core.data.EnumOptionData;
|
||||
import org.apache.fineract.infrastructure.core.exception.PlatformDataIntegrityException;
|
||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||
import org.apache.fineract.infrastructure.event.business.domain.journalentry.LoanJournalEntryCreatedBusinessEvent;
|
||||
import org.apache.fineract.infrastructure.event.business.service.BusinessEventNotifierService;
|
||||
import org.apache.fineract.organisation.office.domain.Office;
|
||||
@@ -502,12 +503,9 @@ public class AccountingProcessorHelper {
|
||||
* @param transactionDate
|
||||
*/
|
||||
public void checkForBranchClosures(final GLClosure latestGLClosure, final LocalDate transactionDate) {
|
||||
/**
|
||||
* check if an accounting closure has happened for this branch after the transaction Date
|
||||
**/
|
||||
// check if an accounting closure has happened for this branch after the transaction Date
|
||||
if (latestGLClosure != null) {
|
||||
if (latestGLClosure.getClosingDate().isAfter(transactionDate)
|
||||
|| latestGLClosure.getClosingDate().compareTo(transactionDate) == 0 ? Boolean.TRUE : Boolean.FALSE) {
|
||||
if (!DateUtils.isBefore(latestGLClosure.getClosingDate(), transactionDate)) {
|
||||
throw new JournalEntryInvalidException(GlJournalEntryInvalidReason.ACCOUNTING_CLOSED, latestGLClosure.getClosingDate(),
|
||||
null, null);
|
||||
}
|
||||
|
||||
+2
-3
@@ -175,8 +175,7 @@ public class JournalEntryRunningBalanceUpdateServiceImpl implements JournalEntry
|
||||
BigDecimal runningBalance = calculateRunningBalance(entryData, runningBalanceMap);
|
||||
|
||||
params.add(new Object[] { Boolean.TRUE, runningBalance, officeRunningBalance,
|
||||
platformSecurityContext.authenticatedUser().getId(), DateUtils.getOffsetDateTimeOfTenantWithMostPrecision(),
|
||||
entryData.getId() });
|
||||
platformSecurityContext.authenticatedUser().getId(), DateUtils.getAuditOffsetDateTime(), entryData.getId() });
|
||||
batchIndex++;
|
||||
if (batchIndex == batchUpdateSize || index == entryDataList.size() - 1) {
|
||||
this.jdbcTemplate.batchUpdate(sql, params);
|
||||
@@ -213,7 +212,7 @@ public class JournalEntryRunningBalanceUpdateServiceImpl implements JournalEntry
|
||||
for (JournalEntryData entryData : entryDataList) {
|
||||
BigDecimal runningBalance = calculateRunningBalance(entryData, runningBalanceMap);
|
||||
params.add(new Object[] { runningBalance, platformSecurityContext.authenticatedUser().getId(),
|
||||
DateUtils.getOffsetDateTimeOfTenantWithMostPrecision(), entryData.getId() });
|
||||
DateUtils.getAuditOffsetDateTime(), entryData.getId() });
|
||||
}
|
||||
this.jdbcTemplate.batchUpdate(sql, params);
|
||||
}
|
||||
|
||||
+5
-9
@@ -314,9 +314,7 @@ public class JournalEntryWritePlatformServiceJpaRepositoryImpl implements Journa
|
||||
final LocalDate journalEntriesTransactionDate = journalEntries.get(0).getTransactionDate();
|
||||
final GLClosure latestGLClosureByBranch = this.glClosureRepository.getLatestGLClosureByBranch(officeId);
|
||||
if (latestGLClosureByBranch != null) {
|
||||
if (latestGLClosureByBranch.getClosingDate().isAfter(journalEntriesTransactionDate)
|
||||
|| latestGLClosureByBranch.getClosingDate().compareTo(journalEntriesTransactionDate) == 0 ? Boolean.TRUE
|
||||
: Boolean.FALSE) {
|
||||
if (!DateUtils.isBefore(latestGLClosureByBranch.getClosingDate(), journalEntriesTransactionDate)) {
|
||||
final String accountName = null;
|
||||
final String accountGLCode = null;
|
||||
throw new JournalEntryInvalidException(GlJournalEntryInvalidReason.ACCOUNTING_CLOSED,
|
||||
@@ -555,24 +553,22 @@ public class JournalEntryWritePlatformServiceJpaRepositoryImpl implements Journa
|
||||
}
|
||||
|
||||
private void validateBusinessRulesForJournalEntries(final JournalEntryCommand command) {
|
||||
/** check if date of Journal entry is valid ***/
|
||||
// check if date of Journal entry is valid
|
||||
final LocalDate transactionDate = command.getTransactionDate();
|
||||
// shouldn't be in the future
|
||||
final LocalDate todaysDate = DateUtils.getBusinessLocalDate();
|
||||
if (transactionDate.isAfter(todaysDate)) {
|
||||
if (DateUtils.isDateInTheFuture(transactionDate)) {
|
||||
throw new JournalEntryInvalidException(GlJournalEntryInvalidReason.FUTURE_DATE, transactionDate, null, null);
|
||||
}
|
||||
// shouldn't be before an accounting closure
|
||||
final GLClosure latestGLClosure = this.glClosureRepository.getLatestGLClosureByBranch(command.getOfficeId());
|
||||
if (latestGLClosure != null) {
|
||||
if (latestGLClosure.getClosingDate().isAfter(transactionDate)
|
||||
|| latestGLClosure.getClosingDate().compareTo(transactionDate) == 0 ? Boolean.TRUE : Boolean.FALSE) {
|
||||
if (!DateUtils.isBefore(latestGLClosure.getClosingDate(), transactionDate)) {
|
||||
throw new JournalEntryInvalidException(GlJournalEntryInvalidReason.ACCOUNTING_CLOSED, latestGLClosure.getClosingDate(),
|
||||
null, null);
|
||||
}
|
||||
}
|
||||
|
||||
/*** check if credits and debits are valid **/
|
||||
// check if credits and debits are valid
|
||||
final SingleDebitOrCreditEntryCommand[] credits = command.getCredits();
|
||||
final SingleDebitOrCreditEntryCommand[] debits = command.getDebits();
|
||||
|
||||
|
||||
+2
-1
@@ -43,6 +43,7 @@ import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.apache.fineract.infrastructure.core.data.CommandProcessingResultBuilder;
|
||||
import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
|
||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
|
||||
import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency;
|
||||
import org.apache.fineract.organisation.monetary.domain.Money;
|
||||
@@ -107,7 +108,7 @@ public class ProvisioningEntriesWritePlatformServiceJpaRepositoryImpl implements
|
||||
private void validateForCreateJournalEntry(ProvisioningEntryData existingEntry, ProvisioningEntry requested) {
|
||||
LocalDate existingDate = existingEntry.getCreatedDate();
|
||||
LocalDate requestedDate = requested.getCreatedDate();
|
||||
if (existingDate.isAfter(requestedDate) || existingDate.compareTo(requestedDate) == 0 ? Boolean.TRUE : Boolean.FALSE) {
|
||||
if (!DateUtils.isBefore(existingDate, requestedDate)) {
|
||||
throw new ProvisioningJournalEntriesCannotbeCreatedException(existingEntry.getCreatedDate(), requestedDate);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ public class LoanAccountLock {
|
||||
public LoanAccountLock(Long loanId, LockOwner lockOwner, LocalDate lockPlacedOnCobBusinessDate) {
|
||||
this.loanId = loanId;
|
||||
this.lockOwner = lockOwner;
|
||||
this.lockPlacedOn = DateUtils.getOffsetDateTimeOfTenantWithMostPrecision();
|
||||
this.lockPlacedOn = DateUtils.getAuditOffsetDateTime();
|
||||
this.lockPlacedOnCobBusinessDate = lockPlacedOnCobBusinessDate;
|
||||
}
|
||||
|
||||
@@ -75,6 +75,6 @@ public class LoanAccountLock {
|
||||
|
||||
public void setNewLockOwner(LockOwner newLockOwner) {
|
||||
this.lockOwner = newLockOwner;
|
||||
this.lockPlacedOn = DateUtils.getOffsetDateTimeOfTenantWithMostPrecision();
|
||||
this.lockPlacedOn = DateUtils.getAuditOffsetDateTime();
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -81,8 +81,8 @@ public class LoanCOBPartitioner implements Partitioner {
|
||||
}
|
||||
StopWatch sw = new StopWatch();
|
||||
sw.start();
|
||||
List<LoanCOBPartition> loanCOBPartitions = new ArrayList<>(retrieveLoanIdService.retrieveLoanCOBPartitions(numberOfDays,
|
||||
businessDate, isCatchUp != null ? isCatchUp : false, partitionSize));
|
||||
List<LoanCOBPartition> loanCOBPartitions = new ArrayList<>(
|
||||
retrieveLoanIdService.retrieveLoanCOBPartitions(numberOfDays, businessDate, isCatchUp != null && isCatchUp, partitionSize));
|
||||
sw.stop();
|
||||
// if there is no loan to be closed, we still would like to create at least one partition
|
||||
|
||||
|
||||
+2
-2
@@ -67,7 +67,7 @@ public class LoanLockingServiceImpl implements LoanLockingService {
|
||||
UPDATE m_loan_account_locks SET version= version + 1, lock_owner = ?, lock_placed_on = ? WHERE loan_id = ?
|
||||
""", accountsToLock, getInClauseParameterSizeLimit(), (ps, id) -> {
|
||||
ps.setString(1, lockOwner.name());
|
||||
ps.setObject(2, DateUtils.getOffsetDateTimeOfTenantWithMostPrecision());
|
||||
ps.setObject(2, DateUtils.getAuditOffsetDateTime());
|
||||
ps.setLong(3, id);
|
||||
});
|
||||
}
|
||||
@@ -97,7 +97,7 @@ public class LoanLockingServiceImpl implements LoanLockingService {
|
||||
ps.setLong(1, loanId);
|
||||
ps.setLong(2, 1);
|
||||
ps.setString(3, lockOwner.name());
|
||||
ps.setObject(4, DateUtils.getOffsetDateTimeOfTenantWithMostPrecision());
|
||||
ps.setObject(4, DateUtils.getAuditOffsetDateTime());
|
||||
ps.setObject(5, cobBusinessDate);
|
||||
});
|
||||
}
|
||||
|
||||
+3
-2
@@ -32,6 +32,7 @@ import org.apache.fineract.cob.loan.RetrieveLoanIdService;
|
||||
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType;
|
||||
import org.apache.fineract.infrastructure.core.config.TaskExecutorConstant;
|
||||
import org.apache.fineract.infrastructure.core.domain.FineractContext;
|
||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||
import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil;
|
||||
import org.apache.fineract.infrastructure.jobs.data.JobParameterDTO;
|
||||
import org.apache.fineract.infrastructure.jobs.domain.JobParameterRepository;
|
||||
@@ -73,7 +74,7 @@ public class AsyncLoanCOBExecutorServiceImpl implements AsyncLoanCOBExecutorServ
|
||||
LocalDate oldestCOBProcessedDate = !loanIdAndLastClosedBusinessDate.isEmpty()
|
||||
? loanIdAndLastClosedBusinessDate.get(0).getLastClosedBusinessDate()
|
||||
: cobBusinessDate;
|
||||
if (oldestCOBProcessedDate.isBefore(cobBusinessDate)) {
|
||||
if (DateUtils.isBefore(oldestCOBProcessedDate, cobBusinessDate)) {
|
||||
executeLoanCOBDayByDayUntilCOBBusinessDate(oldestCOBProcessedDate, cobBusinessDate);
|
||||
}
|
||||
} catch (NoSuchJobException e) {
|
||||
@@ -92,7 +93,7 @@ public class AsyncLoanCOBExecutorServiceImpl implements AsyncLoanCOBExecutorServ
|
||||
Job job = jobLocator.getJob(LoanCOBConstant.JOB_NAME);
|
||||
ScheduledJobDetail scheduledJobDetail = scheduledJobDetailRepository.findByJobName(LoanCOBConstant.JOB_HUMAN_READABLE_NAME);
|
||||
LocalDate executingBusinessDate = oldestCOBProcessedDate.plusDays(1);
|
||||
while (!executingBusinessDate.isAfter(cobBusinessDate)) {
|
||||
while (!DateUtils.isAfter(executingBusinessDate, cobBusinessDate)) {
|
||||
JobParameterDTO jobParameterDTO = new JobParameterDTO(LoanCOBConstant.BUSINESS_DATE_PARAMETER_NAME,
|
||||
executingBusinessDate.format(DateTimeFormatter.ISO_DATE));
|
||||
JobParameterDTO jobParameterCatchUpDTO = new JobParameterDTO(LoanCOBConstant.IS_CATCH_UP_PARAMETER_NAME, "true");
|
||||
|
||||
+3
-2
@@ -51,6 +51,7 @@ import org.apache.fineract.infrastructure.core.data.CommandProcessingResultBuild
|
||||
import org.apache.fineract.infrastructure.core.exception.PlatformInternalServerException;
|
||||
import org.apache.fineract.infrastructure.core.exception.PlatformRequestBodyItemLimitValidationException;
|
||||
import org.apache.fineract.infrastructure.core.serialization.GoogleGsonSerializerHelper;
|
||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||
import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil;
|
||||
import org.apache.fineract.infrastructure.jobs.data.JobParameterDTO;
|
||||
import org.apache.fineract.infrastructure.jobs.domain.CustomJobParameterRepository;
|
||||
@@ -112,7 +113,7 @@ public class InlineLoanCOBExecutorServiceImpl implements InlineExecutorService<L
|
||||
List<LoanIdAndLastClosedBusinessDate> loansToBeProcessed = getLoansToBeProcessed(loanIds, cobBusinessDate);
|
||||
LocalDate executingBusinessDate = getOldestCOBBusinessDate(loansToBeProcessed).plusDays(1);
|
||||
if (!loansToBeProcessed.isEmpty()) {
|
||||
while (!executingBusinessDate.isAfter(cobBusinessDate)) {
|
||||
while (!DateUtils.isAfter(executingBusinessDate, cobBusinessDate)) {
|
||||
execute(getLoanIdsToBeProcessed(loansToBeProcessed, executingBusinessDate), jobName, executingBusinessDate);
|
||||
executingBusinessDate = executingBusinessDate.plusDays(1);
|
||||
}
|
||||
@@ -123,7 +124,7 @@ public class InlineLoanCOBExecutorServiceImpl implements InlineExecutorService<L
|
||||
List<Long> loanIdsToBeProcessed = new ArrayList<>();
|
||||
loansToBeProcessed.forEach(loan -> {
|
||||
if (loan.getLastClosedBusinessDate() != null) {
|
||||
if (loan.getLastClosedBusinessDate().isBefore(executingBusinessDate)) {
|
||||
if (DateUtils.isBefore(loan.getLastClosedBusinessDate(), executingBusinessDate)) {
|
||||
loanIdsToBeProcessed.add(loan.getId());
|
||||
}
|
||||
} else {
|
||||
|
||||
+1
-1
@@ -73,7 +73,7 @@ public class ImportDocument extends AbstractPersistableCustom {
|
||||
final Boolean completed = Boolean.FALSE;
|
||||
final Integer successCount = 0;
|
||||
final Integer failureCount = 0;
|
||||
final LocalDateTime endTime = LocalDateTime.now(DateUtils.getDateTimeZoneOfTenant());
|
||||
final LocalDateTime endTime = DateUtils.getLocalDateTimeOfTenant();
|
||||
|
||||
return new ImportDocument(document, importTime, endTime, completed, entityType, createdBy, totalRecords, successCount,
|
||||
failureCount);
|
||||
|
||||
+1
-2
@@ -145,8 +145,7 @@ public final class ImportHandlerUtils {
|
||||
return null;
|
||||
}
|
||||
|
||||
LocalDate localDate = LocalDate.ofInstant(c.getDateCellValue().toInstant(), DateUtils.getDateTimeZoneOfTenant());
|
||||
return localDate;
|
||||
return LocalDate.ofInstant(c.getDateCellValue().toInstant(), DateUtils.getDateTimeZoneOfTenant());
|
||||
}
|
||||
|
||||
public static Boolean readAsBoolean(int colIndex, Row row) {
|
||||
|
||||
+1
-2
@@ -101,8 +101,7 @@ public class SharedProductsSheetPopulator extends AbstractWorkbookPopulator {
|
||||
if (marketDataSet != null && !marketDataSet.isEmpty()) {
|
||||
LocalDate currentDate = DateUtils.getBusinessLocalDate();
|
||||
for (ShareProductMarketPriceData data : marketDataSet) {
|
||||
LocalDate futureDate = data.getFromDate();
|
||||
if (currentDate.isAfter(futureDate)) {
|
||||
if (DateUtils.isBefore(data.getFromDate(), currentDate)) {
|
||||
marketValue = data.getShareValue();
|
||||
}
|
||||
}
|
||||
|
||||
+9
-27
@@ -160,7 +160,7 @@ public class EmailCampaign extends AbstractPersistableCustom {
|
||||
final Locale locale = command.extractLocale();
|
||||
final DateTimeFormatter fmt = DateTimeFormatter.ofPattern(command.dateFormat()).withLocale(locale);
|
||||
|
||||
LocalDateTime recurrenceStartDate = LocalDateTime.now(DateUtils.getDateTimeZoneOfTenant());
|
||||
LocalDateTime recurrenceStartDate = DateUtils.getLocalDateTimeOfTenant();
|
||||
if (EmailCampaignType.fromInt(campaignType.intValue()).isSchedule()) {
|
||||
if (command.hasParameter(EmailCampaignValidator.recurrenceStartDate)) {
|
||||
recurrenceStartDate = LocalDateTime.parse(command.stringValueOfParameterNamed(EmailCampaignValidator.recurrenceStartDate),
|
||||
@@ -178,7 +178,6 @@ public class EmailCampaign extends AbstractPersistableCustom {
|
||||
}
|
||||
|
||||
public Map<String, Object> update(JsonCommand command) {
|
||||
|
||||
final Map<String, Object> actualChanges = new LinkedHashMap<>(5);
|
||||
|
||||
if (command.isChangeInStringParameterNamed(EmailCampaignValidator.campaignName, this.campaignName)) {
|
||||
@@ -229,7 +228,6 @@ public class EmailCampaign 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.";
|
||||
@@ -271,14 +269,13 @@ public class EmailCampaign 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.";
|
||||
final ApiParameterError error = ApiParameterError.parameterError("error.msg.campaign.must.be.closed", defaultUserMessage,
|
||||
EmailCampaignValidator.statusParamName, EmailCampaignStatus.fromInt(this.status).getCode());
|
||||
|
||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
|
||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
|
||||
dataValidationErrors.add(error);
|
||||
|
||||
throw new PlatformApiDataValidationException(dataValidationErrors);
|
||||
@@ -352,55 +349,45 @@ public class EmailCampaign extends AbstractPersistableCustom {
|
||||
}
|
||||
|
||||
private void validateActivationDate(final List<ApiParameterError> dataValidationErrors) {
|
||||
|
||||
if (getSubmittedOnDate() != null && isDateInTheFuture(getSubmittedOnDate())) {
|
||||
|
||||
if (getSubmittedOnDate() != null && 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, EmailCampaignValidator.submittedOnDateParamName, this.submittedOnDate);
|
||||
|
||||
dataValidationErrors.add(error);
|
||||
}
|
||||
|
||||
if (getApprovedOnDate() != null && getSubmittedOnDate() != null && getSubmittedOnDate().isAfter(getApprovedOnDate())) {
|
||||
|
||||
if (getApprovedOnDate() != null && DateUtils.isAfter(getSubmittedOnDate(), getApprovedOnDate())) {
|
||||
final String defaultUserMessage = "submitted date cannot be after the activation date";
|
||||
final ApiParameterError error = ApiParameterError.parameterError("error.msg.campaign.submittedOnDate.after.activation.date",
|
||||
defaultUserMessage, EmailCampaignValidator.submittedOnDateParamName, this.submittedOnDate);
|
||||
|
||||
dataValidationErrors.add(error);
|
||||
}
|
||||
|
||||
if (getApprovedOnDate() != null && isDateInTheFuture(getApprovedOnDate())) {
|
||||
|
||||
if (DateUtils.isDateInTheFuture(getApprovedOnDate())) {
|
||||
final String defaultUserMessage = "Activation date cannot be in the future.";
|
||||
final ApiParameterError error = ApiParameterError.parameterError("error.msg.campaign.activationDate.in.the.future",
|
||||
defaultUserMessage, EmailCampaignValidator.activationDateParamName, getApprovedOnDate());
|
||||
|
||||
dataValidationErrors.add(error);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void validateReactivationDate(final List<ApiParameterError> dataValidationErrors) {
|
||||
if (getApprovedOnDate() != null && isDateInTheFuture(getApprovedOnDate())) {
|
||||
|
||||
if (DateUtils.isDateInTheFuture(getApprovedOnDate())) {
|
||||
final String defaultUserMessage = "Activation date cannot be in the future.";
|
||||
final ApiParameterError error = ApiParameterError.parameterError("error.msg.campaign.activationDate.in.the.future",
|
||||
defaultUserMessage, EmailCampaignValidator.activationDateParamName, getApprovedOnDate());
|
||||
|
||||
dataValidationErrors.add(error);
|
||||
}
|
||||
if (getApprovedOnDate() != null && getSubmittedOnDate() != null && getSubmittedOnDate().isAfter(getApprovedOnDate())) {
|
||||
|
||||
if (getApprovedOnDate() != null && DateUtils.isAfter(getSubmittedOnDate(), getApprovedOnDate())) {
|
||||
final String defaultUserMessage = "submitted date cannot be after the activation date";
|
||||
final ApiParameterError error = ApiParameterError.parameterError("error.msg.campaign.submittedOnDate.after.activation.date",
|
||||
defaultUserMessage, EmailCampaignValidator.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, EmailCampaignValidator.submittedOnDateParamName, this.submittedOnDate);
|
||||
@@ -411,7 +398,7 @@ public class EmailCampaign extends AbstractPersistableCustom {
|
||||
}
|
||||
|
||||
private void validateClosureDate(final List<ApiParameterError> dataValidationErrors) {
|
||||
if (getClosureDate() != null && isDateInTheFuture(getClosureDate())) {
|
||||
if (getClosureDate() != null && 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, EmailCampaignValidator.closureDateParamName, this.closureDate);
|
||||
@@ -419,9 +406,4 @@ public class EmailCampaign extends AbstractPersistableCustom {
|
||||
dataValidationErrors.add(error);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isDateInTheFuture(final LocalDate localDate) {
|
||||
return localDate.isAfter(DateUtils.getBusinessLocalDate());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+23
-49
@@ -31,7 +31,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.time.format.DateTimeFormatterBuilder;
|
||||
import java.util.ArrayList;
|
||||
@@ -56,11 +55,9 @@ 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.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.ReportParameterUsage;
|
||||
@@ -98,7 +95,6 @@ public class EmailCampaignWritePlatformCommandHandlerImpl implements EmailCampai
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult create(JsonCommand command) {
|
||||
|
||||
final AppUser currentUser = this.context.authenticatedUser();
|
||||
|
||||
this.emailCampaignValidator.validateCreate(command.json());
|
||||
@@ -286,24 +282,21 @@ public class EmailCampaignWritePlatformCommandHandlerImpl implements EmailCampai
|
||||
if (emailCampaign.isDirect()) {
|
||||
insertDirectCampaignIntoEmailOutboundTable(emailCampaign.getParamValue(), emailCampaign.getEmailSubject(),
|
||||
emailCampaign.getEmailMessage(), emailCampaign.getCampaignName(), emailCampaign.getId());
|
||||
} else {
|
||||
if (emailCampaign.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
|
||||
*/
|
||||
LocalDateTime nextTriggerDateWithTime;
|
||||
if (emailCampaign.getRecurrenceStartDate().isBefore(tenantDateTime())) {
|
||||
nextTriggerDateWithTime = CalendarUtils.getNextRecurringDate(emailCampaign.getRecurrence(),
|
||||
emailCampaign.getRecurrenceStartDate(), DateUtils.getLocalDateTimeOfTenant());
|
||||
} else {
|
||||
nextTriggerDateWithTime = emailCampaign.getRecurrenceStartDate();
|
||||
}
|
||||
|
||||
emailCampaign.setNextTriggerDate(nextTriggerDateWithTime);
|
||||
this.emailCampaignRepository.saveAndFlush(emailCampaign);
|
||||
} else if (emailCampaign.isSchedule()) {
|
||||
// if recurrence start date is in the past, calculate next trigger date, otherwise use recurrence start
|
||||
// date as next trigger date when activating
|
||||
LocalDateTime nextTriggerDateWithTime;
|
||||
LocalDateTime recurrenceStartDate = emailCampaign.getRecurrenceStartDate();
|
||||
LocalDateTime tenantDateTime = DateUtils.getLocalDateTimeOfTenant();
|
||||
if (DateUtils.isBefore(recurrenceStartDate, tenantDateTime)) {
|
||||
nextTriggerDateWithTime = CalendarUtils.getNextRecurringDate(emailCampaign.getRecurrence(), recurrenceStartDate,
|
||||
tenantDateTime);
|
||||
} else {
|
||||
nextTriggerDateWithTime = recurrenceStartDate;
|
||||
}
|
||||
|
||||
emailCampaign.setNextTriggerDate(nextTriggerDateWithTime);
|
||||
this.emailCampaignRepository.saveAndFlush(emailCampaign);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -420,7 +413,6 @@ public class EmailCampaignWritePlatformCommandHandlerImpl implements EmailCampai
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult reactivateEmailCampaign(final Long campaignId, JsonCommand command) {
|
||||
|
||||
this.emailCampaignValidator.validateActivation(command.json());
|
||||
|
||||
final AppUser currentUser = this.context.authenticatedUser();
|
||||
@@ -433,23 +425,18 @@ public class EmailCampaignWritePlatformCommandHandlerImpl implements EmailCampai
|
||||
final LocalDate reactivationDate = command.localDateValueOfParameterNamed("activationDate");
|
||||
emailCampaign.reactivate(currentUser, fmt, reactivationDate);
|
||||
if (emailCampaign.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 (emailCampaign.getRecurrenceStartDate().isBefore(tenantDateTime())) {
|
||||
nextTriggerDate = CalendarUtils.getNextRecurringDate(emailCampaign.getRecurrence(), emailCampaign.getRecurrenceStartDate(),
|
||||
DateUtils.getLocalDateTimeOfTenant());
|
||||
LocalDateTime tenantDateTime = DateUtils.getLocalDateTimeOfTenant();
|
||||
LocalDateTime recurrenceStartDate = emailCampaign.getRecurrenceStartDate();
|
||||
if (DateUtils.isBefore(recurrenceStartDate, tenantDateTime)) {
|
||||
nextTriggerDate = CalendarUtils.getNextRecurringDate(emailCampaign.getRecurrence(), recurrenceStartDate, tenantDateTime);
|
||||
} else {
|
||||
nextTriggerDate = emailCampaign.getRecurrenceStartDate();
|
||||
nextTriggerDate = recurrenceStartDate;
|
||||
}
|
||||
// to get time of tenant
|
||||
final LocalDateTime getTime = emailCampaign.getRecurrenceStartDate();
|
||||
|
||||
final String dateString = nextTriggerDate.toString() + " " + getTime.getHour() + ":" + getTime.getMinute() + ":"
|
||||
+ getTime.getSecond();
|
||||
final String dateString = nextTriggerDate.toString() + " " + recurrenceStartDate.getHour() + ":"
|
||||
+ recurrenceStartDate.getMinute() + ":" + recurrenceStartDate.getSecond();
|
||||
final DateTimeFormatter simpleDateFormat = new DateTimeFormatterBuilder().parseCaseInsensitive().parseLenient()
|
||||
.appendPattern("yyyy-MM-dd HH:mm:ss").toFormatter();
|
||||
final LocalDateTime nextTriggerDateWithTime = LocalDateTime.parse(dateString, simpleDateFormat);
|
||||
@@ -470,17 +457,4 @@ public class EmailCampaignWritePlatformCommandHandlerImpl implements EmailCampai
|
||||
throw new PlatformDataIntegrityException("error.msg.email.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;
|
||||
}
|
||||
}
|
||||
|
||||
-41
@@ -1,41 +0,0 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
package org.apache.fineract.infrastructure.campaigns.jobs;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
import org.apache.fineract.infrastructure.core.domain.FineractPlatformTenant;
|
||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||
import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil;
|
||||
|
||||
public final class TenantDateTimeUtil {
|
||||
|
||||
private TenantDateTimeUtil() {}
|
||||
|
||||
public static LocalDateTime tenantDateTime() {
|
||||
LocalDateTime today = LocalDateTime.now(DateUtils.getDateTimeZoneOfTenant());
|
||||
final FineractPlatformTenant tenant = ThreadLocalContextUtil.getTenant();
|
||||
|
||||
if (tenant != null) {
|
||||
final ZoneId zone = ZoneId.of(tenant.getTimezoneId());
|
||||
today = LocalDateTime.now(zone);
|
||||
}
|
||||
return today;
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -80,7 +80,7 @@ public class ExecuteReportMailingJobsTasklet implements Tasklet {
|
||||
final LocalDateTime localDateTimeOftenant = DateUtils.getLocalDateTimeOfTenant();
|
||||
final LocalDateTime nextRunDateTime = reportMailingJob.getNextRunDateTime();
|
||||
|
||||
if (nextRunDateTime != null && nextRunDateTime.isBefore(localDateTimeOftenant)) {
|
||||
if (nextRunDateTime != null && DateUtils.isBefore(nextRunDateTime, localDateTimeOftenant)) {
|
||||
final ReportMailingJobEmailAttachmentFileFormat emailAttachmentFileFormat = ReportMailingJobEmailAttachmentFileFormat
|
||||
.newInstance(reportMailingJob.getEmailAttachmentFileFormat());
|
||||
|
||||
|
||||
+7
-9
@@ -43,7 +43,6 @@ import org.apache.fineract.infrastructure.campaigns.email.domain.EmailMessageRep
|
||||
import org.apache.fineract.infrastructure.campaigns.email.exception.EmailCampaignNotFound;
|
||||
import org.apache.fineract.infrastructure.campaigns.email.service.EmailCampaignReadPlatformService;
|
||||
import org.apache.fineract.infrastructure.campaigns.email.service.EmailCampaignWritePlatformService;
|
||||
import org.apache.fineract.infrastructure.campaigns.jobs.TenantDateTimeUtil;
|
||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||
import org.apache.fineract.portfolio.calendar.service.CalendarUtils;
|
||||
import org.apache.fineract.portfolio.client.domain.Client;
|
||||
@@ -69,11 +68,11 @@ public class UpdateEmailOutboundWithCampaignMessageTasklet implements Tasklet {
|
||||
.retrieveAllScheduleActiveCampaign();
|
||||
if (emailCampaignDataCollection != null) {
|
||||
for (EmailCampaignData emailCampaignData : emailCampaignDataCollection) {
|
||||
LocalDateTime tenantDateNow = TenantDateTimeUtil.tenantDateTime();
|
||||
LocalDateTime tenantDateNow = DateUtils.getLocalDateTimeOfTenant();
|
||||
LocalDateTime nextTriggerDate = emailCampaignData.getNextTriggerDate().toLocalDateTime();
|
||||
|
||||
log.debug("tenant time {} trigger time {}", tenantDateNow, nextTriggerDate);
|
||||
if (nextTriggerDate.isBefore(tenantDateNow)) {
|
||||
if (DateUtils.isBefore(nextTriggerDate, tenantDateNow)) {
|
||||
insertDirectCampaignIntoEmailOutboundTable(emailCampaignData.getParamValue(), emailCampaignData.getEmailSubject(),
|
||||
emailCampaignData.getEmailMessage(), emailCampaignData.getCampaignName(), emailCampaignData.getId());
|
||||
updateTriggerDates(emailCampaignData.getId());
|
||||
@@ -115,13 +114,12 @@ public class UpdateEmailOutboundWithCampaignMessageTasklet implements Tasklet {
|
||||
.orElseThrow(() -> new EmailCampaignNotFound(campaignId));
|
||||
LocalDateTime nextTriggerDate = emailCampaign.getNextTriggerDate();
|
||||
emailCampaign.setLastTriggerDate(nextTriggerDate);
|
||||
LocalDateTime newTriggerDateWithTime = CalendarUtils.getNextRecurringDate(emailCampaign.getRecurrence(),
|
||||
emailCampaign.getNextTriggerDate(), nextTriggerDate);
|
||||
if (newTriggerDateWithTime.isBefore(DateUtils.getLocalDateTimeOfTenant())) {
|
||||
newTriggerDateWithTime = CalendarUtils.getNextRecurringDate(emailCampaign.getRecurrence(), emailCampaign.getNextTriggerDate(),
|
||||
DateUtils.getLocalDateTimeOfTenant());
|
||||
LocalDateTime newTriggerDateWithTime = CalendarUtils.getNextRecurringDate(emailCampaign.getRecurrence(), nextTriggerDate,
|
||||
nextTriggerDate);
|
||||
LocalDateTime tenantDateTime = DateUtils.getLocalDateTimeOfTenant();
|
||||
if (DateUtils.isBefore(newTriggerDateWithTime, tenantDateTime)) {
|
||||
newTriggerDateWithTime = CalendarUtils.getNextRecurringDate(emailCampaign.getRecurrence(), nextTriggerDate, tenantDateTime);
|
||||
}
|
||||
|
||||
emailCampaign.setNextTriggerDate(newTriggerDateWithTime);
|
||||
emailCampaignRepository.saveAndFlush(emailCampaign);
|
||||
}
|
||||
|
||||
+6
-8
@@ -23,7 +23,6 @@ import java.util.Collection;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.fineract.infrastructure.campaigns.jobs.TenantDateTimeUtil;
|
||||
import org.apache.fineract.infrastructure.campaigns.sms.constants.SmsCampaignStatus;
|
||||
import org.apache.fineract.infrastructure.campaigns.sms.constants.SmsCampaignTriggerType;
|
||||
import org.apache.fineract.infrastructure.campaigns.sms.domain.SmsCampaign;
|
||||
@@ -51,12 +50,12 @@ public class UpdateSmsOutboundWithCampaignMessageTasklet implements Tasklet {
|
||||
.findByTriggerTypeAndStatus(SmsCampaignTriggerType.SCHEDULE.getValue(), SmsCampaignStatus.ACTIVE.getValue());
|
||||
if (!CollectionUtils.isEmpty(smsCampaignDataCollection)) {
|
||||
for (SmsCampaign smsCampaign : smsCampaignDataCollection) {
|
||||
LocalDateTime tenantDateNow = TenantDateTimeUtil.tenantDateTime();
|
||||
LocalDateTime tenantDateNow = DateUtils.getLocalDateTimeOfTenant();
|
||||
LocalDateTime nextTriggerDate = smsCampaign.getNextTriggerDate();
|
||||
|
||||
log.debug("tenant time {} trigger time {} {}", tenantDateNow, nextTriggerDate,
|
||||
JobName.UPDATE_SMS_OUTBOUND_WITH_CAMPAIGN_MESSAGE.name());
|
||||
if (nextTriggerDate.isBefore(tenantDateNow)) {
|
||||
if (DateUtils.isBefore(nextTriggerDate, tenantDateNow)) {
|
||||
smsCampaignWritePlatformService.insertDirectCampaignIntoSmsOutboundTable(smsCampaign);
|
||||
updateTriggerDates(smsCampaign.getId());
|
||||
}
|
||||
@@ -70,11 +69,10 @@ public class UpdateSmsOutboundWithCampaignMessageTasklet implements Tasklet {
|
||||
.orElseThrow(() -> new SmsCampaignNotFound(campaignId));
|
||||
LocalDateTime nextTriggerDate = smsCampaign.getNextTriggerDate();
|
||||
smsCampaign.setLastTriggerDate(nextTriggerDate);
|
||||
LocalDateTime nextRuntime = CalendarUtils.getNextRecurringDate(smsCampaign.getRecurrence(), smsCampaign.getNextTriggerDate(),
|
||||
nextTriggerDate);
|
||||
if (nextRuntime.isBefore(DateUtils.getLocalDateTimeOfTenant())) {
|
||||
nextRuntime = CalendarUtils.getNextRecurringDate(smsCampaign.getRecurrence(), smsCampaign.getNextTriggerDate(),
|
||||
DateUtils.getLocalDateTimeOfTenant());
|
||||
LocalDateTime nextRuntime = CalendarUtils.getNextRecurringDate(smsCampaign.getRecurrence(), nextTriggerDate, nextTriggerDate);
|
||||
LocalDateTime tenantDateTime = DateUtils.getLocalDateTimeOfTenant();
|
||||
if (DateUtils.isBefore(nextRuntime, tenantDateTime)) {
|
||||
nextRuntime = CalendarUtils.getNextRecurringDate(smsCampaign.getRecurrence(), nextTriggerDate, tenantDateTime);
|
||||
}
|
||||
|
||||
smsCampaign.setNextTriggerDate(nextRuntime);
|
||||
|
||||
+3
-6
@@ -18,10 +18,10 @@
|
||||
*/
|
||||
package org.apache.fineract.infrastructure.core.domain;
|
||||
|
||||
import static org.apache.fineract.useradministration.service.AppUserConstants.ADMIN_USER_ID;
|
||||
|
||||
import java.util.Optional;
|
||||
import org.apache.fineract.useradministration.domain.AppUser;
|
||||
import org.apache.fineract.useradministration.domain.AppUserRepository;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.AuditorAware;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.context.SecurityContext;
|
||||
@@ -29,9 +29,6 @@ import org.springframework.security.core.context.SecurityContextHolder;
|
||||
|
||||
public class AuditorAwareImpl implements AuditorAware<Long> {
|
||||
|
||||
@Autowired
|
||||
private AppUserRepository userRepository;
|
||||
|
||||
@Override
|
||||
public Optional<Long> getCurrentAuditor() {
|
||||
Optional<Long> currentUserId;
|
||||
@@ -50,6 +47,6 @@ public class AuditorAwareImpl implements AuditorAware<Long> {
|
||||
}
|
||||
|
||||
private Optional<Long> retrieveSuperUser() {
|
||||
return Optional.of(1L);
|
||||
return Optional.of(ADMIN_USER_ID); // TODO change to SYSTEM_USER_ID and add rights
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -420,7 +420,7 @@ public class ThitsaWorksCreditBureauIntegrationWritePlatformServiceImpl implemen
|
||||
LocalDate current = DateUtils.getLocalDateOfTenant();
|
||||
LocalDate getExpiryDate = creditBureauToken.getExpires();
|
||||
|
||||
if (getExpiryDate.isBefore(current)) {
|
||||
if (DateUtils.isBefore(getExpiryDate, current)) {
|
||||
this.tokenRepositoryWrapper.delete(creditBureauToken);
|
||||
creditBureauToken = null;
|
||||
}
|
||||
|
||||
+3
-5
@@ -33,6 +33,7 @@ import lombok.Setter;
|
||||
import lombok.experimental.Accessors;
|
||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||
import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom;
|
||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||
import org.apache.fineract.infrastructure.entityaccess.api.FineractEntityApiResourceConstants;
|
||||
import org.apache.fineract.infrastructure.entityaccess.exception.FineractEntityToEntityMappingDateException;
|
||||
|
||||
@@ -69,7 +70,6 @@ public class FineractEntityToEntityMapping extends AbstractPersistableCustom {
|
||||
}
|
||||
|
||||
public Map<String, Object> updateMap(final JsonCommand command) {
|
||||
|
||||
final Map<String, Object> actualChanges = new LinkedHashMap<>(9);
|
||||
|
||||
if (command.isChangeInLongParameterNamed(FineractEntityApiResourceConstants.fromEnityType, this.fromId)) {
|
||||
@@ -95,10 +95,8 @@ public class FineractEntityToEntityMapping extends AbstractPersistableCustom {
|
||||
actualChanges.put(FineractEntityApiResourceConstants.endDate, valueAsInput);
|
||||
this.endDate = command.localDateValueOfParameterNamed(FineractEntityApiResourceConstants.endDate);
|
||||
}
|
||||
if (startDate != null && endDate != null) {
|
||||
if (endDate.isBefore(startDate)) {
|
||||
throw new FineractEntityToEntityMappingDateException(startDate.toString(), endDate.toString());
|
||||
}
|
||||
if (endDate != null && DateUtils.isBefore(endDate, startDate)) {
|
||||
throw new FineractEntityToEntityMappingDateException(startDate.toString(), endDate.toString());
|
||||
}
|
||||
|
||||
return actualChanges;
|
||||
|
||||
+3
-8
@@ -27,6 +27,7 @@ import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.apache.fineract.infrastructure.core.data.CommandProcessingResultBuilder;
|
||||
import org.apache.fineract.infrastructure.core.exception.PlatformDataIntegrityException;
|
||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||
import org.apache.fineract.infrastructure.entityaccess.api.FineractEntityApiResourceConstants;
|
||||
import org.apache.fineract.infrastructure.entityaccess.data.FineractEntityDataValidator;
|
||||
import org.apache.fineract.infrastructure.entityaccess.domain.FineractEntityAccess;
|
||||
@@ -86,9 +87,7 @@ public class FineractEntityAccessWriteServiceImpl implements FineractEntityAcces
|
||||
@Override
|
||||
@Transactional
|
||||
public CommandProcessingResult createEntityToEntityMapping(Long relId, JsonCommand command) {
|
||||
|
||||
try {
|
||||
|
||||
this.fromApiJsonDeserializer.validateForCreate(command.json());
|
||||
|
||||
final FineractEntityRelation mapId = this.fineractEntityRelationRepositoryWrapper.findOneWithNotFoundDetection(relId);
|
||||
@@ -99,10 +98,8 @@ public class FineractEntityAccessWriteServiceImpl implements FineractEntityAcces
|
||||
final LocalDate endDate = command.localDateValueOfParameterNamed(FineractEntityApiResourceConstants.endDate);
|
||||
|
||||
fromApiJsonDeserializer.checkForEntity(relId.toString(), fromId, toId);
|
||||
if (startDate != null && endDate != null) {
|
||||
if (endDate.isBefore(startDate)) {
|
||||
throw new FineractEntityToEntityMappingDateException(startDate.toString(), endDate.toString());
|
||||
}
|
||||
if (endDate != null && DateUtils.isBefore(endDate, startDate)) {
|
||||
throw new FineractEntityToEntityMappingDateException(startDate.toString(), endDate.toString());
|
||||
}
|
||||
|
||||
final FineractEntityToEntityMapping newMap = FineractEntityToEntityMapping.newMap(mapId, fromId, toId, startDate, endDate);
|
||||
@@ -123,9 +120,7 @@ public class FineractEntityAccessWriteServiceImpl implements FineractEntityAcces
|
||||
@Override
|
||||
@Transactional
|
||||
public CommandProcessingResult updateEntityToEntityMapping(Long mapId, JsonCommand command) {
|
||||
|
||||
try {
|
||||
|
||||
this.fromApiJsonDeserializer.validateForUpdate(command.json());
|
||||
|
||||
final FineractEntityToEntityMapping mapForUpdate = this.fineractEntityToEntityMappingRepositoryWrapper
|
||||
|
||||
+2
-3
@@ -63,7 +63,7 @@ public class UpdateNpaTasklet implements Tasklet {
|
||||
resetNPASqlBuilder.append("set is_npa = false").append(", last_modified_by = ?, last_modified_on_utc = ? ").append(" FROM ")
|
||||
.append(fromPart).append(wherePart);
|
||||
}
|
||||
jdbcTemplate.update(resetNPASqlBuilder.toString(), user.getId(), DateUtils.getOffsetDateTimeOfTenantWithMostPrecision());
|
||||
jdbcTemplate.update(resetNPASqlBuilder.toString(), user.getId(), DateUtils.getAuditOffsetDateTime());
|
||||
|
||||
final StringBuilder updateSqlBuilder = new StringBuilder(900);
|
||||
|
||||
@@ -82,8 +82,7 @@ public class UpdateNpaTasklet implements Tasklet {
|
||||
.append(fromPart).append(wherePart);
|
||||
}
|
||||
|
||||
final int result = jdbcTemplate.update(updateSqlBuilder.toString(), user.getId(),
|
||||
DateUtils.getOffsetDateTimeOfTenantWithMostPrecision());
|
||||
final int result = jdbcTemplate.update(updateSqlBuilder.toString(), user.getId(), DateUtils.getAuditOffsetDateTime());
|
||||
|
||||
log.debug("{}: Records affected by updateNPA: {}", ThreadLocalContextUtil.getTenant().getName(), result);
|
||||
return RepeatStatus.FINISHED;
|
||||
|
||||
+2
-9
@@ -67,19 +67,12 @@ public class TFAccessToken extends AbstractPersistableCustom {
|
||||
}
|
||||
|
||||
public boolean isValid() {
|
||||
return this.enabled && isDateInTheFuture(getValidTo()) && isDateInThePast(getValidFrom());
|
||||
// valid_from is in the past inclusive, valid_to is in the future exclusive
|
||||
return this.enabled && !DateUtils.isAfterTenantDateTime(getValidFrom()) && DateUtils.isAfterTenantDateTime(getValidTo());
|
||||
}
|
||||
|
||||
public AccessTokenData toTokenData() {
|
||||
return new AccessTokenData().setToken(this.token).setValidFrom(getValidFrom().atZone(DateUtils.getDateTimeZoneOfTenant()))
|
||||
.setValidTo(getValidTo().atZone(DateUtils.getDateTimeZoneOfTenant()));
|
||||
}
|
||||
|
||||
private boolean isDateInTheFuture(LocalDateTime dateTime) {
|
||||
return dateTime.isAfter(DateUtils.getLocalDateTimeOfTenant());
|
||||
}
|
||||
|
||||
private boolean isDateInThePast(LocalDateTime dateTime) {
|
||||
return (dateTime.isBefore(DateUtils.getLocalDateTimeOfTenant()) || dateTime.isEqual(DateUtils.getLocalDateTimeOfTenant()));
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -157,7 +157,7 @@ public class SpringSecurityPlatformSecurityContext implements PlatformSecurityCo
|
||||
|
||||
final LocalDate passwordExpirationDate = passWordLastUpdateDate.plusDays(passwordDurationDays);
|
||||
|
||||
if (DateUtils.getLocalDateOfTenant().isAfter(passwordExpirationDate)) {
|
||||
if (DateUtils.isBeforeTenantDate(passwordExpirationDate)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -23,6 +23,7 @@ import java.util.List;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||
import org.apache.fineract.portfolio.savings.domain.SavingsAccount;
|
||||
import org.apache.fineract.portfolio.savings.domain.SavingsAccountTransaction;
|
||||
|
||||
@@ -41,7 +42,7 @@ public class InteropTransactionsData extends CommandProcessingResult {
|
||||
}
|
||||
|
||||
List<InteropTransactionData> trans = account.getTransactions().stream().filter(filter).sorted((t1, t2) -> {
|
||||
int i = t2.getDateOf().compareTo(t1.getDateOf());
|
||||
int i = DateUtils.compare(t2.getDateOf(), t1.getDateOf());
|
||||
return i != 0 ? i : Long.signum(t2.getId() - t1.getId());
|
||||
}).map(InteropTransactionData::build).collect(Collectors.toList());
|
||||
return new InteropTransactionsData(account.getId(), trans);
|
||||
|
||||
+8
-11
@@ -33,6 +33,7 @@ import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.apache.fineract.infrastructure.core.data.CommandProcessingResultBuilder;
|
||||
import org.apache.fineract.infrastructure.core.exception.PlatformDataIntegrityException;
|
||||
import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
|
||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
|
||||
import org.apache.fineract.organisation.holiday.api.HolidayApiConstants;
|
||||
import org.apache.fineract.organisation.holiday.data.HolidayDataValidator;
|
||||
@@ -206,18 +207,15 @@ public class HolidayWritePlatformServiceJpaRepositoryImpl implements HolidayWrit
|
||||
}
|
||||
|
||||
private void validateInputDates(final LocalDate fromDate, final LocalDate toDate, final LocalDate repaymentsRescheduledTo) {
|
||||
|
||||
String defaultUserMessage = "";
|
||||
|
||||
if (toDate.isBefore(fromDate)) {
|
||||
if (DateUtils.isBefore(toDate, fromDate)) {
|
||||
defaultUserMessage = "To Date date cannot be before the From Date.";
|
||||
throw new HolidayDateException("to.date.cannot.be.before.from.date", defaultUserMessage, fromDate.toString(),
|
||||
toDate.toString());
|
||||
}
|
||||
if (repaymentsRescheduledTo != null) {
|
||||
if ((repaymentsRescheduledTo.isEqual(fromDate) || repaymentsRescheduledTo.isEqual(toDate)
|
||||
|| (repaymentsRescheduledTo.isAfter(fromDate) && repaymentsRescheduledTo.isBefore(toDate)))) {
|
||||
|
||||
if (!DateUtils.isBefore(repaymentsRescheduledTo, fromDate) && !DateUtils.isAfter(repaymentsRescheduledTo, toDate)) {
|
||||
defaultUserMessage = "Repayments rescheduled date should be before from date or after to date.";
|
||||
throw new HolidayDateException("repayments.rescheduled.date.should.be.before.from.date.or.after.to.date",
|
||||
defaultUserMessage, repaymentsRescheduledTo.toString());
|
||||
@@ -235,13 +233,12 @@ public class HolidayWritePlatformServiceJpaRepositoryImpl implements HolidayWrit
|
||||
// validate repaymentsRescheduledTo date
|
||||
// 1. should be within a 30 days date range.
|
||||
// 2. Alternative date should not be an exist holiday.//TBD
|
||||
// 3. Holiday should not be on an repaymentsRescheduledTo date of
|
||||
// another holiday.//TBD
|
||||
// 3. Holiday should not be on an repaymentsRescheduledTo date of another holiday.//TBD
|
||||
|
||||
// restricting repaymentsRescheduledTo date to be within 30 days
|
||||
// range
|
||||
// before or after from date and to date.
|
||||
if (repaymentsRescheduledTo.isBefore(fromDate.minusDays(30)) || repaymentsRescheduledTo.isAfter(toDate.plusDays(30))) {
|
||||
// restricting repaymentsRescheduledTo date to be within 30 days range before or after from date and to
|
||||
// date.
|
||||
if (DateUtils.isBefore(repaymentsRescheduledTo, fromDate.minusDays(30))
|
||||
|| DateUtils.isAfter(repaymentsRescheduledTo, toDate.plusDays(30))) {
|
||||
defaultUserMessage = "Repayments Rescheduled to date must be within 30 days before or after from and to dates";
|
||||
throw new HolidayDateException("repayments.rescheduled.to.must.be.within.range", defaultUserMessage, fromDate.toString(),
|
||||
toDate.toString(), repaymentsRescheduledTo.toString());
|
||||
|
||||
+15
-21
@@ -20,10 +20,10 @@ package org.apache.fineract.organisation.teller.data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.time.OffsetDateTime;
|
||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||
import org.apache.fineract.infrastructure.core.service.MathUtil;
|
||||
import org.apache.fineract.infrastructure.core.service.SearchParameters;
|
||||
import org.apache.fineract.organisation.teller.domain.Cashier;
|
||||
import org.apache.fineract.organisation.teller.domain.Teller;
|
||||
@@ -54,7 +54,6 @@ public class CashierTransactionDataValidator {
|
||||
}
|
||||
|
||||
public void validateSettleCashAndCashOutTransactions(final Long cashierId, String currencyCode, final BigDecimal transactionAmount) {
|
||||
|
||||
final Integer offset = null;
|
||||
final Integer limit = null;
|
||||
final String orderBy = null;
|
||||
@@ -64,7 +63,7 @@ public class CashierTransactionDataValidator {
|
||||
final SearchParameters searchParameters = SearchParameters.forPagination(offset, limit, orderBy, sortOrder);
|
||||
final CashierTransactionsWithSummaryData cashierTxnWithSummary = this.tellerManagementReadPlatformService
|
||||
.retrieveCashierTransactionsWithSummary(cashierId, false, fromDate, toDate, currencyCode, searchParameters);
|
||||
if (cashierTxnWithSummary.getNetCash().subtract(transactionAmount).compareTo(BigDecimal.ZERO) < 0) {
|
||||
if (MathUtil.isGreaterThan(transactionAmount, cashierTxnWithSummary.getNetCash())) {
|
||||
throw new CashierInsufficientAmountException();
|
||||
}
|
||||
}
|
||||
@@ -81,16 +80,12 @@ public class CashierTransactionDataValidator {
|
||||
final LocalDate endDate = cashier.getEndDate();
|
||||
final LocalDate tellerFromDate = teller.getStartDate();
|
||||
final LocalDate tellerEndDate = teller.getEndDate();
|
||||
/**
|
||||
* to validate cashier date range in range of teller date range
|
||||
*/
|
||||
if (fromDate.isBefore(tellerFromDate) || endDate.isBefore(tellerFromDate)
|
||||
|| (tellerEndDate != null && (fromDate.isAfter(tellerEndDate) || endDate.isAfter(tellerEndDate)))) {
|
||||
// to validate cashier date range in range of teller date range
|
||||
if (DateUtils.isBefore(fromDate, tellerFromDate) || DateUtils.isBefore(endDate, tellerFromDate)
|
||||
|| (tellerEndDate != null && (DateUtils.isAfter(fromDate, tellerEndDate) || DateUtils.isAfter(endDate, tellerEndDate)))) {
|
||||
throw new CashierDateRangeOutOfTellerDateRangeException();
|
||||
}
|
||||
/**
|
||||
* to validate cashier has not been assigned for same duration
|
||||
*/
|
||||
// to validate cashier has not been assigned for same duration
|
||||
String sql = "select count(*) from m_cashiers c where c.staff_id = " + staffId + " AND " + "(('" + fromDate
|
||||
+ "' BETWEEN c.start_date AND c.end_date OR '" + endDate + "' BETWEEN c.start_date AND c.end_date )"
|
||||
+ " OR ( c.start_date BETWEEN '" + fromDate + "' AND '" + endDate + "' OR c.end_date BETWEEN '" + fromDate + "' AND '"
|
||||
@@ -98,8 +93,8 @@ public class CashierTransactionDataValidator {
|
||||
if (!cashier.getIsFullDay()) {
|
||||
String startTime = cashier.getStartTime();
|
||||
String endTime = cashier.getEndTime();
|
||||
sql = sql + " AND ( Time(c.start_time) BETWEEN TIME(?) and TIME('" + endTime + "') or Time(c.end_time) BETWEEN TIME('"
|
||||
+ startTime + "') and TIME('" + endTime + "')) ";
|
||||
sql = sql + " AND ( Time(c.start_time) BETWEEN TIME('" + startTime + "') and TIME('" + endTime
|
||||
+ "') or Time(c.end_time) BETWEEN TIME('" + startTime + "') and TIME('" + endTime + "')) ";
|
||||
}
|
||||
int count = this.jdbcTemplate.queryForObject(sql, Integer.class); // NOSONAR
|
||||
if (count > 0) {
|
||||
@@ -108,13 +103,13 @@ public class CashierTransactionDataValidator {
|
||||
}
|
||||
|
||||
public void validateOnLoanDisbursal(AppUser user, String currencyCode, BigDecimal transactionAmount) {
|
||||
LocalDateTime localDateTime = DateUtils.getLocalDateTimeOfTenant();
|
||||
LocalDate tenantDate = DateUtils.getLocalDateOfTenant();
|
||||
OffsetDateTime tenantDateTime = DateUtils.getOffsetDateTimeOfTenant();
|
||||
if (user.getStaff() != null) {
|
||||
String sql = "select c.id from m_cashiers c where c.staff_id = " + user.getStaff().getId() + " AND "
|
||||
+ " (case when c.full_day then '" + localDateTime.toLocalDate() + "' BETWEEN c.start_date AND c.end_date " + " else ('"
|
||||
+ localDateTime.toLocalDate() + "' BETWEEN c.start_date AND c.end_date and " + " TIME('"
|
||||
+ ZonedDateTime.of(localDateTime, DateUtils.getDateTimeZoneOfTenant())
|
||||
+ "') BETWEEN TIME(c.start_time) AND TIME(c.end_time) ) end)";
|
||||
String sql = "select c.id from m_cashiers c where c.staff_id = " + user.getStaff().getId() + " AND (case when c.full_day then '"
|
||||
+ tenantDate + "' BETWEEN c.start_date AND c.end_date else ('" + tenantDate
|
||||
+ "' BETWEEN c.start_date AND c.end_date and TIME('" + tenantDateTime
|
||||
+ "') BETWEEN TIME(c.start_time) AND TIME(c.end_time)) end)";
|
||||
try {
|
||||
Long cashierId = this.jdbcTemplate.queryForObject(sql, Long.class); // NOSONAR
|
||||
validateSettleCashAndCashOutTransactions(cashierId, currencyCode, transactionAmount);
|
||||
@@ -122,6 +117,5 @@ public class CashierTransactionDataValidator {
|
||||
LOG.error("Problem occurred in validateOnLoanDisbursal function", e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -35,6 +35,7 @@ import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder;
|
||||
import org.apache.fineract.infrastructure.core.exception.InvalidJsonException;
|
||||
import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException;
|
||||
import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
|
||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||
import org.apache.fineract.organisation.teller.exception.InvalidDateInputException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
@@ -113,7 +114,7 @@ public final class TellerCommandFromApiJsonDeserializer {
|
||||
final String status = this.fromApiJsonHelper.extractStringNamed(STATUS, element);
|
||||
baseDataValidator.reset().parameter(STATUS).value(status).notBlank().notExceedingLengthOf(50);
|
||||
|
||||
if (endDate != null && endDate.isBefore(startDate)) {
|
||||
if (endDate != null && DateUtils.isBefore(endDate, startDate)) {
|
||||
throw new InvalidDateInputException(startDate.toString(), endDate.toString());
|
||||
}
|
||||
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
||||
|
||||
+2
-2
@@ -75,12 +75,12 @@ public class ExecuteStandingInstructionsTasklet implements Tasklet {
|
||||
LocalDate startDate = data.validFrom();
|
||||
if (frequencyType.isMonthly()) {
|
||||
startDate = startDate.withDayOfMonth(data.recurrenceOnDay());
|
||||
if (startDate.isBefore(data.validFrom())) {
|
||||
if (DateUtils.isBefore(startDate, data.validFrom())) {
|
||||
startDate = startDate.plusMonths(1);
|
||||
}
|
||||
} else if (frequencyType.isYearly()) {
|
||||
startDate = startDate.withDayOfMonth(data.recurrenceOnDay()).withMonth(data.recurrenceOnMonth());
|
||||
if (startDate.isBefore(data.validFrom())) {
|
||||
if (DateUtils.isBefore(startDate, data.validFrom())) {
|
||||
startDate = startDate.plusYears(1);
|
||||
}
|
||||
}
|
||||
|
||||
+1
-2
@@ -536,8 +536,7 @@ public class AccountTransfersWritePlatformServiceImpl implements AccountTransfer
|
||||
BigDecimal overpaid = this.loanReadPlatformService.retrieveTotalPaidInAdvance(fromLoanAccountId).getPaidInAdvance();
|
||||
final boolean backdatedTxnsAllowedTill = false;
|
||||
|
||||
if (overpaid == null || overpaid.compareTo(BigDecimal.ZERO) == 0 ? Boolean.TRUE
|
||||
: Boolean.FALSE || transactionAmount.floatValue() > overpaid.floatValue()) {
|
||||
if (overpaid == null || overpaid.compareTo(BigDecimal.ZERO) == 0 || transactionAmount.floatValue() > overpaid.floatValue()) {
|
||||
if (overpaid == null) {
|
||||
overpaid = BigDecimal.ZERO;
|
||||
}
|
||||
|
||||
+3
-3
@@ -279,7 +279,7 @@ public class CalendarReadPlatformServiceImpl implements CalendarReadPlatformServ
|
||||
periodStartDate = fromDate;
|
||||
} else {
|
||||
final LocalDate currentDate = DateUtils.getLocalDateOfTenant();
|
||||
if (seedDate.isBefore(currentDate.minusYears(1))) {
|
||||
if (DateUtils.isBefore(seedDate, currentDate.minusYears(1))) {
|
||||
periodStartDate = currentDate.minusYears(1);
|
||||
} else {
|
||||
periodStartDate = recurrenceStartDate;
|
||||
@@ -294,7 +294,7 @@ public class CalendarReadPlatformServiceImpl implements CalendarReadPlatformServ
|
||||
|
||||
if (tillDate != null) {
|
||||
if (endDate != null) {
|
||||
if (endDate.isAfter(tillDate)) {
|
||||
if (DateUtils.isAfter(endDate, tillDate)) {
|
||||
// to retrieve meeting dates tillspecified date (tillDate)
|
||||
periodEndDate = tillDate;
|
||||
}
|
||||
@@ -302,7 +302,7 @@ public class CalendarReadPlatformServiceImpl implements CalendarReadPlatformServ
|
||||
// end date is null then fetch meeting dates tillDate
|
||||
periodEndDate = tillDate;
|
||||
}
|
||||
} else if (endDate == null || endDate.isAfter(currentDate.plusYears(1))) {
|
||||
} else if (endDate == null || DateUtils.isAfter(endDate, currentDate.plusYears(1))) {
|
||||
periodEndDate = currentDate.plusYears(1);
|
||||
}
|
||||
return periodEndDate;
|
||||
|
||||
+2
-2
@@ -80,8 +80,8 @@ public class InternalClientInformationApiResource implements InitializingBean {
|
||||
|
||||
final Client client = clientRepositoryWrapper.findOneWithNotFoundDetection(clientId);
|
||||
Map<String, Object> auditFields = new HashMap<>(
|
||||
Map.of(CREATED_BY, client.getCreatedBy().orElse(null), CREATED_DATE, client.getCreatedDate().orElse(null), LAST_MODIFIED_BY,
|
||||
client.getLastModifiedBy().orElse(null), LAST_MODIFIED_DATE, client.getLastModifiedDate().orElse(null)));
|
||||
Map.of(CREATED_BY, client.getCreatedBy().orElse(null), CREATED_DATE, client.getCreatedDateTime(), LAST_MODIFIED_BY,
|
||||
client.getLastModifiedBy().orElse(null), LAST_MODIFIED_DATE, client.getLastModifiedDateTime()));
|
||||
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
||||
return this.toApiJsonSerializer.serialize(settings, auditFields);
|
||||
}
|
||||
|
||||
+2
-2
@@ -36,6 +36,7 @@ import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||
import org.apache.fineract.infrastructure.core.data.ApiParameterError;
|
||||
import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom;
|
||||
import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException;
|
||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||
import org.apache.fineract.portfolio.client.api.ClientApiConstants;
|
||||
|
||||
@Entity
|
||||
@@ -116,8 +117,7 @@ public class ClientNonPerson extends AbstractPersistableCustom {
|
||||
|
||||
private void validateIncorpValidityTillDate(final Client client, final List<ApiParameterError> dataValidationErrors) {
|
||||
if (getIncorpValidityTillLocalDate() != null && client.dateOfBirthLocalDate() != null
|
||||
&& client.dateOfBirthLocalDate().isAfter(getIncorpValidityTillLocalDate())) {
|
||||
|
||||
&& DateUtils.isAfter(client.dateOfBirthLocalDate(), getIncorpValidityTillLocalDate())) {
|
||||
final String defaultUserMessage = "incorpvaliditytill date cannot be after the incorporation date";
|
||||
final ApiParameterError error = ApiParameterError.parameterError("error.msg.clients.incorpValidityTill.after.incorp.date",
|
||||
defaultUserMessage, ClientApiConstants.incorpValidityTillParamName, this.incorpValidityTill);
|
||||
|
||||
+3
-3
@@ -99,9 +99,9 @@ public class ClientChargeWritePlatformServiceImpl implements ClientChargeWritePl
|
||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
|
||||
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
|
||||
.resource(ClientApiConstants.CLIENT_CHARGES_RESOURCE_NAME);
|
||||
LocalDate activationDate = client.getActivationLocalDate();
|
||||
LocalDate activationDate = client.getActivationDate();
|
||||
LocalDate dueDate = clientCharge.getDueLocalDate();
|
||||
if (dueDate.isBefore(activationDate)) {
|
||||
if (DateUtils.isBefore(dueDate, activationDate)) {
|
||||
baseDataValidator.reset().parameter(ClientApiConstants.dueAsOfDateParamName).value(dueDate.format(fmt))
|
||||
.failWithCodeNoParameterAddedToErrorCode("dueDate.before.activationDate");
|
||||
|
||||
@@ -275,7 +275,7 @@ public class ClientChargeWritePlatformServiceImpl implements ClientChargeWritePl
|
||||
if (requiresTransactionDateValidation) {
|
||||
validateTransactionDateOnWorkingDay(transactionDate, clientCharge, fmt);
|
||||
|
||||
if (client.getActivationLocalDate() != null && transactionDate.isBefore(client.getActivationLocalDate())) {
|
||||
if (DateUtils.isBefore(transactionDate, client.getActivationDate())) {
|
||||
baseDataValidator.reset().parameter(ClientApiConstants.transactionDateParamName).value(transactionDate.format(fmt))
|
||||
.failWithCodeNoParameterAddedToErrorCode("transaction.before.activationDate");
|
||||
throw new PlatformApiDataValidationException(dataValidationErrors);
|
||||
|
||||
+10
-10
@@ -277,7 +277,7 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
|
||||
if (command.hasParameter(ClientApiConstants.submittedOnDateParamName)) {
|
||||
submittedOnDate = command.localDateValueOfParameterNamed(ClientApiConstants.submittedOnDateParamName);
|
||||
}
|
||||
if (active && submittedOnDate.isAfter(activationDate)) {
|
||||
if (active && DateUtils.isAfter(submittedOnDate, activationDate)) {
|
||||
submittedOnDate = activationDate;
|
||||
}
|
||||
final Long savingsAccountId = null;
|
||||
@@ -743,7 +743,7 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
|
||||
CommandProcessingResult commandProcessingResult = CommandProcessingResult.empty();
|
||||
if (client.isActive() && client.savingsProductId() != null) {
|
||||
SavingsAccountDataDTO savingsAccountDataDTO = new SavingsAccountDataDTO(client, null, client.savingsProductId(),
|
||||
client.getActivationLocalDate(), client.activatedBy(), fmt);
|
||||
client.getActivationDate(), client.activatedBy(), fmt);
|
||||
commandProcessingResult = this.savingsApplicationProcessWritePlatformService.createActiveApplication(savingsAccountDataDTO);
|
||||
if (commandProcessingResult.getSavingsId() != null) {
|
||||
this.savingsRepositoryWrapper.findOneWithNotFoundDetection(commandProcessingResult.getSavingsId());
|
||||
@@ -851,10 +851,10 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
|
||||
throw new InvalidClientStateTransitionException("close", "is.under.transfer", errorMessage);
|
||||
}
|
||||
|
||||
if (client.isNotPending() && client.getActivationLocalDate() != null && client.getActivationLocalDate().isAfter(closureDate)) {
|
||||
if (client.isNotPending() && DateUtils.isAfter(client.getActivationDate(), closureDate)) {
|
||||
final String errorMessage = "The client closureDate cannot be before the client ActivationDate.";
|
||||
throw new InvalidClientStateTransitionException("close", "date.cannot.before.client.actvation.date", errorMessage,
|
||||
closureDate, client.getActivationLocalDate());
|
||||
closureDate, client.getActivationDate());
|
||||
}
|
||||
final LegalForm legalForm = LegalForm.fromInt(client.getLegalForm());
|
||||
entityDatatableChecksWritePlatformService.runTheCheck(clientId, EntityTables.CLIENT.getName(), StatusEnum.CLOSE.getCode(),
|
||||
@@ -866,7 +866,7 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
|
||||
if (loanStatus.isOpen() || loanStatus.isPendingApproval() || loanStatus.isAwaitingDisbursal()) {
|
||||
final String errorMessage = "Client cannot be closed because of non-closed loans.";
|
||||
throw new InvalidClientStateTransitionException("close", "loan.non-closed", errorMessage);
|
||||
} else if (loanStatus.isClosed() && loan.getClosedOnDate().isAfter(closureDate)) {
|
||||
} else if (loanStatus.isClosed() && DateUtils.isAfter(loan.getClosedOnDate(), closureDate)) {
|
||||
final String errorMessage = "The client closureDate cannot be before the loan closedOnDate.";
|
||||
throw new InvalidClientStateTransitionException("close", "date.cannot.before.loan.closed.date", errorMessage,
|
||||
closureDate, loan.getClosedOnDate());
|
||||
@@ -976,7 +976,7 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
|
||||
final String errorMessage = "Only clients pending activation may be withdrawn.";
|
||||
throw new InvalidClientStateTransitionException("rejection", "on.account.not.in.pending.activation.status", errorMessage,
|
||||
rejectionDate, client.getSubmittedOnDate());
|
||||
} else if (client.getSubmittedOnDate().isAfter(rejectionDate)) {
|
||||
} else if (DateUtils.isAfter(client.getSubmittedOnDate(), rejectionDate)) {
|
||||
final String errorMessage = "The client rejection date cannot be before the client submitted date.";
|
||||
throw new InvalidClientStateTransitionException("rejection", "date.cannot.before.client.submitted.date", errorMessage,
|
||||
rejectionDate, client.getSubmittedOnDate());
|
||||
@@ -1008,7 +1008,7 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
|
||||
final String errorMessage = "Only clients pending activation may be withdrawn.";
|
||||
throw new InvalidClientStateTransitionException("withdrawal", "on.account.not.in.pending.activation.status", errorMessage,
|
||||
withdrawalDate, client.getSubmittedOnDate());
|
||||
} else if (client.getSubmittedOnDate().isAfter(withdrawalDate)) {
|
||||
} else if (DateUtils.isAfter(client.getSubmittedOnDate(), withdrawalDate)) {
|
||||
final String errorMessage = "The client withdrawal date cannot be before the client submitted date.";
|
||||
throw new InvalidClientStateTransitionException("withdrawal", "date.cannot.before.client.submitted.date", errorMessage,
|
||||
withdrawalDate, client.getSubmittedOnDate());
|
||||
@@ -1034,7 +1034,7 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
|
||||
if (!client.isClosed()) {
|
||||
final String errorMessage = "only closed clients may be reactivated.";
|
||||
throw new InvalidClientStateTransitionException("reactivation", "on.nonclosed.account", errorMessage);
|
||||
} else if (client.getClosureDate().isAfter(reactivateDate)) {
|
||||
} else if (DateUtils.isAfter(client.getClosureDate(), reactivateDate)) {
|
||||
final String errorMessage = "The client reactivation date cannot be before the client closed date.";
|
||||
throw new InvalidClientStateTransitionException("reactivation", "date.cannot.before.client.closed.date", errorMessage,
|
||||
reactivateDate, client.getClosureDate());
|
||||
@@ -1060,7 +1060,7 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
|
||||
if (!client.isRejected()) {
|
||||
final String errorMessage = "only rejected clients may be reactivated.";
|
||||
throw new InvalidClientStateTransitionException("undorejection", "on.nonrejected.account", errorMessage);
|
||||
} else if (client.getRejectedDate().isAfter(undoRejectDate)) {
|
||||
} else if (DateUtils.isAfter(client.getRejectedDate(), undoRejectDate)) {
|
||||
final String errorMessage = "The client reactivation date cannot be before the client rejected date.";
|
||||
throw new InvalidClientStateTransitionException("reopened", "date.cannot.before.client.rejected.date", errorMessage,
|
||||
undoRejectDate, client.getRejectedDate());
|
||||
@@ -1088,7 +1088,7 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
|
||||
if (!client.isWithdrawn()) {
|
||||
final String errorMessage = "only withdrawal clients may be reactivated.";
|
||||
throw new InvalidClientStateTransitionException("undoWithdrawal", "on.nonwithdrawal.account", errorMessage);
|
||||
} else if (client.getWithdrawalDate().isAfter(undoWithdrawalDate)) {
|
||||
} else if (DateUtils.isAfter(client.getWithdrawalDate(), undoWithdrawalDate)) {
|
||||
final String errorMessage = "The client reactivation date cannot be before the client withdrawal date.";
|
||||
throw new InvalidClientStateTransitionException("reopened", "date.cannot.before.client.withdrawal.date", errorMessage,
|
||||
undoWithdrawalDate, client.getWithdrawalDate());
|
||||
|
||||
+12
-11
@@ -55,7 +55,7 @@ public class LoanDelinquencyDomainServiceImpl implements LoanDelinquencyDomainSe
|
||||
// Get the oldest overdue installment if exists one
|
||||
for (LoanRepaymentScheduleInstallment installment : loan.getRepaymentScheduleInstallments()) {
|
||||
if (!installment.isObligationsMet()) {
|
||||
if (installment.getDueDate().isBefore(businessDate)) {
|
||||
if (DateUtils.isBefore(installment.getDueDate(), businessDate)) {
|
||||
log.debug("Loan Id: {} with installment {} due date {}", loan.getId(), installment.getInstallmentNumber(),
|
||||
installment.getDueDate());
|
||||
outstandingAmount = outstandingAmount.add(installment.getTotalOutstanding(loanCurrency).getAmount());
|
||||
@@ -69,13 +69,13 @@ public class LoanDelinquencyDomainServiceImpl implements LoanDelinquencyDomainSe
|
||||
|
||||
boolean isLatestInstallment = Objects.equals(installment.getId(), latestInstallment.getId());
|
||||
for (LoanTransaction loanTransaction : chargebackTransactions) {
|
||||
boolean isLoanTransactionIsOnOrAfterInstallmentFromDate = loanTransaction.getTransactionDate().isEqual(
|
||||
installment.getFromDate()) || loanTransaction.getTransactionDate().isAfter(installment.getFromDate());
|
||||
boolean isLoanTransactionIsOnOrAfterInstallmentFromDate = DateUtils
|
||||
.isEqual(loanTransaction.getTransactionDate(), installment.getFromDate())
|
||||
|| DateUtils.isAfter(loanTransaction.getTransactionDate(), installment.getFromDate());
|
||||
boolean isLoanTransactionIsBeforeNotLastInstallmentDueDate = !isLatestInstallment
|
||||
&& loanTransaction.getTransactionDate().isBefore(installment.getDueDate());
|
||||
&& DateUtils.isBefore(loanTransaction.getTransactionDate(), installment.getDueDate());
|
||||
boolean isLoanTransactionIsOnOrBeforeLastInstallmentDueDate = isLatestInstallment
|
||||
&& (loanTransaction.getTransactionDate().isEqual(installment.getDueDate())
|
||||
|| loanTransaction.getTransactionDate().isBefore(installment.getDueDate()));
|
||||
&& !DateUtils.isAfter(loanTransaction.getTransactionDate(), installment.getDueDate());
|
||||
if (isLoanTransactionIsOnOrAfterInstallmentFromDate && (isLoanTransactionIsBeforeNotLastInstallmentDueDate
|
||||
|| isLoanTransactionIsOnOrBeforeLastInstallmentDueDate)) {
|
||||
amountAvailable = amountAvailable.subtract(loanTransaction.getAmount());
|
||||
@@ -93,11 +93,12 @@ public class LoanDelinquencyDomainServiceImpl implements LoanDelinquencyDomainSe
|
||||
amountAvailable = installment.getTotalPaid(loanCurrency).getAmount();
|
||||
log.debug("Amount available {}", amountAvailable);
|
||||
for (LoanTransaction loanTransaction : chargebackTransactions) {
|
||||
boolean isLoanTransactionIsOnOrAfterInstallmentFromDate = loanTransaction.getTransactionDate().isEqual(
|
||||
installment.getFromDate()) || loanTransaction.getTransactionDate().isAfter(installment.getFromDate());
|
||||
boolean isLoanTransactionIsBeforeInstallmentDueDate = loanTransaction.getTransactionDate()
|
||||
.isBefore(installment.getDueDate());
|
||||
boolean isLoanTransactionIsBeforeBusinessDate = loanTransaction.getTransactionDate().isBefore(businessDate);
|
||||
boolean isLoanTransactionIsOnOrAfterInstallmentFromDate = !DateUtils.isBefore(loanTransaction.getTransactionDate(),
|
||||
installment.getFromDate());
|
||||
boolean isLoanTransactionIsBeforeInstallmentDueDate = DateUtils.isBefore(loanTransaction.getTransactionDate(),
|
||||
installment.getDueDate());
|
||||
boolean isLoanTransactionIsBeforeBusinessDate = DateUtils.isBefore(loanTransaction.getTransactionDate(),
|
||||
businessDate);
|
||||
if (isLoanTransactionIsOnOrAfterInstallmentFromDate && isLoanTransactionIsBeforeInstallmentDueDate
|
||||
&& isLoanTransactionIsBeforeBusinessDate) {
|
||||
log.debug("Loan CB Transaction: {} {} {}", loanTransaction.getId(), loanTransaction.getTransactionDate(),
|
||||
|
||||
+8
-18
@@ -153,7 +153,7 @@ public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements Group
|
||||
|
||||
final boolean active = command.booleanPrimitiveValueOfParameterNamed(GroupingTypesApiConstants.activeParamName);
|
||||
LocalDate submittedOnDate = DateUtils.getBusinessLocalDate();
|
||||
if (active && submittedOnDate.isAfter(activationDate)) {
|
||||
if (active && DateUtils.isAfter(submittedOnDate, activationDate)) {
|
||||
submittedOnDate = activationDate;
|
||||
}
|
||||
if (command.hasParameter(GroupingTypesApiConstants.submittedOnDateParamName)) {
|
||||
@@ -616,7 +616,7 @@ public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements Group
|
||||
final String errorMessage = groupOrCenter.getGroupLevel().getLevelName() + " cannot be closed because of non-closed loans.";
|
||||
throw new InvalidGroupStateTransitionException(groupOrCenter.getGroupLevel().getLevelName(), "close", "loan.not.closed",
|
||||
errorMessage);
|
||||
} else if (loanStatus.isClosed() && loan.getClosedOnDate().isAfter(closureDate)) {
|
||||
} else if (loanStatus.isClosed() && DateUtils.isAfter(loan.getClosedOnDate(), closureDate)) {
|
||||
final String errorMessage = groupOrCenter.getGroupLevel().getLevelName()
|
||||
+ "closureDate cannot be before the loan closedOnDate.";
|
||||
throw new InvalidGroupStateTransitionException(groupOrCenter.getGroupLevel().getLevelName(), "close",
|
||||
@@ -640,7 +640,7 @@ public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements Group
|
||||
+ " cannot be closed with active savings accounts associated.";
|
||||
throw new InvalidGroupStateTransitionException(groupOrCenter.getGroupLevel().getLevelName(), "close",
|
||||
"savings.account.not.closed", errorMessage);
|
||||
} else if (saving.isClosed() && saving.getClosedOnDate().isAfter(closureDate)) {
|
||||
} else if (saving.isClosed() && DateUtils.isAfter(saving.getClosedOnDate(), closureDate)) {
|
||||
final String errorMessage = groupOrCenter.getGroupLevel().getLevelName()
|
||||
+ " closureDate cannot be before the loan closedOnDate.";
|
||||
throw new InvalidGroupStateTransitionException(groupOrCenter.getGroupLevel().getLevelName(), "close",
|
||||
@@ -906,7 +906,7 @@ public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements Group
|
||||
|
||||
public void validateOfficeOpeningDateisAfterGroupOrCenterOpeningDate(final Office groupOffice, final GroupLevel groupLevel,
|
||||
final LocalDate activationDate) {
|
||||
if (activationDate != null && groupOffice.getOpeningLocalDate().isAfter(activationDate)) {
|
||||
if (activationDate != null && DateUtils.isAfter(groupOffice.getOpeningLocalDate(), activationDate)) {
|
||||
final String levelName = groupLevel.getLevelName();
|
||||
final String errorMessage = levelName + " activation date should be greater than or equal to the parent Office's creation date "
|
||||
+ activationDate.toString();
|
||||
@@ -916,10 +916,7 @@ public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements Group
|
||||
}
|
||||
|
||||
private void checkGroupMembersMeetingSyncWithCenterMeeting(final Long centerId, final Set<Group> groupMembers) {
|
||||
|
||||
/**
|
||||
* Get parent(center) calendar
|
||||
*/
|
||||
// Get parent(center) calendar
|
||||
Calendar ceneterCalendar = null;
|
||||
final CalendarInstance parentCalendarInstance = this.calendarInstanceRepository.findByEntityIdAndEntityTypeIdAndCalendarTypeId(
|
||||
centerId, CalendarEntityType.CENTERS.getValue(), CalendarType.COLLECTION.getValue());
|
||||
@@ -928,9 +925,7 @@ public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements Group
|
||||
}
|
||||
|
||||
for (final Group group : groupMembers) {
|
||||
/**
|
||||
* Get child(group) calendar
|
||||
*/
|
||||
// Get child(group) calendar
|
||||
Calendar groupCalendar = null;
|
||||
final CalendarInstance groupCalendarInstance = this.calendarInstanceRepository.findByEntityIdAndEntityTypeIdAndCalendarTypeId(
|
||||
group.getId(), CalendarEntityType.GROUPS.getValue(), CalendarType.COLLECTION.getValue());
|
||||
@@ -938,19 +933,14 @@ public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements Group
|
||||
groupCalendar = groupCalendarInstance.getCalendar();
|
||||
}
|
||||
|
||||
/**
|
||||
* Group shouldn't have a meeting when no meeting attached for center
|
||||
*/
|
||||
// Group shouldn't have a meeting when no meeting attached for center
|
||||
if (ceneterCalendar == null && groupCalendar != null) {
|
||||
throw new GeneralPlatformDomainRuleException(
|
||||
"error.msg.center.associating.group.not.allowed.with.meeting.attached.to.group",
|
||||
"Group with id " + group.getId() + " is already associated with meeting", group.getId());
|
||||
}
|
||||
/**
|
||||
* Group meeting recurrence should match with center meeting recurrence
|
||||
*/
|
||||
// Group meeting recurrence should match with center meeting recurrence
|
||||
else if (ceneterCalendar != null && groupCalendar != null) {
|
||||
|
||||
if (!ceneterCalendar.getRecurrence().equalsIgnoreCase(groupCalendar.getRecurrence())) {
|
||||
throw new GeneralPlatformDomainRuleException("error.msg.center.associating.group.not.allowed.with.different.meeting",
|
||||
"Group with id " + group.getId() + " meeting recurrence doesnot matched with center meeting recurrence",
|
||||
|
||||
+2
-1
@@ -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;
|
||||
|
||||
/**
|
||||
* Immutable data object representing a InterestRateChart.
|
||||
@@ -143,7 +144,7 @@ public final class InterestRateChartData {
|
||||
}
|
||||
|
||||
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() {
|
||||
|
||||
+5
-9
@@ -47,6 +47,7 @@ import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder;
|
||||
import org.apache.fineract.infrastructure.core.exception.InvalidJsonException;
|
||||
import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException;
|
||||
import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
|
||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||
import org.apache.fineract.portfolio.interestratechart.InterestRateChartApiConstants;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
@@ -115,10 +116,8 @@ public class InterestRateChartDataValidator {
|
||||
isPrimaryGroupingByAmount = false;
|
||||
}
|
||||
|
||||
if (fromDate != null && toDate != null) {
|
||||
if (fromDate.isAfter(toDate)) {
|
||||
baseDataValidator.parameter(fromDateParamName).value(fromDate).failWithCode("from.date.is.after.to.date");
|
||||
}
|
||||
if (toDate != null && DateUtils.isAfter(fromDate, toDate)) {
|
||||
baseDataValidator.parameter(fromDateParamName).value(fromDate).failWithCode("from.date.is.after.to.date");
|
||||
}
|
||||
|
||||
// validate chart Slabs - mandatory when creating
|
||||
@@ -177,11 +176,8 @@ public class InterestRateChartDataValidator {
|
||||
if (isPrimaryGroupingByAmount == null) {
|
||||
isPrimaryGroupingByAmount = false;
|
||||
}
|
||||
|
||||
if (fromDate != null && toDate != null) {
|
||||
if (fromDate.isAfter(toDate)) {
|
||||
baseDataValidator.parameter(fromDateParamName).value(fromDate).failWithCode("from.date.is.after.to.date");
|
||||
}
|
||||
if (toDate != null && DateUtils.isAfter(fromDate, toDate)) {
|
||||
baseDataValidator.parameter(fromDateParamName).value(fromDate).failWithCode("from.date.is.after.to.date");
|
||||
}
|
||||
|
||||
validateChartSlabs(element, baseDataValidator, isPrimaryGroupingByAmount);
|
||||
|
||||
+2
-5
@@ -312,10 +312,7 @@ public class InterestRateChartSlabFields {
|
||||
|
||||
public boolean isBigDecimalSame(final BigDecimal obj1, final BigDecimal obj2) {
|
||||
if (obj1 == null || obj2 == null) {
|
||||
if (Objects.compare(obj1, obj2, Comparator.nullsFirst(Comparator.naturalOrder())) == 0 ? Boolean.TRUE : Boolean.FALSE) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return Objects.compare(obj1, obj2, Comparator.nullsFirst(Comparator.naturalOrder())) == 0;
|
||||
}
|
||||
return obj1.compareTo(obj2) == 0;
|
||||
}
|
||||
@@ -326,7 +323,7 @@ public class InterestRateChartSlabFields {
|
||||
}
|
||||
|
||||
public boolean isAmountRangeProvided() {
|
||||
return (this.amountRangeFrom == null) ? false : true;
|
||||
return this.amountRangeFrom != null;
|
||||
}
|
||||
|
||||
public BigDecimal annualInterestRate() {
|
||||
|
||||
+4
-4
@@ -88,8 +88,8 @@ public class InternalLoanInformationApiResource implements InitializingBean {
|
||||
|
||||
final Loan loan = loanRepositoryWrapper.findOneWithNotFoundDetection(loanId);
|
||||
Map<String, Object> auditFields = new HashMap<>(
|
||||
Map.of(CREATED_BY, loan.getCreatedBy().orElse(null), CREATED_DATE, loan.getCreatedDate().orElse(null), LAST_MODIFIED_BY,
|
||||
loan.getLastModifiedBy().orElse(null), LAST_MODIFIED_DATE, loan.getLastModifiedDate().orElse(null)));
|
||||
Map.of(CREATED_BY, loan.getCreatedBy().orElse(null), CREATED_DATE, loan.getCreatedDateTime(), LAST_MODIFIED_BY,
|
||||
loan.getLastModifiedBy().orElse(null), LAST_MODIFIED_DATE, loan.getLastModifiedDateTime()));
|
||||
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
||||
return this.toApiJsonSerializerForMap.serialize(settings, auditFields);
|
||||
}
|
||||
@@ -108,8 +108,8 @@ public class InternalLoanInformationApiResource implements InitializingBean {
|
||||
|
||||
final LoanTransaction transaction = loanTransactionRepository.findById(transactionId).orElseThrow();
|
||||
Map<String, Object> auditFields = new HashMap<>(Map.of(CREATED_BY, transaction.getCreatedBy().orElse(null), CREATED_DATE,
|
||||
transaction.getCreatedDate().orElse(null), LAST_MODIFIED_BY, transaction.getLastModifiedBy().orElse(null),
|
||||
LAST_MODIFIED_DATE, transaction.getLastModifiedDate().orElse(null)));
|
||||
transaction.getCreatedDateTime(), LAST_MODIFIED_BY, transaction.getLastModifiedBy().orElse(null), LAST_MODIFIED_DATE,
|
||||
transaction.getLastModifiedDateTime()));
|
||||
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
||||
return this.toApiJsonSerializerForMap.serialize(settings, auditFields);
|
||||
}
|
||||
|
||||
+14
-14
@@ -369,7 +369,7 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
|
||||
final Integer transactionType, Integer installmentNumber) {
|
||||
boolean isAccountTransfer = true;
|
||||
checkClientOrGroupActive(loan);
|
||||
if (loan.isChargedOff() && transactionDate.isBefore(loan.getChargedOffOnDate())) {
|
||||
if (loan.isChargedOff() && DateUtils.isBefore(transactionDate, loan.getChargedOffOnDate())) {
|
||||
throw new GeneralPlatformDomainRuleException("error.msg.transaction.date.cannot.be.earlier.than.charge.off.date", "Loan: "
|
||||
+ loan.getId()
|
||||
+ " backdated transaction is not allowed. Transaction date cannot be earlier than the charge-off date of the loan",
|
||||
@@ -465,7 +465,7 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
|
||||
boolean isAccountTransfer = true;
|
||||
final Loan loan = this.loanAccountAssembler.assembleFrom(accountId);
|
||||
checkClientOrGroupActive(loan);
|
||||
if (loan.isChargedOff() && transactionDate.isBefore(loan.getChargedOffOnDate())) {
|
||||
if (loan.isChargedOff() && DateUtils.isBefore(transactionDate, loan.getChargedOffOnDate())) {
|
||||
throw new GeneralPlatformDomainRuleException("error.msg.transaction.date.cannot.be.earlier.than.charge.off.date", "Loan: "
|
||||
+ loan.getId()
|
||||
+ " backdated transaction is not allowed. Transaction date cannot be earlier than the charge-off date of the loan",
|
||||
@@ -518,7 +518,7 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
|
||||
final PaymentDetail paymentDetail, final String noteText, final ExternalId txnExternalId, final boolean isLoanToLoanTransfer) {
|
||||
final Loan loan = this.loanAccountAssembler.assembleFrom(loanId);
|
||||
checkClientOrGroupActive(loan);
|
||||
if (loan.isChargedOff() && transactionDate.isBefore(loan.getChargedOffOnDate())) {
|
||||
if (loan.isChargedOff() && DateUtils.isBefore(transactionDate, loan.getChargedOffOnDate())) {
|
||||
throw new GeneralPlatformDomainRuleException("error.msg.transaction.date.cannot.be.earlier.than.charge.off.date", "Loan: "
|
||||
+ loan.getId()
|
||||
+ " backdated transaction is not allowed. Transaction date cannot be earlier than the charge-off date of the loan",
|
||||
@@ -551,7 +551,7 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
|
||||
@Override
|
||||
public void reverseTransfer(final LoanTransaction loanTransaction) {
|
||||
if (loanTransaction.getLoan().isChargedOff()
|
||||
&& loanTransaction.getTransactionDate().isBefore(loanTransaction.getLoan().getChargedOffOnDate())) {
|
||||
&& DateUtils.isBefore(loanTransaction.getTransactionDate(), loanTransaction.getLoan().getChargedOffOnDate())) {
|
||||
throw new GeneralPlatformDomainRuleException("error.msg.transaction.date.cannot.be.earlier.than.charge.off.date",
|
||||
"Loan transaction: " + loanTransaction.getId()
|
||||
+ " reversal is not allowed before or on the date when the loan got charged-off",
|
||||
@@ -614,10 +614,10 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
|
||||
Set<LoanCharge> loanCharges = loan.getActiveCharges();
|
||||
|
||||
for (LoanRepaymentScheduleInstallment installment : installments) {
|
||||
if (installment.getDueDate().isAfter(loan.getMaturityDate())) {
|
||||
if (DateUtils.isAfter(installment.getDueDate(), loan.getMaturityDate())) {
|
||||
accruedTill = DateUtils.getBusinessLocalDate();
|
||||
}
|
||||
if (!isOrganisationDateEnabled || organisationStartDate.isBefore(installment.getDueDate())) {
|
||||
if (!isOrganisationDateEnabled || DateUtils.isBefore(organisationStartDate, installment.getDueDate())) {
|
||||
generateLoanScheduleAccrualData(accruedTill, loanScheduleAccrualList, loanId, officeId, accrualStartDate,
|
||||
repaymentFrequency, repayEvery, interestCalculatedFrom, loanProductId, currency, currencyData, loanCharges,
|
||||
installment);
|
||||
@@ -641,12 +641,12 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
|
||||
final LocalDate interestCalculatedFrom, final Long loanProductId, final MonetaryCurrency currency,
|
||||
final CurrencyData currencyData, final Set<LoanCharge> loanCharges, final LoanRepaymentScheduleInstallment installment) {
|
||||
|
||||
if (!accruedTill.isBefore(installment.getDueDate())
|
||||
|| (accruedTill.isAfter(installment.getFromDate()) && !accruedTill.isAfter(installment.getDueDate()))) {
|
||||
if (!DateUtils.isBefore(accruedTill, installment.getDueDate()) || (DateUtils.isAfter(accruedTill, installment.getFromDate())
|
||||
&& !DateUtils.isAfter(accruedTill, installment.getDueDate()))) {
|
||||
BigDecimal dueDateFeeIncome = BigDecimal.ZERO;
|
||||
BigDecimal dueDatePenaltyIncome = BigDecimal.ZERO;
|
||||
LocalDate chargesTillDate = installment.getDueDate();
|
||||
if (!accruedTill.isAfter(installment.getDueDate())) {
|
||||
if (!DateUtils.isAfter(accruedTill, installment.getDueDate())) {
|
||||
chargesTillDate = accruedTill;
|
||||
}
|
||||
|
||||
@@ -685,7 +685,7 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
|
||||
@Override
|
||||
public LoanTransaction creditBalanceRefund(final Loan loan, final LocalDate transactionDate, final BigDecimal transactionAmount,
|
||||
final String noteText, final ExternalId externalId, PaymentDetail paymentDetail) {
|
||||
if (loan.isChargedOff() && transactionDate.isBefore(loan.getChargedOffOnDate())) {
|
||||
if (loan.isChargedOff() && DateUtils.isBefore(transactionDate, loan.getChargedOffOnDate())) {
|
||||
throw new GeneralPlatformDomainRuleException("error.msg.transaction.date.cannot.be.earlier.than.charge.off.date", "Loan: "
|
||||
+ loan.getId()
|
||||
+ " backdated transaction is not allowed. Transaction date cannot be earlier than the charge-off date of the loan",
|
||||
@@ -729,7 +729,7 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
|
||||
final List<Long> existingReversedTransactionIds = new ArrayList<>();
|
||||
|
||||
final Money refundAmount = Money.of(loan.getCurrency(), transactionAmount);
|
||||
if (loan.isChargedOff() && transactionDate.isBefore(loan.getChargedOffOnDate())) {
|
||||
if (loan.isChargedOff() && DateUtils.isBefore(transactionDate, loan.getChargedOffOnDate())) {
|
||||
throw new GeneralPlatformDomainRuleException("error.msg.transaction.date.cannot.be.earlier.than.charge.off.date", "Loan: "
|
||||
+ loan.getId()
|
||||
+ " backdated transaction is not allowed. Transaction date cannot be earlier than the charge-off date of the loan",
|
||||
@@ -768,7 +768,7 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
|
||||
@Override
|
||||
public LoanTransaction foreCloseLoan(Loan loan, final LocalDate foreClosureDate, final String noteText, final ExternalId externalId,
|
||||
Map<String, Object> changes) {
|
||||
if (loan.isChargedOff() && foreClosureDate.isBefore(loan.getChargedOffOnDate())) {
|
||||
if (loan.isChargedOff() && DateUtils.isBefore(foreClosureDate, loan.getChargedOffOnDate())) {
|
||||
throw new GeneralPlatformDomainRuleException("error.msg.transaction.date.cannot.be.earlier.than.charge.off.date", "Loan: "
|
||||
+ loan.getId()
|
||||
+ " backdated transaction is not allowed. Transaction date cannot be earlier than the charge-off date of the loan",
|
||||
@@ -785,7 +785,7 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
|
||||
final ScheduleGeneratorDTO scheduleGeneratorDTO = null;
|
||||
final LoanRepaymentScheduleInstallment foreCloseDetail = loan.fetchLoanForeclosureDetail(foreClosureDate);
|
||||
if (loan.isPeriodicAccrualAccountingEnabledOnLoanProduct()
|
||||
&& (loan.getAccruedTill() == null || !foreClosureDate.isEqual(loan.getAccruedTill()))) {
|
||||
&& (loan.getAccruedTill() == null || !DateUtils.isEqual(foreClosureDate, loan.getAccruedTill()))) {
|
||||
loan.reverseAccrualsAfter(foreClosureDate);
|
||||
Money[] accruedReceivables = loan.getReceivableIncome(foreClosureDate);
|
||||
Money interestPortion = foreCloseDetail.getInterestCharged(currency).minus(accruedReceivables[0]);
|
||||
@@ -805,7 +805,7 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
|
||||
loan.addLoanTransaction(accrualTransaction);
|
||||
Set<LoanChargePaidBy> accrualCharges = accrualTransaction.getLoanChargesPaid();
|
||||
for (LoanCharge loanCharge : loan.getActiveCharges()) {
|
||||
boolean isDue = fromDate.isEqual(loan.getDisbursementDate())
|
||||
boolean isDue = DateUtils.isEqual(fromDate, loan.getDisbursementDate())
|
||||
? loanCharge.isDueForCollectionFromIncludingAndUpToAndIncluding(fromDate, foreClosureDate)
|
||||
: loanCharge.isDueForCollectionFromAndUpToAndIncluding(fromDate, foreClosureDate);
|
||||
if (loanCharge.isActive() && !loanCharge.isPaid() && (isDue || loanCharge.isInstalmentFee())) {
|
||||
|
||||
-30
@@ -1,30 +0,0 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
package org.apache.fineract.portfolio.loanaccount.domain;
|
||||
|
||||
import java.util.Comparator;
|
||||
import org.apache.fineract.portfolio.loanaccount.data.LoanTransactionData;
|
||||
|
||||
public class LoanRepaymentDataComparator implements Comparator<LoanTransactionData> {
|
||||
|
||||
@Override
|
||||
public int compare(final LoanTransactionData o1, final LoanTransactionData o2) {
|
||||
return o2.getDate().compareTo(o1.getDate());
|
||||
}
|
||||
}
|
||||
+2
-4
@@ -29,10 +29,8 @@ public class LoanTermVariationsComparator implements Comparator<LoanTermVariatio
|
||||
public int compare(final LoanTermVariations o1, final LoanTermVariations o2) {
|
||||
int compareResult = 0;
|
||||
final int comparsion = o1.getTermApplicableFrom().compareTo(o2.getTermApplicableFrom());
|
||||
/**
|
||||
* For Terms bearing the same effective date, we sort based on modified date (when available) and new inserted
|
||||
* installment
|
||||
**/
|
||||
// For Terms bearing the same effective date, we sort based on modified date (when available) and new inserted
|
||||
// installment
|
||||
if (comparsion == 0) {
|
||||
if (o2.getTermType().isDueDateVariation() || o2.getTermType().isInsertInstallment()) {
|
||||
compareResult = 1;
|
||||
|
||||
+16
-14
@@ -27,6 +27,7 @@ import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
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;
|
||||
@@ -312,7 +313,7 @@ public abstract class AbstractLoanRepaymentScheduleTransactionProcessor implemen
|
||||
protected boolean isTransactionInAdvanceOfInstallment(final int installmentIndex,
|
||||
final List<LoanRepaymentScheduleInstallment> installments, final LocalDate transactionDate) {
|
||||
final LoanRepaymentScheduleInstallment currentInstallment = installments.get(installmentIndex);
|
||||
return transactionDate.isBefore(currentInstallment.getDueDate());
|
||||
return DateUtils.isBefore(transactionDate, currentInstallment.getDueDate());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -325,7 +326,7 @@ public abstract class AbstractLoanRepaymentScheduleTransactionProcessor implemen
|
||||
protected boolean isTransactionALateRepaymentOnInstallment(final int installmentIndex,
|
||||
final List<LoanRepaymentScheduleInstallment> installments, final LocalDate transactionDate) {
|
||||
final LoanRepaymentScheduleInstallment currentInstallment = installments.get(installmentIndex);
|
||||
return transactionDate.isAfter(currentInstallment.getDueDate());
|
||||
return DateUtils.isAfter(transactionDate, currentInstallment.getDueDate());
|
||||
}
|
||||
|
||||
private void recalculateChargeOffTransaction(ChangedTransactionDetail changedTransactionDetail, LoanTransaction loanTransaction,
|
||||
@@ -477,7 +478,7 @@ public abstract class AbstractLoanRepaymentScheduleTransactionProcessor implemen
|
||||
LocalDate pastDueDate = null;
|
||||
for (final LoanRepaymentScheduleInstallment currentInstallment : installments) {
|
||||
pastDueDate = currentInstallment.getDueDate();
|
||||
if (!currentInstallment.isAdditional() && currentInstallment.getDueDate().isAfter(transactionDate)) {
|
||||
if (!currentInstallment.isAdditional() && DateUtils.isAfter(currentInstallment.getDueDate(), transactionDate)) {
|
||||
currentInstallment.addToCredits(transactionAmount.getAmount());
|
||||
currentInstallment.addToPrincipal(transactionDate, transactionAmount);
|
||||
if (repaidAmount.isGreaterThanZero()) {
|
||||
@@ -491,7 +492,7 @@ public abstract class AbstractLoanRepaymentScheduleTransactionProcessor implemen
|
||||
// If already exists an additional installment just update the due date and
|
||||
// principal from the Loan chargeback / CBR transaction
|
||||
} else if (currentInstallment.isAdditional()) {
|
||||
if (transactionDate.isAfter(currentInstallment.getDueDate())) {
|
||||
if (DateUtils.isAfter(transactionDate, currentInstallment.getDueDate())) {
|
||||
currentInstallment.updateDueDate(transactionDate);
|
||||
}
|
||||
|
||||
@@ -669,18 +670,19 @@ public abstract class AbstractLoanRepaymentScheduleTransactionProcessor implemen
|
||||
if (loanCharge.getAmountOutstanding(currency).isGreaterThanZero() && !loanCharge.isDueAtDisbursement()) {
|
||||
if (loanCharge.isInstalmentFee()) {
|
||||
LoanInstallmentCharge unpaidLoanChargePerInstallment = loanCharge.getUnpaidInstallmentLoanCharge();
|
||||
if (chargePerInstallment == null || chargePerInstallment.getRepaymentInstallment().getDueDate()
|
||||
.isAfter(unpaidLoanChargePerInstallment.getRepaymentInstallment().getDueDate())) {
|
||||
if (chargePerInstallment == null || DateUtils.isAfter(chargePerInstallment.getRepaymentInstallment().getDueDate(),
|
||||
unpaidLoanChargePerInstallment.getRepaymentInstallment().getDueDate())) {
|
||||
installemntCharge = loanCharge;
|
||||
chargePerInstallment = unpaidLoanChargePerInstallment;
|
||||
}
|
||||
} else if (earliestUnpaidCharge == null || loanCharge.getDueLocalDate().isBefore(earliestUnpaidCharge.getDueLocalDate())) {
|
||||
} else if (earliestUnpaidCharge == null
|
||||
|| DateUtils.isBefore(loanCharge.getDueLocalDate(), earliestUnpaidCharge.getDueLocalDate())) {
|
||||
earliestUnpaidCharge = loanCharge;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (earliestUnpaidCharge == null || (chargePerInstallment != null
|
||||
&& earliestUnpaidCharge.getDueLocalDate().isAfter(chargePerInstallment.getRepaymentInstallment().getDueDate()))) {
|
||||
if (earliestUnpaidCharge == null || (chargePerInstallment != null && DateUtils.isAfter(earliestUnpaidCharge.getDueLocalDate(),
|
||||
chargePerInstallment.getRepaymentInstallment().getDueDate()))) {
|
||||
earliestUnpaidCharge = installemntCharge;
|
||||
}
|
||||
|
||||
@@ -791,20 +793,20 @@ public abstract class AbstractLoanRepaymentScheduleTransactionProcessor implemen
|
||||
if (loanCharge.isInstalmentFee()) {
|
||||
LoanInstallmentCharge paidLoanChargePerInstallment = loanCharge
|
||||
.getLastPaidOrPartiallyPaidInstallmentLoanCharge(currency);
|
||||
if (chargePerInstallment == null
|
||||
|| (paidLoanChargePerInstallment != null && chargePerInstallment.getRepaymentInstallment().getDueDate()
|
||||
.isBefore(paidLoanChargePerInstallment.getRepaymentInstallment().getDueDate()))) {
|
||||
if (chargePerInstallment == null || (paidLoanChargePerInstallment != null
|
||||
&& DateUtils.isBefore(chargePerInstallment.getRepaymentInstallment().getDueDate(),
|
||||
paidLoanChargePerInstallment.getRepaymentInstallment().getDueDate()))) {
|
||||
installemntCharge = loanCharge;
|
||||
chargePerInstallment = paidLoanChargePerInstallment;
|
||||
}
|
||||
} else if (latestPaidCharge == null || (loanCharge.isPaidOrPartiallyPaid(currency)
|
||||
&& loanCharge.getDueLocalDate().isAfter(latestPaidCharge.getDueLocalDate()))) {
|
||||
&& DateUtils.isAfter(loanCharge.getDueLocalDate(), latestPaidCharge.getDueLocalDate()))) {
|
||||
latestPaidCharge = loanCharge;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (latestPaidCharge == null || (chargePerInstallment != null
|
||||
&& latestPaidCharge.getDueLocalDate().isAfter(chargePerInstallment.getRepaymentInstallment().getDueDate()))) {
|
||||
&& DateUtils.isAfter(latestPaidCharge.getDueLocalDate(), chargePerInstallment.getRepaymentInstallment().getDueDate()))) {
|
||||
latestPaidCharge = installemntCharge;
|
||||
}
|
||||
|
||||
|
||||
+5
-5
@@ -194,7 +194,7 @@ public class AdvancedPaymentScheduleTransactionProcessor extends AbstractLoanRep
|
||||
switch (paymentAllocationType.getDueType()) {
|
||||
case PAST_DUE -> {
|
||||
currentInstallment = installments.stream().filter(LoanRepaymentScheduleInstallment::isNotFullyPaidOff)
|
||||
.filter(e -> loanTransaction.getTransactionDate().isAfter(e.getDueDate()))
|
||||
.filter(e -> loanTransaction.isAfter(e.getDueDate()))
|
||||
.min(Comparator.comparing(LoanRepaymentScheduleInstallment::getInstallmentNumber)).orElse(null);
|
||||
if (currentInstallment != null) {
|
||||
LoanTransactionToRepaymentScheduleMapping loanTransactionToRepaymentScheduleMapping = getTransactionMapping(
|
||||
@@ -206,7 +206,7 @@ public class AdvancedPaymentScheduleTransactionProcessor extends AbstractLoanRep
|
||||
}
|
||||
case DUE -> {
|
||||
currentInstallment = installments.stream().filter(LoanRepaymentScheduleInstallment::isNotFullyPaidOff)
|
||||
.filter(e -> loanTransaction.getTransactionDate().isEqual(e.getDueDate()))
|
||||
.filter(e -> loanTransaction.isOn(e.getDueDate()))
|
||||
.min(Comparator.comparing(LoanRepaymentScheduleInstallment::getInstallmentNumber)).orElse(null);
|
||||
if (currentInstallment != null) {
|
||||
LoanTransactionToRepaymentScheduleMapping loanTransactionToRepaymentScheduleMapping = getTransactionMapping(
|
||||
@@ -222,14 +222,14 @@ public class AdvancedPaymentScheduleTransactionProcessor extends AbstractLoanRep
|
||||
List<LoanRepaymentScheduleInstallment> currentInstallments = new ArrayList<>();
|
||||
if (FutureInstallmentAllocationRule.REAMORTIZATION.equals(futureInstallmentAllocationRule)) {
|
||||
currentInstallments = installments.stream().filter(LoanRepaymentScheduleInstallment::isNotFullyPaidOff)
|
||||
.filter(e -> loanTransaction.getTransactionDate().isBefore(e.getDueDate())).toList();
|
||||
.filter(e -> loanTransaction.isBefore(e.getDueDate())).toList();
|
||||
} else if (FutureInstallmentAllocationRule.NEXT_INSTALLMENT.equals(futureInstallmentAllocationRule)) {
|
||||
currentInstallments = installments.stream().filter(LoanRepaymentScheduleInstallment::isNotFullyPaidOff)
|
||||
.filter(e -> loanTransaction.getTransactionDate().isBefore(e.getDueDate()))
|
||||
.filter(e -> loanTransaction.isBefore(e.getDueDate()))
|
||||
.min(Comparator.comparing(LoanRepaymentScheduleInstallment::getInstallmentNumber)).stream().toList();
|
||||
} else if (FutureInstallmentAllocationRule.LAST_INSTALLMENT.equals(futureInstallmentAllocationRule)) {
|
||||
currentInstallments = installments.stream().filter(LoanRepaymentScheduleInstallment::isNotFullyPaidOff)
|
||||
.filter(e -> loanTransaction.getTransactionDate().isBefore(e.getDueDate()))
|
||||
.filter(e -> loanTransaction.isBefore(e.getDueDate()))
|
||||
.max(Comparator.comparing(LoanRepaymentScheduleInstallment::getInstallmentNumber)).stream().toList();
|
||||
}
|
||||
int numberOfInstallments = currentInstallments.size();
|
||||
|
||||
+3
-2
@@ -21,6 +21,7 @@ package org.apache.fineract.portfolio.loanaccount.domain.transactionprocessor.im
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
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.loanaccount.domain.LoanCharge;
|
||||
@@ -102,7 +103,7 @@ public class DuePenFeeIntPriInAdvancePriPenFeeIntLoanRepaymentScheduleTransactio
|
||||
|
||||
List<LoanCharge> orderedLoanChargesByDueDate = charges.stream().filter(LoanCharge::isActive).filter(LoanCharge::isChargePending)
|
||||
.filter(loanCharge -> loanCharge.getEffectiveDueDate() == null
|
||||
|| !loanCharge.getEffectiveDueDate().isAfter(transactionDate))
|
||||
|| !DateUtils.isAfter(loanCharge.getEffectiveDueDate(), transactionDate))
|
||||
.sorted(LoanChargeEffectiveDueDateComparator.INSTANCE).toList();
|
||||
Money calculatedPenaltyCharge = Money.zero(currency);
|
||||
Money calculatedFeeCharge = Money.zero(currency);
|
||||
@@ -141,7 +142,7 @@ public class DuePenFeeIntPriInAdvancePriPenFeeIntLoanRepaymentScheduleTransactio
|
||||
feeChargesPortion = feeChargesPortion.add(subFeePortion);
|
||||
|
||||
Money subInterestPortion;
|
||||
if (ignoreDueDateCheck || !transactionDate.isBefore(currentInstallment.getDueDate())) {
|
||||
if (ignoreDueDateCheck || !DateUtils.isBefore(transactionDate, currentInstallment.getDueDate())) {
|
||||
subInterestPortion = currentInstallment.payInterestComponent(transactionDate, transactionAmountRemaining);
|
||||
transactionAmountRemaining = transactionAmountRemaining.minus(subInterestPortion);
|
||||
interestPortion = interestPortion.add(subInterestPortion);
|
||||
|
||||
+3
-4
@@ -21,6 +21,7 @@ package org.apache.fineract.portfolio.loanaccount.domain.transactionprocessor.im
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
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.loanaccount.domain.LoanCharge;
|
||||
@@ -102,7 +103,7 @@ public class DuePenIntPriFeeInAdvancePenIntPriFeeLoanRepaymentScheduleTransactio
|
||||
|
||||
List<LoanCharge> orderedLoanChargesByDueDate = charges.stream().filter(LoanCharge::isActive).filter(LoanCharge::isChargePending)
|
||||
.filter(loanCharge -> loanCharge.getEffectiveDueDate() == null
|
||||
|| !loanCharge.getEffectiveDueDate().isAfter(transactionDate))
|
||||
|| !DateUtils.isAfter(loanCharge.getEffectiveDueDate(), transactionDate))
|
||||
.sorted(LoanChargeEffectiveDueDateComparator.INSTANCE).toList();
|
||||
Money calculatedPenaltyCharge = Money.zero(currency);
|
||||
Money calculatedFeeCharge = Money.zero(currency);
|
||||
@@ -129,13 +130,11 @@ public class DuePenIntPriFeeInAdvancePenIntPriFeeLoanRepaymentScheduleTransactio
|
||||
penaltyChargesPortion = penaltyChargesPortion.add(subPenaltyPortion);
|
||||
|
||||
Money subInterestPortion;
|
||||
if (ignoreDueDateCheck || !transactionDate.isBefore(currentInstallment.getDueDate())) {
|
||||
if (ignoreDueDateCheck || !DateUtils.isBefore(transactionDate, currentInstallment.getDueDate())) {
|
||||
subInterestPortion = currentInstallment.payInterestComponent(transactionDate, transactionAmountRemaining);
|
||||
transactionAmountRemaining = transactionAmountRemaining.minus(subInterestPortion);
|
||||
interestPortion = interestPortion.add(subInterestPortion);
|
||||
}
|
||||
|
||||
if (ignoreDueDateCheck || !transactionDate.isBefore(currentInstallment.getDueDate())) {
|
||||
Money subPrincipalPortion = currentInstallment.payPrincipalComponent(transactionDate, transactionAmountRemaining);
|
||||
transactionAmountRemaining = transactionAmountRemaining.minus(subPrincipalPortion);
|
||||
principalPortion = principalPortion.add(subPrincipalPortion);
|
||||
|
||||
+2
-3
@@ -21,6 +21,7 @@ package org.apache.fineract.portfolio.loanaccount.domain.transactionprocessor.im
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
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.loanaccount.domain.LoanCharge;
|
||||
@@ -85,9 +86,7 @@ public class HeavensFamilyLoanRepaymentScheduleTransactionProcessor extends Abst
|
||||
final LoanRepaymentScheduleInstallment previousInstallment = installments.get(previousInstallmentIndex);
|
||||
lastInstallmentDueDate = previousInstallment.getDueDate();
|
||||
|
||||
isInAdvance = !(transactionDate.isAfter(lastInstallmentDueDate) || transactionDate.isEqual(lastInstallmentDueDate));
|
||||
|
||||
return isInAdvance;
|
||||
return DateUtils.isBefore(transactionDate, lastInstallmentDueDate);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+4
-5
@@ -21,6 +21,7 @@ package org.apache.fineract.portfolio.loanaccount.domain.transactionprocessor.im
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
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.loanaccount.domain.LoanCharge;
|
||||
@@ -174,14 +175,12 @@ public class RBILoanRepaymentScheduleTransactionProcessor extends AbstractLoanRe
|
||||
|
||||
private LoanRepaymentScheduleInstallment nearestInstallment(final LocalDate transactionDate,
|
||||
final List<LoanRepaymentScheduleInstallment> installments) {
|
||||
|
||||
LoanRepaymentScheduleInstallment nearest = installments.get(0);
|
||||
LoanRepaymentScheduleInstallment nearest = installments.get(0); // installments must be sorted by dates
|
||||
for (final LoanRepaymentScheduleInstallment installment : installments) {
|
||||
if (installment.getDueDate().isBefore(transactionDate) || installment.getDueDate().isEqual(transactionDate)) {
|
||||
nearest = installment;
|
||||
} else if (installment.getDueDate().isAfter(transactionDate)) {
|
||||
if (DateUtils.isBefore(transactionDate, installment.getDueDate())) {
|
||||
break;
|
||||
}
|
||||
nearest = installment;
|
||||
}
|
||||
return nearest;
|
||||
}
|
||||
|
||||
+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.getTransactionDate().isAfter(loan.getApprovedOnDate())) {
|
||||
if (!DateUtils.isAfter(transaction.getTransactionDate(), loan.getApprovedOnDate())) {
|
||||
transactions.add(transaction);
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -187,7 +187,7 @@ public class GuarantorWritePlatformServiceJpaRepositoryIImpl implements Guaranto
|
||||
|
||||
private void validateGuarantorSavingsAccountActivationDateWithLoanSubmittedOnDate(final Loan loan,
|
||||
final SavingsAccount savingsAccount) {
|
||||
if (loan.getSubmittedOnDate().isBefore(savingsAccount.getActivationDate())) {
|
||||
if (DateUtils.isBefore(loan.getSubmittedOnDate(), 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.getActivationDate()
|
||||
|
||||
+7
-7
@@ -27,6 +27,7 @@ import java.util.Set;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.fineract.infrastructure.configuration.domain.ConfigurationDomainService;
|
||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||
import org.apache.fineract.infrastructure.event.business.domain.loan.LoanRescheduledDueHolidayBusinessEvent;
|
||||
import org.apache.fineract.infrastructure.event.business.service.BusinessEventNotifierService;
|
||||
import org.apache.fineract.organisation.holiday.domain.Holiday;
|
||||
@@ -120,16 +121,15 @@ public class ApplyHolidaysToLoansTasklet implements Tasklet {
|
||||
// Loop through all loanRepayments
|
||||
List<LoanRepaymentScheduleInstallment> installments = loan.getRepaymentScheduleInstallments();
|
||||
for (final LoanRepaymentScheduleInstallment loanRepaymentScheduleInstallment : installments) {
|
||||
|
||||
final LocalDate oldDueDate = loanRepaymentScheduleInstallment.getDueDate();
|
||||
|
||||
// update from date if it's not same as previous installment's due
|
||||
// date.
|
||||
if (!loanRepaymentScheduleInstallment.getFromDate().isEqual(tmpFromDate)) {
|
||||
if (!DateUtils.isEqual(tmpFromDate, loanRepaymentScheduleInstallment.getFromDate())) {
|
||||
loanRepaymentScheduleInstallment.updateFromDate(tmpFromDate);
|
||||
}
|
||||
|
||||
if (oldDueDate.equals(holiday.getFromDate()) || oldDueDate.isAfter(holiday.getFromDate())) {
|
||||
if (!DateUtils.isBefore(oldDueDate, holiday.getFromDate())) {
|
||||
// FIXME: AA do we need to apply non-working days.
|
||||
// Assuming holiday's repayment reschedule to date cannot be
|
||||
// created on a non-working day.
|
||||
@@ -146,7 +146,7 @@ public class ApplyHolidaysToLoansTasklet implements Tasklet {
|
||||
LocalDate adjustedRescheduleToDate = null;
|
||||
final LocalDate rescheduleToDate = holiday.getToDate();
|
||||
for (final LoanRepaymentScheduleInstallment loanRepaymentScheduleInstallment : loan.getRepaymentScheduleInstallments()) {
|
||||
if (rescheduleToDate.isEqual(loanRepaymentScheduleInstallment.getDueDate())) {
|
||||
if (DateUtils.isEqual(rescheduleToDate, loanRepaymentScheduleInstallment.getDueDate())) {
|
||||
adjustedRescheduleToDate = rescheduleToDate;
|
||||
break;
|
||||
} else {
|
||||
@@ -160,9 +160,9 @@ public class ApplyHolidaysToLoansTasklet implements Tasklet {
|
||||
private LocalDate doStandardMonthlyCheck(LocalDate adjustedRescheduleToDate, LocalDate rescheduleToDate,
|
||||
LoanRepaymentScheduleInstallment loanRepaymentScheduleInstallment) {
|
||||
// Standard Monthly Loan Holiday check
|
||||
if (rescheduleToDate.isAfter(loanRepaymentScheduleInstallment.getDueDate())
|
||||
&& rescheduleToDate.isBefore(loanRepaymentScheduleInstallment.getDueDate().plusDays(30))) {
|
||||
adjustedRescheduleToDate = loanRepaymentScheduleInstallment.getDueDate();
|
||||
LocalDate dueDate = loanRepaymentScheduleInstallment.getDueDate();
|
||||
if (DateUtils.isAfter(rescheduleToDate, dueDate) && DateUtils.isBefore(rescheduleToDate, dueDate.plusDays(30))) {
|
||||
adjustedRescheduleToDate = dueDate;
|
||||
}
|
||||
return adjustedRescheduleToDate;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user