Merge pull request #501 from ShruthiRajaram/FINERACT-669
FINERACT-669 back dated client transfer changes
This commit is contained in:
+12
-6
@@ -18,7 +18,6 @@
|
||||
*/
|
||||
package org.apache.fineract.portfolio.client.api;
|
||||
|
||||
import io.swagger.annotations.*;
|
||||
import java.io.InputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
@@ -72,6 +71,14 @@ import org.springframework.stereotype.Component;
|
||||
import com.sun.jersey.core.header.FormDataContentDisposition;
|
||||
import com.sun.jersey.multipart.FormDataParam;
|
||||
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiImplicitParam;
|
||||
import io.swagger.annotations.ApiImplicitParams;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import io.swagger.annotations.ApiParam;
|
||||
import io.swagger.annotations.ApiResponse;
|
||||
import io.swagger.annotations.ApiResponses;
|
||||
|
||||
@Path("/clients")
|
||||
@Component
|
||||
@Scope("singleton")
|
||||
@@ -389,16 +396,15 @@ public class ClientsApiResource {
|
||||
return this.toApiJsonSerializer.serialize(ObligeeList);
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("{clientId}/transferproposaldate")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String retrieveTransferTemplate(@PathParam("clientId") final Long clientId, @Context final UriInfo uriInfo) {
|
||||
|
||||
this.context.authenticatedUser().validateHasReadPermission(ClientApiConstants.CLIENT_RESOURCE_NAME);
|
||||
this.context.authenticatedUser().validateHasReadPermission(ClientApiConstants.CLIENT_RESOURCE_NAME);
|
||||
|
||||
final Date transferDate = this.clientReadPlatformService.retrieveClientTransferProposalDate(clientId);
|
||||
if (transferDate != null) {
|
||||
return this.toApiJsonSerializer.serialize(new LocalDate(transferDate));
|
||||
}
|
||||
return this.toApiJsonSerializer.serialize(transferDate);
|
||||
return this.toApiJsonSerializer.serialize((transferDate != null ? new LocalDate(transferDate) : null));
|
||||
}
|
||||
}
|
||||
+13
@@ -232,6 +232,10 @@ public final class Client extends AbstractPersistableCustom<Long> {
|
||||
@JoinColumn(name = "reopened_by_userid", nullable = true)
|
||||
private AppUser reopenedBy;
|
||||
|
||||
@Column(name = "proposed_transfer_date", nullable = true)
|
||||
@Temporal(TemporalType.DATE)
|
||||
private Date proposedTransferDate;
|
||||
|
||||
public static Client createNew(final AppUser currentUser, final Office clientOffice, final Group clientParentGroup, final Staff staff,
|
||||
final Long savingsProductId, final CodeValue gender, final CodeValue clientType, final CodeValue clientClassification,
|
||||
final Integer legalForm, final JsonCommand command) {
|
||||
@@ -1058,4 +1062,13 @@ public final class Client extends AbstractPersistableCustom<Long> {
|
||||
public String getMiddlename(){return this.middlename;}
|
||||
|
||||
public String getLastname(){return this.lastname;}
|
||||
|
||||
public Date getProposedTransferDate() {
|
||||
return proposedTransferDate;
|
||||
}
|
||||
|
||||
public void updateProposedTransferDate(Date proposedTransferDate) {
|
||||
this.proposedTransferDate = proposedTransferDate;
|
||||
}
|
||||
|
||||
}
|
||||
+83
@@ -0,0 +1,83 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.apache.fineract.portfolio.client.domain;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Table;
|
||||
import javax.persistence.Temporal;
|
||||
import javax.persistence.TemporalType;
|
||||
|
||||
import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
@Entity
|
||||
@Table(name = "m_client_transfer_details")
|
||||
public class ClientTransferDetails extends AbstractPersistableCustom<Long> {
|
||||
|
||||
@Column(name = "client_id", length = 20, unique = true, nullable = false)
|
||||
private Long clientId;
|
||||
|
||||
@Column(name = "from_office_id", nullable = false)
|
||||
private Long fromOfficeId;
|
||||
|
||||
@Column(name = "to_office_id", nullable = false)
|
||||
private Long toOfficeId;
|
||||
|
||||
@Column(name = "proposed_transfer_date", nullable = true)
|
||||
@Temporal(TemporalType.DATE)
|
||||
private Date proposedTransferDate;
|
||||
|
||||
@Column(name = "transfer_type", nullable = false)
|
||||
private Integer transferEventType;
|
||||
|
||||
@Column(name = "submitted_on", nullable = false)
|
||||
@Temporal(TemporalType.DATE)
|
||||
private Date submittedOn;
|
||||
|
||||
@Column(name = "submitted_by", nullable = false)
|
||||
private Long submittedBy;
|
||||
|
||||
protected ClientTransferDetails() {
|
||||
}
|
||||
|
||||
private ClientTransferDetails(final Long clientId, final Long fromOfficeId, final Long toOfficeId,
|
||||
final Date proposedTransferDate, final Integer transferEventType, final Date submittedOn,
|
||||
final Long submittedBy) {
|
||||
this.clientId = clientId;
|
||||
this.fromOfficeId = fromOfficeId;
|
||||
this.toOfficeId = toOfficeId;
|
||||
this.proposedTransferDate = proposedTransferDate;
|
||||
this.transferEventType = transferEventType;
|
||||
this.submittedOn = submittedOn;
|
||||
this.submittedBy = submittedBy;
|
||||
}
|
||||
|
||||
public static ClientTransferDetails instance(final Long clientId, final Long fromOfficeId, final Long toOfficeId,
|
||||
final Date proposedTransferDate, final Integer transferEventType, final Date submittedOn,
|
||||
final Long submittedBy) {
|
||||
return new ClientTransferDetails(clientId, fromOfficeId, toOfficeId, proposedTransferDate, transferEventType,
|
||||
submittedOn, submittedBy);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.apache.fineract.portfolio.client.domain;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||
|
||||
public interface ClientTransferDetailsRepository
|
||||
extends JpaRepository<ClientTransferDetails, Long>, JpaSpecificationExecutor<ClientTransferDetails> {
|
||||
|
||||
}
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.apache.fineract.portfolio.client.domain;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class ClientTransferDetailsRepositoryWrapper {
|
||||
|
||||
private final ClientTransferDetailsRepository repository;
|
||||
|
||||
@Autowired
|
||||
public ClientTransferDetailsRepositoryWrapper(final ClientTransferDetailsRepository repository) {
|
||||
this.repository = repository;
|
||||
}
|
||||
|
||||
public void save(final ClientTransferDetails clientTransferDetails) {
|
||||
this.repository.save(clientTransferDetails);
|
||||
}
|
||||
|
||||
}
|
||||
-4
@@ -49,9 +49,5 @@ public interface ClientReadPlatformService {
|
||||
|
||||
Date retrieveClientTransferProposalDate(Long clientId);
|
||||
|
||||
Date retrieveClientTransferProposalDateByLoan(Long clientId);
|
||||
|
||||
Date retrieveClientTransferProposalDateBySavings(Long clientId);
|
||||
|
||||
void validateClient(Long clientId);
|
||||
}
|
||||
+6
-34
@@ -61,11 +61,7 @@ import org.apache.fineract.portfolio.client.domain.ClientStatus;
|
||||
import org.apache.fineract.portfolio.client.domain.LegalForm;
|
||||
import org.apache.fineract.portfolio.client.exception.ClientNotFoundException;
|
||||
import org.apache.fineract.portfolio.group.data.GroupGeneralData;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanStatus;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanTransactionType;
|
||||
import org.apache.fineract.portfolio.savings.SavingsAccountTransactionType;
|
||||
import org.apache.fineract.portfolio.savings.data.SavingsProductData;
|
||||
import org.apache.fineract.portfolio.savings.domain.SavingsAccountStatusType;
|
||||
import org.apache.fineract.portfolio.savings.service.SavingsProductReadPlatformService;
|
||||
import org.apache.fineract.useradministration.domain.AppUser;
|
||||
import org.joda.time.LocalDate;
|
||||
@@ -823,41 +819,17 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
|
||||
clientNonPersonConstitutionOptions, clientNonPersonMainBusinessLineOptions, clientLegalFormOptions,null,null,null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date retrieveClientTransferProposalDateByLoan(Long clientId) {
|
||||
try {
|
||||
String sql = "SELECT t.transaction_date FROM m_client c LEFT JOIN m_loan loan ON c.id = loan.client_id AND c.id = ? AND loan.loan_status_id = ? LEFT JOIN m_loan_transaction t ON loan.id = t.loan_id AND t.transaction_type_enum = ? ORDER BY t.id DESC LIMIT 1";
|
||||
return this.jdbcTemplate.queryForObject(sql, Date.class, clientId,
|
||||
LoanStatus.TRANSFER_IN_PROGRESS.getValue(), LoanTransactionType.INITIATE_TRANSFER.getValue());
|
||||
} catch (final EmptyResultDataAccessException e) {
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date retrieveClientTransferProposalDateBySavings(Long clientId) {
|
||||
try {
|
||||
String sql = "SELECT t.transaction_date FROM m_client c LEFT JOIN m_savings_account savings ON c.id = savings.client_id AND c.id = ? AND savings.status_enum = ? LEFT JOIN m_savings_account_transaction t ON savings.id = t.savings_account_id AND t.transaction_type_enum = ? ORDER BY t.id DESC LIMIT 1";
|
||||
return this.jdbcTemplate.queryForObject(sql, Date.class, clientId,
|
||||
SavingsAccountStatusType.TRANSFER_IN_PROGRESS.getValue(),
|
||||
SavingsAccountTransactionType.INITIATE_TRANSFER.getValue());
|
||||
} catch (final EmptyResultDataAccessException e) {
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date retrieveClientTransferProposalDate(Long clientId) {
|
||||
validateClient(clientId);
|
||||
Date transferDateForLoan = retrieveClientTransferProposalDateByLoan(clientId);
|
||||
if (transferDateForLoan == null) {
|
||||
transferDateForLoan = retrieveClientTransferProposalDateBySavings(clientId);
|
||||
final String sql = "SELECT cl.proposed_transfer_date FROM m_client cl WHERE cl.id =? ";
|
||||
try {
|
||||
return this.jdbcTemplate.queryForObject(sql, Date.class, clientId);
|
||||
} catch (final EmptyResultDataAccessException e) {
|
||||
return null;
|
||||
}
|
||||
return transferDateForLoan;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void validateClient(Long clientId) {
|
||||
try {
|
||||
|
||||
+24
-6
@@ -27,6 +27,7 @@ import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.apache.fineract.infrastructure.core.data.CommandProcessingResultBuilder;
|
||||
import org.apache.fineract.infrastructure.core.exception.GeneralPlatformDomainRuleException;
|
||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
|
||||
import org.apache.fineract.organisation.office.domain.Office;
|
||||
import org.apache.fineract.organisation.office.domain.OfficeRepositoryWrapper;
|
||||
import org.apache.fineract.organisation.staff.domain.Staff;
|
||||
@@ -40,6 +41,8 @@ import org.apache.fineract.portfolio.calendar.service.CalendarUtils;
|
||||
import org.apache.fineract.portfolio.client.domain.Client;
|
||||
import org.apache.fineract.portfolio.client.domain.ClientRepositoryWrapper;
|
||||
import org.apache.fineract.portfolio.client.domain.ClientStatus;
|
||||
import org.apache.fineract.portfolio.client.domain.ClientTransferDetails;
|
||||
import org.apache.fineract.portfolio.client.domain.ClientTransferDetailsRepositoryWrapper;
|
||||
import org.apache.fineract.portfolio.client.exception.ClientHasBeenClosedException;
|
||||
import org.apache.fineract.portfolio.group.domain.Group;
|
||||
import org.apache.fineract.portfolio.group.domain.GroupRepositoryWrapper;
|
||||
@@ -81,6 +84,8 @@ public class TransferWritePlatformServiceJpaRepositoryImpl implements TransferWr
|
||||
private final TransfersDataValidator transfersDataValidator;
|
||||
private final NoteWritePlatformService noteWritePlatformService;
|
||||
private final StaffRepositoryWrapper staffRepositoryWrapper;
|
||||
private final ClientTransferDetailsRepositoryWrapper clientTransferDetailsRepositoryWrapper;
|
||||
private final PlatformSecurityContext context;
|
||||
|
||||
@Autowired
|
||||
public TransferWritePlatformServiceJpaRepositoryImpl(final ClientRepositoryWrapper clientRepositoryWrapper,
|
||||
@@ -89,8 +94,10 @@ public class TransferWritePlatformServiceJpaRepositoryImpl implements TransferWr
|
||||
final LoanRepositoryWrapper loanRepositoryWrapper, final TransfersDataValidator transfersDataValidator,
|
||||
final NoteWritePlatformService noteWritePlatformService, final StaffRepositoryWrapper staffRepositoryWrapper,
|
||||
final SavingsAccountRepositoryWrapper savingsAccountRepositoryWrapper,
|
||||
final SavingsAccountWritePlatformService savingsAccountWritePlatformService) {
|
||||
this.clientRepositoryWrapper = clientRepositoryWrapper;
|
||||
final SavingsAccountWritePlatformService savingsAccountWritePlatformService,
|
||||
final ClientTransferDetailsRepositoryWrapper clientTransferDetailsRepositoryWrapper,
|
||||
final PlatformSecurityContext context) {
|
||||
this.clientRepositoryWrapper = clientRepositoryWrapper;
|
||||
this.officeRepository = officeRepository;
|
||||
this.calendarInstanceRepository = calendarInstanceRepository;
|
||||
this.loanWritePlatformService = loanWritePlatformService;
|
||||
@@ -101,7 +108,9 @@ public class TransferWritePlatformServiceJpaRepositoryImpl implements TransferWr
|
||||
this.staffRepositoryWrapper = staffRepositoryWrapper;
|
||||
this.savingsAccountRepositoryWrapper = savingsAccountRepositoryWrapper;
|
||||
this.savingsAccountWritePlatformService = savingsAccountWritePlatformService;
|
||||
}
|
||||
this.clientTransferDetailsRepositoryWrapper = clientTransferDetailsRepositoryWrapper;
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
@@ -438,7 +447,8 @@ public class TransferWritePlatformServiceJpaRepositoryImpl implements TransferWr
|
||||
client.setStatus(ClientStatus.ACTIVE.getValue());
|
||||
client.updateTransferToOffice(null);
|
||||
client.updateOffice(destinationOffice);
|
||||
client.updateOfficeJoiningDate(todaysDate);
|
||||
client.updateOfficeJoiningDate(client.getProposedTransferDate());
|
||||
client.updateProposedTransferDate(null);
|
||||
if (client.getGroups().size() == 1) {
|
||||
if (destinationGroup == null) {
|
||||
throw new TransferNotSupportedException(TRANSFER_NOT_SUPPORTED_REASON.CLIENT_DESTINATION_GROUP_NOT_SPECIFIED,
|
||||
@@ -458,18 +468,26 @@ public class TransferWritePlatformServiceJpaRepositoryImpl implements TransferWr
|
||||
case PROPOSAL:
|
||||
client.setStatus(ClientStatus.TRANSFER_IN_PROGRESS.getValue());
|
||||
client.updateTransferToOffice(destinationOffice);
|
||||
client.updateProposedTransferDate(transferDate.toDate());
|
||||
break;
|
||||
case REJECTION:
|
||||
client.setStatus(ClientStatus.TRANSFER_ON_HOLD.getValue());
|
||||
client.updateTransferToOffice(null);
|
||||
client.updateProposedTransferDate(null);
|
||||
break;
|
||||
case WITHDRAWAL:
|
||||
client.setStatus(ClientStatus.ACTIVE.getValue());
|
||||
client.updateTransferToOffice(null);
|
||||
client.updateProposedTransferDate(null);
|
||||
}
|
||||
|
||||
this.noteWritePlatformService.createAndPersistClientNote(client, jsonCommand);
|
||||
}
|
||||
this.noteWritePlatformService.createAndPersistClientNote(client, jsonCommand);
|
||||
Date proposedTransferDate = transferDate != null ? transferDate.toDate() : null;
|
||||
this.clientTransferDetailsRepositoryWrapper
|
||||
.save(ClientTransferDetails.instance(client.getId(), client.getOffice().getId(),
|
||||
destinationOffice.getId(), proposedTransferDate, transferEventType.getValue(),
|
||||
DateUtils.getLocalDateTimeOfTenant().toDate(), this.context.authenticatedUser().getId()));
|
||||
}
|
||||
|
||||
private List<Client> assembleListOfClients(final JsonCommand command) {
|
||||
|
||||
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
--
|
||||
-- Licensed to the Apache Software Foundation (ASF) under one
|
||||
-- or more contributor license agreements. See the NOTICE file
|
||||
-- distributed with this work for additional information
|
||||
-- regarding copyright ownership. The ASF licenses this file
|
||||
-- to you under the Apache License, Version 2.0 (the
|
||||
-- "License"); you may not use this file except in compliance
|
||||
-- with the License. You may obtain a copy of the License at
|
||||
--
|
||||
-- http://www.apache.org/licenses/LICENSE-2.0
|
||||
--
|
||||
-- Unless required by applicable law or agreed to in writing,
|
||||
-- software distributed under the License is distributed on an
|
||||
-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
-- KIND, either express or implied. See the License for the
|
||||
-- specific language governing permissions and limitations
|
||||
-- under the License.
|
||||
--
|
||||
|
||||
ALTER TABLE `m_client`
|
||||
ADD COLUMN `proposed_transfer_date` DATE NULL DEFAULT NULL AFTER `email_address`;
|
||||
|
||||
CREATE TABLE `m_client_transfer_details` (
|
||||
`id` BIGINT(20) NOT NULL AUTO_INCREMENT,
|
||||
`client_id` BIGINT(20) NOT NULL,
|
||||
`from_office_id` BIGINT(20) NOT NULL,
|
||||
`to_office_id` BIGINT(20) NOT NULL,
|
||||
`proposed_transfer_date` DATE NULL DEFAULT NULL,
|
||||
`transfer_type` TINYINT(2) NOT NULL,
|
||||
`submitted_on` DATE NOT NULL,
|
||||
`submitted_by` BIGINT(20) NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
INDEX `FK_m_client_transfer_details_m_client` (`client_id`),
|
||||
INDEX `FK_m_client_transfer_details_m_office` (`from_office_id`),
|
||||
INDEX `FK_m_client_transfer_details_m_office_2` (`to_office_id`),
|
||||
INDEX `FK_m_client_transfer_details_m_appuser` (`submitted_by`),
|
||||
CONSTRAINT `FK_m_client_transfer_details_m_appuser` FOREIGN KEY (`submitted_by`) REFERENCES `m_appuser` (`id`),
|
||||
CONSTRAINT `FK_m_client_transfer_details_m_client` FOREIGN KEY (`client_id`) REFERENCES `m_client` (`id`),
|
||||
CONSTRAINT `FK_m_client_transfer_details_m_office` FOREIGN KEY (`from_office_id`) REFERENCES `m_office` (`id`),
|
||||
CONSTRAINT `FK_m_client_transfer_details_m_office_2` FOREIGN KEY (`to_office_id`) REFERENCES `m_office` (`id`)
|
||||
);
|
||||
Reference in New Issue
Block a user