This is an automated email from the ASF dual-hosted git repository.
adamsaghy pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract.git
The following commit(s) were added to refs/heads/develop by this push:
new 1c53fe213 FINERACT-2090: Restructure Withdraw Loan Application Logic
1c53fe213 is described below
commit 1c53fe2136b6e453e81a2f82b99259d49e24e4ee
Author: Ruchi Dhamankar <[email protected]>
AuthorDate: Wed Jun 19 11:34:54 2024 +0530
FINERACT-2090: Restructure Withdraw Loan Application Logic
---
.../portfolio/loanaccount/domain/Loan.java | 62 -----------------
.../LoanApplicationTransitionValidator.java | 64 ++++++++++++++----
...ationWritePlatformServiceJpaRepositoryImpl.java | 77 ++++++++--------------
.../loanaccount/service/LoanAssembler.java | 49 ++++++++++++++
4 files changed, 129 insertions(+), 123 deletions(-)
diff --git
a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/Loan.java
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/Loan.java
index 3f7f49aa1..f8e960e39 100644
---
a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/Loan.java
+++
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/Loan.java
@@ -42,7 +42,6 @@ import jakarta.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.math.MathContext;
import java.time.LocalDate;
-import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.Collection;
@@ -1741,54 +1740,6 @@ public class Loan extends
AbstractAuditableWithUTCDateTimeCustom<Long> {
return maturityDate;
}
- public Map<String, Object> loanApplicationWithdrawnByApplicant(final
AppUser currentUser, final JsonCommand command,
- final LoanLifecycleStateMachine loanLifecycleStateMachine) {
- final Map<String, Object> actualChanges = new LinkedHashMap<>();
-
- final LoanStatus statusEnum =
loanLifecycleStateMachine.dryTransition(LoanEvent.LOAN_WITHDRAWN, this);
- if (!statusEnum.hasStateOf(LoanStatus.fromInt(this.loanStatus))) {
- loanLifecycleStateMachine.transition(LoanEvent.LOAN_WITHDRAWN,
this);
- actualChanges.put(PARAM_STATUS,
LoanEnumerations.status(this.loanStatus));
-
- LocalDate withdrawnOn =
command.localDateValueOfParameterNamed(WITHDRAWN_ON_DATE);
- if (withdrawnOn == null) {
- withdrawnOn =
command.localDateValueOfParameterNamed(EVENT_DATE);
- }
-
- final Locale locale = new Locale(command.locale());
- final DateTimeFormatter fmt =
DateTimeFormatter.ofPattern(command.dateFormat()).withLocale(locale);
-
- this.withdrawnOnDate = withdrawnOn;
- this.withdrawnBy = currentUser;
- this.closedOnDate = withdrawnOn;
- this.closedBy = currentUser;
-
- actualChanges.put(LOCALE, command.locale());
- actualChanges.put(DATE_FORMAT, command.dateFormat());
- actualChanges.put(WITHDRAWN_ON_DATE, withdrawnOn.format(fmt));
- actualChanges.put(CLOSED_ON_DATE, withdrawnOn.format(fmt));
-
- if (DateUtils.isBefore(withdrawnOn, getSubmittedOnDate())) {
- final String errorMessage = "The date on which a loan is
withdrawn cannot be before its submittal date: "
- + getSubmittedOnDate().toString();
- throw new InvalidLoanStateTransitionException("withdraw",
"cannot.be.before.submittal.date", errorMessage, command,
- getSubmittedOnDate());
- }
-
-
validateActivityNotBeforeClientOrGroupTransferDate(LoanEvent.LOAN_WITHDRAWN,
withdrawnOn);
-
- if (DateUtils.isDateInTheFuture(withdrawnOn)) {
- final String errorMessage = "The date on which a loan is
withdrawn cannot be in the future.";
- throw new InvalidLoanStateTransitionException("withdraw",
"cannot.be.a.future.date", errorMessage, command);
- }
- } else {
- final String errorMessage = "Only the loan applications with
status 'Submitted and pending approval' are allowed to be withdrawn by
applicant.";
- throw new InvalidLoanStateTransitionException("withdraw",
"cannot.withdraw", errorMessage);
- }
-
- return actualChanges;
- }
-
public Map<String, Object> loanApplicationApproval(final AppUser
currentUser, final JsonCommand command,
final JsonArray disbursementDataArray, final
LoanLifecycleStateMachine loanLifecycleStateMachine) {
validateAccountStatus(LoanEvent.LOAN_APPROVED);
@@ -4278,11 +4229,6 @@ public class Loan extends
AbstractAuditableWithUTCDateTimeCustom<Long> {
action = "repayment.or.waiver";
postfix = "cannot.be.made.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";
- postfix = "cannot.be.before.client.transfer.date";
- }
case WRITE_OFF_OUTSTANDING -> {
errorMessage = "The date on which a write off is made
cannot be earlier than client's transfer date to this office";
action = "writeoff";
@@ -4478,14 +4424,6 @@ public class Loan extends
AbstractAuditableWithUTCDateTimeCustom<Long> {
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.";
- final ApiParameterError error = ApiParameterError
-
.generalError("error.msg.loan.withdrawn.account.is.not.submitted.pending.approval.state",
defaultUserMessage);
- dataValidationErrors.add(error);
- }
- }
case WRITE_OFF_OUTSTANDING -> {
if (!isOpen()) {
final String defaultUserMessage = "Loan Written off is not
allowed. Loan Account is not active.";
diff --git
a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/serialization/LoanApplicationTransitionValidator.java
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/serialization/LoanApplicationTransitionValidator.java
index a8c343538..34d40c727 100644
---
a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/serialization/LoanApplicationTransitionValidator.java
+++
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/serialization/LoanApplicationTransitionValidator.java
@@ -29,6 +29,7 @@ import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.apache.fineract.infrastructure.core.api.JsonCommand;
import org.apache.fineract.infrastructure.core.data.ApiParameterError;
@@ -47,18 +48,14 @@ 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
+@RequiredArgsConstructor
public final class LoanApplicationTransitionValidator {
private final FromJsonHelper fromApiJsonHelper;
-
- @Autowired
- public LoanApplicationTransitionValidator(final FromJsonHelper
fromApiJsonHelper) {
- this.fromApiJsonHelper = fromApiJsonHelper;
- }
+ private final LoanLifecycleStateMachine defaultLoanLifecycleStateMachine;
private void throwExceptionIfValidationWarningsExist(final
List<ApiParameterError> dataValidationErrors) {
if (!dataValidationErrors.isEmpty()) {
@@ -112,13 +109,13 @@ public final class LoanApplicationTransitionValidator {
throwExceptionIfValidationWarningsExist(dataValidationErrors);
}
- public void validateRejection(final JsonCommand command, final Loan loan,
final LoanLifecycleStateMachine loanLifecycleStateMachine) {
+ public void validateRejection(final JsonCommand command, final Loan loan) {
// validate request body
final String json = command.json();
validateLoanRejectionRequestBody(json);
// validate loan rejection
- validateLoanRejection(command, loan, loanLifecycleStateMachine);
+ validateLoanRejection(command, loan);
}
private void validateLoanRejectionRequestBody(String json) {
@@ -146,8 +143,7 @@ public final class LoanApplicationTransitionValidator {
throwExceptionIfValidationWarningsExist(dataValidationErrors);
}
- private void validateLoanRejection(final JsonCommand command, final Loan
loan,
- final LoanLifecycleStateMachine loanLifecycleStateMachine) {
+ private void validateLoanRejection(final JsonCommand command, final Loan
loan) {
// validate client or group is active
checkClientOrGroupActive(loan);
@@ -156,7 +152,7 @@ public final class LoanApplicationTransitionValidator {
// validate loan state transition
- final LoanStatus statusEnum =
loanLifecycleStateMachine.dryTransition(LoanEvent.LOAN_REJECTED, loan);
+ final LoanStatus statusEnum =
defaultLoanLifecycleStateMachine.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())) {
@@ -178,8 +174,16 @@ public final class LoanApplicationTransitionValidator {
}
}
- public void validateApplicantWithdrawal(final String json) {
+ public void validateApplicantWithdrawal(final JsonCommand command, final
Loan loan) {
+ // validate request body
+ final String json = command.json();
+ validateApplicantWithdrawalRequestBody(json);
+ // validate Loan application withdrawal by applicant
+ validateLoanApplicantWithdrawal(command, loan);
+ }
+
+ private void validateApplicantWithdrawalRequestBody(String json) {
if (StringUtils.isBlank(json)) {
throw new InvalidJsonException();
}
@@ -204,6 +208,37 @@ public final class LoanApplicationTransitionValidator {
throwExceptionIfValidationWarningsExist(dataValidationErrors);
}
+ private void validateLoanApplicantWithdrawal(final JsonCommand command,
final Loan loan) {
+ // validate client or group is active
+ checkClientOrGroupActive(loan);
+
+ // validate loan state transition
+ final LoanStatus statusEnum =
defaultLoanLifecycleStateMachine.dryTransition(LoanEvent.LOAN_WITHDRAWN, loan);
+ if (!statusEnum.hasStateOf(LoanStatus.fromInt(loan.getLoanStatus()))) {
+ LocalDate withdrawnOn =
command.localDateValueOfParameterNamed(Loan.WITHDRAWN_ON_DATE);
+ if (withdrawnOn == null) {
+ withdrawnOn =
command.localDateValueOfParameterNamed(Loan.EVENT_DATE);
+ }
+ if (DateUtils.isBefore(withdrawnOn, loan.getSubmittedOnDate())) {
+ final String errorMessage = "The date on which a loan is
withdrawn cannot be before its submittal date: "
+ + loan.getSubmittedOnDate().toString();
+ throw new InvalidLoanStateTransitionException("withdraw",
"cannot.be.before.submittal.date", errorMessage, command,
+ loan.getSubmittedOnDate());
+ }
+
+ validateActivityNotBeforeClientOrGroupTransferDate(loan,
LoanEvent.LOAN_WITHDRAWN, withdrawnOn);
+
+ if (DateUtils.isDateInTheFuture(withdrawnOn)) {
+ final String errorMessage = "The date on which a loan is
withdrawn cannot be in the future.";
+ throw new InvalidLoanStateTransitionException("withdraw",
"cannot.be.a.future.date", errorMessage, command);
+ }
+ } else {
+ final String errorMessage = "Only the loan applications with
status 'Submitted and pending approval' are allowed to be withdrawn by
applicant.";
+ throw new InvalidLoanStateTransitionException("withdraw",
"cannot.withdraw", errorMessage);
+ }
+
+ }
+
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();
@@ -217,6 +252,11 @@ public final class LoanApplicationTransitionValidator {
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";
+ postfix = "cannot.be.before.client.transfer.date";
+ }
default -> {
}
}
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanApplicationWritePlatformServiceJpaRepositoryImpl.java
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanApplicationWritePlatformServiceJpaRepositoryImpl.java
index fae97c795..94aad8ec9 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanApplicationWritePlatformServiceJpaRepositoryImpl.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanApplicationWritePlatformServiceJpaRepositoryImpl.java
@@ -26,13 +26,10 @@ 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;
@@ -96,7 +93,6 @@ import
org.apache.fineract.portfolio.loanaccount.serialization.LoanApplicationTr
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;
@@ -492,6 +488,7 @@ public class
LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
this.accountAssociationsRepository.delete(accountAssociations);
}
+ // Note: check if releaseAttachedCollaterals method can be used here
Set<LoanCollateralManagement> loanCollateralManagements =
loan.getLoanCollateralManagements();
for (LoanCollateralManagement loanCollateralManagement :
loanCollateralManagements) {
BigDecimal quantity = loanCollateralManagement.getQuantity();
@@ -797,20 +794,23 @@ public class
LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
Loan loan = retrieveLoanBy(loanId);
// validate loan rejection
- loanApplicationTransitionValidator.validateRejection(command, loan,
defaultLoanLifecycleStateMachine);
+ loanApplicationTransitionValidator.validateRejection(command, loan);
// check for mandatory entities
entityDatatableChecksWritePlatformService.runTheCheckForProduct(loanId,
EntityTables.LOAN.getName(),
StatusEnum.REJECTED.getCode().longValue(),
EntityTables.LOAN.getForeignKeyColumnNameOnDatatable(), loan.productId());
// loan application rejection
- final Map<String, Object> changes = loanApplicationRejection(loan,
command);
+ final AppUser currentUser = getAppUserIfPresent();
+ defaultLoanLifecycleStateMachine.transition(LoanEvent.LOAN_REJECTED,
loan);
+ final Map<String, Object> changes =
loanAssembler.updateLoanApplicationAttributesForRejection(loan, command,
currentUser);
if (!changes.isEmpty()) {
loanRepositoryWrapper.saveAndFlush(loan);
final String noteText =
command.stringValueOfParameterNamed("note");
createNote(noteText, loan);
}
+
businessEventNotifierService.notifyPostBusinessEvent(new
LoanRejectedBusinessEvent(loan));
return new CommandProcessingResultBuilder() //
.withCommandId(command.commandId()) //
@@ -824,63 +824,31 @@ 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.loanApplicationTransitionValidator.validateApplicantWithdrawal(command.json());
-
+ // retrieve loan
final Loan loan = retrieveLoanBy(loanId);
- loanApplicationTransitionValidator.checkClientOrGroupActive(loan);
+ // validate withdrawal
+
loanApplicationTransitionValidator.validateApplicantWithdrawal(command, loan);
+
+ // check for mandatory entities
entityDatatableChecksWritePlatformService.runTheCheckForProduct(loanId,
EntityTables.LOAN.getName(),
StatusEnum.WITHDRAWN.getCode().longValue(),
EntityTables.LOAN.getForeignKeyColumnNameOnDatatable(), loan.productId());
- final Map<String, Object> changes =
loan.loanApplicationWithdrawnByApplicant(currentUser, command,
- defaultLoanLifecycleStateMachine);
-
+ // loan application withdrawal
+ final AppUser currentUser = getAppUserIfPresent();
+ defaultLoanLifecycleStateMachine.transition(LoanEvent.LOAN_WITHDRAWN,
loan);
+ final Map<String, Object> changes =
loanAssembler.updateLoanApplicationAttributesForWithdrawal(loan, command,
currentUser);
// Release attached collaterals
if (loan.getLoanType().isIndividualAccount()) {
- Set<LoanCollateralManagement> loanCollateralManagements =
loan.getLoanCollateralManagements();
- for (LoanCollateralManagement loanCollateralManagement :
loanCollateralManagements) {
- ClientCollateralManagement clientCollateralManagement =
loanCollateralManagement.getClientCollateralManagement();
- clientCollateralManagement
-
.updateQuantity(clientCollateralManagement.getQuantity().add(loanCollateralManagement.getQuantity()));
-
loanCollateralManagement.setClientCollateralManagement(clientCollateralManagement);
- loanCollateralManagement.setIsReleased(true);
- }
- loan.updateLoanCollateral(loanCollateralManagements);
+ releaseAttachedCollaterals(loan);
}
if (!changes.isEmpty()) {
- this.loanRepositoryWrapper.saveAndFlush(loan);
+ loanRepositoryWrapper.saveAndFlush(loan);
final String noteText =
command.stringValueOfParameterNamed("note");
createNote(noteText, loan);
@@ -983,4 +951,15 @@ public class
LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
}
}
+ private void releaseAttachedCollaterals(Loan loan) {
+ Set<LoanCollateralManagement> loanCollateralManagements =
loan.getLoanCollateralManagements();
+ for (LoanCollateralManagement loanCollateralManagement :
loanCollateralManagements) {
+ ClientCollateralManagement clientCollateralManagement =
loanCollateralManagement.getClientCollateralManagement();
+
clientCollateralManagement.updateQuantity(clientCollateralManagement.getQuantity().add(loanCollateralManagement.getQuantity()));
+
loanCollateralManagement.setClientCollateralManagement(clientCollateralManagement);
+ loanCollateralManagement.setIsReleased(true);
+ }
+ loan.updateLoanCollateral(loanCollateralManagements);
+ }
+
}
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanAssembler.java
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanAssembler.java
index a62e25b8c..ebfce389e 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanAssembler.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanAssembler.java
@@ -22,9 +22,11 @@ import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import java.math.BigDecimal;
import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
@@ -96,8 +98,10 @@ import
org.apache.fineract.portfolio.loanproduct.domain.LoanProduct;
import
org.apache.fineract.portfolio.loanproduct.domain.LoanProductRelatedDetail;
import org.apache.fineract.portfolio.loanproduct.domain.LoanProductRepository;
import
org.apache.fineract.portfolio.loanproduct.exception.LoanProductNotFoundException;
+import org.apache.fineract.portfolio.loanproduct.service.LoanEnumerations;
import org.apache.fineract.portfolio.rate.domain.Rate;
import org.apache.fineract.portfolio.rate.service.RateAssembler;
+import org.apache.fineract.useradministration.domain.AppUser;
@RequiredArgsConstructor
public class LoanAssembler {
@@ -833,4 +837,49 @@ public class LoanAssembler {
return changes;
}
+
+ public Map<String, Object>
updateLoanApplicationAttributesForWithdrawal(Loan loan, JsonCommand command,
AppUser currentUser) {
+ final Map<String, Object> actualChanges = new LinkedHashMap<>();
+
+ LocalDate withdrawnOn =
command.localDateValueOfParameterNamed(Loan.WITHDRAWN_ON_DATE);
+ if (withdrawnOn == null) {
+ withdrawnOn =
command.localDateValueOfParameterNamed(Loan.EVENT_DATE);
+ }
+
+ loan.setWithdrawnOnDate(withdrawnOn);
+ loan.setWithdrawnBy(currentUser);
+ loan.setClosedOnDate(withdrawnOn);
+ loan.setClosedBy(currentUser);
+
+ 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.WITHDRAWN_ON_DATE, withdrawnOn.format(fmt));
+ actualChanges.put(Loan.CLOSED_ON_DATE, withdrawnOn.format(fmt));
+ return actualChanges;
+ }
+
+ public Map<String, Object>
updateLoanApplicationAttributesForRejection(Loan loan, JsonCommand command,
AppUser currentUser) {
+ final Map<String, Object> actualChanges = new LinkedHashMap<>();
+
+ final LocalDate rejectedOn =
command.localDateValueOfParameterNamed(Loan.REJECTED_ON_DATE);
+
+ loan.setRejectedOnDate(rejectedOn);
+ loan.setRejectedBy(currentUser);
+ loan.setClosedOnDate(rejectedOn);
+ loan.setClosedBy(currentUser);
+
+ 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;
+ }
}