Track group on member loan.
This commit is contained in:
@@ -91,6 +91,10 @@ public class Group extends AbstractAuditableCustom<AppUser, Long> {
|
|||||||
this.clientMembers.add(member);
|
this.clientMembers.add(member);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean hasClientAsMember(final Client client){
|
||||||
|
return this.clientMembers.contains(client);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete is a <i>soft delete</i>. Updates flag on group so it wont appear in query/report results.
|
* Delete is a <i>soft delete</i>. Updates flag on group so it wont appear in query/report results.
|
||||||
*
|
*
|
||||||
|
|||||||
+12
@@ -0,0 +1,12 @@
|
|||||||
|
package org.mifosplatform.portfolio.group.exception;
|
||||||
|
|
||||||
|
import org.mifosplatform.infrastructure.core.exception.AbstractPlatformDomainRuleException;
|
||||||
|
|
||||||
|
public class ClientNotInGroupException extends AbstractPlatformDomainRuleException {
|
||||||
|
|
||||||
|
public ClientNotInGroupException(final Long clientId, final Long groupId) {
|
||||||
|
super("error.msg.group.client.not.in.group", "Client with identifier " + clientId + " is not in Group with identifier " + groupId,
|
||||||
|
clientId, groupId);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+2
-2
@@ -154,7 +154,7 @@ public class GroupReadPlatformServiceImpl implements GroupReadPlatformService {
|
|||||||
|
|
||||||
GroupLoanAccountSummaryDataMapper rm = new GroupLoanAccountSummaryDataMapper();
|
GroupLoanAccountSummaryDataMapper rm = new GroupLoanAccountSummaryDataMapper();
|
||||||
|
|
||||||
String sql = "select " + rm.loanAccountSummarySchema() + " where l.group_id = ?";
|
String sql = "select " + rm.loanAccountSummarySchema() + " where l.group_id = ? and l.client_id is null";
|
||||||
|
|
||||||
List<GroupAccountSummaryData> results = this.jdbcTemplate.query(sql, rm, new Object[] {groupId});
|
List<GroupAccountSummaryData> results = this.jdbcTemplate.query(sql, rm, new Object[] {groupId});
|
||||||
if (results != null) {
|
if (results != null) {
|
||||||
@@ -191,7 +191,7 @@ public class GroupReadPlatformServiceImpl implements GroupReadPlatformService {
|
|||||||
|
|
||||||
GroupLoanAccountSummaryDataMapper rm = new GroupLoanAccountSummaryDataMapper();
|
GroupLoanAccountSummaryDataMapper rm = new GroupLoanAccountSummaryDataMapper();
|
||||||
|
|
||||||
String sql = "select " + rm.loanAccountSummarySchema() + " where l.group_id = ? and l.loan_officer_id = ?";
|
String sql = "select " + rm.loanAccountSummarySchema() + " where l.group_id = ? and l.client_id is null and l.loan_officer_id = ?";
|
||||||
|
|
||||||
List<GroupAccountSummaryData> loanAccounts = this.jdbcTemplate.query(sql, rm, new Object[] {groupId, loanOfficerId});
|
List<GroupAccountSummaryData> loanAccounts = this.jdbcTemplate.query(sql, rm, new Object[] {groupId, loanOfficerId});
|
||||||
|
|
||||||
|
|||||||
+4
-6
@@ -108,13 +108,11 @@ public class LoanApplicationCommand {
|
|||||||
|
|
||||||
DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("loan");
|
DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("loan");
|
||||||
|
|
||||||
if (this.groupId != null) {
|
|
||||||
baseDataValidator.reset().parameter("clientId").value(this.clientId).mustBeBlankWhenParameterProvided("groupId", this.groupId)
|
|
||||||
.longGreaterThanZero();
|
|
||||||
}
|
|
||||||
if (this.clientId != null) {
|
if (this.clientId != null) {
|
||||||
baseDataValidator.reset().parameter("groupId").value(this.groupId).mustBeBlankWhenParameterProvided("clientId", this.clientId)
|
baseDataValidator.reset().parameter("clientId").value(this.clientId).longGreaterThanZero();
|
||||||
.longGreaterThanZero();
|
}
|
||||||
|
if (this.groupId != null) {
|
||||||
|
baseDataValidator.reset().parameter("groupId").value(this.groupId).longGreaterThanZero();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.clientId == null && this.groupId == null) {
|
if (this.clientId == null && this.groupId == null) {
|
||||||
|
|||||||
+14
-27
@@ -195,7 +195,7 @@ public class Loan extends AbstractAuditableCustom<AppUser, Long> {
|
|||||||
public static Loan createNew(final Fund fund, final Staff loanOfficer,
|
public static Loan createNew(final Fund fund, final Staff loanOfficer,
|
||||||
final LoanTransactionProcessingStrategy transactionProcessingStrategy, final LoanProduct loanProduct, final Client client,
|
final LoanTransactionProcessingStrategy transactionProcessingStrategy, final LoanProduct loanProduct, final Client client,
|
||||||
final LoanProductRelatedDetail loanRepaymentScheduleDetail, final Set<LoanCharge> loanCharges) {
|
final LoanProductRelatedDetail loanRepaymentScheduleDetail, final Set<LoanCharge> loanCharges) {
|
||||||
return new Loan(client, fund, loanOfficer, transactionProcessingStrategy, loanProduct, loanRepaymentScheduleDetail, null,
|
return new Loan(client, null, fund, loanOfficer, transactionProcessingStrategy, loanProduct, loanRepaymentScheduleDetail, null,
|
||||||
loanCharges);
|
loanCharges);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -203,7 +203,7 @@ public class Loan extends AbstractAuditableCustom<AppUser, Long> {
|
|||||||
public static Loan createNew(final Fund fund, final Staff loanOfficer,
|
public static Loan createNew(final Fund fund, final Staff loanOfficer,
|
||||||
final LoanTransactionProcessingStrategy transactionProcessingStrategy, final LoanProduct loanProduct, final Group group,
|
final LoanTransactionProcessingStrategy transactionProcessingStrategy, final LoanProduct loanProduct, final Group group,
|
||||||
final LoanProductRelatedDetail loanRepaymentScheduleDetail, final Set<LoanCharge> loanCharges) {
|
final LoanProductRelatedDetail loanRepaymentScheduleDetail, final Set<LoanCharge> loanCharges) {
|
||||||
return new Loan(group, fund, loanOfficer, transactionProcessingStrategy, loanProduct, loanRepaymentScheduleDetail, null,
|
return new Loan(null, group, fund, loanOfficer, transactionProcessingStrategy, loanProduct, loanRepaymentScheduleDetail, null,
|
||||||
loanCharges);
|
loanCharges);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -212,7 +212,7 @@ public class Loan extends AbstractAuditableCustom<AppUser, Long> {
|
|||||||
final Set<LoanCharge> loanCharges) {
|
final Set<LoanCharge> loanCharges) {
|
||||||
final LoanStatus status = null;
|
final LoanStatus status = null;
|
||||||
LoanProductRelatedDetail loanRepaymentScheduleDetail = loanSchedule.loanProductRelatedDetail();
|
LoanProductRelatedDetail loanRepaymentScheduleDetail = loanSchedule.loanProductRelatedDetail();
|
||||||
return new Loan(client, fund, officer, transactionProcessingStrategy, loanProduct, loanRepaymentScheduleDetail, status, loanCharges);
|
return new Loan(client, null, fund, officer, transactionProcessingStrategy, loanProduct, loanRepaymentScheduleDetail, status, loanCharges);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Loan newGroupLoanApplication(final Group group, final LoanProduct loanProduct, final Fund fund, final Staff officer,
|
public static Loan newGroupLoanApplication(final Group group, final LoanProduct loanProduct, final Fund fund, final Staff officer,
|
||||||
@@ -220,39 +220,26 @@ public class Loan extends AbstractAuditableCustom<AppUser, Long> {
|
|||||||
final Set<LoanCharge> loanCharges) {
|
final Set<LoanCharge> loanCharges) {
|
||||||
final LoanStatus status = null;
|
final LoanStatus status = null;
|
||||||
LoanProductRelatedDetail loanRepaymentScheduleDetail = loanSchedule.loanProductRelatedDetail();
|
LoanProductRelatedDetail loanRepaymentScheduleDetail = loanSchedule.loanProductRelatedDetail();
|
||||||
return new Loan(group, fund, officer, transactionProcessingStrategy, loanProduct, loanRepaymentScheduleDetail, status, loanCharges);
|
return new Loan(null, group, fund, officer, transactionProcessingStrategy, loanProduct, loanRepaymentScheduleDetail, status, loanCharges);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Loan newMemberLoanApplication(final Client client, final Group group, final LoanProduct loanProduct, final Fund fund,
|
||||||
|
final Staff officer, final LoanTransactionProcessingStrategy transactionProcessingStrategy, final LoanSchedule loanSchedule,
|
||||||
|
final Set<LoanCharge> loanCharges) {
|
||||||
|
final LoanStatus status = null;
|
||||||
|
LoanProductRelatedDetail loanRepaymentScheduleDetail = loanSchedule.loanProductRelatedDetail();
|
||||||
|
return new Loan(client, group, fund, officer, transactionProcessingStrategy, loanProduct, loanRepaymentScheduleDetail, status,
|
||||||
|
loanCharges);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Loan() {
|
protected Loan() {
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
|
|
||||||
private Loan(final Client client, Fund fund, Staff loanOfficer, final LoanTransactionProcessingStrategy transactionProcessingStrategy,
|
private Loan(final Client client, final Group group, Fund fund, Staff loanOfficer, final LoanTransactionProcessingStrategy transactionProcessingStrategy,
|
||||||
final LoanProduct loanProduct, final LoanProductRelatedDetail loanRepaymentScheduleDetail, final LoanStatus loanStatus,
|
final LoanProduct loanProduct, final LoanProductRelatedDetail loanRepaymentScheduleDetail, final LoanStatus loanStatus,
|
||||||
final Set<LoanCharge> loanCharges) {
|
final Set<LoanCharge> loanCharges) {
|
||||||
this.client = client;
|
this.client = client;
|
||||||
this.fund = fund;
|
|
||||||
this.loanofficer = loanOfficer;
|
|
||||||
this.transactionProcessingStrategy = transactionProcessingStrategy;
|
|
||||||
this.loanProduct = loanProduct;
|
|
||||||
this.loanRepaymentScheduleDetail = loanRepaymentScheduleDetail;
|
|
||||||
if (loanStatus != null) {
|
|
||||||
this.loanStatus = loanStatus.getValue();
|
|
||||||
} else {
|
|
||||||
this.loanStatus = null;
|
|
||||||
}
|
|
||||||
if (loanCharges != null && !loanCharges.isEmpty()) {
|
|
||||||
this.charges = associateChargesWithThisLoan(loanCharges);
|
|
||||||
this.totalChargesDueAtDisbursement = deriveSumTotalOfChargesDueAtDisbursement();
|
|
||||||
} else {
|
|
||||||
this.charges = null;
|
|
||||||
}
|
|
||||||
this.loanOfficerHistory = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Loan(final Group group, Fund fund, Staff loanOfficer, final LoanTransactionProcessingStrategy transactionProcessingStrategy,
|
|
||||||
final LoanProduct loanProduct, final LoanProductRelatedDetail loanRepaymentScheduleDetail, final LoanStatus loanStatus,
|
|
||||||
final Set<LoanCharge> loanCharges) {
|
|
||||||
this.group = group;
|
this.group = group;
|
||||||
this.fund = fund;
|
this.fund = fund;
|
||||||
this.loanofficer = loanOfficer;
|
this.loanofficer = loanOfficer;
|
||||||
|
|||||||
+11
-2
@@ -20,6 +20,7 @@ import org.mifosplatform.portfolio.fund.domain.FundRepository;
|
|||||||
import org.mifosplatform.portfolio.fund.exception.FundNotFoundException;
|
import org.mifosplatform.portfolio.fund.exception.FundNotFoundException;
|
||||||
import org.mifosplatform.portfolio.group.domain.Group;
|
import org.mifosplatform.portfolio.group.domain.Group;
|
||||||
import org.mifosplatform.portfolio.group.domain.GroupRepository;
|
import org.mifosplatform.portfolio.group.domain.GroupRepository;
|
||||||
|
import org.mifosplatform.portfolio.group.exception.ClientNotInGroupException;
|
||||||
import org.mifosplatform.portfolio.group.exception.GroupNotFoundException;
|
import org.mifosplatform.portfolio.group.exception.GroupNotFoundException;
|
||||||
import org.mifosplatform.portfolio.loanaccount.domain.DefaultLoanLifecycleStateMachine;
|
import org.mifosplatform.portfolio.loanaccount.domain.DefaultLoanLifecycleStateMachine;
|
||||||
import org.mifosplatform.portfolio.loanaccount.domain.Loan;
|
import org.mifosplatform.portfolio.loanaccount.domain.Loan;
|
||||||
@@ -98,8 +99,10 @@ public class LoanAssembler {
|
|||||||
LoanSchedule loanSchedule = this.loanScheduleAssembler.fromJson(element, inArrearsTolerance);
|
LoanSchedule loanSchedule = this.loanScheduleAssembler.fromJson(element, inArrearsTolerance);
|
||||||
|
|
||||||
Loan loanApplication = null;
|
Loan loanApplication = null;
|
||||||
|
Client client = null;
|
||||||
|
Group group = null;
|
||||||
if (clientId != null) {
|
if (clientId != null) {
|
||||||
final Client client = this.clientRepository.findOne(clientId);
|
client = this.clientRepository.findOne(clientId);
|
||||||
if (client == null || client.isDeleted()) { throw new ClientNotFoundException(clientId); }
|
if (client == null || client.isDeleted()) { throw new ClientNotFoundException(clientId); }
|
||||||
|
|
||||||
loanApplication = Loan.newIndividualLoanApplication(client, loanProduct, fund, loanOfficer, loanTransactionProcessingStrategy,
|
loanApplication = Loan.newIndividualLoanApplication(client, loanProduct, fund, loanOfficer, loanTransactionProcessingStrategy,
|
||||||
@@ -107,13 +110,19 @@ public class LoanAssembler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (groupId != null) {
|
if (groupId != null) {
|
||||||
final Group group = this.groupRepository.findOne(groupId);
|
group = this.groupRepository.findOne(groupId);
|
||||||
if (group == null || group.isDeleted()) { throw new GroupNotFoundException(groupId); }
|
if (group == null || group.isDeleted()) { throw new GroupNotFoundException(groupId); }
|
||||||
|
|
||||||
loanApplication = Loan.newGroupLoanApplication(group, loanProduct, fund, loanOfficer, loanTransactionProcessingStrategy,
|
loanApplication = Loan.newGroupLoanApplication(group, loanProduct, fund, loanOfficer, loanTransactionProcessingStrategy,
|
||||||
loanSchedule, loanCharges);
|
loanSchedule, loanCharges);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (clientId != null && groupId != null){
|
||||||
|
if (!group.hasClientAsMember(client)) { throw new ClientNotInGroupException(clientId, groupId); }
|
||||||
|
loanApplication = Loan.newMemberLoanApplication(client, group, loanProduct, fund, loanOfficer, loanTransactionProcessingStrategy,
|
||||||
|
loanSchedule, loanCharges);
|
||||||
|
}
|
||||||
|
|
||||||
final String externalId = fromApiJsonHelper.extractStringNamed("externalId", element);
|
final String externalId = fromApiJsonHelper.extractStringNamed("externalId", element);
|
||||||
final LocalDate submittedOnDate = fromApiJsonHelper.extractLocalDateNamed("submittedOnDate", element);
|
final LocalDate submittedOnDate = fromApiJsonHelper.extractLocalDateNamed("submittedOnDate", element);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user