Merge pull request #387 from goutham-M/mifosx438

close client functionality
This commit is contained in:
Vishwas Babu A J
2013-06-21 09:49:31 -07:00
18 changed files with 258 additions and 23 deletions
@@ -0,0 +1,8 @@
INSERT INTO `m_code` (`code_name`, `is_system_defined`) VALUES ('ClientClosureReason', 1)
ALTER TABLE `m_client` ADD COLUMN `closure_reason_cv_id` INT(11) NULL DEFAULT NULL,
ADD COLUMN `closedon_date` DATE NULL DEFAULT NULL,
ADD CONSTRAINT `FK_m_client_m_code` FOREIGN KEY (`closure_reason_cv_id`) REFERENCES `m_code_value` (`id`)
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`) VALUES ('portfolio', 'CLOSE_CLIENT', 'CLIENT', 'CLOSE')
@@ -553,4 +553,7 @@ public class CommandWrapper {
return this.actionName.equalsIgnoreCase("ASSIGNSTAFF") && this.entityName.equalsIgnoreCase("CLIENT");
}
public boolean isClientClose() {
return this.actionName.equalsIgnoreCase("CLOSE") && this.entityName.equalsIgnoreCase("CLIENT");
}
}
@@ -336,6 +336,15 @@ public class CommandWrapperBuilder {
this.href = "/clients/" + clientId + "?command=activate&template=true";
return this;
}
public CommandWrapperBuilder closeClient(final Long clientId) {
this.actionName = "CLOSE";
this.entityName = "CLIENT";
this.entityId = clientId;
this.clientId = clientId;
this.href = "/clients/" + clientId + "?command=close&template=true";
return this;
}
public CommandWrapperBuilder updateClient(final Long clientId) {
this.actionName = "UPDATE";
@@ -161,6 +161,8 @@ public class SynchronousCommandProcessingService implements CommandProcessingSer
handler = this.applicationContext.getBean("unassignClientStaffCommandHandler", NewCommandSourceHandler.class);
} else if (wrapper.isClientAssignStaff()) {
handler = this.applicationContext.getBean("assignClientStaffCommandHandler", NewCommandSourceHandler.class);
} else if (wrapper.isClientClose()) {
handler = this.applicationContext.getBean("closeClientCommandHandler", NewCommandSourceHandler.class);
} else {
throw new UnsupportedCommandException(wrapper.commandName());
}
@@ -14,6 +14,7 @@ import org.mifosplatform.portfolio.client.data.ClientData;
public class ClientApiConstants {
public static final String CLIENT_RESOURCE_NAME = "client";
public static final String CLIENT_CLOSURE_REASON = "ClientClosureReason";
// general
public static final String localeParamName = "locale";
@@ -32,7 +33,8 @@ public class ClientApiConstants {
public static final String activeParamName = "active";
public static final String activationDateParamName = "activationDate";
public static final String staffIdParamName = "staffId";
public static final String closureDateParamName = "closureDate";
public static final String closureReasonIdParamName = "closureReasonId";
// response parameters
public static final String statusParamName = "status";
public static final String hierarchyParamName = "hierarchy";
@@ -68,4 +70,7 @@ public class ClientApiConstants {
public static final Set<String> ACTIVATION_REQUEST_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(localeParamName,
dateFormatParamName, activationDateParamName));
public static final Set<String> CLIENT_CLOSE_REQUEST_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(localeParamName,
dateFormatParamName, closureDateParamName, closureReasonIdParamName));
}
@@ -84,11 +84,18 @@ public class ClientsApiResource {
@Path("template")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String retrieveTemplate(@Context final UriInfo uriInfo, @QueryParam("officeId") final Long officeId) {
public String retrieveTemplate(@Context final UriInfo uriInfo, @QueryParam("officeId") final Long officeId,
@QueryParam("commandParam") final String commandParam) {
context.authenticatedUser().validateHasReadPermission(ClientApiConstants.CLIENT_RESOURCE_NAME);
final ClientData clientData = this.clientReadPlatformService.retrieveTemplate(officeId);
ClientData clientData = null;
context.authenticatedUser().validateHasReadPermission(ClientApiConstants.CLIENT_RESOURCE_NAME);
if (is(commandParam, "close")) {
clientData = this.clientReadPlatformService.retrieveAllClosureReasons(ClientApiConstants.CLIENT_CLOSURE_REASON);
}else{
clientData = this.clientReadPlatformService.retrieveTemplate(officeId);
}
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters());
return this.toApiJsonSerializer.serialize(settings, clientData, ClientApiConstants.CLIENT_RESPONSE_DATA_PARAMETERS);
@@ -194,17 +201,21 @@ public class ClientsApiResource {
final CommandWrapperBuilder builder = new CommandWrapperBuilder().withJson(apiRequestBodyAsJson);
CommandProcessingResult result = null;
CommandWrapper commandRequest = null;
if (is(commandParam, "activate")) {
final CommandWrapper commandRequest = builder.activateClient(clientId).build();
commandRequest = builder.activateClient(clientId).build();
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
} else if (is(commandParam, "assignStaff")) {
final CommandWrapper commandRequest = builder.assignClientStaff(clientId).build();
commandRequest = builder.assignClientStaff(clientId).build();
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
return this.toApiJsonSerializer.serialize(result);
} else if (is(commandParam, "unassignStaff")) {
final CommandWrapper commandRequest = builder.unassignClientStaff(clientId).build();
commandRequest = builder.unassignClientStaff(clientId).build();
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
return this.toApiJsonSerializer.serialize(result);
} else if(is(commandParam, "close")) {
commandRequest = builder.closeClient(clientId).build();
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
}
if (result == null) {
@@ -13,6 +13,7 @@ import org.apache.commons.lang.builder.CompareToBuilder;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.joda.time.LocalDate;
import org.mifosplatform.infrastructure.codes.data.CodeValueData;
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
import org.mifosplatform.organisation.office.data.OfficeData;
import org.mifosplatform.organisation.staff.data.StaffData;
@@ -49,14 +50,15 @@ final public class ClientData implements Comparable<ClientData> {
// associations
private final Collection<GroupGeneralData> groups;
// template
private final Collection<OfficeData> officeOptions;
private final Collection<StaffData> staffOptions;
private final Collection<CodeValueData> closureReasons;
public static ClientData template(final Long officeId, final LocalDate joinedDate, final Collection<OfficeData> officeOptions,
final Collection<StaffData> staffOptions) {
return new ClientData(null, null, officeId, null, null, null, null, null, null, null, null, joinedDate, null, null, null, officeOptions, null, staffOptions);
final Collection<StaffData> staffOptions, final Collection<CodeValueData> closureReasons) {
return new ClientData(null, null, officeId, null, null, null, null, null, null, null, null, joinedDate, null, null, null, officeOptions, null, staffOptions, closureReasons);
}
public static ClientData templateOnTop(final ClientData clientData, final List<OfficeData> allowedOffices, final Collection<StaffData> staffOptions) {
@@ -64,14 +66,14 @@ final public class ClientData implements Comparable<ClientData> {
return new ClientData(clientData.accountNo, clientData.status, clientData.officeId, clientData.officeName, clientData.id,
clientData.firstname, clientData.middlename, clientData.lastname, clientData.fullname, clientData.displayName,
clientData.externalId, clientData.activationDate, clientData.imageId, clientData.staffId, clientData.staffName,
allowedOffices, clientData.groups, staffOptions);
allowedOffices, clientData.groups, staffOptions, null);
}
public static ClientData setParentGroups(final ClientData clientData, final Collection<GroupGeneralData> parentGroups) {
return new ClientData(clientData.accountNo, clientData.status, clientData.officeId, clientData.officeName, clientData.id,
clientData.firstname, clientData.middlename, clientData.lastname, clientData.fullname, clientData.displayName,
clientData.externalId, clientData.activationDate, clientData.imageId, clientData.staffId, clientData.staffName,
clientData.officeOptions, parentGroups, clientData.staffOptions);
clientData.officeOptions, parentGroups, clientData.staffOptions, null);
}
public static ClientData clientIdentifier(final Long id, final String accountNo, final EnumOptionData status, final String firstname,
@@ -79,11 +81,11 @@ final public class ClientData implements Comparable<ClientData> {
final String officeName) {
return new ClientData(accountNo, status, officeId, officeName, id, firstname, middlename, lastname, fullname, displayName, null,
null, null, null, null, null, null,null);
null, null, null, null, null, null,null, null);
}
public static ClientData lookup(final Long id, final String displayName, final Long officeId, final String officeName) {
return new ClientData(null, null, officeId, officeName, id, null, null, null, null, displayName, null, null, null, null, null, null, null, null);
return new ClientData(null, null, officeId, officeName, id, null, null, null, null, displayName, null, null, null, null, null, null, null, null, null);
}
public static ClientData instance(final String accountNo, final EnumOptionData status, final Long officeId, final String officeName,
@@ -91,13 +93,14 @@ final public class ClientData implements Comparable<ClientData> {
final String displayName, final String externalId, final LocalDate activationDate, final Long imageId, final Long staffId,
final String staffName) {
return new ClientData(accountNo, status, officeId, officeName, id, firstname, middlename, lastname, fullname, displayName,
externalId, activationDate, imageId, staffId, staffName, null, null, null);
externalId, activationDate, imageId, staffId, staffName, null, null, null, null);
}
private ClientData(final String accountNo, final EnumOptionData status, final Long officeId, final String officeName, final Long id,
final String firstname, final String middlename, final String lastname, final String fullname, final String displayName,
final String externalId, final LocalDate activationDate, final Long imageId, final Long staffId, final String staffName,
final Collection<OfficeData> allowedOffices, final Collection<GroupGeneralData> groups, final Collection<StaffData> staffOptions) {
final Collection<OfficeData> allowedOffices, final Collection<GroupGeneralData> groups, final Collection<StaffData> staffOptions,
final Collection<CodeValueData> closureReasons) {
this.accountNo = accountNo;
this.status = status;
if (status != null) {
@@ -130,6 +133,7 @@ final public class ClientData implements Comparable<ClientData> {
// template
this.officeOptions = allowedOffices;
this.staffOptions = staffOptions;
this.closureReasons = closureReasons;
}
public Long id() {
@@ -374,4 +374,29 @@ public final class ClientDataValidator {
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); }
}
public void validateClose(final JsonCommand command) {
final String json = command.json();
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, ClientApiConstants.CLIENT_CLOSE_REQUEST_DATA_PARAMETERS);
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
.resource(ClientApiConstants.CLIENT_RESOURCE_NAME);
final JsonElement element = command.parsedJson();
final LocalDate closureDate = this.fromApiJsonHelper.extractLocalDateNamed(ClientApiConstants.closureDateParamName, element);
baseDataValidator.reset().parameter(ClientApiConstants.closureDateParamName).value(closureDate).notNull();
final Long closureReasonId = this.fromApiJsonHelper.extractLongNamed(ClientApiConstants.closureReasonIdParamName, element);
baseDataValidator.reset().parameter(ClientApiConstants.closureReasonIdParamName).value(closureReasonId).notNull().longGreaterThanZero();
throwExceptionIfValidationWarningsExist(dataValidationErrors);
}
}
@@ -95,6 +95,15 @@ public final class Client extends AbstractPersistable<Long> {
@Transient
private boolean accountNumberRequiresAutoGeneration = false;
@SuppressWarnings("unused")
@Column(name = "closure_reason_cv_id", nullable = true)
private Long closureReasonId;
@SuppressWarnings("unused")
@Column(name = "closedon_date", nullable = true)
@Temporal(TemporalType.DATE)
private Date closureDate;
public static Client createNew(final Office clientOffice, final Group clientParentGroup, final Staff staff, final JsonCommand command) {
@@ -447,4 +456,14 @@ public final class Client extends AbstractPersistable<Long> {
this.staff = staff;
}
public void close(final Long closureReasonId, final Date closureDate) {
this.closureReasonId = closureReasonId;
this.closureDate = closureDate;
this.status = ClientStatus.CLOSED.getValue();
}
public Integer getStatus() {
return status;
}
}
@@ -0,0 +1,20 @@
/**
* 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.client.exception;
import org.mifosplatform.infrastructure.core.exception.AbstractPlatformDomainRuleException;
/**
* {@link AbstractPlatformDomainRuleException} thrown an action to transition a loan from one state to another violates a domain rule.
*/
public class InvalidClientStateTransitionException extends AbstractPlatformDomainRuleException {
public InvalidClientStateTransitionException(final String action, String postFix, String defaultUserMessage, Object... defaultUserMessageArgs) {
super("error.msg.client." + action + "." + postFix, defaultUserMessage, defaultUserMessageArgs);
// TODO Auto-generated constructor stub
}
}
@@ -0,0 +1,27 @@
package org.mifosplatform.portfolio.client.handler;
import org.mifosplatform.commands.handler.NewCommandSourceHandler;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
import org.mifosplatform.portfolio.client.service.ClientWritePlatformService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class CloseClientCommandHandler implements NewCommandSourceHandler {
private final ClientWritePlatformService clientWritePlatformService;
@Autowired
public CloseClientCommandHandler(final ClientWritePlatformService clientWritePlatformService) {
this.clientWritePlatformService = clientWritePlatformService;
}
@Transactional
@Override
public CommandProcessingResult processCommand(final JsonCommand command) {
return this.clientWritePlatformService.closeClient(command.entityId(), command);
}
}
@@ -33,4 +33,6 @@ public interface ClientReadPlatformService {
ClientData retrieveClientByIdentifier(Long identifierTypeId, String identifierKey);
Collection<ClientData> retrieveClientMembersOfGroup(Long groupId);
ClientData retrieveAllClosureReasons(String clientClosureReason);
}
@@ -13,6 +13,8 @@ import java.util.List;
import org.apache.commons.lang.StringUtils;
import org.joda.time.LocalDate;
import org.mifosplatform.infrastructure.codes.data.CodeValueData;
import org.mifosplatform.infrastructure.codes.service.CodeValueReadPlatformService;
import org.mifosplatform.infrastructure.core.api.ApiParameterHelper;
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
import org.mifosplatform.infrastructure.core.domain.JdbcSupport;
@@ -51,7 +53,7 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
private final PlatformSecurityContext context;
private final OfficeReadPlatformService officeReadPlatformService;
private final StaffReadPlatformService staffReadPlatformService;
private final CodeValueReadPlatformService codeValueReadPlatformService;
// data mappers
private final PaginationHelper<ClientData> paginationHelper = new PaginationHelper<ClientData>();
private final ClientMapper clientMapper = new ClientMapper();
@@ -61,11 +63,13 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
@Autowired
public ClientReadPlatformServiceImpl(final PlatformSecurityContext context, final TenantAwareRoutingDataSource dataSource,
final OfficeReadPlatformService officeReadPlatformService, final StaffReadPlatformService staffReadPlatformService) {
final OfficeReadPlatformService officeReadPlatformService, final StaffReadPlatformService staffReadPlatformService,
final CodeValueReadPlatformService codeValueReadPlatformService) {
this.context = context;
this.officeReadPlatformService = officeReadPlatformService;
this.jdbcTemplate = new JdbcTemplate(dataSource);
this.staffReadPlatformService = staffReadPlatformService;
this.codeValueReadPlatformService = codeValueReadPlatformService;
}
@Override
@@ -82,7 +86,7 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
staffOptions = null;
}
return ClientData.template(defaultOfficeId, new LocalDate(), offices, staffOptions);
return ClientData.template(defaultOfficeId, new LocalDate(), offices, staffOptions, null);
}
@Override
@@ -586,4 +590,11 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
}
return defaultOfficeId;
}
@Override
public ClientData retrieveAllClosureReasons(String clientClosureReason) {
final List<CodeValueData> closureReasons = new ArrayList<CodeValueData>(codeValueReadPlatformService.retrieveCodeValuesByCode(clientClosureReason));
return ClientData.template(null, null, null, null, closureReasons);
}
}
@@ -19,6 +19,8 @@ public interface ClientWritePlatformService {
CommandProcessingResult deleteClient(Long clientId);
CommandProcessingResult unassignClientStaff(Long clientId, JsonCommand command);
CommandProcessingResult closeClient(final Long clientId, final JsonCommand command);
CommandProcessingResult assignClientStaff(Long clientId, JsonCommand command);
@@ -13,6 +13,7 @@ import java.util.Map;
import org.joda.time.LocalDate;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import org.mifosplatform.infrastructure.codes.domain.CodeValueRepositoryWrapper;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResultBuilder;
@@ -29,13 +30,19 @@ import org.mifosplatform.portfolio.client.domain.AccountNumberGenerator;
import org.mifosplatform.portfolio.client.domain.AccountNumberGeneratorFactory;
import org.mifosplatform.portfolio.client.domain.Client;
import org.mifosplatform.portfolio.client.domain.ClientRepositoryWrapper;
import org.mifosplatform.portfolio.client.domain.ClientStatus;
import org.mifosplatform.portfolio.client.exception.ClientHasNoStaffException;
import org.mifosplatform.portfolio.client.exception.ClientMustBePendingToBeDeletedException;
import org.mifosplatform.portfolio.client.exception.InvalidClientStateTransitionException;
import org.mifosplatform.portfolio.group.domain.Group;
import org.mifosplatform.portfolio.group.domain.GroupRepository;
import org.mifosplatform.portfolio.group.exception.GroupNotFoundException;
import org.mifosplatform.portfolio.loanaccount.domain.Loan;
import org.mifosplatform.portfolio.loanaccount.domain.LoanRepository;
import org.mifosplatform.portfolio.note.domain.Note;
import org.mifosplatform.portfolio.note.domain.NoteRepository;
import org.mifosplatform.portfolio.savings.domain.SavingsAccount;
import org.mifosplatform.portfolio.savings.domain.SavingsAccountRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@@ -56,12 +63,16 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
private final ClientDataValidator fromApiJsonDeserializer;
private final AccountNumberGeneratorFactory accountIdentifierGeneratorFactory;
private final StaffRepositoryWrapper staffRepository;
private final CodeValueRepositoryWrapper codeValueRepository;
private final LoanRepository loanRepository;
private final SavingsAccountRepository savingsRepository;
@Autowired
public ClientWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context,
final ClientRepositoryWrapper clientRepository, final OfficeRepository officeRepository, final NoteRepository noteRepository,
final ClientDataValidator fromApiJsonDeserializer, final AccountNumberGeneratorFactory accountIdentifierGeneratorFactory,
final GroupRepository groupRepository, final StaffRepositoryWrapper staffRepository) {
final GroupRepository groupRepository, final StaffRepositoryWrapper staffRepository, final CodeValueRepositoryWrapper codeValueRepository,
final LoanRepository loanRepository, final SavingsAccountRepository savingsRepository) {
this.context = context;
this.clientRepository = clientRepository;
this.officeRepository = officeRepository;
@@ -70,6 +81,9 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
this.accountIdentifierGeneratorFactory = accountIdentifierGeneratorFactory;
this.groupRepository = groupRepository;
this.staffRepository = staffRepository;
this.codeValueRepository = codeValueRepository;
this.loanRepository = loanRepository;
this.savingsRepository = savingsRepository;
}
@Transactional
@@ -305,4 +319,64 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
.with(actualChanges) //
.build();
}
@Transactional
@Override
public CommandProcessingResult closeClient(final Long clientId, final JsonCommand command) {
try {
this.fromApiJsonDeserializer.validateClose(command);
Client client = this.clientRepository.findOneWithNotFoundDetection(clientId);
final LocalDate closureDate = command.localDateValueOfParameterNamed(ClientApiConstants.closureDateParamName);
final Long closureReasonId = command.longValueOfParameterNamed(ClientApiConstants.closureReasonIdParamName);
this.codeValueRepository.findOneByCodeNameAndIdWithNotFoundDetection(ClientApiConstants.CLIENT_CLOSURE_REASON, closureReasonId);
if (ClientStatus.fromInt(client.getStatus()).isClosed()) {
final String errorMessage = "Client is alread closed.";
throw new InvalidClientStateTransitionException("close", "is.already.closed", errorMessage);
}
if (client.isNotPending() && client.getActivationLocalDate().isAfter(closureDate)) {
final String errorMessage = "The client closureDate cannot be before the client ActivationDate.";
throw new InvalidClientStateTransitionException("close", "date.cannot.before.client.actvation.date", errorMessage,
closureDate, client.getActivationLocalDate());
}
List<Loan> clientLoans = this.loanRepository.findLoanByClientId(clientId);
for (Loan loan : clientLoans) {
LoanStatusMapper loanStatus = new LoanStatusMapper(loan.status().getValue());
if (loanStatus.isOpen()) {
final String errorMessage = "Client cannot be closed because of non-closed loans.";
throw new InvalidClientStateTransitionException("close", "loan.non-closed", errorMessage);
} else if (loanStatus.isClosed() && loan.getClosedOnDate().after(closureDate.toDate())) {
final String errorMessage = "The client closureDate cannot be before the loan closedOnDate.";
throw new InvalidClientStateTransitionException("close", "date.cannot.before.loan.closed.date", errorMessage,
closureDate, loan.getClosedOnDate());
}
}
List<SavingsAccount> clientSavingAccounts = this.savingsRepository.findSavingAccountByClientId(clientId);
for (SavingsAccount saving : clientSavingAccounts) {
if (saving.isActive()) {
final String errorMessage = "Client cannot be closed because of non-closed savings account.";
throw new InvalidClientStateTransitionException("close", "non-closed.savings.account", errorMessage);
}
}
client.close(closureReasonId, closureDate.toDate());
this.clientRepository.saveAndFlush(client);
return new CommandProcessingResultBuilder() //
.withCommandId(command.commandId()) //
.withClientId(clientId) //
.withEntityId(clientId) //
.build();
} catch (DataIntegrityViolationException dve) {
handleDataIntegrityIssues(command, dve);
return CommandProcessingResult.empty();
}
}
}
@@ -2317,8 +2317,12 @@ public class Loan extends AbstractPersistable<Long> {
this.transactionProcessorFactory = transactionProcessorFactory;
}
public boolean isSyncDisbursementWithMeeting() {
return this.syncDisbursementWithMeeting == null ? false : this.syncDisbursementWithMeeting;
}
public boolean isSyncDisbursementWithMeeting() {
return this.syncDisbursementWithMeeting == null ? false : this.syncDisbursementWithMeeting;
}
public Date getClosedOnDate() {
return this.closedOnDate;
}
}
@@ -16,4 +16,7 @@ public interface LoanRepository extends JpaRepository<Loan, Long>,
JpaSpecificationExecutor<Loan> {
@Query("from Loan loan where loan.client.id = :clientId and loan.group.id = :groupId")
List<Loan> findByClientIdAndGroupId(@Param("clientId") Long clientId, @Param("groupId") Long groupId);
@Query("from Loan loan where loan.client.id = :clientId")
List<Loan> findLoanByClientId(@Param("clientId") Long clientId);
}
@@ -5,9 +5,15 @@
*/
package org.mifosplatform.portfolio.savings.domain;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
public interface SavingsAccountRepository extends JpaRepository<SavingsAccount, Long>, JpaSpecificationExecutor<SavingsAccount> {
@Query("from SavingsAccount s_acc where s_acc.client.id = :clientId")
List<SavingsAccount> findSavingAccountByClientId(@Param("clientId") Long clientId);
}