cleaning up transfers functionality and prepping for 1.9 release
This commit is contained in:
+123
-23
@@ -90,7 +90,7 @@
|
||||
<body>
|
||||
<div id="page-wrapper">
|
||||
<div id="flybar">
|
||||
<div id="nav-logo">1.8.1.RELEASE API</div>
|
||||
<div id="nav-logo">1.9.0.RELEASE API</div>
|
||||
<div class="flybar-nav">
|
||||
<h2 class="flybar-button">Overview</h2>
|
||||
<div class="flybar-menu-overview">
|
||||
@@ -209,8 +209,32 @@
|
||||
</tr>
|
||||
<tr class="alt">
|
||||
<td></td>
|
||||
<td>clients/{clientId}?command=transfer</td>
|
||||
<td><a href="#clients_transfer">Transfer Client</a></td>
|
||||
<td>clients/{clientId}?command=proposeTransfer</td>
|
||||
<td><a href="#clients_propose_transfer">Propose a Client Transfer</a></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td>clients/{clientId}?command=withdrawTransfer</td>
|
||||
<td><a href="#clients_withdraw_transfer">Withdraw Client Transfer Proposal</a></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr class="alt">
|
||||
<td></td>
|
||||
<td>clients/{clientId}?command=acceptTransfer</td>
|
||||
<td><a href="#clients_accept_transfer">Accept Client Transfer</a></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td>clients/{clientId}?command=rejectTransfer</td>
|
||||
<td><a href="#clients_reject_transfer">Reject Client Transfer</a></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
@@ -586,7 +610,7 @@
|
||||
<tr>
|
||||
<td></td>
|
||||
<td>groups/{groupId}?command=transferClients</td>
|
||||
<td><a href="#groups_transfer_clients">Transfer Clients</a></td>
|
||||
<td><a href="#groups_transfer_clients">Bulk Transfer Clients across Groups</a></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
@@ -2138,19 +2162,20 @@ Request Body:
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a id="clients_transfer" name="clients_transfer" class="old-syle-anchor"> </a>
|
||||
<a id="clients_propose_transfer" name="clients_propose_transfer" class="old-syle-anchor"> </a>
|
||||
<div class="method-section">
|
||||
<div class="method-description">
|
||||
<h4>Transfer a Client</h4>
|
||||
<p>Allows you to transfer a <i>Client</i> between <i>Offices</i>.</p>
|
||||
<h4>Propose a Client Transfer</h4>
|
||||
<p>Allows you to propose the transfer of a <i>Client</i> to a different <i>Offices</i>.</p>
|
||||
</div>
|
||||
<div class="method-example">
|
||||
<code class="method-declaration">POST https://Domain Name/api/v1/clients/{clientId}?command=transfer</code>
|
||||
<code class="method-request">POST clients/1?command=transfer
|
||||
<code class="method-declaration">POST https://Domain Name/api/v1/clients/{clientId}?command=proposeTransfer</code>
|
||||
<code class="method-request">POST clients/1?command=proposeTransfer
|
||||
Content-Type: application/json
|
||||
Request Body:
|
||||
{
|
||||
destinationOfficeId:1
|
||||
"destinationOfficeId":"2",
|
||||
"note":"Client Relocating to Bangalore"
|
||||
}
|
||||
</code>
|
||||
<code class="method-response">
|
||||
@@ -2162,7 +2187,92 @@ Request Body:
|
||||
|
||||
</code>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a id="clients_withdraw_transfer" name="clients_withdraw_transfer" class="old-syle-anchor"> </a>
|
||||
<div class="method-section">
|
||||
<div class="method-description">
|
||||
<h4>Withdraw a Client Transfer</h4>
|
||||
<p>Allows you to withdraw the proposed the transfer of a <i>Client</i> to a different <i>Offices</i>.</p>
|
||||
<p>Withdrawal can happen only if the destination Branch (to which the transfer was
|
||||
<a href="#clients_propose_transfer">proposed</a>) has not already
|
||||
<a href="#clients_accept_transfer">accepted</a> the transfer proposal </p>
|
||||
</div>
|
||||
<div class="method-example">
|
||||
<code class="method-declaration">POST https://Domain Name/api/v1/clients/{clientId}?command=withdrawTransfer</code>
|
||||
<code class="method-request">POST clients/1?command=withdrawTransfer
|
||||
Content-Type: application/json
|
||||
Request Body:
|
||||
{
|
||||
"note":"Sorry, data entry error"
|
||||
}
|
||||
</code>
|
||||
<code class="method-response">
|
||||
{
|
||||
"clientId": 2,
|
||||
"resourceId": 2
|
||||
}
|
||||
|
||||
|
||||
</code>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a id="clients_reject_transfer" name="clients_reject_transfer" class="old-syle-anchor"> </a>
|
||||
<div class="method-section">
|
||||
<div class="method-description">
|
||||
<h4>Reject a Client Transfer</h4>
|
||||
<p>Allows the Destination Branch to reject the <a href="#clients_propose_transfer">proposed</a> Client Transfer.</p>
|
||||
</div>
|
||||
<div class="method-example">
|
||||
<code class="method-declaration">POST https://Domain Name/api/v1/clients/{clientId}?command=rejectTransfer</code>
|
||||
<code class="method-request">POST clients/1?command=rejectTransfer
|
||||
Content-Type: application/json
|
||||
Request Body:
|
||||
{
|
||||
"note":"We cannot accept tranfers of clients having loans with less than 1 repayment left"
|
||||
}
|
||||
</code>
|
||||
<code class="method-response">
|
||||
{
|
||||
"clientId": 2,
|
||||
"resourceId": 2
|
||||
}
|
||||
|
||||
|
||||
</code>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a id="clients_accept_transfer" name="clients_accept_transfer" class="old-syle-anchor"> </a>
|
||||
<div class="method-section">
|
||||
<div class="method-description">
|
||||
<h4>Reject a Client Transfer</h4>
|
||||
<p>Allows the Destination Branch to accept the <a href="#clients_propose_transfer">proposed</a> Client Transfer.</p>
|
||||
<p>The destination branch may also choose to link this client to a group (in which case, any existing active JLG loan of the client is rescheduled to match the meeting frequency of the group) and loan Officer at the time of accepting
|
||||
the transfer</p>
|
||||
</div>
|
||||
<div class="method-example">
|
||||
<code class="method-declaration">POST https://Domain Name/api/v1/clients/{clientId}?command=acceptTransfer</code>
|
||||
<code class="method-request">POST clients/1?command=acceptTransfer
|
||||
Content-Type: application/json
|
||||
Request Body:
|
||||
{
|
||||
"note":"Due Diligence done and all documents received"
|
||||
}
|
||||
</code>
|
||||
<code class="method-response">
|
||||
{
|
||||
"clientId": 2,
|
||||
"resourceId": 2
|
||||
}
|
||||
|
||||
|
||||
</code>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<a id="clients_retrieve" name="clients_retrieve" class="old-syle-anchor"> </a>
|
||||
<div class="method-section">
|
||||
<div class="method-description">
|
||||
@@ -3866,7 +3976,8 @@ Request Body:
|
||||
<td>destinationGroupId</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class=fielddesc>The identifier of the group to which the clients are to be transferred.</td>
|
||||
<td class=fielddesc>The identifier of the group to which the clients are to be transferred (
|
||||
has to be in the same branch as the source Group).</td>
|
||||
</tr>
|
||||
<tr class=alt>
|
||||
<td>clients</td>
|
||||
@@ -3883,15 +3994,6 @@ Request Body:
|
||||
should be linked to the assigned loan officer for the group
|
||||
</td>
|
||||
</tr>
|
||||
<tr class=alt>
|
||||
<td>transferActiveLoans</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class=fielddesc>Flag specifies if transfers should proceed when active loans are encountered.
|
||||
If set to true, the schedules of the actives loans are updated to match that meeting schedule
|
||||
of the destination Group
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br/>
|
||||
<table class=matrixHeading>
|
||||
@@ -3911,8 +4013,6 @@ Request Body:
|
||||
<td>inheritDestinationGroupLoanOfficer (defaults to true), transferActiveLoans (defaults to true)</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
/***Store destination office Id while client is pending transfers and effective joining date in a particular branch**/
|
||||
ALTER TABLE `m_client`
|
||||
ADD COLUMN `office_joining_date` DATE NULL AFTER `activation_date`,
|
||||
ADD COLUMN `transfer_to_office_id` BIGINT(20) NULL AFTER `office_id`,
|
||||
ADD CONSTRAINT `FK_m_client_m_office` FOREIGN KEY (`transfer_to_office_id`) REFERENCES `m_office` (`id`);
|
||||
|
||||
|
||||
/**For current Clients, set the office joining date to activation date**/
|
||||
update m_client set office_joining_date=activation_date;
|
||||
+1
-1
@@ -363,7 +363,7 @@ public class CommandWrapperBuilder {
|
||||
}
|
||||
|
||||
public CommandWrapperBuilder withdrawClientTransferRequest(final Long clientId) {
|
||||
this.actionName = "PROPOSETRANSFER";
|
||||
this.actionName = "WITHDRAWTRANSFER";
|
||||
this.entityName = "CLIENT";
|
||||
this.entityId = clientId;
|
||||
this.clientId = clientId;
|
||||
|
||||
+6
-2
@@ -22,6 +22,10 @@ import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidation
|
||||
|
||||
public class DateUtils {
|
||||
|
||||
public static Date getDateOfTenant() {
|
||||
return getLocalDateOfTenant().toDateMidnight().toDate();
|
||||
}
|
||||
|
||||
public static LocalDate getLocalDateOfTenant() {
|
||||
|
||||
LocalDate today = new LocalDate();
|
||||
@@ -53,8 +57,8 @@ public class DateUtils {
|
||||
dataValidationErrors);
|
||||
}
|
||||
}
|
||||
|
||||
public static String formatToSqlDate(final Date date){
|
||||
|
||||
public static String formatToSqlDate(final Date date) {
|
||||
final DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
|
||||
final String formattedSqlDate = df.format(date);
|
||||
return formattedSqlDate;
|
||||
|
||||
+1
-1
@@ -27,7 +27,7 @@ public interface CalendarInstanceRepository extends JpaRepository<CalendarInstan
|
||||
Collection<CalendarInstance> findByCalendarIdAndEntityTypeId(Long calendarId, Integer entityTypeId);
|
||||
|
||||
/**Should use in clause, can I do it without creating a new class?**/
|
||||
@Query("from CalendarInstance ci where ci.entityId in (select id from Loan loan where loan.client.id = :clientId and loan.group.id=:groupId and (loan.loanStatus = 100 or loan.loanStatus = 200 or loan.loanStatus = 300)) and ci.entityTypeId = 3")
|
||||
@Query("from CalendarInstance ci where ci.entityId in (select id from Loan loan where loan.client.id = :clientId and loan.group.id = :groupId and (loan.loanStatus = 100 or loan.loanStatus = 200 or loan.loanStatus = 300)) and ci.entityTypeId = 3")
|
||||
List<CalendarInstance> findCalendarInstancesForActiveLoansByGroupIdAndClientId(@Param("clientId") Long clientId,
|
||||
@Param("groupId") Long groupId);
|
||||
}
|
||||
|
||||
+8
-5
@@ -30,6 +30,7 @@ public class ClientApiConstants {
|
||||
public static final String lastnameParamName = "lastname";
|
||||
public static final String fullnameParamName = "fullname";
|
||||
public static final String officeIdParamName = "officeId";
|
||||
public static final String transferOfficeIdParamName = "transferOfficeIdParamName";
|
||||
public static final String activeParamName = "active";
|
||||
public static final String activationDateParamName = "activationDate";
|
||||
public static final String staffIdParamName = "staffId";
|
||||
@@ -40,6 +41,7 @@ public class ClientApiConstants {
|
||||
public static final String hierarchyParamName = "hierarchy";
|
||||
public static final String displayNameParamName = "displayName";
|
||||
public static final String officeNameParamName = "officeName";
|
||||
public static final String trasnferOfficeNameParamName = "transferOfficeName";
|
||||
public static final String imageKeyParamName = "imageKey";
|
||||
public static final String imagePresentParamName = "imagePresent";
|
||||
|
||||
@@ -55,8 +57,8 @@ public class ClientApiConstants {
|
||||
lastnameParamName, fullnameParamName, officeIdParamName, activeParamName, activationDateParamName, staffIdParamName));
|
||||
|
||||
public static final Set<String> CLIENT_UPDATE_REQUEST_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(localeParamName,
|
||||
dateFormatParamName, accountNoParamName, externalIdParamName, firstnameParamName, middlenameParamName,
|
||||
lastnameParamName, fullnameParamName, activeParamName, activationDateParamName, staffIdParamName));
|
||||
dateFormatParamName, accountNoParamName, externalIdParamName, firstnameParamName, middlenameParamName, lastnameParamName,
|
||||
fullnameParamName, activeParamName, activationDateParamName, staffIdParamName));
|
||||
|
||||
/**
|
||||
* These parameters will match the class level parameters of
|
||||
@@ -65,12 +67,13 @@ public class ClientApiConstants {
|
||||
*/
|
||||
public static final Set<String> CLIENT_RESPONSE_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(idParamName, accountNoParamName,
|
||||
externalIdParamName, statusParamName, activeParamName, activationDateParamName, firstnameParamName, middlenameParamName,
|
||||
lastnameParamName, fullnameParamName, displayNameParamName, officeIdParamName, officeNameParamName, hierarchyParamName,
|
||||
imageKeyParamName, imagePresentParamName, groupsParamName, officeOptionsParamName, staffOptionsParamName));
|
||||
lastnameParamName, fullnameParamName, displayNameParamName, officeIdParamName, officeNameParamName, transferOfficeIdParamName,
|
||||
trasnferOfficeNameParamName, hierarchyParamName, imageKeyParamName, imagePresentParamName, groupsParamName,
|
||||
officeOptionsParamName, staffOptionsParamName));
|
||||
|
||||
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));
|
||||
}
|
||||
+2
@@ -86,6 +86,8 @@ public class ClientsApiResource {
|
||||
context.authenticatedUser().validateHasReadPermission(ClientApiConstants.CLIENT_RESOURCE_NAME);
|
||||
if (is(commandParam, "close")) {
|
||||
clientData = this.clientReadPlatformService.retrieveAllClosureReasons(ClientApiConstants.CLIENT_CLOSURE_REASON);
|
||||
} else if (is(commandParam, "acceptTransfer")) {
|
||||
clientData = this.clientReadPlatformService.retrieveAllClosureReasons(ClientApiConstants.CLIENT_CLOSURE_REASON);
|
||||
} else {
|
||||
clientData = this.clientReadPlatformService.retrieveTemplate(officeId, staffInSelectedOfficeOnly);
|
||||
}
|
||||
|
||||
+29
-22
@@ -40,6 +40,8 @@ final public class ClientData implements Comparable<ClientData> {
|
||||
|
||||
private final Long officeId;
|
||||
private final String officeName;
|
||||
private final Long transferToOfficeId;
|
||||
private final String transferToOfficeName;
|
||||
|
||||
private final Long imageId;
|
||||
private final Boolean imagePresent;
|
||||
@@ -57,49 +59,52 @@ final public class ClientData implements Comparable<ClientData> {
|
||||
|
||||
public static ClientData template(final Long officeId, final LocalDate joinedDate, final Collection<OfficeData> officeOptions,
|
||||
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);
|
||||
return new ClientData(null, null, officeId, null, null, null, null, null, null, null, null, null, null, joinedDate, null, null,
|
||||
null, officeOptions, null, staffOptions, closureReasons);
|
||||
}
|
||||
|
||||
public static ClientData templateOnTop(final ClientData clientData, final ClientData templateData) {
|
||||
|
||||
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,
|
||||
templateData.officeOptions, clientData.groups, templateData.staffOptions, null);
|
||||
return new ClientData(clientData.accountNo, clientData.status, clientData.officeId, clientData.officeName,
|
||||
clientData.transferToOfficeId, clientData.transferToOfficeName, clientData.id, clientData.firstname, clientData.middlename,
|
||||
clientData.lastname, clientData.fullname, clientData.displayName, clientData.externalId, clientData.activationDate,
|
||||
clientData.imageId, clientData.staffId, clientData.staffName, templateData.officeOptions, clientData.groups,
|
||||
templateData.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, null);
|
||||
return new ClientData(clientData.accountNo, clientData.status, clientData.officeId, clientData.officeName,
|
||||
clientData.transferToOfficeId, clientData.transferToOfficeName, 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, null);
|
||||
}
|
||||
|
||||
public static ClientData clientIdentifier(final Long id, final String accountNo, final EnumOptionData status, final String firstname,
|
||||
final String middlename, final String lastname, final String fullname, final String displayName, final Long officeId,
|
||||
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);
|
||||
return new ClientData(accountNo, status, officeId, officeName, null, null, id, firstname, middlename, lastname, fullname,
|
||||
displayName, 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, null);
|
||||
return new ClientData(null, null, officeId, officeName, null, null, 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,
|
||||
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) {
|
||||
return new ClientData(accountNo, status, officeId, officeName, id, firstname, middlename, lastname, fullname, displayName,
|
||||
externalId, activationDate, imageId, staffId, staffName, null, null, null, null);
|
||||
final Long transferToOfficeId, final String transferToOfficeName, 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) {
|
||||
return new ClientData(accountNo, status, officeId, officeName, transferToOfficeId, transferToOfficeName, id, firstname, middlename,
|
||||
lastname, fullname, displayName, 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,
|
||||
private ClientData(final String accountNo, final EnumOptionData status, final Long officeId, final String officeName,
|
||||
final Long transferToOfficeId, final String transferToOfficeName, 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<CodeValueData> closureReasons) {
|
||||
this.accountNo = accountNo;
|
||||
@@ -111,6 +116,8 @@ final public class ClientData implements Comparable<ClientData> {
|
||||
}
|
||||
this.officeId = officeId;
|
||||
this.officeName = officeName;
|
||||
this.transferToOfficeId = transferToOfficeId;
|
||||
this.transferToOfficeName = transferToOfficeName;
|
||||
this.id = id;
|
||||
this.firstname = StringUtils.defaultIfEmpty(firstname, null);
|
||||
this.middlename = StringUtils.defaultIfEmpty(middlename, null);
|
||||
|
||||
+37
-2
@@ -55,6 +55,10 @@ public final class Client extends AbstractPersistable<Long> {
|
||||
@JoinColumn(name = "office_id", nullable = false)
|
||||
private Office office;
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "transfer_to_office_id", nullable = true)
|
||||
private Office transferToOffice;
|
||||
|
||||
@OneToOne(optional = true)
|
||||
@JoinColumn(name = "image_id", nullable = true)
|
||||
private Image image;
|
||||
@@ -69,6 +73,10 @@ public final class Client extends AbstractPersistable<Long> {
|
||||
@Temporal(TemporalType.DATE)
|
||||
private Date activationDate;
|
||||
|
||||
@Column(name = "office_joining_date", nullable = true)
|
||||
@Temporal(TemporalType.DATE)
|
||||
private Date officeJoiningDate;
|
||||
|
||||
@Column(name = "firstname", length = 50)
|
||||
private String firstname;
|
||||
|
||||
@@ -123,13 +131,15 @@ public final class Client extends AbstractPersistable<Long> {
|
||||
}
|
||||
|
||||
LocalDate activationDate = null;
|
||||
LocalDate officeJoiningDate = null;
|
||||
if (active) {
|
||||
status = ClientStatus.ACTIVE;
|
||||
activationDate = command.localDateValueOfParameterNamed(ClientApiConstants.activationDateParamName);
|
||||
officeJoiningDate = activationDate;
|
||||
}
|
||||
|
||||
return new Client(status, clientOffice, clientParentGroup, accountNo, firstname, middlename, lastname, fullname, activationDate,
|
||||
externalId, staff);
|
||||
officeJoiningDate, externalId, staff);
|
||||
}
|
||||
|
||||
protected Client() {
|
||||
@@ -138,7 +148,7 @@ public final class Client extends AbstractPersistable<Long> {
|
||||
|
||||
private Client(final ClientStatus status, final Office office, final Group clientParentGroup, final String accountNo,
|
||||
final String firstname, final String middlename, final String lastname, final String fullname, final LocalDate activationDate,
|
||||
final String externalId, final Staff staff) {
|
||||
final LocalDate officeJoiningDate, final String externalId, final Staff staff) {
|
||||
if (StringUtils.isBlank(accountNo)) {
|
||||
this.accountNumber = new RandomPasswordGenerator(19).generate();
|
||||
this.accountNumberRequiresAutoGeneration = true;
|
||||
@@ -155,6 +165,9 @@ public final class Client extends AbstractPersistable<Long> {
|
||||
if (activationDate != null) {
|
||||
this.activationDate = activationDate.toDateMidnight().toDate();
|
||||
}
|
||||
if (officeJoiningDate != null) {
|
||||
this.officeJoiningDate = officeJoiningDate.toDateMidnight().toDate();
|
||||
}
|
||||
if (StringUtils.isNotBlank(firstname)) {
|
||||
this.firstname = firstname.trim();
|
||||
} else {
|
||||
@@ -243,6 +256,7 @@ public final class Client extends AbstractPersistable<Long> {
|
||||
}
|
||||
|
||||
this.activationDate = activationLocalDate.toDate();
|
||||
this.officeJoiningDate = activationDate;
|
||||
this.status = ClientStatus.ACTIVE.getValue();
|
||||
|
||||
validate();
|
||||
@@ -260,6 +274,14 @@ public final class Client extends AbstractPersistable<Long> {
|
||||
return ClientStatus.fromInt(this.status).isTransferInProgress();
|
||||
}
|
||||
|
||||
public boolean isTransferOnHold() {
|
||||
return ClientStatus.fromInt(this.status).isTransferOnHold();
|
||||
}
|
||||
|
||||
public boolean isTransferInProgressOrOnHold() {
|
||||
return isTransferInProgress() || isTransferOnHold();
|
||||
}
|
||||
|
||||
public boolean isNotPending() {
|
||||
return !isPending();
|
||||
}
|
||||
@@ -334,6 +356,7 @@ public final class Client extends AbstractPersistable<Long> {
|
||||
|
||||
final LocalDate newValue = command.localDateValueOfParameterNamed(ClientApiConstants.activationDateParamName);
|
||||
this.activationDate = newValue.toDate();
|
||||
this.officeJoiningDate = activationDate;
|
||||
}
|
||||
|
||||
validate();
|
||||
@@ -437,10 +460,22 @@ public final class Client extends AbstractPersistable<Long> {
|
||||
return this.office;
|
||||
}
|
||||
|
||||
public Office getTransferToOffice() {
|
||||
return this.transferToOffice;
|
||||
}
|
||||
|
||||
public void updateOffice(final Office office) {
|
||||
this.office = office;
|
||||
}
|
||||
|
||||
public void updateTransferToOffice(final Office office) {
|
||||
this.transferToOffice = office;
|
||||
}
|
||||
|
||||
public void updateOfficeJoiningDate(final Date date) {
|
||||
this.officeJoiningDate = date;
|
||||
}
|
||||
|
||||
private Long staffId() {
|
||||
Long staffId = null;
|
||||
if (this.staff != null) {
|
||||
|
||||
+28
-16
@@ -100,7 +100,7 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
|
||||
StringBuilder sqlBuilder = new StringBuilder(200);
|
||||
sqlBuilder.append("select SQL_CALC_FOUND_ROWS ");
|
||||
sqlBuilder.append(this.clientMapper.schema());
|
||||
sqlBuilder.append(" where o.hierarchy like ?");
|
||||
sqlBuilder.append(" where o.hierarchy like ? or transferToOffice.hierarchy like ?");
|
||||
|
||||
final String extraCriteria = buildSqlStringFromClientCriteria(searchParameters);
|
||||
|
||||
@@ -124,8 +124,8 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
|
||||
}
|
||||
|
||||
final String sqlCountRows = "SELECT FOUND_ROWS()";
|
||||
return this.paginationHelper.fetchPage(this.jdbcTemplate, sqlCountRows, sqlBuilder.toString(),
|
||||
new Object[] { hierarchySearchString }, this.clientMapper);
|
||||
return this.paginationHelper.fetchPage(this.jdbcTemplate, sqlCountRows, sqlBuilder.toString(), new Object[] {
|
||||
hierarchySearchString, hierarchySearchString }, this.clientMapper);
|
||||
}
|
||||
|
||||
private String buildSqlStringFromClientCriteria(final SearchParameters searchParameters) {
|
||||
@@ -184,9 +184,10 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
|
||||
String hierarchy = currentUser.getOffice().getHierarchy();
|
||||
String hierarchySearchString = hierarchy + "%";
|
||||
|
||||
String sql = "select " + this.clientMapper.schema() + " where o.hierarchy like ? and c.id = ?";
|
||||
ClientData clientData = this.jdbcTemplate.queryForObject(sql, this.clientMapper,
|
||||
new Object[] { hierarchySearchString, clientId });
|
||||
String sql = "select " + this.clientMapper.schema()
|
||||
+ " where ( o.hierarchy like ? or transferToOffice.hierarchy like ?) and c.id = ?";
|
||||
ClientData clientData = this.jdbcTemplate.queryForObject(sql, this.clientMapper, new Object[] { hierarchySearchString,
|
||||
hierarchySearchString, clientId });
|
||||
|
||||
String clientGroupsSql = "select " + this.clientGroupsMapper.parentGroupsSchema();
|
||||
|
||||
@@ -255,6 +256,7 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
|
||||
|
||||
sqlBuilder.append("c.id as id, c.account_no as accountNo, c.external_id as externalId, c.status_enum as statusEnum, ");
|
||||
sqlBuilder.append("c.office_id as officeId, o.name as officeName, ");
|
||||
sqlBuilder.append("c.transfer_to_office_id as transferToOfficeId, transferToOffice.name as transferToOfficeName, ");
|
||||
sqlBuilder.append("c.firstname as firstname, c.middlename as middlename, c.lastname as lastname, ");
|
||||
sqlBuilder.append("c.fullname as fullname, c.display_name as displayName, ");
|
||||
sqlBuilder.append("c.activation_date as activationDate, c.image_id as imageId, ");
|
||||
@@ -263,6 +265,7 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
|
||||
sqlBuilder.append("join m_office o on o.id = c.office_id ");
|
||||
sqlBuilder.append("join m_group_client pgc on pgc.client_id = c.id ");
|
||||
sqlBuilder.append("left join m_staff s on s.id = c.staff_id ");
|
||||
sqlBuilder.append("left join m_office transferToOffice on transferToOffice.id = c.transfer_to_office_id ");
|
||||
|
||||
this.schema = sqlBuilder.toString();
|
||||
}
|
||||
@@ -280,6 +283,11 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
|
||||
final EnumOptionData status = ClientEnumerations.status(statusEnum);
|
||||
|
||||
final Long officeId = JdbcSupport.getLong(rs, "officeId");
|
||||
final String officeName = rs.getString("officeName");
|
||||
|
||||
final Long transferToOfficeId = JdbcSupport.getLong(rs, "transferToOfficeId");
|
||||
final String transferToOfficeName = rs.getString("transferToOfficeName");
|
||||
|
||||
final Long id = JdbcSupport.getLong(rs, "id");
|
||||
final String firstname = rs.getString("firstname");
|
||||
final String middlename = rs.getString("middlename");
|
||||
@@ -289,12 +297,11 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
|
||||
final String externalId = rs.getString("externalId");
|
||||
final LocalDate activationDate = JdbcSupport.getLocalDate(rs, "activationDate");
|
||||
final Long imageId = JdbcSupport.getLong(rs, "imageId");
|
||||
final String officeName = rs.getString("officeName");
|
||||
final Long staffId = JdbcSupport.getLong(rs, "staffId");
|
||||
final String staffName = rs.getString("staffName");
|
||||
|
||||
return ClientData.instance(accountNo, status, officeId, officeName, id, firstname, middlename, lastname, fullname, displayName,
|
||||
externalId, activationDate, imageId, staffId, staffName);
|
||||
return ClientData.instance(accountNo, status, officeId, officeName, transferToOfficeId, transferToOfficeName, id, firstname,
|
||||
middlename, lastname, fullname, displayName, externalId, activationDate, imageId, staffId, staffName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -305,13 +312,14 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
|
||||
final String hierarchy = currentUser.getOffice().getHierarchy();
|
||||
final String hierarchySearchString = hierarchy + "%";
|
||||
|
||||
final String sql = "select " + this.membersOfGroupMapper.schema()
|
||||
final String sql = "select "
|
||||
+ this.membersOfGroupMapper.schema()
|
||||
+ " left join m_group g on pgc.group_id=g.id where o.hierarchy like ? and g.parent_id = ? and c.status_enum = ? group by c.id";
|
||||
|
||||
return this.jdbcTemplate.query(sql, this.membersOfGroupMapper,
|
||||
new Object[] { hierarchySearchString, centerId, ClientStatus.ACTIVE.getValue() });
|
||||
}
|
||||
|
||||
|
||||
private static final class ClientMapper implements RowMapper<ClientData> {
|
||||
|
||||
private final String schema;
|
||||
@@ -321,7 +329,7 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
|
||||
|
||||
builder.append("c.id as id, c.account_no as accountNo, c.external_id as externalId, c.status_enum as statusEnum, ");
|
||||
builder.append("c.office_id as officeId, o.name as officeName, ");
|
||||
builder.append("c.office_id as officeId, o.name as officeName, ");
|
||||
builder.append("c.transfer_to_office_id as transferToOfficeId, transferToOffice.name as transferToOfficeName, ");
|
||||
builder.append("c.firstname as firstname, c.middlename as middlename, c.lastname as lastname, ");
|
||||
builder.append("c.fullname as fullname, c.display_name as displayName, ");
|
||||
builder.append("c.activation_date as activationDate, c.image_id as imageId, ");
|
||||
@@ -329,7 +337,7 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
|
||||
builder.append("from m_client c ");
|
||||
builder.append("join m_office o on o.id = c.office_id ");
|
||||
builder.append("left join m_staff s on s.id = c.staff_id ");
|
||||
|
||||
builder.append("left join m_office transferToOffice on transferToOffice.id = c.transfer_to_office_id ");
|
||||
this.schema = builder.toString();
|
||||
}
|
||||
|
||||
@@ -346,6 +354,11 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
|
||||
final EnumOptionData status = ClientEnumerations.status(statusEnum);
|
||||
|
||||
final Long officeId = JdbcSupport.getLong(rs, "officeId");
|
||||
final String officeName = rs.getString("officeName");
|
||||
|
||||
final Long transferToOfficeId = JdbcSupport.getLong(rs, "transferToOfficeId");
|
||||
final String transferToOfficeName = rs.getString("transferToOfficeName");
|
||||
|
||||
final Long id = JdbcSupport.getLong(rs, "id");
|
||||
final String firstname = rs.getString("firstname");
|
||||
final String middlename = rs.getString("middlename");
|
||||
@@ -354,13 +367,12 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
|
||||
final String displayName = rs.getString("displayName");
|
||||
final String externalId = rs.getString("externalId");
|
||||
final LocalDate activationDate = JdbcSupport.getLocalDate(rs, "activationDate");
|
||||
final String officeName = rs.getString("officeName");
|
||||
final Long imageId = JdbcSupport.getLong(rs, "imageId");
|
||||
final Long staffId = JdbcSupport.getLong(rs, "staffId");
|
||||
final String staffName = rs.getString("staffName");
|
||||
|
||||
return ClientData.instance(accountNo, status, officeId, officeName, id, firstname, middlename, lastname, fullname, displayName,
|
||||
externalId, activationDate, imageId, staffId, staffName);
|
||||
return ClientData.instance(accountNo, status, officeId, officeName, transferToOfficeId, transferToOfficeName, id, firstname,
|
||||
middlename, lastname, fullname, displayName, externalId, activationDate, imageId, staffId, staffName);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+15
-24
@@ -5,7 +5,6 @@
|
||||
*/
|
||||
package org.mifosplatform.portfolio.group.api;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
@@ -143,22 +142,11 @@ public class GroupsApiResource {
|
||||
@QueryParam("officeId") final Long officeId, @QueryParam("externalId") final String externalId,
|
||||
@QueryParam("name") final String name, @QueryParam("underHierarchy") final String hierarchy,
|
||||
@QueryParam("offset") final Integer offset, @QueryParam("limit") final Integer limit,
|
||||
@QueryParam("orderBy") final String orderBy, @QueryParam("sortOrder") final String sortOrder,
|
||||
@QueryParam("templateType") final String templateType, @QueryParam("groupId") final Long groupId) {
|
||||
@QueryParam("orderBy") final String orderBy, @QueryParam("sortOrder") final String sortOrder) {
|
||||
|
||||
this.context.authenticatedUser().validateHasReadPermission(GroupingTypesApiConstants.GROUP_RESOURCE_NAME);
|
||||
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
||||
|
||||
if (templateType != null && templateType.equalsIgnoreCase("clientstransfertemplate")) {
|
||||
final Collection<GroupGeneralData> groups;
|
||||
if (officeId != null && groupId != null) {
|
||||
groups = this.groupReadPlatformService.retrieveGroupsForLookup(officeId, groupId);
|
||||
} else {
|
||||
groups = new ArrayList<GroupGeneralData>();
|
||||
}
|
||||
return this.groupGeneralApiJsonSerializer.serialize(settings, groups, GroupingTypesApiConstants.GROUP_RESPONSE_DATA_PARAMETERS);
|
||||
}
|
||||
|
||||
final SearchParameters searchParameters = SearchParameters.forGroups(sqlSearch, officeId, externalId, name, hierarchy, offset,
|
||||
limit, orderBy, sortOrder);
|
||||
final Page<GroupGeneralData> groups = this.groupReadPlatformService.retrieveAll(searchParameters);
|
||||
@@ -186,7 +174,7 @@ public class GroupsApiResource {
|
||||
GroupRoleData selectedRole = null;
|
||||
Collection<CalendarData> calendars = null;
|
||||
CalendarData collectionMeetingCalendar = null;
|
||||
|
||||
|
||||
if (!associationParameters.isEmpty()) {
|
||||
if (associationParameters.contains("all")) {
|
||||
associationParameters.addAll(Arrays.asList("clientMembers", "groupRoles", "calendars", "collectionMeetingCalendar"));
|
||||
@@ -204,26 +192,29 @@ public class GroupsApiResource {
|
||||
}
|
||||
}
|
||||
if (associationParameters.contains("parentCalendars")) {
|
||||
final List<Integer> calendarTypeOptions = CalendarUtils.createIntegerListFromQueryParameter("all");
|
||||
calendars = this.calendarReadPlatformService.retrieveParentCalendarsByEntity(groupId, CalendarEntityType.GROUPS.getValue(), calendarTypeOptions);
|
||||
final List<Integer> calendarTypeOptions = CalendarUtils.createIntegerListFromQueryParameter("all");
|
||||
calendars = this.calendarReadPlatformService.retrieveParentCalendarsByEntity(groupId, CalendarEntityType.GROUPS.getValue(),
|
||||
calendarTypeOptions);
|
||||
if (CollectionUtils.isEmpty(calendars)) {
|
||||
calendars = null;
|
||||
}
|
||||
}
|
||||
if (associationParameters.contains("collectionMeetingCalendar")) {
|
||||
if(group.isChildGroup()){
|
||||
collectionMeetingCalendar = this.calendarReadPlatformService.retrieveCollctionCalendarByEntity(group.getParentId(), CalendarEntityType.CENTERS.getValue());
|
||||
}else {
|
||||
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){
|
||||
if (collectionMeetingCalendar != null) {
|
||||
collectionMeetingCalendar = this.calendarReadPlatformService.generateRecurringDate(collectionMeetingCalendar);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
group = GroupGeneralData.withAssocations(group, membersOfGroup, groupRoles, calendars, collectionMeetingCalendar);
|
||||
}
|
||||
|
||||
|
||||
if (roleId != null) {
|
||||
selectedRole = this.groupRolesReadPlatformService.retrieveGroupRole(groupId, roleId);
|
||||
if (selectedRole != null) {
|
||||
@@ -268,7 +259,7 @@ public class GroupsApiResource {
|
||||
return this.toApiJsonSerializer.serialize(result);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@PUT
|
||||
@Path("{groupId}")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
|
||||
@@ -387,6 +387,14 @@ public final class Group extends AbstractPersistable<Long> {
|
||||
public boolean isTransferInProgress() {
|
||||
return GroupingTypeStatus.fromInt(this.status).isTransferInProgress();
|
||||
}
|
||||
|
||||
public boolean isTransferOnHold() {
|
||||
return GroupingTypeStatus.fromInt(this.status).isTransferOnHold();
|
||||
}
|
||||
|
||||
public boolean isTransferInProgressOrOnHold() {
|
||||
return isTransferInProgress() || isTransferOnHold();
|
||||
}
|
||||
|
||||
public boolean isChildClient(final Long clientId) {
|
||||
if (clientId != null && this.clientMembers != null && !this.clientMembers.isEmpty()) {
|
||||
|
||||
+1
-1
@@ -18,5 +18,5 @@ public interface GroupReadPlatformService {
|
||||
|
||||
GroupGeneralData retrieveOne(Long groupId);
|
||||
|
||||
Collection<GroupGeneralData> retrieveGroupsForLookup(Long officeId, Long groupId);
|
||||
Collection<GroupGeneralData> retrieveGroupsForLookup(Long officeId);
|
||||
}
|
||||
+4
-4
@@ -206,17 +206,17 @@ public class GroupReadPlatformServiceImpl implements GroupReadPlatformService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<GroupGeneralData> retrieveGroupsForLookup(final Long officeId, final Long groupId) {
|
||||
public Collection<GroupGeneralData> retrieveGroupsForLookup(final Long officeId) {
|
||||
this.context.authenticatedUser();
|
||||
GroupLookupDataMapper rm = new GroupLookupDataMapper();
|
||||
String sql = "Select " + rm.schema() + " where g.office_id=? and g.id !=?";
|
||||
return this.jdbcTemplate.query(sql, rm, new Object[] { officeId, groupId });
|
||||
String sql = "Select " + rm.schema() + " and g.office_id=?";
|
||||
return this.jdbcTemplate.query(sql, rm, new Object[] { officeId });
|
||||
}
|
||||
|
||||
private static final class GroupLookupDataMapper implements RowMapper<GroupGeneralData> {
|
||||
|
||||
public final String schema() {
|
||||
return "g.id as id, g.display_name as displayName from m_group g";
|
||||
return "g.id as id, g.display_name as displayName from m_group g where g.level_id = 2 ";
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+3
-3
@@ -52,7 +52,7 @@ public interface LoanRepository extends JpaRepository<Loan, Long>, JpaSpecificat
|
||||
public static final String FIND_ACTIVE_LOANS_PRODUCT_IDS_BY_GROUP = "Select loan.loanProduct.id from Loan loan where "
|
||||
+ "loan.group.id = :groupId and loan.loanStatus = :loanStatus and loan.client.id is NULL group by loan.loanProduct.id";
|
||||
|
||||
public static final String DOES_CLIENT_HAVE_ACTIVE_LOANS = "select case when (count (loan) > 0) then true else false end from Loan loan where loan.client.id = :clientId and loan.loanStatus in (100,200,300,303,304)";
|
||||
public static final String DOES_CLIENT_HAVE_NON_CLOSED_LOANS = "select case when (count (loan) > 0) then true else false end from Loan loan where loan.client.id = :clientId and loan.loanStatus in (100,200,300,303,304)";
|
||||
|
||||
@Query(FIND_GROUP_LOANS_DISBURSED_AFTER)
|
||||
List<Loan> getGroupLoansDisbursedAfter(@Param("disbursementDate") Date disbursementDate, @Param("groupId") Long groupId,
|
||||
@@ -117,7 +117,7 @@ public interface LoanRepository extends JpaRepository<Loan, Long>, JpaSpecificat
|
||||
@Query(FIND_ACTIVE_LOANS_PRODUCT_IDS_BY_GROUP)
|
||||
List<Long> findActiveLoansLoanProductIdsByGroup(@Param("groupId") Long groupId, @Param("loanStatus") Integer loanStatus);
|
||||
|
||||
@Query(DOES_CLIENT_HAVE_ACTIVE_LOANS)
|
||||
boolean doesClientHaveActiveLoans(@Param("clientId") Long clientId);
|
||||
@Query(DOES_CLIENT_HAVE_NON_CLOSED_LOANS)
|
||||
boolean doNonClosedLoanAccountsExistForClient(@Param("clientId") Long clientId);
|
||||
|
||||
}
|
||||
+7
@@ -137,6 +137,13 @@ public final class LoanTransaction extends AbstractPersistable<Long> {
|
||||
.getTotalPenaltyChargesOutstanding(), false, null);
|
||||
}
|
||||
|
||||
public static LoanTransaction withdrawTransfer(final Office office, final Loan loan, final LocalDate transferDate) {
|
||||
return new LoanTransaction(loan, office, LoanTransactionType.APPROVE_TRANSFER.getValue(), transferDate.toDateMidnight().toDate(),
|
||||
loan.getSummary().getTotalOutstanding(), loan.getSummary().getTotalPrincipalOutstanding(), loan.getSummary()
|
||||
.getTotalInterestOutstanding(), loan.getSummary().getTotalFeeChargesOutstanding(), loan.getSummary()
|
||||
.getTotalPenaltyChargesOutstanding(), false, null);
|
||||
}
|
||||
|
||||
public static LoanTransaction refund(final Office office, final Money amount, final PaymentDetail paymentDetail,
|
||||
final LocalDate paymentDate, final String externalId) {
|
||||
return new LoanTransaction(null, office, LoanTransactionType.REFUND, paymentDetail, amount.getAmount(), paymentDate, externalId);
|
||||
|
||||
+1
-1
@@ -178,7 +178,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
||||
/*** TODO Vishwas: Remove references to "Contra" from the codebase ***/
|
||||
String sql = "select "
|
||||
+ rm.LoanPaymentsSchema()
|
||||
+ " where tr.loan_id = ? and tr.transaction_type_enum not in (0, 3) and tr.is_reversed=0 order by tr.transaction_date ASC";
|
||||
+ " where tr.loan_id = ? and tr.transaction_type_enum not in (0, 3) and tr.is_reversed=0 order by tr.transaction_date ASC,id ";
|
||||
return this.jdbcTemplate.query(sql, rm, new Object[] { loanId });
|
||||
} catch (EmptyResultDataAccessException e) {
|
||||
return null;
|
||||
|
||||
+6
-3
@@ -11,6 +11,8 @@ 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.organisation.office.domain.Office;
|
||||
import org.mifosplatform.organisation.staff.domain.Staff;
|
||||
import org.mifosplatform.portfolio.calendar.domain.Calendar;
|
||||
import org.mifosplatform.portfolio.calendar.domain.CalendarInstance;
|
||||
import org.mifosplatform.portfolio.collectionsheet.command.CollectionSheetBulkDisbursalCommand;
|
||||
@@ -59,9 +61,10 @@ public interface LoanWritePlatformService {
|
||||
|
||||
LoanTransaction initiateLoanTransfer(Long accountId, LocalDate TransferDate);
|
||||
|
||||
LoanTransaction acceptLoanTransfer(Long accountId, LocalDate TransferDate);
|
||||
|
||||
LoanTransaction withdrawLoanTransfer(Long accountId, LocalDate TransferDate);
|
||||
|
||||
LoanTransaction rejectLoanTransfer(Long accountId, LocalDate TransferDate);
|
||||
void rejectLoanTransfer(Long accountId);
|
||||
|
||||
LoanTransaction acceptLoanTransfer(Long accountId, LocalDate TransferDate, Office acceptedInOffice, Staff loanOfficer);
|
||||
|
||||
}
|
||||
+30
-25
@@ -53,7 +53,6 @@ import org.mifosplatform.portfolio.charge.exception.LoanChargeCannotBeWaivedExce
|
||||
import org.mifosplatform.portfolio.charge.exception.LoanChargeNotFoundException;
|
||||
import org.mifosplatform.portfolio.client.domain.Client;
|
||||
import org.mifosplatform.portfolio.client.exception.ClientNotActiveException;
|
||||
import org.mifosplatform.portfolio.client.exception.ClientNotAwaitingTransferApprovalException;
|
||||
import org.mifosplatform.portfolio.collectionsheet.command.CollectionSheetBulkDisbursalCommand;
|
||||
import org.mifosplatform.portfolio.collectionsheet.command.CollectionSheetBulkRepaymentCommand;
|
||||
import org.mifosplatform.portfolio.collectionsheet.command.SingleDisbursalCommand;
|
||||
@@ -922,15 +921,38 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public LoanTransaction acceptLoanTransfer(final Long accountId, final LocalDate TransferDate) {
|
||||
public LoanTransaction acceptLoanTransfer(final Long accountId, final LocalDate transferDate, final Office acceptedInOffice,
|
||||
final Staff loanOfficer) {
|
||||
|
||||
final Loan loan = this.loanAssembler.assembleFrom(accountId);
|
||||
validateClientOrGroupAwaitingTransferAcceptance(loan);
|
||||
|
||||
final List<Long> existingTransactionIds = new ArrayList<Long>(loan.findExistingTransactionIds());
|
||||
final List<Long> existingReversedTransactionIds = new ArrayList<Long>(loan.findExistingReversedTransactionIds());
|
||||
|
||||
final LoanTransaction newTransferAcceptanceTransaction = LoanTransaction.approveTransfer(loan.getOffice(), loan, TransferDate);
|
||||
final LoanTransaction newTransferAcceptanceTransaction = LoanTransaction.approveTransfer(acceptedInOffice, loan, transferDate);
|
||||
loan.getLoanTransactions().add(newTransferAcceptanceTransaction);
|
||||
loan.setLoanStatus(LoanStatus.ACTIVE.getValue());
|
||||
if (loanOfficer != null) {
|
||||
loan.reassignLoanOfficer(loanOfficer, transferDate);
|
||||
}
|
||||
|
||||
this.loanTransactionRepository.save(newTransferAcceptanceTransaction);
|
||||
this.loanRepository.save(loan);
|
||||
|
||||
postJournalEntries(loan, existingTransactionIds, existingReversedTransactionIds);
|
||||
|
||||
return newTransferAcceptanceTransaction;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public LoanTransaction withdrawLoanTransfer(Long accountId, LocalDate TransferDate) {
|
||||
final Loan loan = this.loanAssembler.assembleFrom(accountId);
|
||||
|
||||
final List<Long> existingTransactionIds = new ArrayList<Long>(loan.findExistingTransactionIds());
|
||||
final List<Long> existingReversedTransactionIds = new ArrayList<Long>(loan.findExistingReversedTransactionIds());
|
||||
|
||||
final LoanTransaction newTransferAcceptanceTransaction = LoanTransaction.withdrawTransfer(loan.getOffice(), loan, TransferDate);
|
||||
loan.getLoanTransactions().add(newTransferAcceptanceTransaction);
|
||||
loan.setLoanStatus(LoanStatus.ACTIVE.getValue());
|
||||
|
||||
@@ -944,16 +966,10 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public LoanTransaction withdrawLoanTransfer(Long accountId, LocalDate TransferDate) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public LoanTransaction rejectLoanTransfer(Long accountId, LocalDate TransferDate) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
public void rejectLoanTransfer(Long accountId) {
|
||||
final Loan loan = this.loanAssembler.assembleFrom(accountId);
|
||||
loan.setLoanStatus(LoanStatus.TRANSFER_ON_HOLD.getValue());
|
||||
this.loanRepository.save(loan);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@@ -1321,15 +1337,4 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
}
|
||||
}
|
||||
|
||||
private void validateClientOrGroupAwaitingTransferAcceptance(final Loan loan) {
|
||||
final Client client = loan.client();
|
||||
if (client != null) {
|
||||
if (!client.isTransferInProgress()) { throw new ClientNotAwaitingTransferApprovalException(client.getId()); }
|
||||
}
|
||||
final Group group = loan.group();
|
||||
if (group != null) {
|
||||
if (!group.isTransferInProgress()) { throw new ClientNotAwaitingTransferApprovalException(group.getId()); }
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -76,7 +76,7 @@ public class Note extends AbstractAuditableCustom<AppUser, Long> {
|
||||
return new Note(account, note);
|
||||
}
|
||||
|
||||
private Note(final Client client, final String note) {
|
||||
public Note(final Client client, final String note) {
|
||||
this.client = client;
|
||||
this.note = note;
|
||||
this.noteTypeId = NoteType.CLIENT.getValue();
|
||||
|
||||
+3
@@ -7,6 +7,7 @@ package org.mifosplatform.portfolio.note.service;
|
||||
|
||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.mifosplatform.portfolio.client.domain.Client;
|
||||
|
||||
public interface NoteWritePlatformService {
|
||||
|
||||
@@ -15,4 +16,6 @@ public interface NoteWritePlatformService {
|
||||
CommandProcessingResult updateNote(JsonCommand command);
|
||||
|
||||
CommandProcessingResult deleteNote(JsonCommand command);
|
||||
|
||||
void createAndPersistClientNote(Client client, JsonCommand command);
|
||||
}
|
||||
|
||||
+10
@@ -7,6 +7,7 @@ package org.mifosplatform.portfolio.note.service;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResultBuilder;
|
||||
@@ -73,6 +74,15 @@ public class NoteWritePlatformServiceJpaRepositoryImpl implements NoteWritePlatf
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createAndPersistClientNote(final Client client, final JsonCommand command) {
|
||||
final String noteText = command.stringValueOfParameterNamed("note");
|
||||
if (StringUtils.isNotBlank(noteText)) {
|
||||
final Note newNote = new Note(client, noteText);
|
||||
this.noteRepository.save(newNote);
|
||||
}
|
||||
}
|
||||
|
||||
private CommandProcessingResult createGroupNote(final JsonCommand command) {
|
||||
|
||||
final Long resourceId = command.getSupportedEntityId();
|
||||
|
||||
+4
-2
@@ -16,11 +16,13 @@ public interface SavingsAccountRepository extends JpaRepository<SavingsAccount,
|
||||
|
||||
@Query("from SavingsAccount s_acc where s_acc.client.id = :clientId")
|
||||
List<SavingsAccount> findSavingAccountByClientId(@Param("clientId") Long clientId);
|
||||
|
||||
|
||||
@Query("from SavingsAccount s_acc where s_acc.status = :status")
|
||||
List<SavingsAccount> findSavingAccountByStatus(@Param("status") Integer status);
|
||||
|
||||
|
||||
@Query("from SavingsAccount sa where sa.client.id = :clientId and sa.group.id = :groupId")
|
||||
List<SavingsAccount> findByClientIdAndGroupId(@Param("clientId") Long clientId, @Param("groupId") Long groupId);
|
||||
|
||||
@Query("select case when (count (saving) > 0) then true else false end from SavingsAccount saving where saving.client.id = :clientId and saving.status in (100,200,300,303,304)")
|
||||
boolean doNonClosedSavingAccountsExistForClient(@Param("clientId") Long clientId);
|
||||
}
|
||||
+11
-3
@@ -20,15 +20,23 @@ public class TransferApiConstants {
|
||||
public static final String destinationGroupIdParamName = "destinationGroupId";
|
||||
public static final String clients = "clients";
|
||||
public static final String inheritDestinationGroupLoanOfficer = "inheritDestinationGroupLoanOfficer";
|
||||
public static final String newStaffIdParamName = "newStaffId";
|
||||
public static final String newStaffIdParamName = "staffId";
|
||||
public static final String transferActiveLoans = "transferActiveLoans";
|
||||
public static final String destinationOfficeIdParamName = "destinationOfficeId";
|
||||
public static final String note = "note";
|
||||
|
||||
public static final Set<String> TRANSFER_CLIENTS_BETWEEN_GROUPS_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(localeParamName,
|
||||
dateFormatParamName, destinationGroupIdParamName, clients, inheritDestinationGroupLoanOfficer, newStaffIdParamName,
|
||||
transferActiveLoans));
|
||||
|
||||
public static final Set<String> PROPOSE_CLIENT_TRANSFER_BETWEEN_BRANCHES_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(
|
||||
localeParamName, dateFormatParamName, destinationOfficeIdParamName, newStaffIdParamName, transferActiveLoans));
|
||||
public static final Set<String> PROPOSE_CLIENT_TRANSFER_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(localeParamName,
|
||||
dateFormatParamName, destinationOfficeIdParamName, transferActiveLoans, note));
|
||||
|
||||
public static final Set<String> ACCEPT_CLIENT_TRANSFER_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(newStaffIdParamName,
|
||||
destinationGroupIdParamName, note));
|
||||
|
||||
public static final Set<String> REJECT_CLIENT_TRANSFER_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(note));
|
||||
|
||||
public static final Set<String> WITHDRAW_CLIENT_TRANSFER_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(note));
|
||||
|
||||
}
|
||||
+70
-15
@@ -63,13 +63,6 @@ public final class TransfersDataValidator {
|
||||
.integerGreaterThanZero();
|
||||
}
|
||||
|
||||
if (this.fromApiJsonHelper.parameterExists(TransferApiConstants.transferActiveLoans, element)) {
|
||||
final Boolean inheritDestinationGroupLoanOfficer = this.fromApiJsonHelper.extractBooleanNamed(
|
||||
TransferApiConstants.transferActiveLoans, element);
|
||||
baseDataValidator.reset().parameter(TransferApiConstants.transferActiveLoans).value(inheritDestinationGroupLoanOfficer)
|
||||
.notNull();
|
||||
}
|
||||
|
||||
if (this.fromApiJsonHelper.parameterExists(TransferApiConstants.inheritDestinationGroupLoanOfficer, element)) {
|
||||
final Boolean inheritDestinationGroupLoanOfficer = this.fromApiJsonHelper.extractBooleanNamed(
|
||||
TransferApiConstants.inheritDestinationGroupLoanOfficer, element);
|
||||
@@ -80,13 +73,12 @@ public final class TransfersDataValidator {
|
||||
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
||||
}
|
||||
|
||||
public void validateForProposeClientTransferBetweenBranches(final String json) {
|
||||
public void validateForProposeClientTransfer(final String json) {
|
||||
|
||||
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
|
||||
|
||||
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
|
||||
this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json,
|
||||
TransferApiConstants.PROPOSE_CLIENT_TRANSFER_BETWEEN_BRANCHES_DATA_PARAMETERS);
|
||||
this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, TransferApiConstants.PROPOSE_CLIENT_TRANSFER_DATA_PARAMETERS);
|
||||
final JsonElement element = this.fromApiJsonHelper.parse(json);
|
||||
|
||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
|
||||
@@ -99,13 +91,76 @@ public final class TransfersDataValidator {
|
||||
baseDataValidator.reset().parameter(TransferApiConstants.destinationOfficeIdParamName).value(destinationOfficeId).notNull()
|
||||
.integerGreaterThanZero();
|
||||
|
||||
if (this.fromApiJsonHelper.parameterExists(TransferApiConstants.newStaffIdParamName, element)) {
|
||||
final Long newStaffId = this.fromApiJsonHelper.extractLongNamed(TransferApiConstants.newStaffIdParamName, element);
|
||||
baseDataValidator.reset().parameter(TransferApiConstants.newStaffIdParamName).value(newStaffId).ignoreIfNull()
|
||||
.integerGreaterThanZero();
|
||||
}
|
||||
validateNote(baseDataValidator, element);
|
||||
|
||||
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
||||
}
|
||||
|
||||
public void validateForAcceptClientTransfer(final String json) {
|
||||
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
|
||||
|
||||
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
|
||||
this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, TransferApiConstants.ACCEPT_CLIENT_TRANSFER_DATA_PARAMETERS);
|
||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
|
||||
|
||||
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
|
||||
.resource(ClientApiConstants.CLIENT_RESOURCE_NAME);
|
||||
final JsonElement element = fromApiJsonHelper.parse(json);
|
||||
|
||||
if (this.fromApiJsonHelper.parameterExists(TransferApiConstants.newStaffIdParamName, element)) {
|
||||
final Long newStaffId = this.fromApiJsonHelper.extractLongNamed(TransferApiConstants.newStaffIdParamName, element);
|
||||
baseDataValidator.reset().parameter(TransferApiConstants.newStaffIdParamName).value(newStaffId).notNull()
|
||||
.integerGreaterThanZero();
|
||||
}
|
||||
|
||||
if (this.fromApiJsonHelper.parameterExists(TransferApiConstants.destinationGroupIdParamName, element)) {
|
||||
final Long destinationGroupId = this.fromApiJsonHelper.extractLongNamed(TransferApiConstants.destinationGroupIdParamName,
|
||||
element);
|
||||
baseDataValidator.reset().parameter(TransferApiConstants.destinationGroupIdParamName).value(destinationGroupId).notNull()
|
||||
.integerGreaterThanZero();
|
||||
}
|
||||
|
||||
validateNote(baseDataValidator, element);
|
||||
|
||||
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
||||
}
|
||||
|
||||
public void validateForRejectClientTransfer(final String json) {
|
||||
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
|
||||
|
||||
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
|
||||
this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, TransferApiConstants.REJECT_CLIENT_TRANSFER_DATA_PARAMETERS);
|
||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
|
||||
|
||||
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
|
||||
.resource(ClientApiConstants.CLIENT_RESOURCE_NAME);
|
||||
final JsonElement element = fromApiJsonHelper.parse(json);
|
||||
|
||||
validateNote(baseDataValidator, element);
|
||||
|
||||
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
||||
}
|
||||
|
||||
public void validateForWithdrawClientTransfer(final String json) {
|
||||
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
|
||||
|
||||
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
|
||||
this.fromApiJsonHelper
|
||||
.checkForUnsupportedParameters(typeOfMap, json, TransferApiConstants.WITHDRAW_CLIENT_TRANSFER_DATA_PARAMETERS);
|
||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
|
||||
|
||||
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
|
||||
.resource(ClientApiConstants.CLIENT_RESOURCE_NAME);
|
||||
final JsonElement element = fromApiJsonHelper.parse(json);
|
||||
|
||||
validateNote(baseDataValidator, element);
|
||||
|
||||
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
||||
}
|
||||
|
||||
private void validateNote(final DataValidatorBuilder baseDataValidator, final JsonElement element) {
|
||||
final String note = fromApiJsonHelper.extractStringNamed(TransferApiConstants.note, element);
|
||||
baseDataValidator.reset().parameter(TransferApiConstants.note).value(note).notExceedingLengthOf(1000);
|
||||
}
|
||||
|
||||
}
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package org.mifosplatform.portfolio.client.exception;
|
||||
package org.mifosplatform.portfolio.transfer.exception;
|
||||
|
||||
import org.mifosplatform.infrastructure.core.exception.AbstractPlatformDomainRuleException;
|
||||
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
package org.mifosplatform.portfolio.transfer.exception;
|
||||
|
||||
import org.mifosplatform.infrastructure.core.exception.AbstractPlatformDomainRuleException;
|
||||
|
||||
public class ClientNotAwaitingTransferApprovalOrOnHoldException extends AbstractPlatformDomainRuleException {
|
||||
|
||||
public ClientNotAwaitingTransferApprovalOrOnHoldException(final Long clientId) {
|
||||
super("error.msg.client.not.awaiting.transfer.approval.or.on.hold.exception", "The Client with id `" + clientId
|
||||
+ "` is neither awaiting a transfer nor on hold", clientId);
|
||||
}
|
||||
|
||||
}
|
||||
+31
-31
@@ -13,39 +13,39 @@ import org.mifosplatform.infrastructure.core.exception.AbstractPlatformDomainRul
|
||||
*/
|
||||
public class TransferNotSupportedException extends AbstractPlatformDomainRuleException {
|
||||
|
||||
/**
|
||||
* Default Constructor (cannot transfer entities with active loan/savings
|
||||
* accounts)
|
||||
*/
|
||||
public TransferNotSupportedException() {
|
||||
super("error.msg.entity.transfers.with.active.accounts", "Cannot transfer Clients/Groups having active loan or savings accounts");
|
||||
/*** enum of reasons for invalid Journal Entry **/
|
||||
public static enum TRANSFER_NOT_SUPPORTED_REASON {
|
||||
SOURCE_AND_DESTINATION_GROUP_CANNOT_BE_SAME, ACTIVE_SAVINGS_ACCOUNT, BULK_CLIENT_TRANSFER_ACROSS_BRANCHES, DESTINATION_GROUP_MEETING_FREQUENCY_MISMATCH, DESTINATION_GROUP_HAS_NO_MEETING;
|
||||
|
||||
public String errorMessage() {
|
||||
if (name().toString().equalsIgnoreCase("ACTIVE_SAVINGS_ACCOUNT")) {
|
||||
return "Cannot transfer Clients/Groups having active Savings accounts";
|
||||
} else if (name().toString().equalsIgnoreCase("BULK_CLIENT_TRANSFER_ACROSS_BRANCHES")) {
|
||||
return "Bulk Transfers of clients between Groups in different branches not allowed ";
|
||||
} else if (name().toString().equalsIgnoreCase("DESTINATION_GROUP_MEETING_FREQUENCY_MISMATCH")) {
|
||||
return "Cannot transfer Clients with active accounts between groups with different meeting frequency";
|
||||
} else if (name().toString().equalsIgnoreCase("SOURCE_AND_DESTINATION_GROUP_CANNOT_BE_SAME")) {
|
||||
return "Source and destination groups for bulk client transfers should be different";
|
||||
} else if (name().toString().equalsIgnoreCase("DESTINATION_GROUP_HAS_NO_MEETING")) { return "Cannot transfer Client with active accounts to a groups with no meeting frequency"; }
|
||||
return name().toString();
|
||||
}
|
||||
|
||||
public String errorCode() {
|
||||
if (name().toString().equalsIgnoreCase("ACTIVE_SAVINGS_ACCOUNT")) {
|
||||
return "error.msg.entity.transfers.with.active.savings.accounts";
|
||||
} else if (name().toString().equalsIgnoreCase("BULK_CLIENT_TRANSFER_ACROSS_BRANCHES")) {
|
||||
return "error.msg.groups.bulk.client.transfers.to.different.office";
|
||||
} else if (name().toString().equalsIgnoreCase("DESTINATION_GROUP_MEETING_FREQUENCY_MISMATCH")) {
|
||||
return "error.msg.client.transfers.with.active.accounts.between.groups.with.different.meeting.frequency";
|
||||
} else if (name().toString().equalsIgnoreCase("SOURCE_AND_DESTINATION_GROUP_CANNOT_BE_SAME")) {
|
||||
return "error.msg.groups.bulk.client.transfers.to.same.group";
|
||||
} else if (name().toString().equalsIgnoreCase("DESTINATION_GROUP_HAS_NO_MEETING")) { return "error.msg.client.transfers.with.active.accounts.to.group.with.no.meeting.frequencys"; }
|
||||
return name().toString();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Overloaded Constructor (Cannot transfer Clients with active accounts
|
||||
* between groups with different meeting frequency)
|
||||
*
|
||||
* @param clientId
|
||||
* @param sourceGroupId
|
||||
* @param destinationGroupId
|
||||
*/
|
||||
public TransferNotSupportedException(Long clientId, Long sourceGroupId, Long destinationGroupId) {
|
||||
super("error.msg.client.transfers.with.active.accounts.between.groups.with.different.meeting.frequency",
|
||||
"Cannot transfer Clients with active accounts between groups with different meeting frequency", clientId, sourceGroupId,
|
||||
destinationGroupId);
|
||||
public TransferNotSupportedException(final TRANSFER_NOT_SUPPORTED_REASON reason, final Object... defaultUserMessageArgs) {
|
||||
super(reason.errorCode(), reason.errorMessage(), defaultUserMessageArgs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Overloaded Constructor (Cannot transfer Clients with active (JLG)
|
||||
* accounts to a group with no meetings defined)
|
||||
*
|
||||
* @param clientId
|
||||
* @param sourceGroupId
|
||||
* @param destinationGroupId
|
||||
*/
|
||||
public TransferNotSupportedException(Long clientId, Long sourceGroupId, Long destinationGroupId, boolean destinationGroupMeetingAbsent) {
|
||||
super("error.msg.client.transfers.with.active.accounts.to.group.with.no.meeting.frequency",
|
||||
"Cannot transfer Client with active accounts to a groups with no meeting frequency", clientId, sourceGroupId,
|
||||
destinationGroupId,destinationGroupMeetingAbsent);
|
||||
}
|
||||
}
|
||||
+147
-78
@@ -6,6 +6,7 @@
|
||||
package org.mifosplatform.portfolio.transfer.service;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
@@ -15,6 +16,7 @@ import org.mifosplatform.infrastructure.core.service.DateUtils;
|
||||
import org.mifosplatform.organisation.office.domain.Office;
|
||||
import org.mifosplatform.organisation.office.domain.OfficeRepositoryWrapper;
|
||||
import org.mifosplatform.organisation.staff.domain.Staff;
|
||||
import org.mifosplatform.organisation.staff.domain.StaffRepositoryWrapper;
|
||||
import org.mifosplatform.portfolio.calendar.domain.Calendar;
|
||||
import org.mifosplatform.portfolio.calendar.domain.CalendarEntityType;
|
||||
import org.mifosplatform.portfolio.calendar.domain.CalendarInstance;
|
||||
@@ -31,13 +33,19 @@ import org.mifosplatform.portfolio.group.exception.ClientNotInGroupException;
|
||||
import org.mifosplatform.portfolio.loanaccount.domain.Loan;
|
||||
import org.mifosplatform.portfolio.loanaccount.domain.LoanRepository;
|
||||
import org.mifosplatform.portfolio.loanaccount.service.LoanWritePlatformService;
|
||||
import org.mifosplatform.portfolio.note.service.NoteWritePlatformService;
|
||||
import org.mifosplatform.portfolio.savings.domain.SavingsAccountRepository;
|
||||
import org.mifosplatform.portfolio.transfer.api.TransferApiConstants;
|
||||
import org.mifosplatform.portfolio.transfer.data.TransfersDataValidator;
|
||||
import org.mifosplatform.portfolio.transfer.exception.ClientNotAwaitingTransferApprovalException;
|
||||
import org.mifosplatform.portfolio.transfer.exception.ClientNotAwaitingTransferApprovalOrOnHoldException;
|
||||
import org.mifosplatform.portfolio.transfer.exception.TransferNotSupportedException;
|
||||
import org.mifosplatform.portfolio.transfer.exception.TransferNotSupportedException.TRANSFER_NOT_SUPPORTED_REASON;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
@@ -50,13 +58,18 @@ public class TransferWritePlatformServiceJpaRepositoryImpl implements TransferWr
|
||||
private final GroupRepositoryWrapper groupRepository;
|
||||
private final LoanWritePlatformService loanWritePlatformService;
|
||||
private final LoanRepository loanRepository;
|
||||
private final SavingsAccountRepository savingsAccountRepository;
|
||||
private final TransfersDataValidator transfersDataValidator;
|
||||
private final NoteWritePlatformService noteWritePlatformService;
|
||||
private final StaffRepositoryWrapper staffRepositoryWrapper;
|
||||
|
||||
@Autowired
|
||||
public TransferWritePlatformServiceJpaRepositoryImpl(final ClientRepositoryWrapper clientRepository,
|
||||
final OfficeRepositoryWrapper officeRepository, final CalendarInstanceRepository calendarInstanceRepository,
|
||||
final LoanWritePlatformService loanWritePlatformService, final GroupRepositoryWrapper groupRepository,
|
||||
final LoanRepository loanRepository, final TransfersDataValidator transfersDataValidator) {
|
||||
final LoanRepository loanRepository, final TransfersDataValidator transfersDataValidator,
|
||||
final NoteWritePlatformService noteWritePlatformService, final StaffRepositoryWrapper staffRepositoryWrapper,
|
||||
final SavingsAccountRepository savingsAccountRepository) {
|
||||
this.clientRepository = clientRepository;
|
||||
this.officeRepository = officeRepository;
|
||||
this.calendarInstanceRepository = calendarInstanceRepository;
|
||||
@@ -64,6 +77,9 @@ public class TransferWritePlatformServiceJpaRepositoryImpl implements TransferWr
|
||||
this.groupRepository = groupRepository;
|
||||
this.loanRepository = loanRepository;
|
||||
this.transfersDataValidator = transfersDataValidator;
|
||||
this.noteWritePlatformService = noteWritePlatformService;
|
||||
this.staffRepositoryWrapper = staffRepositoryWrapper;
|
||||
this.savingsAccountRepository = savingsAccountRepository;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -74,11 +90,26 @@ public class TransferWritePlatformServiceJpaRepositoryImpl implements TransferWr
|
||||
final Group sourceGroup = this.groupRepository.findOneWithNotFoundDetection(sourceGroupId);
|
||||
final Long destinationGroupId = jsonCommand.longValueOfParameterNamed(TransferApiConstants.destinationGroupIdParamName);
|
||||
final Group destinationGroup = this.groupRepository.findOneWithNotFoundDetection(destinationGroupId);
|
||||
final Long staffId = jsonCommand.longValueOfParameterNamed(TransferApiConstants.newStaffIdParamName);
|
||||
final Boolean inheritDestinationGroupLoanOfficer = jsonCommand
|
||||
.booleanObjectValueOfParameterNamed(TransferApiConstants.inheritDestinationGroupLoanOfficer);
|
||||
Staff staff = null;
|
||||
final Office sourceOffice = sourceGroup.getOffice();
|
||||
if (staffId != null) {
|
||||
staff = this.staffRepositoryWrapper.findByOfficeHierarchyWithNotFoundDetection(staffId, sourceOffice.getHierarchy());
|
||||
}
|
||||
|
||||
final List<Client> clients = this.assembleListOfClients(jsonCommand);
|
||||
|
||||
if (sourceGroupId == destinationGroupId) { throw new TransferNotSupportedException(
|
||||
TRANSFER_NOT_SUPPORTED_REASON.SOURCE_AND_DESTINATION_GROUP_CANNOT_BE_SAME, sourceGroupId, destinationGroupId); }
|
||||
|
||||
/*** Do not allow bulk client transfers across branches ***/
|
||||
if (!(sourceOffice.getId() == destinationGroup.getOffice().getId())) { throw new TransferNotSupportedException(
|
||||
TRANSFER_NOT_SUPPORTED_REASON.BULK_CLIENT_TRANSFER_ACROSS_BRANCHES, sourceGroupId, destinationGroupId); }
|
||||
|
||||
for (Client client : clients) {
|
||||
transferClientBetweenGroups(sourceGroup, client, destinationGroup);
|
||||
transferClientBetweenGroups(sourceGroup, client, destinationGroup, inheritDestinationGroupLoanOfficer, staff);
|
||||
}
|
||||
|
||||
return new CommandProcessingResultBuilder() //
|
||||
@@ -89,80 +120,64 @@ public class TransferWritePlatformServiceJpaRepositoryImpl implements TransferWr
|
||||
/****
|
||||
* Variables that would make sense <br/>
|
||||
* <ul>
|
||||
* <li>inheritDestinationGroupLoanOfficer: Default False</li>
|
||||
* <li>inheritDestinationGroupLoanOfficer: Default true</li>
|
||||
* <li>newStaffId: Optional field with Id of new Loan Officer to be linked
|
||||
* to this client and all his JLG loans for this group</li>
|
||||
* <li>transferActiveLoans:Default False, unless overridden, this client
|
||||
* cannot be transferred between groups within the same branch if he has
|
||||
* active JLG loans and across branches if he has any active loan</li>
|
||||
* <li></li>
|
||||
* <li></li>
|
||||
* <li></li>
|
||||
* <li></li>
|
||||
* <li></li>
|
||||
* <li></li>
|
||||
* <li></li>
|
||||
* </ul>
|
||||
* ***/
|
||||
@Transactional
|
||||
public void transferClientBetweenGroups(final Group sourceGroup, final Client client, final Group destinationGroup) {
|
||||
public void transferClientBetweenGroups(final Group sourceGroup, final Client client, final Group destinationGroup,
|
||||
final Boolean inheritDestinationGroupLoanOfficer, final Staff newLoanOfficer) {
|
||||
|
||||
// next I shall validate that the client is present in this group
|
||||
if (!sourceGroup.hasClientAsMember(client)) { throw new ClientNotInGroupException(client.getId(), sourceGroup.getId()); }
|
||||
// Is client active?
|
||||
if (client.isNotActive()) { throw new ClientHasBeenClosedException(client.getId()); }
|
||||
|
||||
/*** Code for intra-branch transfers ***/
|
||||
if (client.getOffice().getId() == destinationGroup.getOffice().getId()) {
|
||||
/**
|
||||
* TODO: for now we need to ensure that only one collection sheet
|
||||
* calendar can be linked with a center or group entity <br/>
|
||||
**/
|
||||
final CalendarInstance sourceGroupCalendarInstance = this.calendarInstanceRepository
|
||||
.findByEntityIdAndEntityTypeIdAndCalendarTypeId(sourceGroup.getId(), CalendarEntityType.GROUPS.getValue(),
|
||||
/**
|
||||
* TODO: for now we need to ensure that only one collection sheet
|
||||
* calendar can be linked with a center or group entity <br/>
|
||||
**/
|
||||
final CalendarInstance sourceGroupCalendarInstance = this.calendarInstanceRepository
|
||||
.findByEntityIdAndEntityTypeIdAndCalendarTypeId(sourceGroup.getId(), CalendarEntityType.GROUPS.getValue(),
|
||||
CalendarType.COLLECTION.getValue());
|
||||
// get all customer loans synced with this group calendar Instance
|
||||
final List<CalendarInstance> activeLoanCalendarInstances = this.calendarInstanceRepository
|
||||
.findCalendarInstancesForActiveLoansByGroupIdAndClientId(sourceGroup.getId(), client.getId());
|
||||
|
||||
/**
|
||||
* if a calendar is present in the source group along with loans synced
|
||||
* with it, we should ensure that the destination group also has a
|
||||
* collection calendar
|
||||
**/
|
||||
if (sourceGroupCalendarInstance != null && !activeLoanCalendarInstances.isEmpty()) {
|
||||
// get the destination calendar
|
||||
final CalendarInstance destinationGroupCalendarInstance = this.calendarInstanceRepository
|
||||
.findByEntityIdAndEntityTypeIdAndCalendarTypeId(destinationGroup.getId(), CalendarEntityType.GROUPS.getValue(),
|
||||
CalendarType.COLLECTION.getValue());
|
||||
// get all customer loans synced with this group calendar Instance
|
||||
final List<CalendarInstance> activeLoanCalendarInstances = this.calendarInstanceRepository
|
||||
.findCalendarInstancesForActiveLoansByGroupIdAndClientId(sourceGroup.getId(), client.getId());
|
||||
|
||||
/**
|
||||
* if a calendar is present in the source group along with loans
|
||||
* synced with it, we should ensure that the destination group also
|
||||
* has a collection calendar
|
||||
**/
|
||||
if (sourceGroupCalendarInstance != null && !activeLoanCalendarInstances.isEmpty()) {
|
||||
// get the destination calendar
|
||||
final CalendarInstance destinationGroupCalendarInstance = this.calendarInstanceRepository
|
||||
.findByEntityIdAndEntityTypeIdAndCalendarTypeId(destinationGroup.getId(), CalendarEntityType.GROUPS.getValue(),
|
||||
CalendarType.COLLECTION.getValue());
|
||||
if (destinationGroupCalendarInstance == null) { throw new TransferNotSupportedException(
|
||||
TRANSFER_NOT_SUPPORTED_REASON.DESTINATION_GROUP_HAS_NO_MEETING, destinationGroup.getId());
|
||||
|
||||
if (destinationGroupCalendarInstance == null) { throw new TransferNotSupportedException(client.getId(),
|
||||
sourceGroup.getId(), destinationGroup.getId(), false);
|
||||
|
||||
}
|
||||
Calendar sourceGroupCalendar = destinationGroupCalendarInstance.getCalendar();
|
||||
Calendar destinationGroupCalendar = destinationGroupCalendarInstance.getCalendar();
|
||||
|
||||
/***
|
||||
* Ensure that the recurrence pattern are same for collection
|
||||
* meeting in both the source and the destination calendar
|
||||
***/
|
||||
if (!(CalendarUtils.isFrequencySame(sourceGroupCalendar.getRecurrence(), destinationGroupCalendar.getRecurrence()) && CalendarUtils
|
||||
.isIntervalSame(sourceGroupCalendar.getRecurrence(), destinationGroupCalendar.getRecurrence()))) { throw new TransferNotSupportedException(
|
||||
client.getId(), sourceGroup.getId(), destinationGroup.getId()); }
|
||||
|
||||
/** map all JLG loans for this client to the destinationGroup **/
|
||||
for (CalendarInstance calendarInstance : activeLoanCalendarInstances) {
|
||||
calendarInstance.updateCalendar(destinationGroupCalendar);
|
||||
}
|
||||
// reschedule all JLG Loans to follow new Calendar
|
||||
this.loanWritePlatformService.applyMeetingDateChanges(destinationGroupCalendar, activeLoanCalendarInstances);
|
||||
}
|
||||
Calendar sourceGroupCalendar = sourceGroupCalendarInstance.getCalendar();
|
||||
Calendar destinationGroupCalendar = destinationGroupCalendarInstance.getCalendar();
|
||||
|
||||
} else {
|
||||
Office destinationOffice = destinationGroup.getOffice();
|
||||
// handleClientTransfer(client, destinationOffice);
|
||||
// TODO: Fill in the blanks
|
||||
/***
|
||||
* Ensure that the recurrence pattern are same for collection
|
||||
* meeting in both the source and the destination calendar
|
||||
***/
|
||||
if (!(CalendarUtils.isFrequencySame(sourceGroupCalendar.getRecurrence(), destinationGroupCalendar.getRecurrence()) && CalendarUtils
|
||||
.isIntervalSame(sourceGroupCalendar.getRecurrence(), destinationGroupCalendar.getRecurrence()))) { throw new TransferNotSupportedException(
|
||||
TRANSFER_NOT_SUPPORTED_REASON.DESTINATION_GROUP_MEETING_FREQUENCY_MISMATCH, sourceGroup.getId(),
|
||||
destinationGroup.getId()); }
|
||||
|
||||
/** map all JLG loans for this client to the destinationGroup **/
|
||||
for (CalendarInstance calendarInstance : activeLoanCalendarInstances) {
|
||||
calendarInstance.updateCalendar(destinationGroupCalendar);
|
||||
this.calendarInstanceRepository.save(calendarInstance);
|
||||
}
|
||||
// reschedule all JLG Loans to follow new Calendar
|
||||
this.loanWritePlatformService.applyMeetingDateChanges(destinationGroupCalendar, activeLoanCalendarInstances);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -184,8 +199,11 @@ public class TransferWritePlatformServiceJpaRepositoryImpl implements TransferWr
|
||||
for (Loan loan : allClientJLGLoans) {
|
||||
if (loan.status().isActiveOrAwaitingApprovalOrDisbursal()) {
|
||||
loan.updateGroup(destinationGroup);
|
||||
if (destinationGroupLoanOfficer != null) {
|
||||
if (inheritDestinationGroupLoanOfficer != null && inheritDestinationGroupLoanOfficer == true
|
||||
&& destinationGroupLoanOfficer != null) {
|
||||
loan.reassignLoanOfficer(destinationGroupLoanOfficer, DateUtils.getLocalDateOfTenant());
|
||||
} else if (newLoanOfficer != null) {
|
||||
loan.reassignLoanOfficer(newLoanOfficer, DateUtils.getLocalDateOfTenant());
|
||||
}
|
||||
this.loanRepository.saveAndFlush(loan);
|
||||
}
|
||||
@@ -212,14 +230,14 @@ public class TransferWritePlatformServiceJpaRepositoryImpl implements TransferWr
|
||||
@Override
|
||||
public CommandProcessingResult proposeClientTransfer(final Long clientId, final JsonCommand jsonCommand) {
|
||||
// validation
|
||||
this.transfersDataValidator.validateForProposeClientTransferBetweenBranches(jsonCommand.json());
|
||||
this.transfersDataValidator.validateForProposeClientTransfer(jsonCommand.json());
|
||||
|
||||
final Long destinationOfficeId = jsonCommand.longValueOfParameterNamed(TransferApiConstants.destinationOfficeIdParamName);
|
||||
final Office office = this.officeRepository.findOneWithNotFoundDetection(destinationOfficeId);
|
||||
final Client client = this.clientRepository.findOneWithNotFoundDetection(clientId);
|
||||
/*** Remove all group associations for this client ***/
|
||||
client.getGroups().clear();
|
||||
handleClientTransfer(client, office, TransferEventType.PROPOSAL);
|
||||
handleClientTransferLifecycleEvent(client, office, TransferEventType.PROPOSAL, jsonCommand);
|
||||
this.clientRepository.save(client);
|
||||
|
||||
return new CommandProcessingResultBuilder() //
|
||||
@@ -243,10 +261,14 @@ public class TransferWritePlatformServiceJpaRepositoryImpl implements TransferWr
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult acceptClientTransfer(final Long clientId, final JsonCommand jsonCommand) {
|
||||
// validation
|
||||
this.transfersDataValidator.validateForAcceptClientTransfer(jsonCommand.json());
|
||||
final Client client = this.clientRepository.findOneWithNotFoundDetection(clientId);
|
||||
/*** Remove all group associations for this client ***/
|
||||
validateClientAwaitingTransferAcceptance(client);
|
||||
|
||||
/*** Remove all (old) group associations for this client ***/
|
||||
client.getGroups().clear();
|
||||
handleClientTransfer(client, client.getOffice(), TransferEventType.ACCEPTANCE);
|
||||
handleClientTransferLifecycleEvent(client, client.getTransferToOffice(), TransferEventType.ACCEPTANCE, jsonCommand);
|
||||
this.clientRepository.save(client);
|
||||
|
||||
return new CommandProcessingResultBuilder() //
|
||||
@@ -258,10 +280,12 @@ public class TransferWritePlatformServiceJpaRepositoryImpl implements TransferWr
|
||||
@Override
|
||||
@Transactional
|
||||
public CommandProcessingResult withdrawClientTransfer(Long clientId, JsonCommand jsonCommand) {
|
||||
// validation
|
||||
this.transfersDataValidator.validateForWithdrawClientTransfer(jsonCommand.json());
|
||||
final Client client = this.clientRepository.findOneWithNotFoundDetection(clientId);
|
||||
/*** Remove all group associations for this client ***/
|
||||
client.getGroups().clear();
|
||||
handleClientTransfer(client, client.getOffice(), TransferEventType.WITHDRAWAL);
|
||||
validateClientAwaitingTransferAcceptanceOnHold(client);
|
||||
|
||||
handleClientTransferLifecycleEvent(client, client.getOffice(), TransferEventType.WITHDRAWAL, jsonCommand);
|
||||
this.clientRepository.save(client);
|
||||
|
||||
return new CommandProcessingResultBuilder() //
|
||||
@@ -273,10 +297,10 @@ public class TransferWritePlatformServiceJpaRepositoryImpl implements TransferWr
|
||||
@Override
|
||||
@Transactional
|
||||
public CommandProcessingResult rejectClientTransfer(Long clientId, JsonCommand jsonCommand) {
|
||||
// validation
|
||||
this.transfersDataValidator.validateForRejectClientTransfer(jsonCommand.json());
|
||||
final Client client = this.clientRepository.findOneWithNotFoundDetection(clientId);
|
||||
/*** Remove all group associations for this client ***/
|
||||
client.getGroups().clear();
|
||||
handleClientTransfer(client, client.getOffice(), TransferEventType.REJECTION);
|
||||
handleClientTransferLifecycleEvent(client, client.getOffice(), TransferEventType.REJECTION, jsonCommand);
|
||||
this.clientRepository.save(client);
|
||||
|
||||
return new CommandProcessingResultBuilder() //
|
||||
@@ -285,20 +309,36 @@ public class TransferWritePlatformServiceJpaRepositoryImpl implements TransferWr
|
||||
.build();
|
||||
}
|
||||
|
||||
private void handleClientTransfer(final Client client, final Office destinationOffice, TransferEventType transferEventType) {
|
||||
if (loanRepository.doesClientHaveActiveLoans(client.getId())) {
|
||||
private void handleClientTransferLifecycleEvent(final Client client, final Office destinationOffice,
|
||||
TransferEventType transferEventType, JsonCommand jsonCommand) {
|
||||
Date todaysDate = DateUtils.getDateOfTenant();
|
||||
/** Get destination loan officer if exists **/
|
||||
Staff staff = null;
|
||||
Group destinationGroup = null;
|
||||
final Long staffId = jsonCommand.longValueOfParameterNamed(TransferApiConstants.newStaffIdParamName);
|
||||
final Long destinationGroupId = jsonCommand.longValueOfParameterNamed(TransferApiConstants.destinationGroupIdParamName);
|
||||
if (staffId != null) {
|
||||
staff = this.staffRepositoryWrapper.findByOfficeHierarchyWithNotFoundDetection(staffId, destinationOffice.getHierarchy());
|
||||
}
|
||||
if (destinationGroupId != null) {
|
||||
destinationGroup = this.groupRepository.findOneWithNotFoundDetection(destinationGroupId);
|
||||
}
|
||||
|
||||
/*** Handle Active Loans ***/
|
||||
if (loanRepository.doNonClosedLoanAccountsExistForClient(client.getId())) {
|
||||
// get each individual loan for the client
|
||||
for (Loan loan : loanRepository.findLoanByClientId(client.getId())) {
|
||||
if (!loan.isClosed()) {
|
||||
switch (transferEventType) {
|
||||
case ACCEPTANCE:
|
||||
this.loanWritePlatformService.acceptLoanTransfer(loan.getId(), DateUtils.getLocalDateOfTenant());
|
||||
this.loanWritePlatformService.acceptLoanTransfer(loan.getId(), DateUtils.getLocalDateOfTenant(),
|
||||
destinationOffice, staff);
|
||||
break;
|
||||
case PROPOSAL:
|
||||
this.loanWritePlatformService.initiateLoanTransfer(loan.getId(), DateUtils.getLocalDateOfTenant());
|
||||
break;
|
||||
case REJECTION:
|
||||
this.loanWritePlatformService.rejectLoanTransfer(loan.getId(), DateUtils.getLocalDateOfTenant());
|
||||
// do nothing
|
||||
break;
|
||||
case WITHDRAWAL:
|
||||
this.loanWritePlatformService.withdrawLoanTransfer(loan.getId(), DateUtils.getLocalDateOfTenant());
|
||||
@@ -307,21 +347,34 @@ public class TransferWritePlatformServiceJpaRepositoryImpl implements TransferWr
|
||||
}
|
||||
}
|
||||
|
||||
/*** Handle Active Savings (Currently throw and exception) ***/
|
||||
if (savingsAccountRepository.doNonClosedSavingAccountsExistForClient(client.getId())) { throw new TransferNotSupportedException(
|
||||
TRANSFER_NOT_SUPPORTED_REASON.ACTIVE_SAVINGS_ACCOUNT, client.getId()); }
|
||||
|
||||
switch (transferEventType) {
|
||||
case ACCEPTANCE:
|
||||
client.setStatus(ClientStatus.ACTIVE.getValue());
|
||||
client.updateTransferToOffice(null);
|
||||
client.updateOffice(destinationOffice);
|
||||
client.updateOfficeJoiningDate(todaysDate);
|
||||
if (client.getGroups().size() == 1) {
|
||||
transferClientBetweenGroups(Iterables.get(client.getGroups(), 0), client, destinationGroup, true, staff);
|
||||
}
|
||||
break;
|
||||
case PROPOSAL:
|
||||
client.setStatus(ClientStatus.TRANSFER_IN_PROGRESS.getValue());
|
||||
client.updateOffice(destinationOffice);
|
||||
client.updateTransferToOffice(destinationOffice);
|
||||
break;
|
||||
case REJECTION:
|
||||
client.setStatus(ClientStatus.TRANSFER_ON_HOLD.getValue());
|
||||
client.updateTransferToOffice(null);
|
||||
break;
|
||||
// TODO update client with previous office
|
||||
case WITHDRAWAL:
|
||||
client.setStatus(ClientStatus.ACTIVE.getValue());
|
||||
client.updateTransferToOffice(null);
|
||||
}
|
||||
|
||||
noteWritePlatformService.createAndPersistClientNote(client, jsonCommand);
|
||||
}
|
||||
|
||||
private List<Client> assembleListOfClients(final JsonCommand command) {
|
||||
@@ -345,4 +398,20 @@ public class TransferWritePlatformServiceJpaRepositoryImpl implements TransferWr
|
||||
return clients;
|
||||
}
|
||||
|
||||
private void validateClientAwaitingTransferAcceptance(final Client client) {
|
||||
if (!client.isTransferInProgress()) { throw new ClientNotAwaitingTransferApprovalException(client.getId()); }
|
||||
}
|
||||
|
||||
private void validateGroupAwaitingTransferAcceptance(final Group group) {
|
||||
if (!group.isTransferInProgress()) { throw new ClientNotAwaitingTransferApprovalException(group.getId()); }
|
||||
}
|
||||
|
||||
private void validateClientAwaitingTransferAcceptanceOnHold(final Client client) {
|
||||
if (!client.isTransferInProgressOrOnHold()) { throw new ClientNotAwaitingTransferApprovalOrOnHoldException(client.getId()); }
|
||||
}
|
||||
|
||||
private void validateGroupAwaitingTransferAcceptanceOnHold(final Group group) {
|
||||
if (!group.isTransferInProgressOrOnHold()) { throw new ClientNotAwaitingTransferApprovalException(group.getId()); }
|
||||
}
|
||||
|
||||
}
|
||||
@@ -17,6 +17,7 @@
|
||||
<!-- <property name="hibernate.hbm2ddl.auto" value="update"/> -->
|
||||
<property name="hibernate.jdbc.batch_size" value="100" />
|
||||
<property name="hibernate.order_inserts" value="true" />
|
||||
<!-- <property name = "hibernate.show_sql" value = "true" /> -->
|
||||
</properties>
|
||||
</persistence-unit>
|
||||
</persistence>
|
||||
Reference in New Issue
Block a user