Merge pull request #548 from ashok-conflux/MIFOSX-607
MIFOSX-607 - capture client atendance in collection sheet
This commit is contained in:
+5
@@ -6,6 +6,7 @@
|
||||
package org.mifosplatform.commands.service;
|
||||
|
||||
import org.mifosplatform.commands.domain.CommandWrapper;
|
||||
import org.mifosplatform.portfolio.calendar.domain.CalendarEntityType;
|
||||
|
||||
public class CommandWrapperBuilder {
|
||||
|
||||
@@ -1016,6 +1017,8 @@ public class CommandWrapperBuilder {
|
||||
this.entityName = "GROUP";
|
||||
this.entityId = groupId;
|
||||
this.groupId = groupId;
|
||||
this.supportedEntityId = groupId;
|
||||
this.supportedEntityType = CalendarEntityType.GROUPS.name();
|
||||
this.href = "/groups/" + groupId + "?command=saveCollectionSheet";
|
||||
return this;
|
||||
}
|
||||
@@ -1145,6 +1148,8 @@ public class CommandWrapperBuilder {
|
||||
this.actionName = "SAVECOLLECTIONSHEET";
|
||||
this.entityName = "CENTER";
|
||||
this.entityId = centerId;
|
||||
this.supportedEntityId = centerId;
|
||||
this.supportedEntityType = CalendarEntityType.CENTERS.name();
|
||||
this.href = "/centers/" + centerId + "?command=saveCollectionSheet";
|
||||
return this;
|
||||
}
|
||||
|
||||
+16
-3
@@ -37,6 +37,7 @@ public class CalendarData {
|
||||
private final Collection<LocalDate> recurringDates;
|
||||
private final Collection<LocalDate> nextTenRecurringDates;
|
||||
private final String humanReadable;
|
||||
private final LocalDate recentEligibleMeetingDate;
|
||||
|
||||
private final LocalDate createdDate;
|
||||
private final LocalDate lastUpdatedDate;
|
||||
@@ -53,7 +54,7 @@ public class CalendarData {
|
||||
public CalendarData(final Long id, final Long entityId, final EnumOptionData entityType, final String title, final String description,
|
||||
final String location, final LocalDate startDate, final LocalDate endDate, final Integer duration, final EnumOptionData type,
|
||||
final boolean repeating, final String recurrence, final EnumOptionData remindBy, final Integer firstReminder,
|
||||
final Integer secondReminder, final String humanReadable, final LocalDate createdDate, final LocalDate lastUpdatedDate,
|
||||
final Integer secondReminder, final String humanReadable, final LocalDate recentEligibleMeetingDate, final LocalDate createdDate, final LocalDate lastUpdatedDate,
|
||||
final Long createdByUserId, final String createdByUsername, final Long lastUpdatedByUserId, final String lastUpdatedByUsername) {
|
||||
|
||||
this.id = id;
|
||||
@@ -77,6 +78,7 @@ public class CalendarData {
|
||||
this.recurringDates = null;
|
||||
this.nextTenRecurringDates = null;
|
||||
this.humanReadable = humanReadable;
|
||||
this.recentEligibleMeetingDate = recentEligibleMeetingDate;
|
||||
|
||||
this.createdDate = createdDate;
|
||||
this.lastUpdatedDate = lastUpdatedDate;
|
||||
@@ -109,6 +111,7 @@ public class CalendarData {
|
||||
this.recurringDates = calendarData.recurringDates;
|
||||
this.nextTenRecurringDates = calendarData.nextTenRecurringDates;
|
||||
this.humanReadable = calendarData.humanReadable;
|
||||
this.recentEligibleMeetingDate = calendarData.recentEligibleMeetingDate;
|
||||
this.createdDate = calendarData.createdDate;
|
||||
this.lastUpdatedDate = calendarData.lastUpdatedDate;
|
||||
this.createdByUserId = calendarData.createdByUserId;
|
||||
@@ -117,7 +120,7 @@ public class CalendarData {
|
||||
this.lastUpdatedByUsername = calendarData.lastUpdatedByUsername;
|
||||
}
|
||||
|
||||
public CalendarData(final CalendarData calendarData, final Collection<LocalDate> recurringDates, final Collection<LocalDate> nextTenRecurringDates) {
|
||||
public CalendarData(final CalendarData calendarData, final Collection<LocalDate> recurringDates, final Collection<LocalDate> nextTenRecurringDates, final LocalDate recentEligibleMeetingDate) {
|
||||
this.id = calendarData.id;
|
||||
this.entityId = calendarData.entityId;
|
||||
this.entityType = calendarData.entityType;
|
||||
@@ -139,6 +142,7 @@ public class CalendarData {
|
||||
this.recurringDates = recurringDates;
|
||||
this.nextTenRecurringDates = nextTenRecurringDates;
|
||||
this.humanReadable = calendarData.humanReadable;
|
||||
this.recentEligibleMeetingDate = recentEligibleMeetingDate;
|
||||
this.createdDate = calendarData.createdDate;
|
||||
this.lastUpdatedDate = calendarData.lastUpdatedDate;
|
||||
this.createdByUserId = calendarData.createdByUserId;
|
||||
@@ -165,9 +169,18 @@ public class CalendarData {
|
||||
final Integer firstReminder = new Integer(0);
|
||||
final Integer secondReminder = new Integer(0);
|
||||
final String humanReadable = null;
|
||||
final LocalDate recentEligibleMeetingDate = null;
|
||||
|
||||
final LocalDate createdDate = null;
|
||||
final LocalDate lastUpdatedDate = null;
|
||||
final Long createdByUserId = null;
|
||||
final String createdByUsername = null;
|
||||
final Long lastUpdatedByUserId = null;
|
||||
final String lastUpdatedByUsername = null;
|
||||
|
||||
return new CalendarData(id, entityId, entityType, title, description, location, startDate, endDate, duration, type, repeating,
|
||||
recurrence, remindBy, firstReminder, secondReminder, humanReadable, null, null, null, null, null, null);
|
||||
recurrence, remindBy, firstReminder, secondReminder, humanReadable, recentEligibleMeetingDate, createdDate,
|
||||
lastUpdatedDate, createdByUserId, createdByUsername, lastUpdatedByUserId, lastUpdatedByUsername);
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
/**
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
package org.mifosplatform.portfolio.calendar.domain;
|
||||
|
||||
import org.mifosplatform.portfolio.calendar.exception.CalendarNotFoundException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Wrapper for {@link CalendarRepository} that is responsible for checking
|
||||
* if {@link Calendar} is returned when using <code>findOne</code>
|
||||
* repository method and throwing an appropriate not found exception.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* This is to avoid need for checking and throwing in multiple areas of code
|
||||
* base where {@link CalendarRepository} is required.
|
||||
* </p>
|
||||
*/
|
||||
@Service
|
||||
public class CalendarRepositoryWrapper {
|
||||
|
||||
private final CalendarRepository repository;
|
||||
|
||||
@Autowired
|
||||
public CalendarRepositoryWrapper(final CalendarRepository repository) {
|
||||
this.repository = repository;
|
||||
}
|
||||
|
||||
public Calendar findOneWithNotFoundDetection(final Long calendarId) {
|
||||
final Calendar calendar = this.repository.findOne(calendarId);
|
||||
if (calendar == null) { throw new CalendarNotFoundException(calendarId); }
|
||||
return calendar;
|
||||
}
|
||||
|
||||
public void save(final Calendar calendar) {
|
||||
this.repository.save(calendar);
|
||||
}
|
||||
|
||||
public void delete(final Calendar calendar) {
|
||||
this.repository.delete(calendar);
|
||||
}
|
||||
|
||||
public void saveAndFlush(final Calendar calendar) {
|
||||
this.repository.saveAndFlush(calendar);
|
||||
}
|
||||
}
|
||||
+5
-2
@@ -81,9 +81,11 @@ public class CalendarReadPlatformServiceImpl implements CalendarReadPlatformServ
|
||||
final String createdByUserName = rs.getString("creatingUserName");
|
||||
final Long lastUpdatedByUserId = rs.getLong("updatingUserId");
|
||||
final String lastUpdatedByUserName = rs.getString("updatingUserName");
|
||||
|
||||
final LocalDate recentEligibleMeetingDate = null;
|
||||
|
||||
return new CalendarData(id, entityId, entityType, title, description, location, startDate, endDate, duration, type, repeating,
|
||||
recurrence, remindBy, firstReminder, secondReminder, humanReadable, createdDate, lastUpdatedDate, createdByUserId,
|
||||
recurrence, remindBy, firstReminder, secondReminder, humanReadable, recentEligibleMeetingDate, createdDate, lastUpdatedDate, createdByUserId,
|
||||
createdByUserName, lastUpdatedByUserId, lastUpdatedByUserName);
|
||||
}
|
||||
}
|
||||
@@ -207,7 +209,8 @@ public class CalendarReadPlatformServiceImpl implements CalendarReadPlatformServ
|
||||
|
||||
final Collection<LocalDate> recurringDates = CalendarUtils.getRecurringDates(rrule, seedDate, startDate, endDate, -1);
|
||||
final Collection<LocalDate> nextTenRecurringDates = CalendarUtils.getRecurringDates(rrule, seedDate, endDate);
|
||||
return new CalendarData(calendarData, recurringDates, nextTenRecurringDates);
|
||||
final LocalDate recentEligibleMeetingDate = CalendarUtils.getRecentEligibleMeetingDate(rrule, seedDate);
|
||||
return new CalendarData(calendarData, recurringDates, nextTenRecurringDates, recentEligibleMeetingDate);
|
||||
|
||||
}
|
||||
|
||||
|
||||
+22
@@ -415,4 +415,26 @@ public class CalendarUtils {
|
||||
sqlCalendarTypeOptions += calendarTypeOptions.get(size - 1).toString();
|
||||
return sqlCalendarTypeOptions;
|
||||
}
|
||||
|
||||
public static LocalDate getRecentEligibleMeetingDate(final String recurringRule, final LocalDate seedDate){
|
||||
LocalDate currentDate = DateUtils.getLocalDateOfTenant();
|
||||
final Recur recur = CalendarUtils.getICalRecur(recurringRule);
|
||||
if (recur == null) { return null; }
|
||||
|
||||
if(isValidRecurringDate(recur, seedDate, currentDate)){
|
||||
return currentDate;
|
||||
}
|
||||
|
||||
if(recur.getFrequency().equals(Recur.DAILY)){
|
||||
currentDate = currentDate.plusDays(recur.getInterval());
|
||||
}else if(recur.getFrequency().equals(Recur.WEEKLY)){
|
||||
currentDate = currentDate.plusWeeks(recur.getInterval());
|
||||
}else if(recur.getFrequency().equals(Recur.MONTHLY)){
|
||||
currentDate = currentDate.plusMonths(recur.getInterval());
|
||||
}else if(recur.getFrequency().equals(Recur.YEARLY)){
|
||||
currentDate = currentDate.plusYears(recur.getInterval());
|
||||
}
|
||||
|
||||
return getNextRecurringDate(recur, seedDate, currentDate);
|
||||
}
|
||||
}
|
||||
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
/**
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
package org.mifosplatform.portfolio.collectionsheet;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class CollectionSheetConstants {
|
||||
|
||||
public static final String COLLECTIONSHEET_RESOURCE_NAME = "collectionsheet";
|
||||
|
||||
public static final String localeParamName = "locale";
|
||||
public static final String dateFormatParamName = "dateFormat";
|
||||
|
||||
public static final String transactionDateParamName = "transactionDate";
|
||||
public static final String actualDisbursementDateParamName = "actualDisbursementDate";
|
||||
public static final String bulkRepaymentTransactionsParamName = "bulkRepaymentTransactions";
|
||||
public static final String bulkDisbursementTransactionsParamName = "bulkDisbursementTransactions";
|
||||
public static final String noteParamName = "note";
|
||||
public static final String calendarIdParamName = "calendarId";
|
||||
|
||||
// attendance parameters
|
||||
public static final String clientsAttendanceParamName = "clientsAttendance";
|
||||
public static final String clientIdParamName = "clientId";
|
||||
public static final String attendanceTypeParamName = "attendanceType";
|
||||
|
||||
public static final String loanIdParamName = "loanId";
|
||||
public static final String transactionAmountParamName = "transactionAmount";
|
||||
|
||||
public static final Set<String> COLLECTIONSHEET_REQUEST_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(localeParamName,
|
||||
dateFormatParamName, transactionDateParamName, actualDisbursementDateParamName, bulkRepaymentTransactionsParamName,
|
||||
bulkDisbursementTransactionsParamName, noteParamName, calendarIdParamName, clientsAttendanceParamName));
|
||||
}
|
||||
+154
@@ -0,0 +1,154 @@
|
||||
/**
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
package org.mifosplatform.portfolio.collectionsheet.data;
|
||||
|
||||
import static org.mifosplatform.portfolio.collectionsheet.CollectionSheetConstants.COLLECTIONSHEET_REQUEST_DATA_PARAMETERS;
|
||||
import static org.mifosplatform.portfolio.collectionsheet.CollectionSheetConstants.COLLECTIONSHEET_RESOURCE_NAME;
|
||||
import static org.mifosplatform.portfolio.collectionsheet.CollectionSheetConstants.attendanceTypeParamName;
|
||||
import static org.mifosplatform.portfolio.collectionsheet.CollectionSheetConstants.bulkDisbursementTransactionsParamName;
|
||||
import static org.mifosplatform.portfolio.collectionsheet.CollectionSheetConstants.bulkRepaymentTransactionsParamName;
|
||||
import static org.mifosplatform.portfolio.collectionsheet.CollectionSheetConstants.calendarIdParamName;
|
||||
import static org.mifosplatform.portfolio.collectionsheet.CollectionSheetConstants.clientIdParamName;
|
||||
import static org.mifosplatform.portfolio.collectionsheet.CollectionSheetConstants.clientsAttendanceParamName;
|
||||
import static org.mifosplatform.portfolio.collectionsheet.CollectionSheetConstants.loanIdParamName;
|
||||
import static org.mifosplatform.portfolio.collectionsheet.CollectionSheetConstants.noteParamName;
|
||||
import static org.mifosplatform.portfolio.collectionsheet.CollectionSheetConstants.transactionAmountParamName;
|
||||
import static org.mifosplatform.portfolio.collectionsheet.CollectionSheetConstants.transactionDateParamName;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.joda.time.LocalDate;
|
||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
import org.mifosplatform.infrastructure.core.data.ApiParameterError;
|
||||
import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder;
|
||||
import org.mifosplatform.infrastructure.core.exception.InvalidJsonException;
|
||||
import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException;
|
||||
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
@Component
|
||||
public class CollectionSheetTransactionDataValidator {
|
||||
|
||||
private final FromJsonHelper fromApiJsonHelper;
|
||||
|
||||
@Autowired
|
||||
public CollectionSheetTransactionDataValidator(final FromJsonHelper fromApiJsonHelper) {
|
||||
this.fromApiJsonHelper = fromApiJsonHelper;
|
||||
}
|
||||
|
||||
public void validateTransaction(final JsonCommand command) {
|
||||
final String json = command.json();
|
||||
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
|
||||
|
||||
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
|
||||
fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, COLLECTIONSHEET_REQUEST_DATA_PARAMETERS);
|
||||
|
||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
|
||||
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
|
||||
.resource(COLLECTIONSHEET_RESOURCE_NAME);
|
||||
|
||||
final JsonElement element = fromApiJsonHelper.parse(json);
|
||||
|
||||
final LocalDate transactionDate = fromApiJsonHelper.extractLocalDateNamed(transactionDateParamName, element);
|
||||
baseDataValidator.reset().parameter(transactionDateParamName).value(transactionDate).notNull();
|
||||
|
||||
final String note = fromApiJsonHelper.extractStringNamed(noteParamName, element);
|
||||
if (StringUtils.isNotBlank(note)) {
|
||||
baseDataValidator.reset().parameter(noteParamName).value(note).notExceedingLengthOf(1000);
|
||||
}
|
||||
|
||||
final Long calendarId = this.fromApiJsonHelper.extractLongNamed(calendarIdParamName, element);
|
||||
baseDataValidator.reset().parameter(calendarIdParamName).value(calendarId).notNull();
|
||||
|
||||
validateAttendanceDetails(element, baseDataValidator);
|
||||
|
||||
validateDisbursementTransactions(element, baseDataValidator);
|
||||
|
||||
validateRepaymentTransactions(element, baseDataValidator);
|
||||
|
||||
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
||||
}
|
||||
|
||||
private void validateAttendanceDetails(final JsonElement element, final DataValidatorBuilder baseDataValidator) {
|
||||
final JsonObject topLevelJsonElement = element.getAsJsonObject();
|
||||
if (element.isJsonObject()) {
|
||||
if (topLevelJsonElement.has(clientsAttendanceParamName) && topLevelJsonElement.get(clientsAttendanceParamName).isJsonArray()) {
|
||||
final JsonArray array = topLevelJsonElement.get(clientsAttendanceParamName).getAsJsonArray();
|
||||
for (int i = 0; i < array.size(); i++) {
|
||||
final JsonObject attendanceElement = array.get(i).getAsJsonObject();
|
||||
final Long clientId = this.fromApiJsonHelper.extractLongNamed(clientIdParamName, attendanceElement);
|
||||
final Long attendanceType = this.fromApiJsonHelper.extractLongNamed(attendanceTypeParamName, attendanceElement);
|
||||
baseDataValidator.reset().parameter(clientsAttendanceParamName + "[" + i + "]." + clientIdParamName).value(clientId)
|
||||
.notNull().integerGreaterThanZero();
|
||||
baseDataValidator.reset().parameter(clientsAttendanceParamName + "[" + i + "]." + attendanceTypeParamName)
|
||||
.value(attendanceType).notNull().integerGreaterThanZero();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void validateDisbursementTransactions(final JsonElement element, final DataValidatorBuilder baseDataValidator) {
|
||||
final JsonObject topLevelJsonElement = element.getAsJsonObject();
|
||||
final Locale locale = this.fromApiJsonHelper.extractLocaleParameter(topLevelJsonElement);
|
||||
if (element.isJsonObject()) {
|
||||
if (topLevelJsonElement.has(bulkDisbursementTransactionsParamName)
|
||||
&& topLevelJsonElement.get(bulkDisbursementTransactionsParamName).isJsonArray()) {
|
||||
final JsonArray array = topLevelJsonElement.get(bulkDisbursementTransactionsParamName).getAsJsonArray();
|
||||
|
||||
for (int i = 0; i < array.size(); i++) {
|
||||
final JsonObject loanTransactionElement = array.get(i).getAsJsonObject();
|
||||
final Long loanId = this.fromApiJsonHelper.extractLongNamed(loanIdParamName, loanTransactionElement);
|
||||
final BigDecimal disbursementAmount = this.fromApiJsonHelper.extractBigDecimalNamed(transactionAmountParamName,
|
||||
loanTransactionElement, locale);
|
||||
|
||||
baseDataValidator.reset().parameter("bulktransaction" + "[" + i + "].loan.id").value(loanId).notNull()
|
||||
.integerGreaterThanZero();
|
||||
baseDataValidator.reset().parameter("bulktransaction" + "[" + i + "].disbursement.amount").value(disbursementAmount)
|
||||
.notNull().zeroOrPositiveAmount();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void validateRepaymentTransactions(final JsonElement element, final DataValidatorBuilder baseDataValidator) {
|
||||
final JsonObject topLevelJsonElement = element.getAsJsonObject();
|
||||
final Locale locale = this.fromApiJsonHelper.extractLocaleParameter(topLevelJsonElement);
|
||||
if (element.isJsonObject()) {
|
||||
if (topLevelJsonElement.has(bulkRepaymentTransactionsParamName)
|
||||
&& topLevelJsonElement.get(bulkRepaymentTransactionsParamName).isJsonArray()) {
|
||||
final JsonArray array = topLevelJsonElement.get(bulkRepaymentTransactionsParamName).getAsJsonArray();
|
||||
|
||||
for (int i = 0; i < array.size(); i++) {
|
||||
final JsonObject loanTransactionElement = array.get(i).getAsJsonObject();
|
||||
final Long loanId = this.fromApiJsonHelper.extractLongNamed(loanIdParamName, loanTransactionElement);
|
||||
final BigDecimal disbursementAmount = this.fromApiJsonHelper.extractBigDecimalNamed(transactionAmountParamName,
|
||||
loanTransactionElement, locale);
|
||||
|
||||
baseDataValidator.reset().parameter("bulktransaction" + "[" + i + "].loan.id").value(loanId).notNull()
|
||||
.integerGreaterThanZero();
|
||||
baseDataValidator.reset().parameter("bulktransaction" + "[" + i + "].disbursement.amount").value(disbursementAmount)
|
||||
.notNull().zeroOrPositiveAmount();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void throwExceptionIfValidationWarningsExist(final List<ApiParameterError> dataValidationErrors) {
|
||||
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); }
|
||||
}
|
||||
}
|
||||
+8
-3
@@ -7,25 +7,30 @@ package org.mifosplatform.portfolio.collectionsheet.data;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
|
||||
|
||||
/**
|
||||
* Immutable data object for clients with loans due for disbursement or collection.
|
||||
*/
|
||||
public class ClientLoansData {
|
||||
public class JLGClientData {
|
||||
|
||||
private final Long clientId;
|
||||
private final String clientName;
|
||||
private Collection<LoanDueData> loans;
|
||||
private final EnumOptionData attendanceType;
|
||||
|
||||
public ClientLoansData(final Long clientId, final String clientName, final Collection<LoanDueData> loans) {
|
||||
public JLGClientData(final Long clientId, final String clientName, final Collection<LoanDueData> loans, final EnumOptionData attendanceType) {
|
||||
this.clientId = clientId;
|
||||
this.clientName = clientName;
|
||||
this.loans = loans;
|
||||
this.attendanceType = attendanceType;
|
||||
}
|
||||
|
||||
public ClientLoansData(final Long clientId, final String clientName) {
|
||||
public JLGClientData(final Long clientId, final String clientName, final EnumOptionData attendanceType) {
|
||||
this.clientId = clientId;
|
||||
this.clientName = clientName;
|
||||
this.loans = null;
|
||||
this.attendanceType = attendanceType;
|
||||
}
|
||||
|
||||
public Long getClientId() {
|
||||
+9
-3
@@ -6,8 +6,10 @@
|
||||
package org.mifosplatform.portfolio.collectionsheet.data;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.joda.time.LocalDate;
|
||||
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
|
||||
import org.mifosplatform.portfolio.loanproduct.data.LoanProductData;
|
||||
|
||||
/**
|
||||
@@ -17,19 +19,23 @@ public class JLGCollectionSheetData {
|
||||
|
||||
private final LocalDate dueDate;
|
||||
private final Collection<LoanProductData> loanProducts;
|
||||
private final Collection<JLGClientsData> groups;
|
||||
private final Collection<JLGGroupData> groups;
|
||||
@SuppressWarnings("unused")
|
||||
private final List<EnumOptionData> attendanceTypeOptions;
|
||||
|
||||
public JLGCollectionSheetData(final LocalDate date, final Collection<LoanProductData> loanProducts, final Collection<JLGClientsData> groups) {
|
||||
public JLGCollectionSheetData(final LocalDate date, final Collection<LoanProductData> loanProducts,
|
||||
final Collection<JLGGroupData> groups, final List<EnumOptionData> attendanceTypeOptions) {
|
||||
this.dueDate = date;
|
||||
this.loanProducts = loanProducts;
|
||||
this.groups = groups;
|
||||
this.attendanceTypeOptions = attendanceTypeOptions;
|
||||
}
|
||||
|
||||
public LocalDate getDate() {
|
||||
return this.dueDate;
|
||||
}
|
||||
|
||||
public Collection<JLGClientsData> getGroups() {
|
||||
public Collection<JLGGroupData> getGroups() {
|
||||
return this.groups;
|
||||
}
|
||||
|
||||
|
||||
+8
-5
@@ -7,6 +7,7 @@ package org.mifosplatform.portfolio.collectionsheet.data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
|
||||
import org.mifosplatform.organisation.monetary.data.CurrencyData;
|
||||
|
||||
/**
|
||||
@@ -34,12 +35,13 @@ public class JLGCollectionSheetFlatData {
|
||||
private BigDecimal interestDue = BigDecimal.ZERO;
|
||||
private BigDecimal interestPaid = BigDecimal.ZERO;
|
||||
private BigDecimal chargesDue = BigDecimal.ZERO;
|
||||
private final EnumOptionData attendanceType;
|
||||
|
||||
public JLGCollectionSheetFlatData(final String groupName, final Long groupId, final Long staffId, final String staffName,
|
||||
final Long levelId, final String levelName, final String clientName, final Long clientId, final Long loanId,
|
||||
final String accountId, final Integer accountStatusId, final String productShortName, final Long productId,
|
||||
final CurrencyData currency, final BigDecimal disbursementAmount, final BigDecimal principalDue,
|
||||
final BigDecimal principalPaid, final BigDecimal interestDue, final BigDecimal interestPaid, final BigDecimal chargesDue) {
|
||||
final BigDecimal principalPaid, final BigDecimal interestDue, final BigDecimal interestPaid, final BigDecimal chargesDue, final EnumOptionData attendanceType) {
|
||||
this.groupName = groupName;
|
||||
this.groupId = groupId;
|
||||
this.staffId = staffId;
|
||||
@@ -60,6 +62,7 @@ public class JLGCollectionSheetFlatData {
|
||||
this.interestDue = interestDue;
|
||||
this.interestPaid = interestPaid;
|
||||
this.chargesDue = chargesDue;
|
||||
this.attendanceType = attendanceType;
|
||||
}
|
||||
|
||||
public String getGroupName() {
|
||||
@@ -147,13 +150,13 @@ public class JLGCollectionSheetFlatData {
|
||||
this.disbursementAmount, this.principalDue, this.principalPaid, this.interestDue, this.interestPaid, this.chargesDue);
|
||||
}
|
||||
|
||||
public ClientLoansData getClientLoansData() {
|
||||
return new ClientLoansData(this.clientId, this.clientName);
|
||||
public JLGClientData getClientData() {
|
||||
return new JLGClientData(this.clientId, this.clientName, this.attendanceType);
|
||||
}
|
||||
|
||||
public JLGClientsData getJLGClientsData() {
|
||||
public JLGGroupData getJLGGroupData() {
|
||||
|
||||
return new JLGClientsData(this.groupId, this.groupName, this.staffId, this.staffName, this.levelId, this.levelName);
|
||||
return new JLGGroupData(this.groupId, this.groupName, this.staffId, this.staffName, this.levelId, this.levelName);
|
||||
}
|
||||
|
||||
}
|
||||
+5
-5
@@ -10,7 +10,7 @@ import java.util.Collection;
|
||||
/**
|
||||
* Immutable data object for groups with clients due for disbursement or collection.
|
||||
*/
|
||||
public class JLGClientsData {
|
||||
public class JLGGroupData {
|
||||
|
||||
private final Long groupId;
|
||||
private final String groupName;
|
||||
@@ -18,9 +18,9 @@ public class JLGClientsData {
|
||||
private final String staffName;
|
||||
private final Long levelId;
|
||||
private final String levelName;
|
||||
private Collection<ClientLoansData> clients;
|
||||
private Collection<JLGClientData> clients;
|
||||
|
||||
public JLGClientsData(final Long groupId, final String groupName, final Long staffId, final String staffName, final Long levelId,
|
||||
public JLGGroupData(final Long groupId, final String groupName, final Long staffId, final String staffName, final Long levelId,
|
||||
final String levelName) {
|
||||
this.groupId = groupId;
|
||||
this.groupName = groupName;
|
||||
@@ -54,11 +54,11 @@ public class JLGClientsData {
|
||||
return this.levelName;
|
||||
}
|
||||
|
||||
public Collection<ClientLoansData> getCutomers() {
|
||||
public Collection<JLGClientData> getClients() {
|
||||
return this.clients;
|
||||
}
|
||||
|
||||
public void setClients(final Collection<ClientLoansData> clients) {
|
||||
public void setClients(final Collection<JLGClientData> clients) {
|
||||
this.clients = clients;
|
||||
}
|
||||
}
|
||||
+3
-52
@@ -5,22 +5,12 @@
|
||||
*/
|
||||
package org.mifosplatform.portfolio.collectionsheet.serialization;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.joda.time.LocalDate;
|
||||
import org.mifosplatform.infrastructure.core.data.ApiParameterError;
|
||||
import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder;
|
||||
import org.mifosplatform.infrastructure.core.exception.InvalidJsonException;
|
||||
import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException;
|
||||
import org.mifosplatform.infrastructure.core.serialization.AbstractFromApiJsonDeserializer;
|
||||
import org.mifosplatform.infrastructure.core.serialization.FromApiJsonDeserializer;
|
||||
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
|
||||
@@ -32,7 +22,6 @@ import org.springframework.stereotype.Component;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
/**
|
||||
* Implementation of {@link FromApiJsonDeserializer} for
|
||||
@@ -52,21 +41,12 @@ public final class CollectionSheetBulkDisbursalCommandFromApiJsonDeserializer ex
|
||||
public CollectionSheetBulkDisbursalCommand commandFromApiJson(final String json) {
|
||||
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
|
||||
|
||||
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
|
||||
//TODO: AA need to refactor transactionDate and actualDisbursementDate
|
||||
//actualDisbursementDate used in Loan.disburse()
|
||||
final Set<String> supportedParameters = new HashSet<String>(Arrays.asList("transactionDate", "actualDisbursementDate", "bulkRepaymentTransactions", "bulkDisbursementTransactions", "note",
|
||||
"locale", "dateFormat"));
|
||||
this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParameters);
|
||||
|
||||
final JsonElement element = this.fromApiJsonHelper.parse(json);
|
||||
|
||||
final LocalDate transactionDate = fromApiJsonHelper.extractLocalDateNamed("transactionDate", element);
|
||||
|
||||
final String note = fromApiJsonHelper.extractStringNamed("note", element);
|
||||
|
||||
final JsonObject topLevelJsonElement = element.getAsJsonObject();
|
||||
|
||||
final Locale locale = this.fromApiJsonHelper.extractLocaleParameter(topLevelJsonElement);
|
||||
final LocalDate transactionDate = fromApiJsonHelper.extractLocalDateNamed("transactionDate", element);
|
||||
final String note = fromApiJsonHelper.extractStringNamed("note", element);
|
||||
|
||||
SingleDisbursalCommand[] loanDisbursementTransactions = null;
|
||||
|
||||
@@ -86,33 +66,4 @@ public final class CollectionSheetBulkDisbursalCommandFromApiJsonDeserializer ex
|
||||
}
|
||||
return new CollectionSheetBulkDisbursalCommand(note, transactionDate, loanDisbursementTransactions);
|
||||
}
|
||||
|
||||
public void validateBulkDisbursalTransaction(final CollectionSheetBulkDisbursalCommand bulkDisburseCommand) {
|
||||
|
||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
|
||||
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("loan.bulk.disbursement.transaction");
|
||||
|
||||
baseDataValidator.reset().parameter("transactionDate").value(bulkDisburseCommand.getTransactionDate()).notNull();
|
||||
|
||||
if (StringUtils.isNotBlank(bulkDisburseCommand.getNote())) {
|
||||
baseDataValidator.reset().parameter("note").value(bulkDisburseCommand.getNote()).notExceedingLengthOf(1000);
|
||||
}
|
||||
final SingleDisbursalCommand[] loanDisbursements = bulkDisburseCommand.getDisburseTransactions();
|
||||
if (loanDisbursements != null) {
|
||||
for (int i = 0; i < loanDisbursements.length; i++) {
|
||||
SingleDisbursalCommand singleLoanDisburseCommand = loanDisbursements[i];
|
||||
|
||||
baseDataValidator.reset().parameter("bulktransaction" + "[" + i + "].loan.id").value(singleLoanDisburseCommand.getLoanId())
|
||||
.notNull().integerGreaterThanZero();
|
||||
baseDataValidator.reset().parameter("bulktransaction" + "[" + i + "].disbursement.amount")
|
||||
.value(singleLoanDisburseCommand.getTransactionAmount()).notNull().zeroOrPositiveAmount();
|
||||
}
|
||||
}
|
||||
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
||||
}
|
||||
|
||||
private void throwExceptionIfValidationWarningsExist(final List<ApiParameterError> dataValidationErrors) {
|
||||
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
|
||||
"Validation errors exist.", dataValidationErrors); }
|
||||
}
|
||||
}
|
||||
-44
@@ -5,22 +5,12 @@
|
||||
*/
|
||||
package org.mifosplatform.portfolio.collectionsheet.serialization;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.joda.time.LocalDate;
|
||||
import org.mifosplatform.infrastructure.core.data.ApiParameterError;
|
||||
import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder;
|
||||
import org.mifosplatform.infrastructure.core.exception.InvalidJsonException;
|
||||
import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException;
|
||||
import org.mifosplatform.infrastructure.core.serialization.AbstractFromApiJsonDeserializer;
|
||||
import org.mifosplatform.infrastructure.core.serialization.FromApiJsonDeserializer;
|
||||
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
|
||||
@@ -32,7 +22,6 @@ import org.springframework.stereotype.Component;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
/**
|
||||
* Implementation of {@link FromApiJsonDeserializer} for
|
||||
@@ -52,11 +41,6 @@ public final class CollectionSheetBulkRepaymentCommandFromApiJsonDeserializer ex
|
||||
public CollectionSheetBulkRepaymentCommand commandFromApiJson(final String json) {
|
||||
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
|
||||
|
||||
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
|
||||
final Set<String> supportedParameters = new HashSet<String>(Arrays.asList("transactionDate", "actualDisbursementDate", "bulkRepaymentTransactions", "bulkDisbursementTransactions", "note",
|
||||
"locale", "dateFormat"));
|
||||
this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParameters);
|
||||
|
||||
final JsonElement element = this.fromApiJsonHelper.parse(json);
|
||||
|
||||
final LocalDate transactionDate = fromApiJsonHelper.extractLocalDateNamed("transactionDate", element);
|
||||
@@ -84,33 +68,5 @@ public final class CollectionSheetBulkRepaymentCommandFromApiJsonDeserializer ex
|
||||
}
|
||||
return new CollectionSheetBulkRepaymentCommand(note, transactionDate, loanRepaymentTransactions);
|
||||
}
|
||||
|
||||
public void validateBulkRepaymentTransaction(final CollectionSheetBulkRepaymentCommand bulkRepaymentCommand) {
|
||||
|
||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
|
||||
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("loan.bulk.repayment.transaction");
|
||||
|
||||
baseDataValidator.reset().parameter("transactionDate").value(bulkRepaymentCommand.getTransactionDate()).notNull();
|
||||
|
||||
if (StringUtils.isNotBlank(bulkRepaymentCommand.getNote())) {
|
||||
baseDataValidator.reset().parameter("note").value(bulkRepaymentCommand.getNote()).notExceedingLengthOf(1000);
|
||||
}
|
||||
|
||||
final SingleRepaymentCommand[] loanRepayments = bulkRepaymentCommand.getLoanTransactions();
|
||||
if (loanRepayments != null) {
|
||||
for (int i = 0; i < loanRepayments.length; i++) {
|
||||
SingleRepaymentCommand singleLoanRepaymentCommand = loanRepayments[i];
|
||||
baseDataValidator.reset().parameter("bulktransaction" + "[" + i + "].loan.id")
|
||||
.value(singleLoanRepaymentCommand.getLoanId()).notNull().integerGreaterThanZero();
|
||||
baseDataValidator.reset().parameter("bulktransaction" + "[" + i + "].transaction.amount")
|
||||
.value(singleLoanRepaymentCommand.getTransactionAmount()).notNull().zeroOrPositiveAmount();
|
||||
}
|
||||
}
|
||||
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
||||
}
|
||||
|
||||
private void throwExceptionIfValidationWarningsExist(final List<ApiParameterError> dataValidationErrors) {
|
||||
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
|
||||
"Validation errors exist.", dataValidationErrors); }
|
||||
}
|
||||
}
|
||||
+15
-7
@@ -13,6 +13,11 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.mifosplatform.portfolio.collectionsheet.CollectionSheetConstants.localeParamName;
|
||||
import static org.mifosplatform.portfolio.collectionsheet.CollectionSheetConstants.dateFormatParamName;
|
||||
import static org.mifosplatform.portfolio.collectionsheet.CollectionSheetConstants.calendarIdParamName;
|
||||
import static org.mifosplatform.portfolio.collectionsheet.CollectionSheetConstants.transactionDateParamName;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.joda.time.LocalDate;
|
||||
import org.mifosplatform.infrastructure.core.data.ApiParameterError;
|
||||
@@ -32,7 +37,8 @@ public class CollectionSheetGenerateCommandFromApiJsonDeserializer {
|
||||
/**
|
||||
* The parameters supported for this command.
|
||||
*/
|
||||
final Set<String> supportedParameters = new HashSet<String>(Arrays.asList("dueDate", "locale", "dateFormat"));
|
||||
final Set<String> supportedParameters = new HashSet<String>(Arrays.asList(transactionDateParamName, localeParamName,
|
||||
dateFormatParamName, calendarIdParamName));
|
||||
|
||||
private final FromJsonHelper fromApiJsonHelper;
|
||||
|
||||
@@ -53,15 +59,17 @@ public class CollectionSheetGenerateCommandFromApiJsonDeserializer {
|
||||
|
||||
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("collectionsheet");
|
||||
|
||||
final String dueDateParameterName = "dueDate";
|
||||
final String dueDateStr = this.fromApiJsonHelper.extractStringNamed(dueDateParameterName, element);
|
||||
baseDataValidator.reset().parameter(dueDateParameterName).value(dueDateStr).notBlank();
|
||||
final String transactionDateStr = this.fromApiJsonHelper.extractStringNamed(transactionDateParamName, element);
|
||||
baseDataValidator.reset().parameter(transactionDateParamName).value(transactionDateStr).notBlank();
|
||||
|
||||
if(!StringUtils.isBlank(dueDateStr)){
|
||||
final LocalDate dueDate = this.fromApiJsonHelper.extractLocalDateNamed(dueDateParameterName, element);
|
||||
baseDataValidator.reset().parameter(dueDateParameterName).value(dueDate).notNull();
|
||||
if (!StringUtils.isBlank(transactionDateStr)) {
|
||||
final LocalDate dueDate = this.fromApiJsonHelper.extractLocalDateNamed(transactionDateParamName, element);
|
||||
baseDataValidator.reset().parameter(transactionDateParamName).value(dueDate).notNull();
|
||||
}
|
||||
|
||||
final Long calendarId = this.fromApiJsonHelper.extractLongNamed(calendarIdParamName, element);
|
||||
baseDataValidator.reset().parameter(calendarIdParamName).value(calendarId).notNull();
|
||||
|
||||
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
|
||||
"Validation errors exist.", dataValidationErrors); }
|
||||
}
|
||||
|
||||
+78
-46
@@ -5,6 +5,9 @@
|
||||
*/
|
||||
package org.mifosplatform.portfolio.collectionsheet.service;
|
||||
|
||||
import static org.mifosplatform.portfolio.collectionsheet.CollectionSheetConstants.calendarIdParamName;
|
||||
import static org.mifosplatform.portfolio.collectionsheet.CollectionSheetConstants.transactionDateParamName;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
@@ -18,14 +21,20 @@ import java.util.Set;
|
||||
|
||||
import org.joda.time.LocalDate;
|
||||
import org.mifosplatform.infrastructure.core.api.JsonQuery;
|
||||
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
|
||||
import org.mifosplatform.infrastructure.core.domain.JdbcSupport;
|
||||
import org.mifosplatform.infrastructure.core.service.RoutingDataSource;
|
||||
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
|
||||
import org.mifosplatform.organisation.monetary.data.CurrencyData;
|
||||
import org.mifosplatform.portfolio.collectionsheet.data.ClientLoansData;
|
||||
import org.mifosplatform.portfolio.collectionsheet.data.JLGClientsData;
|
||||
import org.mifosplatform.portfolio.calendar.domain.Calendar;
|
||||
import org.mifosplatform.portfolio.calendar.domain.CalendarEntityType;
|
||||
import org.mifosplatform.portfolio.calendar.domain.CalendarRepositoryWrapper;
|
||||
import org.mifosplatform.portfolio.calendar.exception.NotValidRecurringDateException;
|
||||
import org.mifosplatform.portfolio.calendar.service.CalendarUtils;
|
||||
import org.mifosplatform.portfolio.collectionsheet.data.JLGClientData;
|
||||
import org.mifosplatform.portfolio.collectionsheet.data.JLGCollectionSheetData;
|
||||
import org.mifosplatform.portfolio.collectionsheet.data.JLGCollectionSheetFlatData;
|
||||
import org.mifosplatform.portfolio.collectionsheet.data.JLGGroupData;
|
||||
import org.mifosplatform.portfolio.collectionsheet.data.LoanDueData;
|
||||
import org.mifosplatform.portfolio.collectionsheet.serialization.CollectionSheetGenerateCommandFromApiJsonDeserializer;
|
||||
import org.mifosplatform.portfolio.group.data.CenterData;
|
||||
@@ -33,6 +42,8 @@ import org.mifosplatform.portfolio.group.data.GroupGeneralData;
|
||||
import org.mifosplatform.portfolio.group.service.CenterReadPlatformService;
|
||||
import org.mifosplatform.portfolio.group.service.GroupReadPlatformService;
|
||||
import org.mifosplatform.portfolio.loanproduct.data.LoanProductData;
|
||||
import org.mifosplatform.portfolio.meeting.attendance.service.AttendanceDropdownReadPlatformService;
|
||||
import org.mifosplatform.portfolio.meeting.attendance.service.AttendanceEnumerations;
|
||||
import org.mifosplatform.useradministration.domain.AppUser;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.jdbc.core.RowMapper;
|
||||
@@ -49,16 +60,22 @@ public class CollectionSheetReadPlatformServiceImpl implements CollectionSheetRe
|
||||
private final CenterReadPlatformService centerReadPlatformService;
|
||||
private final GroupReadPlatformService groupReadPlatformService;
|
||||
private final CollectionSheetGenerateCommandFromApiJsonDeserializer collectionSheetGenerateCommandFromApiJsonDeserializer;
|
||||
private final CalendarRepositoryWrapper calendarRepositoryWrapper;
|
||||
private final AttendanceDropdownReadPlatformService attendanceDropdownReadPlatformService;
|
||||
|
||||
@Autowired
|
||||
public CollectionSheetReadPlatformServiceImpl(final PlatformSecurityContext context, final RoutingDataSource dataSource,
|
||||
final CenterReadPlatformService centerReadPlatformService, final GroupReadPlatformService groupReadPlatformService,
|
||||
final CollectionSheetGenerateCommandFromApiJsonDeserializer collectionSheetGenerateCommandFromApiJsonDeserializer) {
|
||||
final CollectionSheetGenerateCommandFromApiJsonDeserializer collectionSheetGenerateCommandFromApiJsonDeserializer,
|
||||
final CalendarRepositoryWrapper calendarRepositoryWrapper,
|
||||
final AttendanceDropdownReadPlatformService attendanceDropdownReadPlatformService) {
|
||||
this.context = context;
|
||||
this.centerReadPlatformService = centerReadPlatformService;
|
||||
this.namedParameterjdbcTemplate = new NamedParameterJdbcTemplate(dataSource);
|
||||
this.collectionSheetGenerateCommandFromApiJsonDeserializer = collectionSheetGenerateCommandFromApiJsonDeserializer;
|
||||
this.groupReadPlatformService = groupReadPlatformService;
|
||||
this.calendarRepositoryWrapper = calendarRepositoryWrapper;
|
||||
this.attendanceDropdownReadPlatformService = attendanceDropdownReadPlatformService;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -92,9 +109,9 @@ public class CollectionSheetReadPlatformServiceImpl implements CollectionSheetRe
|
||||
Long prevGroupId = null;
|
||||
Long prevClientId = null;
|
||||
|
||||
final List<JLGClientsData> jlgClientsDatas = new ArrayList<JLGClientsData>();
|
||||
List<ClientLoansData> clientLoansDatas = new ArrayList<ClientLoansData>();
|
||||
List<LoanDueData> loanDueDatas = new ArrayList<LoanDueData>();
|
||||
final List<JLGGroupData> jlgGroupsData = new ArrayList<JLGGroupData>();
|
||||
List<JLGClientData> clientsData = new ArrayList<JLGClientData>();
|
||||
List<LoanDueData> loansDueData = new ArrayList<LoanDueData>();
|
||||
|
||||
JLGCollectionSheetData jlgCollectionSheetData = null;
|
||||
JLGCollectionSheetFlatData prevCollectioSheetFlatData = null;
|
||||
@@ -113,35 +130,35 @@ public class CollectionSheetReadPlatformServiceImpl implements CollectionSheetRe
|
||||
if (firstTime || collectionSheetFlatData.getGroupId().equals(prevGroupId)) {
|
||||
if (firstTime || collectionSheetFlatData.getClientId().equals(prevClientId)) {
|
||||
if (collectionSheetFlatData.getLoanId() != null) {
|
||||
loanDueDatas.add(collectionSheetFlatData.getLoanDueData());
|
||||
loansDueData.add(collectionSheetFlatData.getLoanDueData());
|
||||
}
|
||||
} else {
|
||||
final ClientLoansData clientLoansData = prevCollectioSheetFlatData.getClientLoansData();
|
||||
clientLoansData.setLoans(loanDueDatas);
|
||||
clientLoansDatas.add(clientLoansData);
|
||||
loanDueDatas = new ArrayList<LoanDueData>();
|
||||
final JLGClientData clientData = prevCollectioSheetFlatData.getClientData();
|
||||
clientData.setLoans(loansDueData);
|
||||
clientsData.add(clientData);
|
||||
loansDueData = new ArrayList<LoanDueData>();
|
||||
|
||||
if (collectionSheetFlatData.getLoanId() != null) {
|
||||
loanDueDatas.add(collectionSheetFlatData.getLoanDueData());
|
||||
loansDueData.add(collectionSheetFlatData.getLoanDueData());
|
||||
}
|
||||
|
||||
}
|
||||
} else {
|
||||
|
||||
final ClientLoansData clientLoansData = prevCollectioSheetFlatData.getClientLoansData();
|
||||
clientLoansData.setLoans(loanDueDatas);
|
||||
clientLoansDatas.add(clientLoansData);
|
||||
final JLGClientData clientData = prevCollectioSheetFlatData.getClientData();
|
||||
clientData.setLoans(loansDueData);
|
||||
clientsData.add(clientData);
|
||||
|
||||
final JLGClientsData jlgClientsData = prevCollectioSheetFlatData.getJLGClientsData();
|
||||
jlgClientsData.setClients(clientLoansDatas);
|
||||
final JLGGroupData jlgGroupData = prevCollectioSheetFlatData.getJLGGroupData();
|
||||
jlgGroupData.setClients(clientsData);
|
||||
|
||||
jlgClientsDatas.add(jlgClientsData);
|
||||
jlgGroupsData.add(jlgGroupData);
|
||||
|
||||
loanDueDatas = new ArrayList<LoanDueData>();
|
||||
clientLoansDatas = new ArrayList<ClientLoansData>();
|
||||
loansDueData = new ArrayList<LoanDueData>();
|
||||
clientsData = new ArrayList<JLGClientData>();
|
||||
|
||||
if (collectionSheetFlatData.getLoanId() != null) {
|
||||
loanDueDatas.add(collectionSheetFlatData.getLoanDueData());
|
||||
loansDueData.add(collectionSheetFlatData.getLoanDueData());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -155,16 +172,17 @@ public class CollectionSheetReadPlatformServiceImpl implements CollectionSheetRe
|
||||
// client/group or new client / previous group or new client / new
|
||||
// group
|
||||
if (corrCollectioSheetFlatData != null) {
|
||||
final ClientLoansData lastClientLoansData = corrCollectioSheetFlatData.getClientLoansData();
|
||||
lastClientLoansData.setLoans(loanDueDatas);
|
||||
clientLoansDatas.add(lastClientLoansData);
|
||||
final JLGClientData lastClientData = corrCollectioSheetFlatData.getClientData();
|
||||
lastClientData.setLoans(loansDueData);
|
||||
clientsData.add(lastClientData);
|
||||
|
||||
final JLGClientsData jlgClientsData = corrCollectioSheetFlatData.getJLGClientsData();
|
||||
jlgClientsData.setClients(clientLoansDatas);
|
||||
jlgClientsDatas.add(jlgClientsData);
|
||||
final JLGGroupData jlgGroupData = corrCollectioSheetFlatData.getJLGGroupData();
|
||||
jlgGroupData.setClients(clientsData);
|
||||
jlgGroupsData.add(jlgGroupData);
|
||||
}
|
||||
|
||||
jlgCollectionSheetData = new JLGCollectionSheetData(dueDate, loanProducts, jlgClientsDatas);
|
||||
jlgCollectionSheetData = new JLGCollectionSheetData(dueDate, loanProducts, jlgGroupsData,
|
||||
attendanceDropdownReadPlatformService.retrieveAttendanceTypeOptions());
|
||||
}
|
||||
|
||||
return jlgCollectionSheetData;
|
||||
@@ -206,7 +224,8 @@ public class CollectionSheetReadPlatformServiceImpl implements CollectionSheetRe
|
||||
+ "ln.principal_repaid_derived As principalPaid, "
|
||||
+ "sum(ifnull(if(ln.loan_status_id = 300, ls.interest_amount, 0.0), 0.0) - ifnull(if(ln.loan_status_id = 300, ls.interest_completed_derived, 0.0), 0.0)) As interestDue, "
|
||||
+ "ln.interest_repaid_derived As interestPaid, "
|
||||
+ "sum(if(ln.loan_status_id = 300, lc.amount_outstanding_derived, 0.0)) as chargesDue "
|
||||
+ "sum(if(ln.loan_status_id = 300, lc.amount_outstanding_derived, 0.0)) as chargesDue, "
|
||||
+ "ca.attendance_type_enum as attendanceTypeId "
|
||||
+ "FROM m_group gp "
|
||||
+ "LEFT JOIN m_office of ON of.id = gp.office_id AND of.hierarchy like :officeHierarchy "
|
||||
// + "LEFT JOIN m_office of ON of.id = gp.office_id "
|
||||
@@ -218,7 +237,10 @@ public class CollectionSheetReadPlatformServiceImpl implements CollectionSheetRe
|
||||
+ "LEFT JOIN m_product_loan pl ON pl.id = ln.product_id "
|
||||
+ "LEFT JOIN m_currency rc on rc.`code` = ln.currency_code "
|
||||
+ "LEFT JOIN m_loan_repayment_schedule ls ON ls.loan_id = ln.id AND ls.completed_derived = 0 AND ls.duedate <= :dueDate "
|
||||
+ "LEFT JOIN m_loan_charge lc ON lc.loan_id = ln.id AND lc.is_paid_derived = 0 AND ( lc.due_for_collection_as_of_date <= :dueDate OR lc.charge_time_enum = 1) ";
|
||||
+ "LEFT JOIN m_loan_charge lc ON lc.loan_id = ln.id AND lc.is_paid_derived = 0 AND ( lc.due_for_collection_as_of_date <= :dueDate OR lc.charge_time_enum = 1) "
|
||||
+ "left join m_calendar_instance ci on gp.parent_id = ci.entity_id and ci.entity_type_enum =:entityTypeId "
|
||||
+ "left join m_meeting mt on ci.id = mt.calendar_instance_id and mt.meeting_date =:dueDate "
|
||||
+ "left join m_client_attendance ca on ca.meeting_id=mt.id and ca.client_id=cl.id ";
|
||||
|
||||
// + "WHERE gp.hierarchy like :hierarchy " +
|
||||
// "GROUP BY gp.id ,cl.id , ln.id " +
|
||||
@@ -261,9 +283,12 @@ public class CollectionSheetReadPlatformServiceImpl implements CollectionSheetRe
|
||||
final BigDecimal interestPaid = rs.getBigDecimal("interestPaid");
|
||||
final BigDecimal chargesDue = rs.getBigDecimal("chargesDue");
|
||||
|
||||
final Integer attendanceTypeId = rs.getInt("attendanceTypeId");
|
||||
final EnumOptionData attendanceType = AttendanceEnumerations.attendanceType(attendanceTypeId);
|
||||
|
||||
return new JLGCollectionSheetFlatData(groupName, groupId, staffId, staffName, levelId, levelName, clientName, clientId, loanId,
|
||||
accountId, accountStatusId, productShortName, productId, currencyData, disbursementAmount, principalDue, principalPaid,
|
||||
interestDue, interestPaid, chargesDue);
|
||||
interestDue, interestPaid, chargesDue, attendanceType);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -273,28 +298,34 @@ public class CollectionSheetReadPlatformServiceImpl implements CollectionSheetRe
|
||||
|
||||
this.collectionSheetGenerateCommandFromApiJsonDeserializer.validateForGenerateCollectionSheet(query.json());
|
||||
|
||||
final Long calendarId = query.longValueOfParameterNamed(calendarIdParamName);
|
||||
final LocalDate transactionDate = query.localDateValueOfParameterNamed(transactionDateParamName);
|
||||
final DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
|
||||
final String transactionDateStr = df.format(transactionDate.toDate());
|
||||
|
||||
final Calendar calendar = this.calendarRepositoryWrapper.findOneWithNotFoundDetection(calendarId);
|
||||
if (!CalendarUtils.isValidRedurringDate(calendar.getRecurrence(), calendar.getStartDateLocalDate(), transactionDate)) { throw new NotValidRecurringDateException(
|
||||
"collectionsheet", "The date '" + transactionDate + "' is not a valid meeting date.", transactionDate); }
|
||||
|
||||
final AppUser currentUser = this.context.authenticatedUser();
|
||||
final String hierarchy = currentUser.getOffice().getHierarchy();
|
||||
final String officeHierarchy = hierarchy + "%";
|
||||
|
||||
final GroupGeneralData group = this.groupReadPlatformService.retrieveOne(groupId);
|
||||
|
||||
final LocalDate dueDate = query.localDateValueOfParameterNamed("dueDate");
|
||||
final DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
|
||||
final String dueDateStr = df.format(dueDate.toDate());
|
||||
|
||||
final JLGCollectionSheetFaltDataMapper mapper = new JLGCollectionSheetFaltDataMapper();
|
||||
|
||||
String sql = mapper.collectionSheetSchema();
|
||||
sql += "WHERE gp.id = :groupId GROUP BY gp.id ,cl.id , ln.id ORDER BY gp.id , cl.id , ln.id";
|
||||
StringBuilder sql = new StringBuilder(mapper.collectionSheetSchema());
|
||||
sql.append(" WHERE gp.id = :groupId GROUP BY gp.id ,cl.id , ln.id ORDER BY gp.id , cl.id , ln.id ");
|
||||
|
||||
final SqlParameterSource namedParameters = new MapSqlParameterSource().addValue("dueDate", dueDateStr)
|
||||
.addValue("groupId", group.getId()).addValue("officeHierarchy", officeHierarchy);
|
||||
final SqlParameterSource namedParameters = new MapSqlParameterSource().addValue("dueDate", transactionDateStr)
|
||||
.addValue("groupId", group.getId()).addValue("officeHierarchy", officeHierarchy)
|
||||
.addValue("entityTypeId", CalendarEntityType.CENTERS.getValue());
|
||||
|
||||
final Collection<JLGCollectionSheetFlatData> collectionSheetFlatDatas = this.namedParameterjdbcTemplate.query(sql, namedParameters,
|
||||
mapper);
|
||||
final Collection<JLGCollectionSheetFlatData> collectionSheetFlatDatas = this.namedParameterjdbcTemplate.query(sql.toString(),
|
||||
namedParameters, mapper);
|
||||
|
||||
return buildJLGCollectionSheet(dueDate, collectionSheetFlatDatas);
|
||||
return buildJLGCollectionSheet(transactionDate, collectionSheetFlatDatas);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -308,9 +339,9 @@ public class CollectionSheetReadPlatformServiceImpl implements CollectionSheetRe
|
||||
|
||||
final CenterData center = this.centerReadPlatformService.retrieveOne(centerId);
|
||||
|
||||
final LocalDate dueDate = query.localDateValueOfParameterNamed("dueDate");
|
||||
final LocalDate transactionDate = query.localDateValueOfParameterNamed(transactionDateParamName);
|
||||
final DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
|
||||
final String dueDateStr = df.format(dueDate.toDate());
|
||||
final String dueDateStr = df.format(transactionDate.toDate());
|
||||
|
||||
final JLGCollectionSheetFaltDataMapper mapper = new JLGCollectionSheetFaltDataMapper();
|
||||
|
||||
@@ -318,12 +349,13 @@ public class CollectionSheetReadPlatformServiceImpl implements CollectionSheetRe
|
||||
sql += "WHERE gp.parent_id = :centerId GROUP BY gp.id ,cl.id , ln.id ORDER BY gp.id , cl.id , ln.id";
|
||||
|
||||
final SqlParameterSource namedParameters = new MapSqlParameterSource().addValue("dueDate", dueDateStr)
|
||||
.addValue("centerId", center.getId()).addValue("officeHierarchy", officeHierarchy);
|
||||
.addValue("centerId", center.getId()).addValue("officeHierarchy", officeHierarchy)
|
||||
.addValue("entityTypeId", CalendarEntityType.CENTERS.getValue());
|
||||
|
||||
final Collection<JLGCollectionSheetFlatData> collectionSheetFlatDatas = this.namedParameterjdbcTemplate.query(sql, namedParameters,
|
||||
mapper);
|
||||
|
||||
return buildJLGCollectionSheet(dueDate, collectionSheetFlatDatas);
|
||||
return buildJLGCollectionSheet(transactionDate, collectionSheetFlatDatas);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+13
-5
@@ -14,9 +14,11 @@ import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResultBuilder;
|
||||
import org.mifosplatform.portfolio.collectionsheet.command.CollectionSheetBulkDisbursalCommand;
|
||||
import org.mifosplatform.portfolio.collectionsheet.command.CollectionSheetBulkRepaymentCommand;
|
||||
import org.mifosplatform.portfolio.collectionsheet.data.CollectionSheetTransactionDataValidator;
|
||||
import org.mifosplatform.portfolio.collectionsheet.serialization.CollectionSheetBulkDisbursalCommandFromApiJsonDeserializer;
|
||||
import org.mifosplatform.portfolio.collectionsheet.serialization.CollectionSheetBulkRepaymentCommandFromApiJsonDeserializer;
|
||||
import org.mifosplatform.portfolio.loanaccount.service.LoanWritePlatformService;
|
||||
import org.mifosplatform.portfolio.meeting.service.MeetingWritePlatformService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@@ -25,21 +27,27 @@ public class CollectionSheetWritePlatformServiceJpaRepositoryImpl implements Col
|
||||
|
||||
private final LoanWritePlatformService loanWritePlatformService;
|
||||
private final CollectionSheetBulkRepaymentCommandFromApiJsonDeserializer bulkRepaymentCommandFromApiJsonDeserializer;
|
||||
private final CollectionSheetBulkDisbursalCommandFromApiJsonDeserializer bulkDisbursalCommandFromApiJsonDeserializer;
|
||||
private final CollectionSheetBulkDisbursalCommandFromApiJsonDeserializer bulkDisbursalCommandFromApiJsonDeserializer;
|
||||
private final CollectionSheetTransactionDataValidator transactionDataValidator;
|
||||
private final MeetingWritePlatformService meetingWritePlatformService;
|
||||
|
||||
@Autowired
|
||||
public CollectionSheetWritePlatformServiceJpaRepositoryImpl(LoanWritePlatformService loanWritePlatformService,
|
||||
CollectionSheetBulkRepaymentCommandFromApiJsonDeserializer bulkRepaymentCommandFromApiJsonDeserializer,
|
||||
CollectionSheetBulkDisbursalCommandFromApiJsonDeserializer bulkDisbursalCommandFromApiJsonDeserializer) {
|
||||
CollectionSheetBulkDisbursalCommandFromApiJsonDeserializer bulkDisbursalCommandFromApiJsonDeserializer,
|
||||
final CollectionSheetTransactionDataValidator transactionDataValidator, final MeetingWritePlatformService meetingWritePlatformService) {
|
||||
this.loanWritePlatformService = loanWritePlatformService;
|
||||
this.bulkRepaymentCommandFromApiJsonDeserializer = bulkRepaymentCommandFromApiJsonDeserializer;
|
||||
this.bulkDisbursalCommandFromApiJsonDeserializer = bulkDisbursalCommandFromApiJsonDeserializer;
|
||||
this.transactionDataValidator = transactionDataValidator;
|
||||
this.meetingWritePlatformService = meetingWritePlatformService;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public CommandProcessingResult updateCollectionSheet(JsonCommand command) {
|
||||
|
||||
this.transactionDataValidator.validateTransaction(command);
|
||||
|
||||
Map<String, Object> changes = new HashMap<String, Object>();
|
||||
changes.put("locale", command.locale());
|
||||
changes.put("dateFormat", command.dateFormat());
|
||||
@@ -52,6 +60,8 @@ public class CollectionSheetWritePlatformServiceJpaRepositoryImpl implements Col
|
||||
changes.putAll(updateBulkReapayments(command));
|
||||
|
||||
changes.putAll(updateBulkDisbursals(command));
|
||||
|
||||
this.meetingWritePlatformService.updateCollectionSheetAttendance(command);
|
||||
|
||||
return new CommandProcessingResultBuilder() //
|
||||
.withCommandId(command.commandId()) //
|
||||
@@ -64,7 +74,6 @@ public class CollectionSheetWritePlatformServiceJpaRepositoryImpl implements Col
|
||||
private Map<String, Object> updateBulkReapayments(JsonCommand command) {
|
||||
Map<String, Object> changes = new HashMap<String, Object>();
|
||||
final CollectionSheetBulkRepaymentCommand bulkRepaymentCommand = this.bulkRepaymentCommandFromApiJsonDeserializer.commandFromApiJson(command.json());
|
||||
this.bulkRepaymentCommandFromApiJsonDeserializer.validateBulkRepaymentTransaction(bulkRepaymentCommand);
|
||||
changes.putAll(this.loanWritePlatformService.makeLoanBulkRepayment(bulkRepaymentCommand));
|
||||
return changes;
|
||||
}
|
||||
@@ -72,7 +81,6 @@ public class CollectionSheetWritePlatformServiceJpaRepositoryImpl implements Col
|
||||
private Map<String, Object> updateBulkDisbursals(JsonCommand command) {
|
||||
Map<String, Object> changes = new HashMap<String, Object>();
|
||||
final CollectionSheetBulkDisbursalCommand bulkDisbursalCommand = this.bulkDisbursalCommandFromApiJsonDeserializer.commandFromApiJson(command.json());
|
||||
this.bulkDisbursalCommandFromApiJsonDeserializer.validateBulkDisbursalTransaction(bulkDisbursalCommand);
|
||||
changes.putAll(this.loanWritePlatformService.bulkLoanDisbursal(command, bulkDisbursalCommand));
|
||||
return changes;
|
||||
}
|
||||
|
||||
+3
@@ -150,6 +150,9 @@ public class CentersApiResource {
|
||||
|
||||
if (associationParameters.contains("collectionMeetingCalendar")) {
|
||||
collectionMeetingCalendar = this.calendarReadPlatformService.retrieveCollctionCalendarByEntity(centerId, CalendarEntityType.CENTERS.getValue());
|
||||
if(collectionMeetingCalendar != null){
|
||||
collectionMeetingCalendar = this.calendarReadPlatformService.generateRecurringDate(collectionMeetingCalendar);
|
||||
}
|
||||
}
|
||||
|
||||
center = CenterData.withAssociations(center, groups, collectionMeetingCalendar);
|
||||
|
||||
+9
-2
@@ -203,7 +203,7 @@ public class GroupsApiResource {
|
||||
groupRoles = null;
|
||||
}
|
||||
}
|
||||
if (associationParameters.contains("calendars")) {
|
||||
if (associationParameters.contains("parentCalendars")) {
|
||||
final List<Integer> calendarTypeOptions = CalendarUtils.createIntegerListFromQueryParameter("all");
|
||||
calendars = this.calendarReadPlatformService.retrieveParentCalendarsByEntity(groupId, CalendarEntityType.GROUPS.getValue(), calendarTypeOptions);
|
||||
if (CollectionUtils.isEmpty(calendars)) {
|
||||
@@ -211,7 +211,14 @@ public class GroupsApiResource {
|
||||
}
|
||||
}
|
||||
if (associationParameters.contains("collectionMeetingCalendar")) {
|
||||
collectionMeetingCalendar = this.calendarReadPlatformService.retrieveCollctionCalendarByEntity(groupId, CalendarEntityType.GROUPS.getValue());
|
||||
if(group.isChildGroup()){
|
||||
collectionMeetingCalendar = this.calendarReadPlatformService.retrieveCollctionCalendarByEntity(group.getParentId(), CalendarEntityType.CENTERS.getValue());
|
||||
}else {
|
||||
collectionMeetingCalendar = this.calendarReadPlatformService.retrieveCollctionCalendarByEntity(groupId, CalendarEntityType.GROUPS.getValue());
|
||||
}
|
||||
if(collectionMeetingCalendar != null){
|
||||
collectionMeetingCalendar = this.calendarReadPlatformService.generateRecurringDate(collectionMeetingCalendar);
|
||||
}
|
||||
}
|
||||
|
||||
group = GroupGeneralData.withAssocations(group, membersOfGroup, groupRoles, calendars, collectionMeetingCalendar);
|
||||
|
||||
+9
@@ -168,7 +168,16 @@ public class GroupGeneralData {
|
||||
public String getHierarchy() {
|
||||
return this.hierarchy;
|
||||
}
|
||||
|
||||
public boolean isChildGroup(){
|
||||
return this.centerId == null ? false : true;
|
||||
}
|
||||
|
||||
public Long getParentId(){
|
||||
return this.centerId;
|
||||
}
|
||||
|
||||
|
||||
public static GroupGeneralData updateSelectedRole(final GroupGeneralData grouping, final GroupRoleData selectedRole) {
|
||||
return new GroupGeneralData(grouping.id, grouping.name, grouping.externalId, grouping.status, grouping.activationDate,
|
||||
grouping.officeId, grouping.officeName, grouping.centerId, grouping.centerName, grouping.staffId, grouping.staffName,
|
||||
|
||||
+33
-33
@@ -67,16 +67,15 @@ public class Meeting extends AbstractPersistable<Long> {
|
||||
}
|
||||
|
||||
public static Meeting createNew(final CalendarInstance calendarInstance, final Date meetingDate) {
|
||||
|
||||
if(!isValidMeetingDate(calendarInstance, meetingDate)){
|
||||
throw new NotValidRecurringDateException("meeting", "The date '" + meetingDate + "' is not a valid meeting date.", meetingDate);
|
||||
}
|
||||
|
||||
if (!isValidMeetingDate(calendarInstance, meetingDate)) { throw new NotValidRecurringDateException("meeting", "The date '"
|
||||
+ meetingDate + "' is not a valid meeting date.", meetingDate); }
|
||||
return new Meeting(calendarInstance, meetingDate);
|
||||
}
|
||||
|
||||
public void associateClientsAttendance(final Collection<ClientAttendance> clientsAttendance) {
|
||||
//do not allow to capture attendance in advance.
|
||||
if(isMeetingDateAfter(DateUtils.getLocalDateOfTenant())){
|
||||
// do not allow to capture attendance in advance.
|
||||
if (isMeetingDateAfter(DateUtils.getLocalDateOfTenant())) {
|
||||
final String errorMessage = "Attendance cannot be in the future.";
|
||||
throw new MeetingDateException("cannot.be.a.future.date", errorMessage, getMeetingDateLocalDate());
|
||||
}
|
||||
@@ -95,11 +94,10 @@ public class Meeting extends AbstractPersistable<Long> {
|
||||
actualChanges.put("dateFormat", dateFormatAsInput);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
this.meetingDate = newValue.toDate();
|
||||
|
||||
if(!isValidMeetingDate(this.calendarInstance, this.meetingDate)){
|
||||
throw new NotValidRecurringDateException("meeting", "Not a valid meeting date", meetingDate);
|
||||
}
|
||||
|
||||
|
||||
if (!isValidMeetingDate(this.calendarInstance, this.meetingDate)) { throw new NotValidRecurringDateException("meeting",
|
||||
"Not a valid meeting date", meetingDate); }
|
||||
|
||||
}
|
||||
|
||||
return actualChanges;
|
||||
@@ -108,12 +106,15 @@ public class Meeting extends AbstractPersistable<Long> {
|
||||
public Map<String, Object> updateAttendance(final Collection<ClientAttendance> clientsAttendance) {
|
||||
final Map<String, Object> actualChanges = new LinkedHashMap<String, Object>(1);
|
||||
final Map<String, Object> clientAttendanceChanges = new LinkedHashMap<String, Object>(clientsAttendance.size());
|
||||
|
||||
|
||||
updateAttendanceLoop: for (ClientAttendance clientAttendance : clientsAttendance) {
|
||||
if (this.clientsAttendance == null) {
|
||||
this.clientsAttendance = new HashSet<ClientAttendance>();
|
||||
}
|
||||
for (ClientAttendance clientAttendanceOriginal : this.clientsAttendance) {
|
||||
if (clientAttendanceOriginal.clientId().equals(clientAttendance.clientId())) {
|
||||
final Integer newValue = clientAttendance.getAttendanceTypeId();
|
||||
if(!newValue.equals(clientAttendanceOriginal.getAttendanceTypeId())){
|
||||
final Integer newValue = clientAttendance.getAttendanceTypeId();
|
||||
if (!newValue.equals(clientAttendanceOriginal.getAttendanceTypeId())) {
|
||||
clientAttendanceOriginal.updateAttendanceTypeId(newValue);
|
||||
final Map<String, Object> clientAttendanceChange = new LinkedHashMap<String, Object>(2);
|
||||
clientAttendanceChange.put(clientIdParamName, clientAttendanceOriginal.clientId());
|
||||
@@ -123,32 +124,32 @@ public class Meeting extends AbstractPersistable<Long> {
|
||||
continue updateAttendanceLoop;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
final Map<String, Object> clientAttendanceChange = new LinkedHashMap<String, Object>();
|
||||
clientAttendanceChange.put(clientIdParamName, clientAttendance.clientId());
|
||||
clientAttendanceChange.put(attendanceTypeParamName, clientAttendance.getAttendanceTypeId());
|
||||
clientAttendanceChanges.put(clientAttendance.clientId().toString(), clientAttendanceChange);
|
||||
//New attendance record
|
||||
// New attendance record
|
||||
this.clientsAttendance.add(clientAttendance);
|
||||
}
|
||||
|
||||
|
||||
actualChanges.put(clientsAttendanceParamName, clientAttendanceChanges);
|
||||
|
||||
|
||||
return actualChanges;
|
||||
}
|
||||
|
||||
public Long entityId() {
|
||||
return calendarInstance.getEntityId();
|
||||
}
|
||||
|
||||
public boolean isCenterEntity(){
|
||||
|
||||
public boolean isCenterEntity() {
|
||||
return CalendarEntityType.isCenter(calendarInstance.getEntityTypeId());
|
||||
}
|
||||
|
||||
public boolean isGroupEntity(){
|
||||
public boolean isGroupEntity() {
|
||||
return CalendarEntityType.isGroup(calendarInstance.getEntityTypeId());
|
||||
}
|
||||
|
||||
|
||||
public LocalDate getMeetingDateLocalDate() {
|
||||
LocalDate meetingDateLocalDate = null;
|
||||
if (this.meetingDate != null) {
|
||||
@@ -156,8 +157,8 @@ public class Meeting extends AbstractPersistable<Long> {
|
||||
}
|
||||
return meetingDateLocalDate;
|
||||
}
|
||||
|
||||
public Date getMeetingDate(){
|
||||
|
||||
public Date getMeetingDate() {
|
||||
return this.meetingDate;
|
||||
}
|
||||
|
||||
@@ -165,24 +166,23 @@ public class Meeting extends AbstractPersistable<Long> {
|
||||
return (this.meetingDate != null && newStartDate != null && getMeetingDateLocalDate().isBefore(newStartDate)) ? true : false;
|
||||
}
|
||||
|
||||
private static boolean isValidMeetingDate(final CalendarInstance calendarInstance, final Date meetingDate ){
|
||||
private static boolean isValidMeetingDate(final CalendarInstance calendarInstance, final Date meetingDate) {
|
||||
final Calendar calendar = calendarInstance.getCalendar();
|
||||
LocalDate meetingDateLocalDate = null;
|
||||
LocalDate meetingDateLocalDate = null;
|
||||
if (meetingDate != null) {
|
||||
meetingDateLocalDate = LocalDate.fromDateFields(meetingDate);
|
||||
}
|
||||
if(meetingDateLocalDate == null || !CalendarUtils.isValidRedurringDate(calendar.getRecurrence(), calendar.getStartDateLocalDate(), meetingDateLocalDate)){
|
||||
return false;
|
||||
}
|
||||
if (meetingDateLocalDate == null
|
||||
|| !CalendarUtils.isValidRedurringDate(calendar.getRecurrence(), calendar.getStartDateLocalDate(), meetingDateLocalDate)) { return false; }
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean isMeetingDateAfter(final LocalDate date){
|
||||
|
||||
private boolean isMeetingDateAfter(final LocalDate date) {
|
||||
return getMeetingDateLocalDate().isAfter(date);
|
||||
}
|
||||
|
||||
|
||||
public Collection<ClientAttendance> getClientsAttendance() {
|
||||
return this.clientsAttendance;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
+3
-1
@@ -5,9 +5,11 @@
|
||||
*/
|
||||
package org.mifosplatform.portfolio.meeting.domain;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||
|
||||
public interface MeetingRepository extends JpaRepository<Meeting, Long>, JpaSpecificationExecutor<Meeting> {
|
||||
|
||||
Meeting findByCalendarInstanceIdAndMeetingDate(Long calendarInstanceId, Date meetingDate);
|
||||
}
|
||||
|
||||
+2
@@ -11,6 +11,8 @@ import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||
public interface MeetingWritePlatformService {
|
||||
|
||||
CommandProcessingResult createMeeting(JsonCommand command);
|
||||
|
||||
void updateCollectionSheetAttendance(JsonCommand command);
|
||||
|
||||
CommandProcessingResult updateMeeting(JsonCommand command);
|
||||
|
||||
|
||||
+59
-28
@@ -10,12 +10,14 @@ import static org.mifosplatform.portfolio.meeting.MeetingApiConstants.calendarId
|
||||
import static org.mifosplatform.portfolio.meeting.MeetingApiConstants.clientIdParamName;
|
||||
import static org.mifosplatform.portfolio.meeting.MeetingApiConstants.clientsAttendanceParamName;
|
||||
import static org.mifosplatform.portfolio.meeting.MeetingApiConstants.meetingDateParamName;
|
||||
import static org.mifosplatform.portfolio.collectionsheet.CollectionSheetConstants.transactionDateParamName;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
|
||||
import org.joda.time.LocalDate;
|
||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResultBuilder;
|
||||
@@ -36,6 +38,7 @@ import org.mifosplatform.portfolio.group.exception.ClientNotInGroupException;
|
||||
import org.mifosplatform.portfolio.meeting.attendance.domain.ClientAttendance;
|
||||
import org.mifosplatform.portfolio.meeting.data.MeetingDataValidator;
|
||||
import org.mifosplatform.portfolio.meeting.domain.Meeting;
|
||||
import org.mifosplatform.portfolio.meeting.domain.MeetingRepository;
|
||||
import org.mifosplatform.portfolio.meeting.domain.MeetingRepositoryWrapper;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.dao.DataIntegrityViolationException;
|
||||
@@ -48,7 +51,8 @@ import com.google.gson.JsonObject;
|
||||
@Service
|
||||
public class MeetingWritePlatformServiceJpaRepositoryImpl implements MeetingWritePlatformService {
|
||||
|
||||
private final MeetingRepositoryWrapper meetingRepository;
|
||||
private final MeetingRepositoryWrapper meetingRepositoryWrapper;
|
||||
private final MeetingRepository meetingRepository;
|
||||
private final MeetingDataValidator meetingDataValidator;
|
||||
private final CalendarInstanceRepository calendarInstanceRepository;
|
||||
private final CalendarRepository calendarRepository;
|
||||
@@ -57,10 +61,11 @@ public class MeetingWritePlatformServiceJpaRepositoryImpl implements MeetingWrit
|
||||
private final FromJsonHelper fromApiJsonHelper;
|
||||
|
||||
@Autowired
|
||||
public MeetingWritePlatformServiceJpaRepositoryImpl(MeetingRepositoryWrapper meetingRepository,
|
||||
MeetingDataValidator meetingDataValidator, CalendarInstanceRepository calendarInstanceRepository,
|
||||
CalendarRepository calendarRepository, final ClientRepository clientRepository, final GroupRepository groupRepository,
|
||||
final FromJsonHelper fromApiJsonHelper) {
|
||||
public MeetingWritePlatformServiceJpaRepositoryImpl(final MeetingRepositoryWrapper meetingRepositoryWrapper,
|
||||
final MeetingRepository meetingRepository, final MeetingDataValidator meetingDataValidator,
|
||||
final CalendarInstanceRepository calendarInstanceRepository, final CalendarRepository calendarRepository,
|
||||
final ClientRepository clientRepository, final GroupRepository groupRepository, final FromJsonHelper fromApiJsonHelper) {
|
||||
this.meetingRepositoryWrapper = meetingRepositoryWrapper;
|
||||
this.meetingRepository = meetingRepository;
|
||||
this.meetingDataValidator = meetingDataValidator;
|
||||
this.calendarInstanceRepository = calendarInstanceRepository;
|
||||
@@ -71,7 +76,7 @@ public class MeetingWritePlatformServiceJpaRepositoryImpl implements MeetingWrit
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandProcessingResult createMeeting(JsonCommand command) {
|
||||
public CommandProcessingResult createMeeting(final JsonCommand command) {
|
||||
|
||||
this.meetingDataValidator.validateForCreate(command);
|
||||
|
||||
@@ -87,13 +92,13 @@ public class MeetingWritePlatformServiceJpaRepositoryImpl implements MeetingWrit
|
||||
newMeeting.associateClientsAttendance(clientsAttendance);
|
||||
}
|
||||
// save meeting details
|
||||
this.meetingRepository.save(newMeeting);
|
||||
this.meetingRepositoryWrapper.save(newMeeting);
|
||||
final Long groupId = newMeeting.isGroupEntity() ? newMeeting.entityId() : null;
|
||||
return new CommandProcessingResultBuilder() //
|
||||
.withEntityId(newMeeting.getId()) //
|
||||
.withGroupId(groupId).build();
|
||||
|
||||
} catch (DataIntegrityViolationException dve) {
|
||||
} catch (final DataIntegrityViolationException dve) {
|
||||
handleMeetingDataIntegrityIssues(meetingDate, dve);
|
||||
return new CommandProcessingResultBuilder() //
|
||||
.build();
|
||||
@@ -107,11 +112,12 @@ public class MeetingWritePlatformServiceJpaRepositoryImpl implements MeetingWrit
|
||||
if (calendarForUpdate == null) { throw new CalendarNotFoundException(calendarId); }
|
||||
|
||||
final Integer entityTypeId = CalendarEntityType.valueOf(command.getSupportedEntityType().toUpperCase()).getValue();
|
||||
final CalendarInstance calendarInstance = calendarInstanceRepository.findByCalendarIdAndEntityIdAndEntityTypeId(
|
||||
final CalendarInstance calendarInstance = this.calendarInstanceRepository.findByCalendarIdAndEntityIdAndEntityTypeId(
|
||||
calendarForUpdate.getId(), entityId, entityTypeId);
|
||||
if(calendarInstance == null) {
|
||||
if (calendarInstance == null) {
|
||||
final String postFix = "for." + command.getSupportedEntityType() + "not.found";
|
||||
final String defaultUserMessage = "No Calendar Instance details found for group with identifier " + entityId + " and calendar with identifier " + calendarId;
|
||||
final String defaultUserMessage = "No Calendar Instance details found for group with identifier " + entityId
|
||||
+ " and calendar with identifier " + calendarId;
|
||||
throw new CalendarInstanceNotFoundException(postFix, defaultUserMessage, entityId, calendarId);
|
||||
}
|
||||
return calendarInstance;
|
||||
@@ -144,16 +150,17 @@ public class MeetingWritePlatformServiceJpaRepositoryImpl implements MeetingWrit
|
||||
} else if (meeting.isCenterEntity()) {
|
||||
if (childGroups != null && !childGroups.isEmpty()) {
|
||||
boolean isChildClient = false;
|
||||
for (Group group : childGroups) {
|
||||
if (group.isChildClient(clientId)){
|
||||
for (final Group group : childGroups) {
|
||||
if (group.isChildClient(clientId)) {
|
||||
isChildClient = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!isChildClient){
|
||||
if (!isChildClient) {
|
||||
final String defaultUserMessage = "Client with identifier " + clientId + " is not in center "
|
||||
+ meeting.entityId();
|
||||
throw new ClientNotInGroupException("client.not.in.center", defaultUserMessage, clientId, meeting.entityId());
|
||||
throw new ClientNotInGroupException("client.not.in.center", defaultUserMessage, clientId,
|
||||
meeting.entityId());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -167,17 +174,17 @@ public class MeetingWritePlatformServiceJpaRepositoryImpl implements MeetingWrit
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandProcessingResult updateMeeting(JsonCommand command) {
|
||||
public CommandProcessingResult updateMeeting(final JsonCommand command) {
|
||||
this.meetingDataValidator.validateForUpdate(command);
|
||||
|
||||
final Meeting meetingForUpdate = this.meetingRepository.findOneWithNotFoundDetection(command.entityId());
|
||||
final Meeting meetingForUpdate = this.meetingRepositoryWrapper.findOneWithNotFoundDetection(command.entityId());
|
||||
final Map<String, Object> changes = meetingForUpdate.update(command);
|
||||
|
||||
try {
|
||||
if (!changes.isEmpty()) {
|
||||
this.meetingRepository.saveAndFlush(meetingForUpdate);
|
||||
this.meetingRepositoryWrapper.saveAndFlush(meetingForUpdate);
|
||||
}
|
||||
} catch (DataIntegrityViolationException dve) {
|
||||
} catch (final DataIntegrityViolationException dve) {
|
||||
handleMeetingDataIntegrityIssues(meetingForUpdate.getMeetingDate(), dve);
|
||||
return new CommandProcessingResultBuilder() //
|
||||
.build();
|
||||
@@ -191,23 +198,23 @@ public class MeetingWritePlatformServiceJpaRepositoryImpl implements MeetingWrit
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandProcessingResult deleteMeeting(Long meetingId) {
|
||||
final Meeting meetingForDelete = this.meetingRepository.findOneWithNotFoundDetection(meetingId);
|
||||
this.meetingRepository.delete(meetingForDelete);
|
||||
public CommandProcessingResult deleteMeeting(final Long meetingId) {
|
||||
final Meeting meetingForDelete = this.meetingRepositoryWrapper.findOneWithNotFoundDetection(meetingId);
|
||||
this.meetingRepositoryWrapper.delete(meetingForDelete);
|
||||
return new CommandProcessingResultBuilder() //
|
||||
.withEntityId(meetingId) //
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandProcessingResult saveOrUpdateAttendance(JsonCommand command) {
|
||||
public CommandProcessingResult saveOrUpdateAttendance(final JsonCommand command) {
|
||||
this.meetingDataValidator.validateForUpdateAttendance(command);
|
||||
|
||||
final Meeting meetingForUpdate = this.meetingRepository.findOneWithNotFoundDetection(command.entityId());
|
||||
final Meeting meetingForUpdate = this.meetingRepositoryWrapper.findOneWithNotFoundDetection(command.entityId());
|
||||
final Collection<ClientAttendance> clientsAttendance = getClientsAttendance(meetingForUpdate, command);
|
||||
final Map<String, Object> changes = meetingForUpdate.updateAttendance(clientsAttendance);
|
||||
|
||||
this.meetingRepository.saveAndFlush(meetingForUpdate);
|
||||
this.meetingRepositoryWrapper.saveAndFlush(meetingForUpdate);
|
||||
final Long groupId = meetingForUpdate.isGroupEntity() ? meetingForUpdate.entityId() : null;
|
||||
return new CommandProcessingResultBuilder() //
|
||||
.withEntityId(meetingForUpdate.getId()) //
|
||||
@@ -219,11 +226,35 @@ public class MeetingWritePlatformServiceJpaRepositoryImpl implements MeetingWrit
|
||||
private void handleMeetingDataIntegrityIssues(final Date meetingDate, final DataIntegrityViolationException dve) {
|
||||
final Throwable realCause = dve.getMostSpecificCause();
|
||||
if (realCause.getMessage().contains("unique_calendar_instance_id_meeting_date")) {
|
||||
|
||||
throw new PlatformDataIntegrityException("error.msg.meeting.duplicate", "A meeting with date '" + meetingDate + "' already exists",
|
||||
meetingDateParamName, meetingDate); }
|
||||
final LocalDate meetingDateLocal = LocalDate.fromDateFields(meetingDate);
|
||||
throw new PlatformDataIntegrityException("error.msg.meeting.duplicate", "A meeting with date '" + meetingDateLocal + "' already exists",
|
||||
meetingDateParamName, meetingDateLocal); }
|
||||
|
||||
throw new PlatformDataIntegrityException("error.msg.meeting.unknown.data.integrity.issue",
|
||||
"Unknown data integrity issue with resource: " + realCause.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateCollectionSheetAttendance(final JsonCommand command) {
|
||||
final Date meetingDate = command.DateValueOfParameterNamed(transactionDateParamName);
|
||||
|
||||
try {
|
||||
final CalendarInstance calendarInstance = getCalendarInstance(command);
|
||||
final Meeting meeting = this.meetingRepository.findByCalendarInstanceIdAndMeetingDate(calendarInstance.getId(), meetingDate);
|
||||
|
||||
// create new meeting
|
||||
final Meeting newMeeting = (meeting != null) ? meeting : Meeting.createNew(calendarInstance, meetingDate);
|
||||
|
||||
final Collection<ClientAttendance> clientsAttendance = getClientsAttendance(newMeeting, command);
|
||||
if (clientsAttendance != null && !clientsAttendance.isEmpty()) {
|
||||
newMeeting.updateAttendance(clientsAttendance);
|
||||
}
|
||||
// save meeting details
|
||||
this.meetingRepositoryWrapper.save(newMeeting);
|
||||
} catch (final DataIntegrityViolationException dve) {
|
||||
handleMeetingDataIntegrityIssues(meetingDate, dve);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user