FINERACT-2090: Improve Loan Application Reject logic
This commit is contained in:
committed by
Adam Saghy
parent
edc7fff86f
commit
35ff4363a8
+2
-62
@@ -1741,53 +1741,6 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom<Long> {
|
||||
return maturityDate;
|
||||
}
|
||||
|
||||
public Map<String, Object> loanApplicationRejection(final AppUser currentUser, final JsonCommand command,
|
||||
final LoanLifecycleStateMachine loanLifecycleStateMachine) {
|
||||
validateAccountStatus(LoanEvent.LOAN_REJECTED);
|
||||
|
||||
final Map<String, Object> actualChanges = new LinkedHashMap<>();
|
||||
|
||||
final LoanStatus statusEnum = loanLifecycleStateMachine.dryTransition(LoanEvent.LOAN_REJECTED, this);
|
||||
if (!statusEnum.hasStateOf(LoanStatus.fromInt(this.loanStatus))) {
|
||||
final LocalDate rejectedOn = command.localDateValueOfParameterNamed(REJECTED_ON_DATE);
|
||||
|
||||
final Locale locale = new Locale(command.locale());
|
||||
final DateTimeFormatter fmt = DateTimeFormatter.ofPattern(command.dateFormat()).withLocale(locale);
|
||||
|
||||
this.rejectedOnDate = rejectedOn;
|
||||
this.rejectedBy = currentUser;
|
||||
this.closedOnDate = rejectedOn;
|
||||
this.closedBy = currentUser;
|
||||
|
||||
loanLifecycleStateMachine.transition(LoanEvent.LOAN_REJECTED, this);
|
||||
actualChanges.put(PARAM_STATUS, LoanEnumerations.status(this.loanStatus));
|
||||
|
||||
actualChanges.put(LOCALE, command.locale());
|
||||
actualChanges.put(DATE_FORMAT, command.dateFormat());
|
||||
actualChanges.put(REJECTED_ON_DATE, rejectedOn.format(fmt));
|
||||
actualChanges.put(CLOSED_ON_DATE, rejectedOn.format(fmt));
|
||||
|
||||
if (DateUtils.isBefore(rejectedOn, getSubmittedOnDate())) {
|
||||
final String errorMessage = "The date on which a loan is rejected cannot be before its submittal date: "
|
||||
+ getSubmittedOnDate().toString();
|
||||
throw new InvalidLoanStateTransitionException("reject", "cannot.be.before.submittal.date", errorMessage, rejectedOn,
|
||||
getSubmittedOnDate());
|
||||
}
|
||||
|
||||
validateActivityNotBeforeClientOrGroupTransferDate(LoanEvent.LOAN_REJECTED, rejectedOn);
|
||||
|
||||
if (DateUtils.isDateInTheFuture(rejectedOn)) {
|
||||
final String errorMessage = "The date on which a loan is rejected cannot be in the future.";
|
||||
throw new InvalidLoanStateTransitionException("reject", "cannot.be.a.future.date", errorMessage, rejectedOn);
|
||||
}
|
||||
} else {
|
||||
final String errorMessage = "Only the loan applications with status 'Submitted and pending approval' are allowed to be rejected.";
|
||||
throw new InvalidLoanStateTransitionException("reject", "cannot.reject", errorMessage);
|
||||
}
|
||||
|
||||
return actualChanges;
|
||||
}
|
||||
|
||||
public Map<String, Object> loanApplicationWithdrawnByApplicant(final AppUser currentUser, final JsonCommand command,
|
||||
final LoanLifecycleStateMachine loanLifecycleStateMachine) {
|
||||
final Map<String, Object> actualChanges = new LinkedHashMap<>();
|
||||
@@ -3559,7 +3512,7 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom<Long> {
|
||||
return getStatus().isApproved();
|
||||
}
|
||||
|
||||
private boolean isNotDisbursed() {
|
||||
public boolean isNotDisbursed() {
|
||||
return !isDisbursed();
|
||||
}
|
||||
|
||||
@@ -3603,7 +3556,7 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom<Long> {
|
||||
return getStatus().isActive();
|
||||
}
|
||||
|
||||
private boolean isAllTranchesNotDisbursed() {
|
||||
public boolean isAllTranchesNotDisbursed() {
|
||||
LoanStatus actualLoanStatus = LoanStatus.fromInt(this.loanStatus);
|
||||
return this.loanProduct.isMultiDisburseLoan() && (actualLoanStatus.isActive() || actualLoanStatus.isApproved()
|
||||
|| actualLoanStatus.isClosedObligationsMet() || actualLoanStatus.isOverpaid()) && isDisbursementAllowed();
|
||||
@@ -4325,11 +4278,6 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom<Long> {
|
||||
action = "repayment.or.waiver";
|
||||
postfix = "cannot.be.made.before.client.transfer.date";
|
||||
}
|
||||
case LOAN_REJECTED -> {
|
||||
errorMessage = "The date on which a loan is rejected cannot be earlier than client's transfer date to this office";
|
||||
action = "reject";
|
||||
postfix = "cannot.be.before.client.transfer.date";
|
||||
}
|
||||
case LOAN_WITHDRAWN -> {
|
||||
errorMessage = "The date on which a loan is withdrawn cannot be earlier than client's transfer date to this office";
|
||||
action = "withdraw";
|
||||
@@ -4530,14 +4478,6 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom<Long> {
|
||||
dataValidationErrors.add(error);
|
||||
}
|
||||
}
|
||||
case LOAN_REJECTED -> {
|
||||
if (!isSubmittedAndPendingApproval()) {
|
||||
final String defaultUserMessage = "Loan application cannot be rejected. Loan Account is not in Submitted and Pending approval state.";
|
||||
final ApiParameterError error = ApiParameterError
|
||||
.generalError("error.msg.loan.reject.account.is.not.submitted.pending.approval.state", defaultUserMessage);
|
||||
dataValidationErrors.add(error);
|
||||
}
|
||||
}
|
||||
case LOAN_WITHDRAWN -> {
|
||||
if (!isSubmittedAndPendingApproval()) {
|
||||
final String defaultUserMessage = "Loan application cannot be withdrawn. Loan Account is not in Submitted and Pending approval state.";
|
||||
|
||||
+108
-3
@@ -30,22 +30,33 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||
import org.apache.fineract.infrastructure.core.data.ApiParameterError;
|
||||
import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder;
|
||||
import org.apache.fineract.infrastructure.core.exception.InvalidJsonException;
|
||||
import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException;
|
||||
import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
|
||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||
import org.apache.fineract.portfolio.client.domain.Client;
|
||||
import org.apache.fineract.portfolio.client.exception.ClientNotActiveException;
|
||||
import org.apache.fineract.portfolio.group.domain.Group;
|
||||
import org.apache.fineract.portfolio.group.exception.GroupNotActiveException;
|
||||
import org.apache.fineract.portfolio.loanaccount.api.LoanApiConstants;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.Loan;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanEvent;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanLifecycleStateMachine;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanStatus;
|
||||
import org.apache.fineract.portfolio.loanaccount.exception.InvalidLoanStateTransitionException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public final class LoanApplicationTransitionApiJsonValidator {
|
||||
public final class LoanApplicationTransitionValidator {
|
||||
|
||||
private final FromJsonHelper fromApiJsonHelper;
|
||||
|
||||
@Autowired
|
||||
public LoanApplicationTransitionApiJsonValidator(final FromJsonHelper fromApiJsonHelper) {
|
||||
public LoanApplicationTransitionValidator(final FromJsonHelper fromApiJsonHelper) {
|
||||
this.fromApiJsonHelper = fromApiJsonHelper;
|
||||
}
|
||||
|
||||
@@ -101,8 +112,16 @@ public final class LoanApplicationTransitionApiJsonValidator {
|
||||
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
||||
}
|
||||
|
||||
public void validateRejection(final String json) {
|
||||
public void validateRejection(final JsonCommand command, final Loan loan, final LoanLifecycleStateMachine loanLifecycleStateMachine) {
|
||||
// validate request body
|
||||
final String json = command.json();
|
||||
validateLoanRejectionRequestBody(json);
|
||||
|
||||
// validate loan rejection
|
||||
validateLoanRejection(command, loan, loanLifecycleStateMachine);
|
||||
}
|
||||
|
||||
private void validateLoanRejectionRequestBody(String json) {
|
||||
if (StringUtils.isBlank(json)) {
|
||||
throw new InvalidJsonException();
|
||||
}
|
||||
@@ -127,6 +146,38 @@ public final class LoanApplicationTransitionApiJsonValidator {
|
||||
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
||||
}
|
||||
|
||||
private void validateLoanRejection(final JsonCommand command, final Loan loan,
|
||||
final LoanLifecycleStateMachine loanLifecycleStateMachine) {
|
||||
// validate client or group is active
|
||||
checkClientOrGroupActive(loan);
|
||||
|
||||
// validate Account Status
|
||||
validateAccountStatus(loan, LoanEvent.LOAN_REJECTED);
|
||||
|
||||
// validate loan state transition
|
||||
|
||||
final LoanStatus statusEnum = loanLifecycleStateMachine.dryTransition(LoanEvent.LOAN_REJECTED, loan);
|
||||
if (!statusEnum.hasStateOf(LoanStatus.fromInt(loan.getLoanStatus()))) {
|
||||
final LocalDate rejectedOn = command.localDateValueOfParameterNamed(Loan.REJECTED_ON_DATE);
|
||||
if (DateUtils.isBefore(rejectedOn, loan.getSubmittedOnDate())) {
|
||||
final String errorMessage = "The date on which a loan is rejected cannot be before its submittal date: "
|
||||
+ loan.getSubmittedOnDate().toString();
|
||||
throw new InvalidLoanStateTransitionException("reject", "cannot.be.before.submittal.date", errorMessage, rejectedOn,
|
||||
loan.getSubmittedOnDate());
|
||||
}
|
||||
|
||||
validateActivityNotBeforeClientOrGroupTransferDate(loan, LoanEvent.LOAN_REJECTED, rejectedOn);
|
||||
|
||||
if (DateUtils.isDateInTheFuture(rejectedOn)) {
|
||||
final String errorMessage = "The date on which a loan is rejected cannot be in the future.";
|
||||
throw new InvalidLoanStateTransitionException("reject", "cannot.be.a.future.date", errorMessage, rejectedOn);
|
||||
}
|
||||
} else {
|
||||
final String errorMessage = "Only the loan applications with status 'Submitted and pending approval' are allowed to be rejected.";
|
||||
throw new InvalidLoanStateTransitionException("reject", "cannot.reject", errorMessage);
|
||||
}
|
||||
}
|
||||
|
||||
public void validateApplicantWithdrawal(final String json) {
|
||||
|
||||
if (StringUtils.isBlank(json)) {
|
||||
@@ -152,4 +203,58 @@ public final class LoanApplicationTransitionApiJsonValidator {
|
||||
|
||||
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
||||
}
|
||||
|
||||
private void validateActivityNotBeforeClientOrGroupTransferDate(final Loan loan, final LoanEvent event, final LocalDate activityDate) {
|
||||
if (loan.getClient() != null && loan.getClient().getOfficeJoiningDate() != null) {
|
||||
final LocalDate clientOfficeJoiningDate = loan.getClient().getOfficeJoiningDate();
|
||||
if (DateUtils.isBefore(activityDate, clientOfficeJoiningDate)) {
|
||||
String errorMessage = null;
|
||||
String action = null;
|
||||
String postfix = null;
|
||||
switch (event) {
|
||||
case LOAN_REJECTED -> {
|
||||
errorMessage = "The date on which a loan is rejected cannot be earlier than client's transfer date to this office";
|
||||
action = "reject";
|
||||
postfix = "cannot.be.before.client.transfer.date";
|
||||
}
|
||||
default -> {
|
||||
}
|
||||
}
|
||||
throw new InvalidLoanStateTransitionException(action, postfix, errorMessage, clientOfficeJoiningDate);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void validateAccountStatus(final Loan loan, final LoanEvent event) {
|
||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
|
||||
|
||||
switch (event) {
|
||||
case LOAN_REJECTED -> {
|
||||
if (!loan.isSubmittedAndPendingApproval()) {
|
||||
final String defaultUserMessage = "Loan application cannot be rejected. Loan Account is not in Submitted and Pending approval state.";
|
||||
final ApiParameterError error = ApiParameterError
|
||||
.generalError("error.msg.loan.reject.account.is.not.submitted.pending.approval.state", defaultUserMessage);
|
||||
dataValidationErrors.add(error);
|
||||
}
|
||||
}
|
||||
default -> {
|
||||
}
|
||||
}
|
||||
|
||||
if (!dataValidationErrors.isEmpty()) {
|
||||
throw new PlatformApiDataValidationException(dataValidationErrors);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void checkClientOrGroupActive(final Loan loan) {
|
||||
final Client client = loan.client();
|
||||
if (client != null && client.isNotActive()) {
|
||||
throw new ClientNotActiveException(client.getId());
|
||||
}
|
||||
final Group group = loan.group();
|
||||
if (group != null && group.isNotActive()) {
|
||||
throw new GroupNotActiveException(group.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
+47
-36
@@ -26,10 +26,13 @@ import com.google.gson.JsonObject;
|
||||
import jakarta.persistence.PersistenceException;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.temporal.ChronoField;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
@@ -69,19 +72,16 @@ import org.apache.fineract.portfolio.calendar.domain.CalendarRepository;
|
||||
import org.apache.fineract.portfolio.calendar.domain.CalendarType;
|
||||
import org.apache.fineract.portfolio.calendar.exception.CalendarNotFoundException;
|
||||
import org.apache.fineract.portfolio.calendar.service.CalendarReadPlatformService;
|
||||
import org.apache.fineract.portfolio.client.domain.Client;
|
||||
import org.apache.fineract.portfolio.client.exception.ClientNotActiveException;
|
||||
import org.apache.fineract.portfolio.collateralmanagement.domain.ClientCollateralManagement;
|
||||
import org.apache.fineract.portfolio.common.domain.PeriodFrequencyType;
|
||||
import org.apache.fineract.portfolio.group.domain.Group;
|
||||
import org.apache.fineract.portfolio.group.exception.GroupMemberNotFoundInGSIMException;
|
||||
import org.apache.fineract.portfolio.group.exception.GroupNotActiveException;
|
||||
import org.apache.fineract.portfolio.loanaccount.api.LoanApiConstants;
|
||||
import org.apache.fineract.portfolio.loanaccount.data.ScheduleGeneratorDTO;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.GLIMAccountInfoRepository;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.GroupLoanIndividualMonitoringAccount;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.Loan;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanCollateralManagement;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanEvent;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanLifecycleStateMachine;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanRepaymentScheduleTransactionProcessorFactory;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanRepository;
|
||||
@@ -92,10 +92,11 @@ import org.apache.fineract.portfolio.loanaccount.domain.LoanTransactionType;
|
||||
import org.apache.fineract.portfolio.loanaccount.exception.LoanApplicationNotInSubmittedAndPendingApprovalStateCannotBeDeleted;
|
||||
import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanApplicationTerms;
|
||||
import org.apache.fineract.portfolio.loanaccount.loanschedule.service.LoanScheduleAssembler;
|
||||
import org.apache.fineract.portfolio.loanaccount.serialization.LoanApplicationTransitionApiJsonValidator;
|
||||
import org.apache.fineract.portfolio.loanaccount.serialization.LoanApplicationTransitionValidator;
|
||||
import org.apache.fineract.portfolio.loanaccount.serialization.LoanApplicationValidator;
|
||||
import org.apache.fineract.portfolio.loanproduct.LoanProductConstants;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.RecalculationFrequencyType;
|
||||
import org.apache.fineract.portfolio.loanproduct.service.LoanEnumerations;
|
||||
import org.apache.fineract.portfolio.note.domain.Note;
|
||||
import org.apache.fineract.portfolio.note.domain.NoteRepository;
|
||||
import org.apache.fineract.portfolio.savings.data.GroupSavingsIndividualMonitoringAccountData;
|
||||
@@ -113,7 +114,7 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
|
||||
|
||||
private final PlatformSecurityContext context;
|
||||
private final FromJsonHelper fromJsonHelper;
|
||||
private final LoanApplicationTransitionApiJsonValidator loanApplicationTransitionApiJsonValidator;
|
||||
private final LoanApplicationTransitionValidator loanApplicationTransitionValidator;
|
||||
private final LoanApplicationValidator loanApplicationValidator;
|
||||
private final LoanRepositoryWrapper loanRepositoryWrapper;
|
||||
private final NoteRepository noteRepository;
|
||||
@@ -476,7 +477,7 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
|
||||
public CommandProcessingResult deleteApplication(final Long loanId) {
|
||||
|
||||
final Loan loan = retrieveLoanBy(loanId);
|
||||
checkClientOrGroupActive(loan);
|
||||
loanApplicationTransitionValidator.checkClientOrGroupActive(loan);
|
||||
|
||||
if (loan.isNotSubmittedAndPendingApproval()) {
|
||||
throw new LoanApplicationNotInSubmittedAndPendingApprovalStateCannotBeDeleted(loanId);
|
||||
@@ -578,7 +579,7 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
|
||||
final AppUser currentUser = getAppUserIfPresent();
|
||||
LocalDate expectedDisbursementDate = null;
|
||||
|
||||
this.loanApplicationTransitionApiJsonValidator.validateApproval(command.json());
|
||||
this.loanApplicationTransitionValidator.validateApproval(command.json());
|
||||
|
||||
Loan loan = retrieveLoanBy(loanId);
|
||||
|
||||
@@ -592,7 +593,7 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
|
||||
this.validateMultiDisbursementData(command, expectedDisbursementDate);
|
||||
}
|
||||
|
||||
checkClientOrGroupActive(loan);
|
||||
loanApplicationTransitionValidator.checkClientOrGroupActive(loan);
|
||||
Boolean isSkipRepaymentOnFirstMonth = false;
|
||||
Integer numberOfDays = 0;
|
||||
// validate expected disbursement date against meeting date
|
||||
@@ -721,7 +722,7 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
|
||||
this.loanApplicationValidator.validateForUndo(command.json());
|
||||
|
||||
Loan loan = retrieveLoanBy(loanId);
|
||||
checkClientOrGroupActive(loan);
|
||||
loanApplicationTransitionValidator.checkClientOrGroupActive(loan);
|
||||
|
||||
final Map<String, Object> changes = loan.undoApproval(defaultLoanLifecycleStateMachine);
|
||||
if (!changes.isEmpty()) {
|
||||
@@ -792,21 +793,21 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
|
||||
@Override
|
||||
public CommandProcessingResult rejectApplication(final Long loanId, final JsonCommand command) {
|
||||
|
||||
final AppUser currentUser = getAppUserIfPresent();
|
||||
// retrieve loan
|
||||
Loan loan = retrieveLoanBy(loanId);
|
||||
|
||||
this.loanApplicationTransitionApiJsonValidator.validateRejection(command.json());
|
||||
|
||||
final Loan loan = retrieveLoanBy(loanId);
|
||||
|
||||
checkClientOrGroupActive(loan);
|
||||
// validate loan rejection
|
||||
loanApplicationTransitionValidator.validateRejection(command, loan, defaultLoanLifecycleStateMachine);
|
||||
|
||||
// check for mandatory entities
|
||||
entityDatatableChecksWritePlatformService.runTheCheckForProduct(loanId, EntityTables.LOAN.getName(),
|
||||
StatusEnum.REJECTED.getCode().longValue(), EntityTables.LOAN.getForeignKeyColumnNameOnDatatable(), loan.productId());
|
||||
|
||||
final Map<String, Object> changes = loan.loanApplicationRejection(currentUser, command, defaultLoanLifecycleStateMachine);
|
||||
if (!changes.isEmpty()) {
|
||||
this.loanRepositoryWrapper.saveAndFlush(loan);
|
||||
// loan application rejection
|
||||
final Map<String, Object> changes = loanApplicationRejection(loan, command);
|
||||
|
||||
if (!changes.isEmpty()) {
|
||||
loanRepositoryWrapper.saveAndFlush(loan);
|
||||
final String noteText = command.stringValueOfParameterNamed("note");
|
||||
createNote(noteText, loan);
|
||||
}
|
||||
@@ -823,16 +824,41 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
|
||||
.build();
|
||||
}
|
||||
|
||||
private Map<String, Object> loanApplicationRejection(Loan loan, final JsonCommand command) {
|
||||
|
||||
final AppUser currentUser = getAppUserIfPresent();
|
||||
final LocalDate rejectedOn = command.localDateValueOfParameterNamed(Loan.REJECTED_ON_DATE);
|
||||
|
||||
loan.setRejectedOnDate(rejectedOn);
|
||||
loan.setRejectedBy(currentUser);
|
||||
loan.setClosedOnDate(rejectedOn);
|
||||
loan.setClosedBy(currentUser);
|
||||
|
||||
defaultLoanLifecycleStateMachine.transition(LoanEvent.LOAN_REJECTED, loan);
|
||||
|
||||
final Map<String, Object> actualChanges = new LinkedHashMap<>();
|
||||
final Locale locale = new Locale(command.locale());
|
||||
final DateTimeFormatter fmt = DateTimeFormatter.ofPattern(command.dateFormat()).withLocale(locale);
|
||||
|
||||
actualChanges.put(Loan.PARAM_STATUS, LoanEnumerations.status(loan.getStatus()));
|
||||
actualChanges.put(Loan.LOCALE, command.locale());
|
||||
actualChanges.put(Loan.DATE_FORMAT, command.dateFormat());
|
||||
actualChanges.put(Loan.REJECTED_ON_DATE, rejectedOn.format(fmt));
|
||||
actualChanges.put(Loan.CLOSED_ON_DATE, rejectedOn.format(fmt));
|
||||
|
||||
return actualChanges;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult applicantWithdrawsFromApplication(final Long loanId, final JsonCommand command) {
|
||||
|
||||
final AppUser currentUser = getAppUserIfPresent();
|
||||
|
||||
this.loanApplicationTransitionApiJsonValidator.validateApplicantWithdrawal(command.json());
|
||||
this.loanApplicationTransitionValidator.validateApplicantWithdrawal(command.json());
|
||||
|
||||
final Loan loan = retrieveLoanBy(loanId);
|
||||
checkClientOrGroupActive(loan);
|
||||
loanApplicationTransitionValidator.checkClientOrGroupActive(loan);
|
||||
|
||||
entityDatatableChecksWritePlatformService.runTheCheckForProduct(loanId, EntityTables.LOAN.getName(),
|
||||
StatusEnum.WITHDRAWN.getCode().longValue(), EntityTables.LOAN.getForeignKeyColumnNameOnDatatable(), loan.productId());
|
||||
@@ -878,21 +904,6 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
|
||||
return loan;
|
||||
}
|
||||
|
||||
private void checkClientOrGroupActive(final Loan loan) {
|
||||
final Client client = loan.client();
|
||||
if (client != null) {
|
||||
if (client.isNotActive()) {
|
||||
throw new ClientNotActiveException(client.getId());
|
||||
}
|
||||
}
|
||||
final Group group = loan.group();
|
||||
if (group != null) {
|
||||
if (group.isNotActive()) {
|
||||
throw new GroupNotActiveException(group.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private AppUser getAppUserIfPresent() {
|
||||
AppUser user = null;
|
||||
if (this.context != null) {
|
||||
|
||||
+3
-3
@@ -84,7 +84,7 @@ import org.apache.fineract.portfolio.loanaccount.loanschedule.service.LoanSchedu
|
||||
import org.apache.fineract.portfolio.loanaccount.mapper.LoanChargeMapper;
|
||||
import org.apache.fineract.portfolio.loanaccount.mapper.LoanCollateralManagementMapper;
|
||||
import org.apache.fineract.portfolio.loanaccount.mapper.LoanTransactionRelationMapper;
|
||||
import org.apache.fineract.portfolio.loanaccount.serialization.LoanApplicationTransitionApiJsonValidator;
|
||||
import org.apache.fineract.portfolio.loanaccount.serialization.LoanApplicationTransitionValidator;
|
||||
import org.apache.fineract.portfolio.loanaccount.serialization.LoanApplicationValidator;
|
||||
import org.apache.fineract.portfolio.loanaccount.serialization.LoanChargeApiJsonValidator;
|
||||
import org.apache.fineract.portfolio.loanaccount.serialization.LoanEventApiJsonValidator;
|
||||
@@ -202,7 +202,7 @@ public class LoanAccountConfiguration {
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(LoanApplicationWritePlatformService.class)
|
||||
public LoanApplicationWritePlatformService loanApplicationWritePlatformService(PlatformSecurityContext context,
|
||||
FromJsonHelper fromJsonHelper, LoanApplicationTransitionApiJsonValidator loanApplicationTransitionApiJsonValidator,
|
||||
FromJsonHelper fromJsonHelper, LoanApplicationTransitionValidator loanApplicationTransitionValidator,
|
||||
LoanApplicationValidator loanApplicationValidator, LoanRepositoryWrapper loanRepositoryWrapper, NoteRepository noteRepository,
|
||||
LoanAssembler loanAssembler, LoanSummaryWrapper loanSummaryWrapper,
|
||||
LoanRepaymentScheduleTransactionProcessorFactory loanRepaymentScheduleTransactionProcessorFactory,
|
||||
@@ -214,7 +214,7 @@ public class LoanAccountConfiguration {
|
||||
EntityDatatableChecksWritePlatformService entityDatatableChecksWritePlatformService, GLIMAccountInfoRepository glimRepository,
|
||||
LoanRepository loanRepository, GSIMReadPlatformService gsimReadPlatformService,
|
||||
LoanLifecycleStateMachine defaultLoanLifecycleStateMachine) {
|
||||
return new LoanApplicationWritePlatformServiceJpaRepositoryImpl(context, fromJsonHelper, loanApplicationTransitionApiJsonValidator,
|
||||
return new LoanApplicationWritePlatformServiceJpaRepositoryImpl(context, fromJsonHelper, loanApplicationTransitionValidator,
|
||||
loanApplicationValidator, loanRepositoryWrapper, noteRepository, loanAssembler, loanSummaryWrapper,
|
||||
loanRepaymentScheduleTransactionProcessorFactory, calendarRepository, calendarInstanceRepository, savingsAccountRepository,
|
||||
accountAssociationsRepository, loanReadPlatformService, businessEventNotifierService, configurationDomainService,
|
||||
|
||||
Reference in New Issue
Block a user