Capturing Time

This commit is contained in:
Koustav Muhuri
2016-04-01 13:00:13 +05:30
parent 8dfec9a375
commit 5178d3a8bf
16 changed files with 199 additions and 27 deletions
@@ -33,10 +33,14 @@ import org.apache.fineract.infrastructure.security.domain.BasicPasswordEncodable
import org.apache.fineract.infrastructure.security.domain.PlatformUser; import org.apache.fineract.infrastructure.security.domain.PlatformUser;
import org.apache.fineract.infrastructure.security.service.PlatformPasswordEncoder; import org.apache.fineract.infrastructure.security.service.PlatformPasswordEncoder;
import org.joda.time.LocalDate; import org.joda.time.LocalDate;
import org.joda.time.LocalDateTime;
import org.joda.time.MonthDay; import org.joda.time.MonthDay;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import com.google.gson.JsonArray; import com.google.gson.JsonArray;
import com.google.gson.JsonElement; import com.google.gson.JsonElement;
import com.google.gson.JsonPrimitive;
import com.google.gson.reflect.TypeToken; import com.google.gson.reflect.TypeToken;
/** /**
@@ -175,6 +179,18 @@ public final class JsonCommand {
return this.productId; return this.productId;
} }
private boolean differenceExistsTime(final LocalDateTime baseValue, final LocalDateTime workingCopyValue) {
boolean differenceExists = false;
if (baseValue != null) {
differenceExists = !baseValue.equals(workingCopyValue);
} else {
differenceExists = workingCopyValue != null;
}
return differenceExists;
}
private boolean differenceExists(final LocalDate baseValue, final LocalDate workingCopyValue) { private boolean differenceExists(final LocalDate baseValue, final LocalDate workingCopyValue) {
boolean differenceExists = false; boolean differenceExists = false;
@@ -286,6 +302,24 @@ public final class JsonCommand {
return isChangeInLocalDateParameterNamed(parameterName, localDate); return isChangeInLocalDateParameterNamed(parameterName, localDate);
} }
public boolean isChangeInTimeParameterNamed(final String parameterName, final Date existingValue,final String timeFormat) {
LocalDateTime time = null;
if (existingValue != null) {
DateTimeFormatter timeFormtter = DateTimeFormat.forPattern(timeFormat);
time = LocalDateTime.parse(existingValue.toString(), timeFormtter);
}
return isChangeInLocalTimeParameterNamed(parameterName, time);
}
public boolean isChangeInLocalTimeParameterNamed(final String parameterName, final LocalDateTime existingValue) {
boolean isChanged = false;
if (parameterExists(parameterName)) {
final LocalDateTime workingValue = localTimeValueOfParameterNamed(parameterName);
isChanged = differenceExistsTime(existingValue, workingValue);
}
return isChanged;
}
public boolean isChangeInLocalDateParameterNamed(final String parameterName, final LocalDate existingValue) { public boolean isChangeInLocalDateParameterNamed(final String parameterName, final LocalDate existingValue) {
boolean isChanged = false; boolean isChanged = false;
if (parameterExists(parameterName)) { if (parameterExists(parameterName)) {
@@ -298,6 +332,9 @@ public final class JsonCommand {
public LocalDate localDateValueOfParameterNamed(final String parameterName) { public LocalDate localDateValueOfParameterNamed(final String parameterName) {
return this.fromApiJsonHelper.extractLocalDateNamed(parameterName, this.parsedCommand); return this.fromApiJsonHelper.extractLocalDateNamed(parameterName, this.parsedCommand);
} }
public LocalDateTime localTimeValueOfParameterNamed(final String parameterName) {
return this.fromApiJsonHelper.extractLocalTimeNamed(parameterName, this.parsedCommand);
}
public MonthDay extractMonthDayNamed(final String parameterName) { public MonthDay extractMonthDayNamed(final String parameterName) {
return this.fromApiJsonHelper.extractMonthDayNamed(parameterName, this.parsedCommand); return this.fromApiJsonHelper.extractMonthDayNamed(parameterName, this.parsedCommand);
@@ -25,7 +25,6 @@ import org.apache.commons.lang.StringUtils;
import org.joda.time.LocalDate; import org.joda.time.LocalDate;
import org.quartz.CronExpression; import org.quartz.CronExpression;
import org.springframework.util.ObjectUtils; import org.springframework.util.ObjectUtils;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.text.ParseException; import java.text.ParseException;
import java.util.Arrays; import java.util.Arrays;
@@ -26,6 +26,7 @@ import java.util.Date;
import org.joda.time.DateTime; import org.joda.time.DateTime;
import org.joda.time.LocalDate; import org.joda.time.LocalDate;
import org.joda.time.LocalTime;
import org.springframework.jdbc.support.JdbcUtils; import org.springframework.jdbc.support.JdbcUtils;
/** /**
@@ -51,7 +52,14 @@ public class JdbcSupport {
} }
return localDate; return localDate;
} }
public static LocalTime getLocalTime(final ResultSet rs, final String columnName) throws SQLException {
LocalTime localTime = null;
final Date timeValue = rs.getTime(columnName);
if (timeValue != null) {
localTime = new LocalTime(timeValue);
}
return localTime;
}
public static Long getLong(final ResultSet rs, final String columnName) throws SQLException { public static Long getLong(final ResultSet rs, final String columnName) throws SQLException {
return (Long) JdbcUtils.getResultSetValue(rs, rs.findColumn(columnName), Long.class); return (Long) JdbcUtils.getResultSetValue(rs, rs.findColumn(columnName), Long.class);
} }
@@ -33,6 +33,7 @@ import org.apache.commons.lang.StringUtils;
import org.apache.fineract.infrastructure.core.exception.InvalidJsonException; import org.apache.fineract.infrastructure.core.exception.InvalidJsonException;
import org.apache.fineract.infrastructure.core.exception.UnsupportedParameterException; import org.apache.fineract.infrastructure.core.exception.UnsupportedParameterException;
import org.joda.time.LocalDate; import org.joda.time.LocalDate;
import org.joda.time.LocalDateTime;
import org.joda.time.MonthDay; import org.joda.time.MonthDay;
import org.springframework.context.annotation.Primary; import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@@ -198,6 +199,10 @@ public class FromJsonHelper {
return this.helperDelegator.extractLocalDateNamed(parameterName, element, new HashSet<String>()); return this.helperDelegator.extractLocalDateNamed(parameterName, element, new HashSet<String>());
} }
public LocalDateTime extractLocalTimeNamed(final String parameterName, final JsonElement element) {
return this.helperDelegator.extractLocalTimeNamed(parameterName, element, new HashSet<String>());
}
public LocalDate extractLocalDateNamed(final String parameterName, final JsonElement element, final String dateFormat, public LocalDate extractLocalDateNamed(final String parameterName, final JsonElement element, final String dateFormat,
final Locale locale) { final Locale locale) {
return this.helperDelegator.extractLocalDateNamed(parameterName, element.getAsJsonObject(), dateFormat, locale, return this.helperDelegator.extractLocalDateNamed(parameterName, element.getAsJsonObject(), dateFormat, locale,
@@ -198,6 +198,20 @@ public class JsonParserHelper {
return value; return value;
} }
public String extractTimeFormatParameter(final JsonObject element) {
String value = null;
if (element.isJsonObject()) {
final JsonObject object = element.getAsJsonObject();
final String timeFormatParameter = "timeFormat";
if (object.has(timeFormatParameter) && object.get(timeFormatParameter).isJsonPrimitive()) {
final JsonPrimitive primitive = object.get(timeFormatParameter).getAsJsonPrimitive();
value = primitive.getAsString();
}
}
return value;
}
public String extractMonthDayFormatParameter(final JsonObject element) { public String extractMonthDayFormatParameter(final JsonObject element) {
String value = null; String value = null;
if (element.isJsonObject()) { if (element.isJsonObject()) {
@@ -344,6 +358,54 @@ public class JsonParserHelper {
return value; return value;
} }
public LocalDateTime extractLocalTimeNamed(final String parameterName, final JsonElement element,
final Set<String> parametersPassedInCommand) {
LocalDateTime value = null;
if (element.isJsonObject()) {
final JsonObject object = element.getAsJsonObject();
final String timeFormat = extractTimeFormatParameter(object);
final Locale clientApplicationLocale = extractLocaleParameter(object);
value = extractLocalTimeNamed(parameterName, object, timeFormat, clientApplicationLocale, parametersPassedInCommand);
}
return value;
}
public LocalDateTime extractLocalTimeNamed(final String parameterName, final JsonObject element, final String timeFormat,
final Locale clientApplicationLocale, final Set<String> parametersPassedInCommand) {
LocalDateTime value = null;
String timeValueAsString=null;
if (element.isJsonObject()) {
final JsonObject object = element.getAsJsonObject();
if (object.has(parameterName) && object.get(parameterName).isJsonPrimitive()) {
parametersPassedInCommand.add(parameterName);
try{
DateTimeFormatter timeFormtter = DateTimeFormat.forPattern(timeFormat);
final JsonPrimitive primitive = object.get(parameterName).getAsJsonPrimitive();
timeValueAsString = primitive.getAsString();
if (StringUtils.isNotBlank(timeValueAsString)) {
value = LocalDateTime.parse(timeValueAsString, timeFormtter);
}
}
catch(IllegalArgumentException e ){
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
final String defaultMessage = new StringBuilder("The parameter '" + timeValueAsString
+ "' is not in correct format.").toString();
final ApiParameterError error = ApiParameterError.parameterError("validation.msg.invalid.TimeFormat", defaultMessage,
parameterName);
dataValidationErrors.add(error);
throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.",
dataValidationErrors);
}
}
}
return value;
}
public LocalDate extractLocalDateNamed(final String parameterName, final JsonObject element, final String dateFormat, public LocalDate extractLocalDateNamed(final String parameterName, final JsonObject element, final String dateFormat,
final Locale clientApplicationLocale, final Set<String> parametersPassedInCommand) { final Locale clientApplicationLocale, final Set<String> parametersPassedInCommand) {
LocalDate value = null; LocalDate value = null;
@@ -31,7 +31,7 @@ public class CalendarConstants {
"typeId"), REPEATING("repeating"), REMIND_BY_ID("remindById"), FIRST_REMINDER("firstReminder"), SECOND_REMINDER( "typeId"), REPEATING("repeating"), REMIND_BY_ID("remindById"), FIRST_REMINDER("firstReminder"), SECOND_REMINDER(
"secondReminder"), LOCALE("locale"), DATE_FORMAT("dateFormat"), FREQUENCY("frequency"), INTERVAL("interval"), REPEATS_ON_DAY( "secondReminder"), LOCALE("locale"), DATE_FORMAT("dateFormat"), FREQUENCY("frequency"), INTERVAL("interval"), REPEATS_ON_DAY(
"repeatsOnDay"), RESCHEDULE_BASED_ON_MEETING_DATES("reschedulebasedOnMeetingDates"), PRESENT_MEETING_DATE( "repeatsOnDay"), RESCHEDULE_BASED_ON_MEETING_DATES("reschedulebasedOnMeetingDates"), PRESENT_MEETING_DATE(
"presentMeetingDate"), NEW_MEETING_DATE("newMeetingDate"), ; "presentMeetingDate"), NEW_MEETING_DATE("newMeetingDate"),MEETING_TIME("meetingtime"),Time_Format("timeFormat"), ;
private final String value; private final String value;
@@ -29,6 +29,7 @@ import org.apache.fineract.portfolio.calendar.domain.CalendarWeekDaysType;
import org.apache.fineract.portfolio.calendar.service.CalendarEnumerations; import org.apache.fineract.portfolio.calendar.service.CalendarEnumerations;
import org.apache.fineract.portfolio.calendar.service.CalendarUtils; import org.apache.fineract.portfolio.calendar.service.CalendarUtils;
import org.joda.time.LocalDate; import org.joda.time.LocalDate;
import org.joda.time.LocalTime;
/** /**
* Immutable data object representing a Calendar. * Immutable data object representing a Calendar.
@@ -44,6 +45,7 @@ public class CalendarData {
private final String location; private final String location;
private final LocalDate startDate; private final LocalDate startDate;
private final LocalDate endDate; private final LocalDate endDate;
private final LocalTime meetingTime;
private final Integer duration; private final Integer duration;
private final EnumOptionData type; private final EnumOptionData type;
private final boolean repeating; private final boolean repeating;
@@ -65,7 +67,6 @@ public class CalendarData {
private final String createdByUsername; private final String createdByUsername;
private final Long lastUpdatedByUserId; private final Long lastUpdatedByUserId;
private final String lastUpdatedByUsername; private final String lastUpdatedByUsername;
// template related // template related
final List<EnumOptionData> entityTypeOptions; final List<EnumOptionData> entityTypeOptions;
final List<EnumOptionData> calendarTypeOptions; final List<EnumOptionData> calendarTypeOptions;
@@ -79,7 +80,7 @@ public class CalendarData {
final EnumOptionData frequency, final Integer interval, final EnumOptionData repeatsOnDay, final EnumOptionData remindBy, final EnumOptionData frequency, final Integer interval, final EnumOptionData repeatsOnDay, final EnumOptionData remindBy,
final Integer firstReminder, final Integer secondReminder, final String humanReadable, final LocalDate createdDate, final Integer firstReminder, final Integer secondReminder, final String humanReadable, final LocalDate createdDate,
final LocalDate lastUpdatedDate, final Long createdByUserId, final String createdByUsername, final Long lastUpdatedByUserId, final LocalDate lastUpdatedDate, final Long createdByUserId, final String createdByUsername, final Long lastUpdatedByUserId,
final String lastUpdatedByUsername) { final String lastUpdatedByUsername, final LocalTime meetingTime) {
final Collection<LocalDate> recurringDates = null; final Collection<LocalDate> recurringDates = null;
final Collection<LocalDate> nextTenRecurringDates = null; final Collection<LocalDate> nextTenRecurringDates = null;
@@ -95,7 +96,7 @@ public class CalendarData {
type, repeating, recurrence, frequency, interval, repeatsOnDay, remindBy, firstReminder, secondReminder, recurringDates, type, repeating, recurrence, frequency, interval, repeatsOnDay, remindBy, firstReminder, secondReminder, recurringDates,
nextTenRecurringDates, humanReadable, recentEligibleMeetingDate, createdDate, lastUpdatedDate, createdByUserId, nextTenRecurringDates, humanReadable, recentEligibleMeetingDate, createdDate, lastUpdatedDate, createdByUserId,
createdByUsername, lastUpdatedByUserId, lastUpdatedByUsername, entityTypeOptions, calendarTypeOptions, remindByOptions, createdByUsername, lastUpdatedByUserId, lastUpdatedByUsername, entityTypeOptions, calendarTypeOptions, remindByOptions,
frequencyOptions, repeatsOnDayOptions); frequencyOptions, repeatsOnDayOptions, meetingTime);
} }
public static CalendarData withRecurringDates(final CalendarData calendarData, final Collection<LocalDate> recurringDates, public static CalendarData withRecurringDates(final CalendarData calendarData, final Collection<LocalDate> recurringDates,
@@ -108,7 +109,7 @@ public class CalendarData {
calendarData.createdDate, calendarData.lastUpdatedDate, calendarData.createdByUserId, calendarData.createdByUsername, calendarData.createdDate, calendarData.lastUpdatedDate, calendarData.createdByUserId, calendarData.createdByUsername,
calendarData.lastUpdatedByUserId, calendarData.lastUpdatedByUsername, calendarData.entityTypeOptions, calendarData.lastUpdatedByUserId, calendarData.lastUpdatedByUsername, calendarData.entityTypeOptions,
calendarData.calendarTypeOptions, calendarData.remindByOptions, calendarData.frequencyOptions, calendarData.calendarTypeOptions, calendarData.remindByOptions, calendarData.frequencyOptions,
calendarData.repeatsOnDayOptions); calendarData.repeatsOnDayOptions,calendarData.meetingTime);
} }
public static CalendarData withRecentEligibleMeetingDate(final CalendarData calendarData, final LocalDate recentEligibleMeetingDate) { public static CalendarData withRecentEligibleMeetingDate(final CalendarData calendarData, final LocalDate recentEligibleMeetingDate) {
@@ -120,7 +121,7 @@ public class CalendarData {
recentEligibleMeetingDate, calendarData.createdDate, calendarData.lastUpdatedDate, calendarData.createdByUserId, recentEligibleMeetingDate, calendarData.createdDate, calendarData.lastUpdatedDate, calendarData.createdByUserId,
calendarData.createdByUsername, calendarData.lastUpdatedByUserId, calendarData.lastUpdatedByUsername, calendarData.createdByUsername, calendarData.lastUpdatedByUserId, calendarData.lastUpdatedByUsername,
calendarData.entityTypeOptions, calendarData.calendarTypeOptions, calendarData.remindByOptions, calendarData.entityTypeOptions, calendarData.calendarTypeOptions, calendarData.remindByOptions,
calendarData.frequencyOptions, calendarData.repeatsOnDayOptions); calendarData.frequencyOptions, calendarData.repeatsOnDayOptions,calendarData.meetingTime);
} }
public static CalendarData sensibleDefaultsForNewCalendarCreation() { public static CalendarData sensibleDefaultsForNewCalendarCreation() {
@@ -160,12 +161,13 @@ public class CalendarData {
final String createdByUsername = null; final String createdByUsername = null;
final Long lastUpdatedByUserId = null; final Long lastUpdatedByUserId = null;
final String lastUpdatedByUsername = null; final String lastUpdatedByUsername = null;
final LocalTime meetingTime = null;
return new CalendarData(id, calendarInstanceId, entityId, entityType, title, description, location, startDate, endDate, duration, return new CalendarData(id, calendarInstanceId, entityId, entityType, title, description, location, startDate, endDate, duration,
type, repeating, recurrence, frequency, interval, repeatsOnDay, remindBy, firstReminder, secondReminder, recurringDates, type, repeating, recurrence, frequency, interval, repeatsOnDay, remindBy, firstReminder, secondReminder, recurringDates,
nextTenRecurringDates, humanReadable, recentEligibleMeetingDate, createdDate, lastUpdatedDate, createdByUserId, nextTenRecurringDates, humanReadable, recentEligibleMeetingDate, createdDate, lastUpdatedDate, createdByUserId,
createdByUsername, lastUpdatedByUserId, lastUpdatedByUsername, entityTypeOptions, calendarTypeOptions, remindByOptions, createdByUsername, lastUpdatedByUserId, lastUpdatedByUsername, entityTypeOptions, calendarTypeOptions, remindByOptions,
frequencyOptions, repeatsOnDayOptions); frequencyOptions, repeatsOnDayOptions, meetingTime);
} }
public static CalendarData withTemplateOptions(final CalendarData calendarData, final List<EnumOptionData> entityTypeOptions, public static CalendarData withTemplateOptions(final CalendarData calendarData, final List<EnumOptionData> entityTypeOptions,
@@ -180,7 +182,7 @@ public class CalendarData {
calendarData.recentEligibleMeetingDate, calendarData.createdDate, calendarData.lastUpdatedDate, calendarData.recentEligibleMeetingDate, calendarData.createdDate, calendarData.lastUpdatedDate,
calendarData.createdByUserId, calendarData.createdByUsername, calendarData.lastUpdatedByUserId, calendarData.createdByUserId, calendarData.createdByUsername, calendarData.lastUpdatedByUserId,
calendarData.lastUpdatedByUsername, entityTypeOptions, calendarTypeOptions, remindByOptions, repeatsOptions, calendarData.lastUpdatedByUsername, entityTypeOptions, calendarTypeOptions, remindByOptions, repeatsOptions,
repeatsOnDayOptions); repeatsOnDayOptions,calendarData.meetingTime);
} }
private CalendarData(final Long id, final Long calendarInstanceId, final Long entityId, final EnumOptionData entityType, private CalendarData(final Long id, final Long calendarInstanceId, final Long entityId, final EnumOptionData entityType,
@@ -192,7 +194,7 @@ public class CalendarData {
final LocalDate createdDate, final LocalDate lastUpdatedDate, final Long createdByUserId, final String createdByUsername, final LocalDate createdDate, final LocalDate lastUpdatedDate, final Long createdByUserId, final String createdByUsername,
final Long lastUpdatedByUserId, final String lastUpdatedByUsername, final List<EnumOptionData> entityTypeOptions, final Long lastUpdatedByUserId, final String lastUpdatedByUsername, final List<EnumOptionData> entityTypeOptions,
final List<EnumOptionData> calendarTypeOptions, final List<EnumOptionData> remindByOptions, final List<EnumOptionData> calendarTypeOptions, final List<EnumOptionData> remindByOptions,
final List<EnumOptionData> repeatsOptions, final List<EnumOptionData> repeatsOnDayOptions) { final List<EnumOptionData> repeatsOptions, final List<EnumOptionData> repeatsOnDayOptions,final LocalTime meetingTime) {
this.id = id; this.id = id;
this.calendarInstanceId = calendarInstanceId; this.calendarInstanceId = calendarInstanceId;
this.entityId = entityId; this.entityId = entityId;
@@ -227,6 +229,7 @@ public class CalendarData {
this.remindByOptions = remindByOptions; this.remindByOptions = remindByOptions;
this.frequencyOptions = repeatsOptions; this.frequencyOptions = repeatsOptions;
this.repeatsOnDayOptions = repeatsOnDayOptions; this.repeatsOnDayOptions = repeatsOnDayOptions;
this.meetingTime = meetingTime;
} }
public Long getId() { public Long getId() {
@@ -49,7 +49,13 @@ import org.apache.fineract.portfolio.calendar.exception.CalendarDateException;
import org.apache.fineract.portfolio.calendar.exception.CalendarParameterUpdateNotSupportedException; import org.apache.fineract.portfolio.calendar.exception.CalendarParameterUpdateNotSupportedException;
import org.apache.fineract.portfolio.calendar.service.CalendarUtils; import org.apache.fineract.portfolio.calendar.service.CalendarUtils;
import org.apache.fineract.useradministration.domain.AppUser; import org.apache.fineract.useradministration.domain.AppUser;
import org.apache.poi.openxml4j.util.Nullable;
import org.joda.time.LocalDate; import org.joda.time.LocalDate;
import org.joda.time.LocalDateTime;
import org.joda.time.LocalTime;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
@Entity @Entity
@Table(name = "m_calendar") @Table(name = "m_calendar")
@@ -93,6 +99,10 @@ public class Calendar extends AbstractAuditableCustom<AppUser, Long> {
@Column(name = "second_reminder", nullable = true) @Column(name = "second_reminder", nullable = true)
private Integer secondReminder; private Integer secondReminder;
@Column(name="meeting_time",nullable=true)
@Temporal(TemporalType.TIME)
private Date meetingtime;
@OneToMany(fetch = FetchType.EAGER) @OneToMany(fetch = FetchType.EAGER)
@JoinColumn(name = "calendar_id") @JoinColumn(name = "calendar_id")
private Set<CalendarHistory> calendarHistory = new HashSet<>(); private Set<CalendarHistory> calendarHistory = new HashSet<>();
@@ -103,7 +113,7 @@ public class Calendar extends AbstractAuditableCustom<AppUser, Long> {
public Calendar(final String title, final String description, final String location, final LocalDate startDate, public Calendar(final String title, final String description, final String location, final LocalDate startDate,
final LocalDate endDate, final Integer duration, final Integer typeId, final boolean repeating, final String recurrence, final LocalDate endDate, final Integer duration, final Integer typeId, final boolean repeating, final String recurrence,
final Integer remindById, final Integer firstReminder, final Integer secondReminder) { final Integer remindById, final Integer firstReminder, final Integer secondReminder,final Date meetingtime) {
final List<ApiParameterError> dataValidationErrors = new ArrayList<>(); final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource(CALENDAR_RESOURCE_NAME); final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource(CALENDAR_RESOURCE_NAME);
@@ -138,6 +148,7 @@ public class Calendar extends AbstractAuditableCustom<AppUser, Long> {
this.remindById = remindById; this.remindById = remindById;
this.firstReminder = firstReminder; this.firstReminder = firstReminder;
this.secondReminder = secondReminder; this.secondReminder = secondReminder;
this.meetingtime=meetingtime;
} }
public static Calendar createRepeatingCalendar(final String title, final LocalDate startDate, final Integer typeId, public static Calendar createRepeatingCalendar(final String title, final LocalDate startDate, final Integer typeId,
@@ -156,8 +167,9 @@ public class Calendar extends AbstractAuditableCustom<AppUser, Long> {
final Integer remindById = null; final Integer remindById = null;
final Integer firstReminder = null; final Integer firstReminder = null;
final Integer secondReminder = null; final Integer secondReminder = null;
final Date meetingtime=null;
return new Calendar(title, description, location, startDate, endDate, duration, typeId, repeating, recurrence, remindById, return new Calendar(title, description, location, startDate, endDate, duration, typeId, repeating, recurrence, remindById,
firstReminder, secondReminder); firstReminder, secondReminder,meetingtime);
} }
public static Calendar fromJson(final JsonCommand command) { public static Calendar fromJson(final JsonCommand command) {
@@ -165,6 +177,7 @@ public class Calendar extends AbstractAuditableCustom<AppUser, Long> {
// final Long entityId = command.getSupportedEntityId(); // final Long entityId = command.getSupportedEntityId();
// final Integer entityTypeId = // final Integer entityTypeId =
// CalendarEntityType.valueOf(command.getSupportedEntityType().toUpperCase()).getValue(); // CalendarEntityType.valueOf(command.getSupportedEntityType().toUpperCase()).getValue();
Date meetingtime=null;
final String title = command.stringValueOfParameterNamed(CALENDAR_SUPPORTED_PARAMETERS.TITLE.getValue()); final String title = command.stringValueOfParameterNamed(CALENDAR_SUPPORTED_PARAMETERS.TITLE.getValue());
final String description = command.stringValueOfParameterNamed(CALENDAR_SUPPORTED_PARAMETERS.DESCRIPTION.getValue()); final String description = command.stringValueOfParameterNamed(CALENDAR_SUPPORTED_PARAMETERS.DESCRIPTION.getValue());
final String location = command.stringValueOfParameterNamed(CALENDAR_SUPPORTED_PARAMETERS.LOCATION.getValue()); final String location = command.stringValueOfParameterNamed(CALENDAR_SUPPORTED_PARAMETERS.LOCATION.getValue());
@@ -178,10 +191,14 @@ public class Calendar extends AbstractAuditableCustom<AppUser, Long> {
.getValue()); .getValue());
final Integer secondReminder = command.integerValueSansLocaleOfParameterNamed(CALENDAR_SUPPORTED_PARAMETERS.SECOND_REMINDER final Integer secondReminder = command.integerValueSansLocaleOfParameterNamed(CALENDAR_SUPPORTED_PARAMETERS.SECOND_REMINDER
.getValue()); .getValue());
final LocalDateTime time= command.localTimeValueOfParameterNamed(CALENDAR_SUPPORTED_PARAMETERS.MEETING_TIME.getValue());
if(time!=null){
meetingtime=time.toDate();
}
final String recurrence = Calendar.constructRecurrence(command, null); final String recurrence = Calendar.constructRecurrence(command, null);
return new Calendar(title, description, location, startDate, endDate, duration, typeId, repeating, recurrence, remindById, return new Calendar(title, description, location, startDate, endDate, duration, typeId, repeating, recurrence, remindById,
firstReminder, secondReminder); firstReminder, secondReminder,meetingtime);
} }
public Map<String, Object> updateStartDateAndDerivedFeilds(final LocalDate newMeetingStartDate) { public Map<String, Object> updateStartDateAndDerivedFeilds(final LocalDate newMeetingStartDate) {
@@ -388,6 +405,18 @@ public class Calendar extends AbstractAuditableCustom<AppUser, Long> {
this.secondReminder = newValue; this.secondReminder = newValue;
} }
final String timeFormat = command.stringValueOfParameterNamed(CALENDAR_SUPPORTED_PARAMETERS.Time_Format.getValue());
final String time = CALENDAR_SUPPORTED_PARAMETERS.MEETING_TIME.getValue();
if (command.isChangeInTimeParameterNamed(CALENDAR_SUPPORTED_PARAMETERS.MEETING_TIME.getValue(), this.meetingtime,timeFormat)) {
final String newValue = command.stringValueOfParameterNamed(CALENDAR_SUPPORTED_PARAMETERS.MEETING_TIME.getValue());
actualChanges.put(CALENDAR_SUPPORTED_PARAMETERS.MEETING_TIME.getValue(), newValue);
LocalDateTime timeInLocalDateTimeFormat=command.localTimeValueOfParameterNamed(time);
if(timeInLocalDateTimeFormat!=null){
this.meetingtime= timeInLocalDateTimeFormat.toDate();
}
}
return actualChanges; return actualChanges;
} }
@@ -459,6 +488,10 @@ public class Calendar extends AbstractAuditableCustom<AppUser, Long> {
return this.secondReminder; return this.secondReminder;
} }
public Date getMeetingTime(){
return this.meetingtime;
}
public LocalDate getStartDateLocalDate() { public LocalDate getStartDateLocalDate() {
LocalDate startDateLocalDate = null; LocalDate startDateLocalDate = null;
if (this.startDate != null) { if (this.startDate != null) {
@@ -38,6 +38,7 @@ import org.apache.fineract.portfolio.calendar.domain.CalendarFrequencyType;
import org.apache.fineract.portfolio.calendar.domain.CalendarRemindBy; import org.apache.fineract.portfolio.calendar.domain.CalendarRemindBy;
import org.apache.fineract.portfolio.calendar.domain.CalendarWeekDaysType; import org.apache.fineract.portfolio.calendar.domain.CalendarWeekDaysType;
import org.joda.time.LocalDate; import org.joda.time.LocalDate;
import org.joda.time.LocalDateTime;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@@ -196,6 +197,12 @@ public class CalendarCommandFromApiJsonDeserializer extends AbstractFromApiJsonD
baseDataValidator.reset().parameter(CALENDAR_SUPPORTED_PARAMETERS.SECOND_REMINDER.getValue()).value(secondReminder) baseDataValidator.reset().parameter(CALENDAR_SUPPORTED_PARAMETERS.SECOND_REMINDER.getValue()).value(secondReminder)
.ignoreIfNull().integerGreaterThanZero(); .ignoreIfNull().integerGreaterThanZero();
} }
if (this.fromApiJsonHelper.parameterExists(CALENDAR_SUPPORTED_PARAMETERS.MEETING_TIME.getValue(), element)) {
final LocalDateTime meetingTime = this.fromApiJsonHelper.extractLocalTimeNamed(CALENDAR_SUPPORTED_PARAMETERS.MEETING_TIME.getValue(),
element);
baseDataValidator.reset().parameter(CALENDAR_SUPPORTED_PARAMETERS.MEETING_TIME.getValue()).value(meetingTime).ignoreIfNull();
}
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
"Validation errors exist.", dataValidationErrors); } "Validation errors exist.", dataValidationErrors); }
@@ -327,6 +334,11 @@ public class CalendarCommandFromApiJsonDeserializer extends AbstractFromApiJsonD
baseDataValidator.reset().parameter(CALENDAR_SUPPORTED_PARAMETERS.SECOND_REMINDER.getValue()).value(secondReminder) baseDataValidator.reset().parameter(CALENDAR_SUPPORTED_PARAMETERS.SECOND_REMINDER.getValue()).value(secondReminder)
.ignoreIfNull(); .ignoreIfNull();
} }
if (this.fromApiJsonHelper.parameterExists(CALENDAR_SUPPORTED_PARAMETERS.MEETING_TIME.getValue(), element)) {
final LocalDateTime startDate = this.fromApiJsonHelper.extractLocalTimeNamed(CALENDAR_SUPPORTED_PARAMETERS.MEETING_TIME.getValue(),
element);
baseDataValidator.reset().parameter(CALENDAR_SUPPORTED_PARAMETERS.MEETING_TIME.getValue()).value(startDate).ignoreIfNull();
}
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
"Validation errors exist.", dataValidationErrors); } "Validation errors exist.", dataValidationErrors); }
@@ -35,6 +35,7 @@ import org.apache.fineract.portfolio.calendar.domain.CalendarType;
import org.apache.fineract.portfolio.calendar.exception.CalendarNotFoundException; import org.apache.fineract.portfolio.calendar.exception.CalendarNotFoundException;
import org.apache.fineract.portfolio.meeting.data.MeetingData; import org.apache.fineract.portfolio.meeting.data.MeetingData;
import org.joda.time.LocalDate; import org.joda.time.LocalDate;
import org.joda.time.LocalTime;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.EmptyResultDataAccessException; import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.JdbcTemplate;
@@ -62,7 +63,7 @@ public class CalendarReadPlatformServiceImpl implements CalendarReadPlatformServ
+ " c.duration as duration, c.calendar_type_enum as typeId, c.repeating as repeating, " + " c.duration as duration, c.calendar_type_enum as typeId, c.repeating as repeating, "
+ " c.recurrence as recurrence, c.remind_by_enum as remindById, c.first_reminder as firstReminder, c.second_reminder as secondReminder, " + " c.recurrence as recurrence, c.remind_by_enum as remindById, c.first_reminder as firstReminder, c.second_reminder as secondReminder, "
+ " c.created_date as createdDate, c.lastmodified_date as updatedDate, creatingUser.id as creatingUserId, creatingUser.username as creatingUserName, " + " c.created_date as createdDate, c.lastmodified_date as updatedDate, creatingUser.id as creatingUserId, creatingUser.username as creatingUserName, "
+ " updatingUser.id as updatingUserId, updatingUser.username as updatingUserName " + " updatingUser.id as updatingUserId, updatingUser.username as updatingUserName,c.meeting_time as meetingTime "
+ " from m_calendar c join m_calendar_instance ci on ci.calendar_id=c.id, m_appuser as creatingUser, m_appuser as updatingUser" + " from m_calendar c join m_calendar_instance ci on ci.calendar_id=c.id, m_appuser as creatingUser, m_appuser as updatingUser"
+ " where c.createdby_id=creatingUser.id and c.lastmodifiedby_id=updatingUser.id "; + " where c.createdby_id=creatingUser.id and c.lastmodifiedby_id=updatingUser.id ";
} }
@@ -106,11 +107,12 @@ public class CalendarReadPlatformServiceImpl implements CalendarReadPlatformServ
final String createdByUserName = rs.getString("creatingUserName"); final String createdByUserName = rs.getString("creatingUserName");
final Long lastUpdatedByUserId = rs.getLong("updatingUserId"); final Long lastUpdatedByUserId = rs.getLong("updatingUserId");
final String lastUpdatedByUserName = rs.getString("updatingUserName"); final String lastUpdatedByUserName = rs.getString("updatingUserName");
final LocalTime meetingTime = JdbcSupport.getLocalTime(rs,"meetingTime");
return CalendarData.instance(id, calendarInstanceId, entityId, entityType, title, description, location, startDate, endDate, return CalendarData.instance(id, calendarInstanceId, entityId, entityType, title, description, location, startDate, endDate,
duration, type, repeating, recurrence, frequency, interval, repeatsOnDay, remindBy, firstReminder, secondReminder, duration, type, repeating, recurrence, frequency, interval, repeatsOnDay, remindBy, firstReminder, secondReminder,
humanReadable, createdDate, lastUpdatedDate, createdByUserId, createdByUserName, lastUpdatedByUserId, humanReadable, createdDate, lastUpdatedDate, createdByUserId, createdByUserName, lastUpdatedByUserId,
lastUpdatedByUserName); lastUpdatedByUserName,meetingTime);
} }
} }
@@ -495,11 +497,12 @@ public class CalendarReadPlatformServiceImpl implements CalendarReadPlatformServ
final String createdByUserName = null; final String createdByUserName = null;
final Long lastUpdatedByUserId = null; final Long lastUpdatedByUserId = null;
final String lastUpdatedByUserName = null; final String lastUpdatedByUserName = null;
final LocalTime meetingTime = null;
return CalendarData.instance(id, calendarInstanceId, entityId, entityType, title, description, location, startDate, endDate, return CalendarData.instance(id, calendarInstanceId, entityId, entityType, title, description, location, startDate, endDate,
duration, type, repeating, recurrence, frequency, interval, repeatsOnDay, remindBy, firstReminder, secondReminder, duration, type, repeating, recurrence, frequency, interval, repeatsOnDay, remindBy, firstReminder, secondReminder,
humanReadable, createdDate, lastUpdatedDate, createdByUserId, createdByUserName, lastUpdatedByUserId, humanReadable, createdDate, lastUpdatedDate, createdByUserId, createdByUserName, lastUpdatedByUserId,
lastUpdatedByUserName); lastUpdatedByUserName, meetingTime);
} }
} }
@@ -288,6 +288,9 @@ public class CalendarWritePlatformServiceJpaRepositoryImpl implements CalendarWr
if (!changes.isEmpty()) { if (!changes.isEmpty()) {
// update calendar history table only if there is a change in // update calendar history table only if there is a change in
// calendar start date. // calendar start date.
if (reschedulebasedOnMeetingDates == null){
presentMeetingDate = command.localDateValueOfParameterNamed(CALENDAR_SUPPORTED_PARAMETERS.START_DATE.getValue());
}
final Date endDate = presentMeetingDate.minusDays(1).toDate(); final Date endDate = presentMeetingDate.minusDays(1).toDate();
calendarHistory.updateEndDate(endDate); calendarHistory.updateEndDate(endDate);
this.calendarHistoryRepository.save(calendarHistory); this.calendarHistoryRepository.save(calendarHistory);
@@ -65,6 +65,7 @@ import org.apache.fineract.portfolio.group.domain.GroupingTypeEnumerations;
import org.apache.fineract.portfolio.group.exception.CenterNotFoundException; import org.apache.fineract.portfolio.group.exception.CenterNotFoundException;
import org.apache.fineract.useradministration.domain.AppUser; import org.apache.fineract.useradministration.domain.AppUser;
import org.joda.time.LocalDate; import org.joda.time.LocalDate;
import org.joda.time.LocalTime;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.EmptyResultDataAccessException; import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.JdbcTemplate;
@@ -234,7 +235,7 @@ public class CenterReadPlatformServiceImpl implements CenterReadPlatformService
+ " g.status_enum as statusEnum, g.activation_date as activationDate, g.hierarchy as hierarchy, " + " g.status_enum as statusEnum, g.activation_date as activationDate, g.hierarchy as hierarchy, "
+ " c.id as calendarId, ci.id as calendarInstanceId, ci.entity_id as entityId, " + " c.id as calendarId, ci.id as calendarInstanceId, ci.entity_id as entityId, "
+ " ci.entity_type_enum as entityTypeId, c.title as title, c.description as description, " + " ci.entity_type_enum as entityTypeId, c.title as title, c.description as description, "
+ " c.location as location, c.start_date as startDate, c.end_date as endDate, c.recurrence as recurrence " + " c.location as location, c.start_date as startDate, c.end_date as endDate, c.recurrence as recurrence,c.meeting_time as meetingTime "
+ " from m_calendar c join m_calendar_instance ci on ci.calendar_id=c.id and ci.entity_type_enum=4 join m_group g " + " from m_calendar c join m_calendar_instance ci on ci.calendar_id=c.id and ci.entity_type_enum=4 join m_group g "
+ " on g.id = ci.entity_id join m_staff s on g.staff_id = s.id where g.office_id=? "; + " on g.id = ci.entity_id join m_staff s on g.staff_id = s.id where g.office_id=? ";
} }
@@ -269,10 +270,11 @@ public class CenterReadPlatformServiceImpl implements CenterReadPlatformService
final LocalDate startDate = JdbcSupport.getLocalDate(rs, "startDate"); final LocalDate startDate = JdbcSupport.getLocalDate(rs, "startDate");
final LocalDate endDate = JdbcSupport.getLocalDate(rs, "endDate"); final LocalDate endDate = JdbcSupport.getLocalDate(rs, "endDate");
final String recurrence = rs.getString("recurrence"); final String recurrence = rs.getString("recurrence");
final LocalTime meetingTime = JdbcSupport.getLocalTime(rs,"meetingTime");
CalendarData calendarData = CalendarData.instance(calendarId, calendarInstanceId, entityId, entityType, title, description, CalendarData calendarData = CalendarData.instance(calendarId, calendarInstanceId, entityId, entityType, title, description,
location, startDate, endDate, null, null, false, recurrence, null, null, null, null, null, null, null, null, null, location, startDate, endDate, null, null, false, recurrence, null, null, null, null, null, null, null, null, null,
null, null, null, null); null, null, null, null,meetingTime);
return CenterData.instance(id, accountNo, name, externalId, status, activationDate, officeId, null, staffId, staffName, hierarchy, null, return CenterData.instance(id, accountNo, name, externalId, status, activationDate, officeId, null, staffId, staffName, hierarchy, null,
calendarData); calendarData);
} }
@@ -115,6 +115,7 @@ import org.apache.fineract.portfolio.loanproduct.service.LoanEnumerations;
import org.apache.fineract.useradministration.domain.AppUser; import org.apache.fineract.useradministration.domain.AppUser;
import org.joda.time.Days; import org.joda.time.Days;
import org.joda.time.LocalDate; import org.joda.time.LocalDate;
import org.joda.time.LocalTime;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@@ -108,6 +108,7 @@ import org.apache.fineract.portfolio.savings.domain.SavingsAccount;
import org.apache.fineract.portfolio.savings.domain.SavingsAccountAssembler; import org.apache.fineract.portfolio.savings.domain.SavingsAccountAssembler;
import org.apache.fineract.useradministration.domain.AppUser; import org.apache.fineract.useradministration.domain.AppUser;
import org.joda.time.LocalDate; import org.joda.time.LocalDate;
import org.joda.time.LocalTime;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@@ -88,6 +88,7 @@ import org.apache.fineract.portfolio.savings.domain.SavingsProductRepository;
import org.apache.fineract.portfolio.savings.exception.SavingsProductNotFoundException; import org.apache.fineract.portfolio.savings.exception.SavingsProductNotFoundException;
import org.apache.fineract.useradministration.domain.AppUser; import org.apache.fineract.useradministration.domain.AppUser;
import org.joda.time.LocalDate; import org.joda.time.LocalDate;
import org.joda.time.LocalTime;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@@ -339,6 +340,7 @@ public class DepositApplicationProcessWritePlatformServiceJpaRepositoryImpl impl
final Integer repeatsOnDay = calendarStartDate.getDayOfWeek(); final Integer repeatsOnDay = calendarStartDate.getDayOfWeek();
final String title = "recurring_savings_" + account.getId(); final String title = "recurring_savings_" + account.getId();
final Calendar calendar = Calendar.createRepeatingCalendar(title, calendarStartDate, CalendarType.COLLECTION.getValue(), final Calendar calendar = Calendar.createRepeatingCalendar(title, calendarStartDate, CalendarType.COLLECTION.getValue(),
CalendarFrequencyType.from(periodFrequencyType), frequency, repeatsOnDay); CalendarFrequencyType.from(periodFrequencyType), frequency, repeatsOnDay);
calendarInstance = CalendarInstance.from(calendar, account.getId(), CalendarEntityType.SAVINGS.getValue()); calendarInstance = CalendarInstance.from(calendar, account.getId(), CalendarEntityType.SAVINGS.getValue());
@@ -0,0 +1 @@
alter table m_calendar add meeting_time Time