FINERACT-1926: Asset externalisation logic enhancements and bugfixes
This commit is contained in:
committed by
Arnold Gálovics
parent
b1af8a3f83
commit
9698b6d5b3
-4
@@ -18,11 +18,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.apache.fineract.portfolio.loanaccount.service;
|
package org.apache.fineract.portfolio.loanaccount.service;
|
||||||
|
|
||||||
import org.apache.fineract.infrastructure.core.data.LoanIdAndExternalIdData;
|
|
||||||
|
|
||||||
public interface LoanReadPlatformServiceCommon {
|
public interface LoanReadPlatformServiceCommon {
|
||||||
|
|
||||||
LoanIdAndExternalIdData getTransferableLoanIdAndExternalId(Long loanId);
|
|
||||||
|
|
||||||
Long getLoanIdByLoanExternalId(String externalId);
|
Long getLoanIdByLoanExternalId(String externalId);
|
||||||
}
|
}
|
||||||
|
|||||||
+26
-29
@@ -53,36 +53,27 @@ public class LoanAccountOwnerTransferBusinessStep implements LoanCOBBusinessStep
|
|||||||
List<ExternalAssetOwnerTransfer> transferDataList = externalAssetOwnerTransferRepository.findAll(
|
List<ExternalAssetOwnerTransfer> transferDataList = externalAssetOwnerTransferRepository.findAll(
|
||||||
(root, query, criteriaBuilder) -> criteriaBuilder.and(criteriaBuilder.equal(root.get("loanId"), loanId),
|
(root, query, criteriaBuilder) -> criteriaBuilder.and(criteriaBuilder.equal(root.get("loanId"), loanId),
|
||||||
criteriaBuilder.equal(root.get("settlementDate"), settlementDate),
|
criteriaBuilder.equal(root.get("settlementDate"), settlementDate),
|
||||||
root.get("status").in(
|
root.get("status").in(List.of(ExternalTransferStatus.PENDING, ExternalTransferStatus.BUYBACK))),
|
||||||
List.of(ExternalTransferStatus.PENDING, ExternalTransferStatus.ACTIVE, ExternalTransferStatus.BUYBACK))),
|
|
||||||
Sort.by(Sort.Direction.ASC, "id"));
|
Sort.by(Sort.Direction.ASC, "id"));
|
||||||
int size = transferDataList.size();
|
int size = transferDataList.size();
|
||||||
|
|
||||||
if (size > 2) {
|
if (size == 2) {
|
||||||
throw new IllegalStateException(
|
|
||||||
String.format("Found too many owner transfers(%s) by the settlement date(%s)", size, settlementDate));
|
|
||||||
} else if (size == 2) {
|
|
||||||
ExternalTransferStatus firstTransferStatus = transferDataList.get(0).getStatus();
|
ExternalTransferStatus firstTransferStatus = transferDataList.get(0).getStatus();
|
||||||
ExternalTransferStatus secondTransferStatus = transferDataList.get(1).getStatus();
|
ExternalTransferStatus secondTransferStatus = transferDataList.get(1).getStatus();
|
||||||
|
|
||||||
if (!ExternalTransferStatus.BUYBACK.equals(secondTransferStatus)) {
|
if (!ExternalTransferStatus.PENDING.equals(firstTransferStatus)
|
||||||
throw new IllegalStateException(String.format("Illegal transfer found. Expected %s, found: %s",
|
|| !ExternalTransferStatus.BUYBACK.equals(secondTransferStatus)) {
|
||||||
ExternalTransferStatus.BUYBACK, secondTransferStatus));
|
throw new IllegalStateException(String.format("Illegal transfer found. Expected %s and %s, found: %s and %s",
|
||||||
}
|
ExternalTransferStatus.PENDING, ExternalTransferStatus.BUYBACK, firstTransferStatus, secondTransferStatus));
|
||||||
|
|
||||||
switch (firstTransferStatus) {
|
|
||||||
case PENDING -> handleSameDaySaleAndBuyback(settlementDate, transferDataList);
|
|
||||||
case ACTIVE -> handleBuyback(loan, settlementDate, transferDataList);
|
|
||||||
default -> throw new IllegalStateException(String.format("Illegal transfer found. Expected %s or %s, found: %s",
|
|
||||||
ExternalTransferStatus.PENDING, ExternalTransferStatus.ACTIVE, firstTransferStatus));
|
|
||||||
}
|
}
|
||||||
|
handleSameDaySaleAndBuyback(settlementDate, transferDataList);
|
||||||
} else if (size == 1) {
|
} else if (size == 1) {
|
||||||
ExternalAssetOwnerTransfer externalAssetOwnerTransfer = transferDataList.get(0);
|
ExternalAssetOwnerTransfer transfer = transferDataList.get(0);
|
||||||
if (!ExternalTransferStatus.PENDING.equals(externalAssetOwnerTransfer.getStatus())) {
|
if (ExternalTransferStatus.PENDING.equals(transfer.getStatus())) {
|
||||||
throw new IllegalStateException(String.format("Illegal transfer found. Expected %s, found: %s",
|
handleSale(loan, settlementDate, transfer);
|
||||||
ExternalTransferStatus.PENDING, externalAssetOwnerTransfer.getStatus()));
|
} else if (ExternalTransferStatus.BUYBACK.equals(transfer.getStatus())) {
|
||||||
|
handleBuyback(loan, settlementDate, transfer);
|
||||||
}
|
}
|
||||||
handleSale(loan, settlementDate, externalAssetOwnerTransfer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
log.debug("end processing loan ownership transfer business step for loan Id [{}]", loan.getId());
|
log.debug("end processing loan ownership transfer business step for loan Id [{}]", loan.getId());
|
||||||
@@ -95,20 +86,25 @@ public class LoanAccountOwnerTransferBusinessStep implements LoanCOBBusinessStep
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void handleBuyback(final Loan loan, final LocalDate settlementDate,
|
private void handleBuyback(final Loan loan, final LocalDate settlementDate,
|
||||||
final List<ExternalAssetOwnerTransfer> externalAssetOwnerTransferList) {
|
final ExternalAssetOwnerTransfer buybackExternalAssetOwnerTransfer) {
|
||||||
ExternalAssetOwnerTransfer newExternalAssetOwnerTransfer = buybackAsset(loan, settlementDate, externalAssetOwnerTransferList);
|
ExternalAssetOwnerTransfer activeExternalAssetOwnerTransfer = externalAssetOwnerTransferRepository
|
||||||
|
.findOne((root, query, criteriaBuilder) -> criteriaBuilder.and(criteriaBuilder.equal(root.get("loanId"), loan.getId()),
|
||||||
|
criteriaBuilder.equal(root.get("ownerId"), buybackExternalAssetOwnerTransfer.getOwnerId()),
|
||||||
|
criteriaBuilder.equal(root.get("status"), ExternalTransferStatus.ACTIVE),
|
||||||
|
criteriaBuilder.equal(root.get("effectiveDateTo"), FUTURE_DATE_9999_12_31)))
|
||||||
|
.orElseThrow();
|
||||||
|
ExternalAssetOwnerTransfer newExternalAssetOwnerTransfer = buybackAsset(loan, settlementDate, buybackExternalAssetOwnerTransfer,
|
||||||
|
activeExternalAssetOwnerTransfer);
|
||||||
// TODO: trigger asset loan transfer executed event
|
// TODO: trigger asset loan transfer executed event
|
||||||
}
|
}
|
||||||
|
|
||||||
private ExternalAssetOwnerTransfer buybackAsset(final Loan loan, final LocalDate settlementDate,
|
private ExternalAssetOwnerTransfer buybackAsset(final Loan loan, final LocalDate settlementDate,
|
||||||
List<ExternalAssetOwnerTransfer> externalAssetOwnerTransferList) {
|
ExternalAssetOwnerTransfer buybackExternalAssetOwnerTransfer, ExternalAssetOwnerTransfer activeExternalAssetOwnerTransfer) {
|
||||||
ExternalAssetOwnerTransfer saleExternalAssetOwnerTransfer = externalAssetOwnerTransferList.get(0);
|
activeExternalAssetOwnerTransfer.setEffectiveDateTo(settlementDate);
|
||||||
ExternalAssetOwnerTransfer buybackExternalAssetOwnerTransfer = externalAssetOwnerTransferList.get(1);
|
|
||||||
saleExternalAssetOwnerTransfer.setEffectiveDateTo(settlementDate);
|
|
||||||
buybackExternalAssetOwnerTransfer.setEffectiveDateTo(buybackExternalAssetOwnerTransfer.getEffectiveDateFrom());
|
buybackExternalAssetOwnerTransfer.setEffectiveDateTo(buybackExternalAssetOwnerTransfer.getEffectiveDateFrom());
|
||||||
externalAssetOwnerTransferRepository.save(saleExternalAssetOwnerTransfer);
|
externalAssetOwnerTransferRepository.save(activeExternalAssetOwnerTransfer);
|
||||||
buybackExternalAssetOwnerTransfer = externalAssetOwnerTransferRepository.save(buybackExternalAssetOwnerTransfer);
|
buybackExternalAssetOwnerTransfer = externalAssetOwnerTransferRepository.save(buybackExternalAssetOwnerTransfer);
|
||||||
externalAssetOwnerTransferLoanMappingRepository.deleteByLoanIdAndOwnerTransfer(loan.getId(), buybackExternalAssetOwnerTransfer);
|
externalAssetOwnerTransferLoanMappingRepository.deleteByLoanIdAndOwnerTransfer(loan.getId(), activeExternalAssetOwnerTransfer);
|
||||||
// TODO: create asset ownership accounting entries
|
// TODO: create asset ownership accounting entries
|
||||||
// TODO: create asset ownership transaction entries
|
// TODO: create asset ownership transaction entries
|
||||||
return buybackExternalAssetOwnerTransfer;
|
return buybackExternalAssetOwnerTransfer;
|
||||||
@@ -161,6 +157,7 @@ public class LoanAccountOwnerTransferBusinessStep implements LoanCOBBusinessStep
|
|||||||
final ExternalTransferSubStatus subStatus, final LocalDate effectiveDateFrom, final LocalDate effectiveDateTo) {
|
final ExternalTransferSubStatus subStatus, final LocalDate effectiveDateFrom, final LocalDate effectiveDateTo) {
|
||||||
ExternalAssetOwnerTransfer newExternalAssetOwnerTransfer = new ExternalAssetOwnerTransfer();
|
ExternalAssetOwnerTransfer newExternalAssetOwnerTransfer = new ExternalAssetOwnerTransfer();
|
||||||
newExternalAssetOwnerTransfer.setOwner(externalAssetOwnerTransfer.getOwner());
|
newExternalAssetOwnerTransfer.setOwner(externalAssetOwnerTransfer.getOwner());
|
||||||
|
newExternalAssetOwnerTransfer.setOwnerId(externalAssetOwnerTransfer.getOwnerId());
|
||||||
newExternalAssetOwnerTransfer.setExternalId(externalAssetOwnerTransfer.getExternalId());
|
newExternalAssetOwnerTransfer.setExternalId(externalAssetOwnerTransfer.getExternalId());
|
||||||
newExternalAssetOwnerTransfer.setStatus(status);
|
newExternalAssetOwnerTransfer.setStatus(status);
|
||||||
newExternalAssetOwnerTransfer.setSubStatus(subStatus);
|
newExternalAssetOwnerTransfer.setSubStatus(subStatus);
|
||||||
|
|||||||
+4
@@ -18,6 +18,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.apache.fineract.investor.domain;
|
package org.apache.fineract.investor.domain;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import org.apache.fineract.infrastructure.core.domain.ExternalId;
|
import org.apache.fineract.infrastructure.core.domain.ExternalId;
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
@@ -39,4 +41,6 @@ public interface ExternalAssetOwnerTransferRepository
|
|||||||
@Query("select e from ExternalAssetOwnerTransfer e where e.loanId = :loanId and e.id = (select max(ex.id) from ExternalAssetOwnerTransfer ex where ex.loanId = :loanId)")
|
@Query("select e from ExternalAssetOwnerTransfer e where e.loanId = :loanId and e.id = (select max(ex.id) from ExternalAssetOwnerTransfer ex where ex.loanId = :loanId)")
|
||||||
Optional<ExternalAssetOwnerTransfer> findLatestByLoanId(@Param("loanId") Long loanId);
|
Optional<ExternalAssetOwnerTransfer> findLatestByLoanId(@Param("loanId") Long loanId);
|
||||||
|
|
||||||
|
@Query("SELECT t FROM ExternalAssetOwnerTransfer t WHERE t.loanId = :loanId AND t.effectiveDateTo > :effectiveDate")
|
||||||
|
List<ExternalAssetOwnerTransfer> findEffectiveTransfers(@Param("loanId") Long loanId, @Param("effectiveDate") LocalDate effectiveDate);
|
||||||
}
|
}
|
||||||
|
|||||||
+104
-52
@@ -33,16 +33,17 @@ import java.util.Optional;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.apache.fineract.cob.data.LoanIdAndExternalIdAndStatus;
|
||||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||||
import org.apache.fineract.infrastructure.core.data.ApiParameterError;
|
import org.apache.fineract.infrastructure.core.data.ApiParameterError;
|
||||||
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
|
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
|
||||||
import org.apache.fineract.infrastructure.core.data.CommandProcessingResultBuilder;
|
import org.apache.fineract.infrastructure.core.data.CommandProcessingResultBuilder;
|
||||||
import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder;
|
import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder;
|
||||||
import org.apache.fineract.infrastructure.core.data.LoanIdAndExternalIdData;
|
|
||||||
import org.apache.fineract.infrastructure.core.domain.ExternalId;
|
import org.apache.fineract.infrastructure.core.domain.ExternalId;
|
||||||
import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException;
|
import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException;
|
||||||
import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
|
import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
|
||||||
import org.apache.fineract.infrastructure.core.serialization.JsonParserHelper;
|
import org.apache.fineract.infrastructure.core.serialization.JsonParserHelper;
|
||||||
|
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||||
import org.apache.fineract.infrastructure.core.service.ExternalIdFactory;
|
import org.apache.fineract.infrastructure.core.service.ExternalIdFactory;
|
||||||
import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil;
|
import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil;
|
||||||
import org.apache.fineract.investor.data.ExternalTransferRequestParameters;
|
import org.apache.fineract.investor.data.ExternalTransferRequestParameters;
|
||||||
@@ -53,7 +54,9 @@ import org.apache.fineract.investor.domain.ExternalAssetOwnerTransfer;
|
|||||||
import org.apache.fineract.investor.domain.ExternalAssetOwnerTransferLoanMappingRepository;
|
import org.apache.fineract.investor.domain.ExternalAssetOwnerTransferLoanMappingRepository;
|
||||||
import org.apache.fineract.investor.domain.ExternalAssetOwnerTransferRepository;
|
import org.apache.fineract.investor.domain.ExternalAssetOwnerTransferRepository;
|
||||||
import org.apache.fineract.investor.exception.ExternalAssetOwnerInitiateTransferException;
|
import org.apache.fineract.investor.exception.ExternalAssetOwnerInitiateTransferException;
|
||||||
import org.apache.fineract.portfolio.loanaccount.service.LoanReadPlatformServiceCommon;
|
import org.apache.fineract.portfolio.loanaccount.domain.LoanRepository;
|
||||||
|
import org.apache.fineract.portfolio.loanaccount.domain.LoanStatus;
|
||||||
|
import org.apache.fineract.portfolio.loanaccount.exception.LoanNotFoundException;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
@@ -61,36 +64,96 @@ import org.springframework.transaction.annotation.Transactional;
|
|||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class ExternalAssetOwnersWriteServiceImpl implements ExternalAssetOwnersWriteService {
|
public class ExternalAssetOwnersWriteServiceImpl implements ExternalAssetOwnersWriteService {
|
||||||
|
|
||||||
|
private static final LocalDate FUTURE_DATE_9999_12_31 = LocalDate.of(9999, 12, 31);
|
||||||
|
private static final List<LoanStatus> NON_CLOSED_LOAN_STATUSES = List.of(LoanStatus.SUBMITTED_AND_PENDING_APPROVAL, LoanStatus.APPROVED,
|
||||||
|
LoanStatus.ACTIVE, LoanStatus.TRANSFER_IN_PROGRESS, LoanStatus.TRANSFER_ON_HOLD);
|
||||||
|
private static final List<ExternalTransferStatus> BUYBACK_READY_STATUSES = List.of(ExternalTransferStatus.PENDING,
|
||||||
|
ExternalTransferStatus.ACTIVE);
|
||||||
private final ExternalAssetOwnerTransferRepository externalAssetOwnerTransferRepository;
|
private final ExternalAssetOwnerTransferRepository externalAssetOwnerTransferRepository;
|
||||||
private final ExternalAssetOwnerTransferLoanMappingRepository externalAssetOwnerTransferLoanMappingRepository;
|
private final ExternalAssetOwnerTransferLoanMappingRepository externalAssetOwnerTransferLoanMappingRepository;
|
||||||
private final ExternalAssetOwnerRepository externalAssetOwnerRepository;
|
private final ExternalAssetOwnerRepository externalAssetOwnerRepository;
|
||||||
private final FromJsonHelper fromApiJsonHelper;
|
private final FromJsonHelper fromApiJsonHelper;
|
||||||
private final LoanReadPlatformServiceCommon loanReadPlatformService;
|
private final LoanRepository loanRepository;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional
|
@Transactional
|
||||||
public CommandProcessingResult saleLoanByLoanId(JsonCommand command) {
|
public CommandProcessingResult saleLoanByLoanId(JsonCommand command) {
|
||||||
|
final JsonElement json = fromApiJsonHelper.parse(command.json());
|
||||||
Long loanId = command.getLoanId();
|
Long loanId = command.getLoanId();
|
||||||
LoanIdAndExternalIdData loanIdAndExternalId = loanReadPlatformService.getTransferableLoanIdAndExternalId(loanId);
|
LocalDate settlementDate = getSettlementDateFromJson(json);
|
||||||
validateLoanStatus(loanIdAndExternalId);
|
LoanIdAndExternalIdAndStatus loanIdAndExternalIdAndStatus = fetchLoanDetails(loanId);
|
||||||
ExternalAssetOwnerTransfer externalAssetOwnerTransfer = parseJson(loanId, command.json(), loanIdAndExternalId.getLoanExternalId(),
|
validateLoanStatus(loanIdAndExternalIdAndStatus);
|
||||||
ExternalTransferStatus.PENDING);
|
ExternalAssetOwnerTransfer externalAssetOwnerTransfer = createSaleTransfer(loanId, command.json(),
|
||||||
|
loanIdAndExternalIdAndStatus.getExternalId());
|
||||||
validateSale(externalAssetOwnerTransfer);
|
validateSale(externalAssetOwnerTransfer);
|
||||||
ExternalAssetOwnerTransfer savedExternalAssetOwnerTransfer = externalAssetOwnerTransferRepository.save(externalAssetOwnerTransfer);
|
externalAssetOwnerTransferRepository.save(externalAssetOwnerTransfer);
|
||||||
return buildResponseData(savedExternalAssetOwnerTransfer);
|
return buildResponseData(externalAssetOwnerTransfer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional
|
@Transactional
|
||||||
public CommandProcessingResult buybackLoanByLoanId(JsonCommand command) {
|
public CommandProcessingResult buybackLoanByLoanId(JsonCommand command) {
|
||||||
|
final JsonElement json = fromApiJsonHelper.parse(command.json());
|
||||||
Long loanId = command.getLoanId();
|
Long loanId = command.getLoanId();
|
||||||
LoanIdAndExternalIdData loanIdAndExternalId = loanReadPlatformService.getTransferableLoanIdAndExternalId(loanId);
|
LocalDate settlementDate = getSettlementDateFromJson(json);
|
||||||
validateLoanStatus(loanIdAndExternalId);
|
ExternalId externalId = getTransferExternalIdFromJson(json);
|
||||||
ExternalAssetOwnerTransfer externalAssetOwnerTransfer = parseJson(loanId, command.json(), loanIdAndExternalId.getLoanExternalId(),
|
LoanIdAndExternalIdAndStatus loanIdAndExternalIdAndStatus = fetchLoanDetails(loanId);
|
||||||
ExternalTransferStatus.BUYBACK);
|
validateLoanStatus(loanIdAndExternalIdAndStatus);
|
||||||
validateBuyBack(externalAssetOwnerTransfer);
|
validateSettlementDate(settlementDate);
|
||||||
ExternalAssetOwnerTransfer savedExternalAssetOwnerTransfer = externalAssetOwnerTransferRepository.save(externalAssetOwnerTransfer);
|
ExternalAssetOwnerTransfer effectiveTransfer = fetchAndValidateEffectiveTransferForBuyback(loanId, settlementDate);
|
||||||
return buildResponseData(savedExternalAssetOwnerTransfer);
|
ExternalAssetOwnerTransfer externalAssetOwnerTransfer = createBuybackTransfer(effectiveTransfer, settlementDate, externalId);
|
||||||
|
externalAssetOwnerTransferRepository.save(externalAssetOwnerTransfer);
|
||||||
|
return buildResponseData(externalAssetOwnerTransfer);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void validateEffectiveTransferForSale(final ExternalAssetOwnerTransfer externalAssetOwnerTransfer) {
|
||||||
|
List<ExternalAssetOwnerTransfer> effectiveTransfers = externalAssetOwnerTransferRepository
|
||||||
|
.findEffectiveTransfers(externalAssetOwnerTransfer.getLoanId(), externalAssetOwnerTransfer.getSettlementDate());
|
||||||
|
|
||||||
|
if (effectiveTransfers.size() > 0) {
|
||||||
|
throw new ExternalAssetOwnerInitiateTransferException("This loan cannot be sold, there is already an in progress transfer");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private ExternalAssetOwnerTransfer fetchAndValidateEffectiveTransferForBuyback(final Long loanId, final LocalDate settlementDate) {
|
||||||
|
List<ExternalAssetOwnerTransfer> effectiveTransfers = externalAssetOwnerTransferRepository.findEffectiveTransfers(loanId,
|
||||||
|
settlementDate);
|
||||||
|
|
||||||
|
if (effectiveTransfers.size() == 0) {
|
||||||
|
throw new ExternalAssetOwnerInitiateTransferException(
|
||||||
|
"This loan cannot be bought back, it is not owned by an external asset owner");
|
||||||
|
} else if (effectiveTransfers.size() == 2) {
|
||||||
|
throw new ExternalAssetOwnerInitiateTransferException(
|
||||||
|
"This loan cannot be bought back, external asset owner buyback transfer is already in progress");
|
||||||
|
} else if (!BUYBACK_READY_STATUSES.contains(effectiveTransfers.get(0).getStatus())) {
|
||||||
|
throw new ExternalAssetOwnerInitiateTransferException(
|
||||||
|
String.format("This loan cannot be bought back, effective transfer is not in right state: %s",
|
||||||
|
effectiveTransfers.get(0).getStatus()));
|
||||||
|
} else if (settlementDate.isBefore(effectiveTransfers.get(0).getSettlementDate())) {
|
||||||
|
throw new ExternalAssetOwnerInitiateTransferException(
|
||||||
|
String.format("This loan cannot be bought back, settlement date is earlier than effective transfer settlement date: %s",
|
||||||
|
effectiveTransfers.get(0).getSettlementDate()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return effectiveTransfers.get(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ExternalAssetOwnerTransfer createBuybackTransfer(ExternalAssetOwnerTransfer effectiveTransfer, LocalDate settlementDate,
|
||||||
|
ExternalId externalId) {
|
||||||
|
LocalDate effectiveDateFrom = DateUtils.getBusinessLocalDate();
|
||||||
|
|
||||||
|
ExternalAssetOwnerTransfer externalAssetOwnerTransfer = new ExternalAssetOwnerTransfer();
|
||||||
|
externalAssetOwnerTransfer.setExternalId(externalId);
|
||||||
|
externalAssetOwnerTransfer.setOwnerId(effectiveTransfer.getOwnerId());
|
||||||
|
externalAssetOwnerTransfer.setStatus(ExternalTransferStatus.BUYBACK);
|
||||||
|
externalAssetOwnerTransfer.setLoanId(effectiveTransfer.getLoanId());
|
||||||
|
externalAssetOwnerTransfer.setExternalLoanId(effectiveTransfer.getExternalLoanId());
|
||||||
|
externalAssetOwnerTransfer.setOwner(effectiveTransfer.getOwner());
|
||||||
|
externalAssetOwnerTransfer.setSettlementDate(settlementDate);
|
||||||
|
externalAssetOwnerTransfer.setEffectiveDateFrom(effectiveDateFrom);
|
||||||
|
externalAssetOwnerTransfer.setEffectiveDateTo(FUTURE_DATE_9999_12_31);
|
||||||
|
externalAssetOwnerTransfer.setPurchasePriceRatio(effectiveTransfer.getPurchasePriceRatio());
|
||||||
|
return externalAssetOwnerTransfer;
|
||||||
}
|
}
|
||||||
|
|
||||||
private CommandProcessingResult buildResponseData(ExternalAssetOwnerTransfer savedExternalAssetOwnerTransfer) {
|
private CommandProcessingResult buildResponseData(ExternalAssetOwnerTransfer savedExternalAssetOwnerTransfer) {
|
||||||
@@ -98,8 +161,7 @@ public class ExternalAssetOwnersWriteServiceImpl implements ExternalAssetOwnersW
|
|||||||
changes.put(ExternalTransferRequestParameters.SETTLEMENT_DATE, savedExternalAssetOwnerTransfer.getSettlementDate());
|
changes.put(ExternalTransferRequestParameters.SETTLEMENT_DATE, savedExternalAssetOwnerTransfer.getSettlementDate());
|
||||||
changes.put(ExternalTransferRequestParameters.OWNER_EXTERNAL_ID,
|
changes.put(ExternalTransferRequestParameters.OWNER_EXTERNAL_ID,
|
||||||
savedExternalAssetOwnerTransfer.getOwner().getExternalId().getValue());
|
savedExternalAssetOwnerTransfer.getOwner().getExternalId().getValue());
|
||||||
changes.put(ExternalTransferRequestParameters.TRANSFER_EXTERNAL_ID,
|
changes.put(ExternalTransferRequestParameters.TRANSFER_EXTERNAL_ID, savedExternalAssetOwnerTransfer.getExternalId().getValue());
|
||||||
savedExternalAssetOwnerTransfer.getOwner().getExternalId().getValue());
|
|
||||||
changes.put(ExternalTransferRequestParameters.PURCHASE_PRICE_RATIO, savedExternalAssetOwnerTransfer.getPurchasePriceRatio());
|
changes.put(ExternalTransferRequestParameters.PURCHASE_PRICE_RATIO, savedExternalAssetOwnerTransfer.getPurchasePriceRatio());
|
||||||
return new CommandProcessingResultBuilder().withEntityId(savedExternalAssetOwnerTransfer.getId())
|
return new CommandProcessingResultBuilder().withEntityId(savedExternalAssetOwnerTransfer.getId())
|
||||||
.withEntityExternalId(savedExternalAssetOwnerTransfer.getExternalId())
|
.withEntityExternalId(savedExternalAssetOwnerTransfer.getExternalId())
|
||||||
@@ -112,11 +174,7 @@ public class ExternalAssetOwnersWriteServiceImpl implements ExternalAssetOwnersW
|
|||||||
private void validateSale(ExternalAssetOwnerTransfer externalAssetOwnerTransfer) {
|
private void validateSale(ExternalAssetOwnerTransfer externalAssetOwnerTransfer) {
|
||||||
validateSettlementDate(externalAssetOwnerTransfer);
|
validateSettlementDate(externalAssetOwnerTransfer);
|
||||||
validateTransferStatusForSale(externalAssetOwnerTransfer);
|
validateTransferStatusForSale(externalAssetOwnerTransfer);
|
||||||
}
|
validateEffectiveTransferForSale(externalAssetOwnerTransfer);
|
||||||
|
|
||||||
private void validateBuyBack(ExternalAssetOwnerTransfer externalAssetOwnerTransfer) {
|
|
||||||
validateSettlementDate(externalAssetOwnerTransfer);
|
|
||||||
validateTransferStatusForBuyBack(externalAssetOwnerTransfer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void validateSettlementDate(ExternalAssetOwnerTransfer externalAssetOwnerTransfer) {
|
private void validateSettlementDate(ExternalAssetOwnerTransfer externalAssetOwnerTransfer) {
|
||||||
@@ -125,9 +183,14 @@ public class ExternalAssetOwnersWriteServiceImpl implements ExternalAssetOwnersW
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void validateLoanStatus(LoanIdAndExternalIdData loanIdAndExternalIdAndExternalId) {
|
private void validateSettlementDate(LocalDate settlementDate) {
|
||||||
if (Objects.isNull(loanIdAndExternalIdAndExternalId.getLoanId())
|
if (settlementDate.isBefore(ThreadLocalContextUtil.getBusinessDate())) {
|
||||||
&& Objects.isNull(loanIdAndExternalIdAndExternalId.getLoanExternalId())) {
|
throw new ExternalAssetOwnerInitiateTransferException("Settlement date cannot be in the past");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void validateLoanStatus(LoanIdAndExternalIdAndStatus entity) {
|
||||||
|
if (!NON_CLOSED_LOAN_STATUSES.contains(LoanStatus.fromInt(entity.getLoanStatus()))) {
|
||||||
throw new ExternalAssetOwnerInitiateTransferException("Loan is not in active status");
|
throw new ExternalAssetOwnerInitiateTransferException("Loan is not in active status");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -140,52 +203,35 @@ public class ExternalAssetOwnersWriteServiceImpl implements ExternalAssetOwnersW
|
|||||||
ExternalTransferStatus latestTransferStatus = latestTransfer.getStatus();
|
ExternalTransferStatus latestTransferStatus = latestTransfer.getStatus();
|
||||||
if (latestTransferStatus.equals(ExternalTransferStatus.PENDING)) {
|
if (latestTransferStatus.equals(ExternalTransferStatus.PENDING)) {
|
||||||
throw new ExternalAssetOwnerInitiateTransferException(
|
throw new ExternalAssetOwnerInitiateTransferException(
|
||||||
"External asset owner transfer is already in PENDING state for this loan.");
|
"External asset owner transfer is already in PENDING state for this loan");
|
||||||
} else if (latestTransferStatus.equals(ExternalTransferStatus.ACTIVE)) {
|
} else if (latestTransferStatus.equals(ExternalTransferStatus.ACTIVE)) {
|
||||||
throw new ExternalAssetOwnerInitiateTransferException(
|
throw new ExternalAssetOwnerInitiateTransferException(
|
||||||
"This loan cannot be sold, because it is owned by an external asset owner.");
|
"This loan cannot be sold, because it is owned by an external asset owner");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void validateTransferStatusForBuyBack(ExternalAssetOwnerTransfer externalAssetOwnerTransfer) {
|
private ExternalAssetOwnerTransfer createSaleTransfer(Long loanId, String apiRequestBodyAsJson, ExternalId externalLoanId) {
|
||||||
Optional<ExternalAssetOwnerTransfer> latestTransferOptional = externalAssetOwnerTransferRepository
|
|
||||||
.findLatestByLoanId(externalAssetOwnerTransfer.getLoanId());
|
|
||||||
if (latestTransferOptional.isEmpty()) {
|
|
||||||
throw new ExternalAssetOwnerInitiateTransferException(
|
|
||||||
"This loan cannot be bought back, because it is not owned by an external asset owner");
|
|
||||||
} else {
|
|
||||||
ExternalAssetOwnerTransfer latestTransfer = latestTransferOptional.get();
|
|
||||||
ExternalTransferStatus latestTransferStatus = latestTransfer.getStatus();
|
|
||||||
if (latestTransferStatus.equals(ExternalTransferStatus.BUYBACK)) {
|
|
||||||
throw new ExternalAssetOwnerInitiateTransferException(
|
|
||||||
"External asset owner transfer is already in BUYBACK state for this loan.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private ExternalAssetOwnerTransfer parseJson(Long loanId, String apiRequestBodyAsJson, ExternalId externalLoanId,
|
|
||||||
ExternalTransferStatus status) {
|
|
||||||
ExternalAssetOwnerTransfer externalAssetOwnerTransfer = new ExternalAssetOwnerTransfer();
|
ExternalAssetOwnerTransfer externalAssetOwnerTransfer = new ExternalAssetOwnerTransfer();
|
||||||
|
LocalDate effectiveFrom = ThreadLocalContextUtil.getBusinessDate();
|
||||||
validateRequestBody(apiRequestBodyAsJson);
|
validateSaleRequestBody(apiRequestBodyAsJson);
|
||||||
final JsonElement json = fromApiJsonHelper.parse(apiRequestBodyAsJson);
|
final JsonElement json = fromApiJsonHelper.parse(apiRequestBodyAsJson);
|
||||||
|
|
||||||
ExternalAssetOwner owner = getOwner(json);
|
ExternalAssetOwner owner = getOwner(json);
|
||||||
externalAssetOwnerTransfer.setOwnerId(owner.getId());
|
externalAssetOwnerTransfer.setOwnerId(owner.getId());
|
||||||
externalAssetOwnerTransfer.setOwner(owner);
|
externalAssetOwnerTransfer.setOwner(owner);
|
||||||
externalAssetOwnerTransfer.setExternalId(getTransferExternalIdFromJson(json));
|
externalAssetOwnerTransfer.setExternalId(getTransferExternalIdFromJson(json));
|
||||||
externalAssetOwnerTransfer.setStatus(status);
|
externalAssetOwnerTransfer.setStatus(ExternalTransferStatus.PENDING);
|
||||||
externalAssetOwnerTransfer.setPurchasePriceRatio(getPurchasePriceRatioFromJson(json));
|
externalAssetOwnerTransfer.setPurchasePriceRatio(getPurchasePriceRatioFromJson(json));
|
||||||
externalAssetOwnerTransfer.setSettlementDate(getSettlementDateFromJson(json));
|
externalAssetOwnerTransfer.setSettlementDate(getSettlementDateFromJson(json));
|
||||||
externalAssetOwnerTransfer.setEffectiveDateFrom(ThreadLocalContextUtil.getBusinessDate());
|
externalAssetOwnerTransfer.setEffectiveDateFrom(effectiveFrom);
|
||||||
externalAssetOwnerTransfer.setEffectiveDateTo(LocalDate.of(9999, 12, 31));
|
externalAssetOwnerTransfer.setEffectiveDateTo(FUTURE_DATE_9999_12_31);
|
||||||
externalAssetOwnerTransfer.setLoanId(loanId);
|
externalAssetOwnerTransfer.setLoanId(loanId);
|
||||||
externalAssetOwnerTransfer.setExternalLoanId(externalLoanId);
|
externalAssetOwnerTransfer.setExternalLoanId(externalLoanId);
|
||||||
return externalAssetOwnerTransfer;
|
return externalAssetOwnerTransfer;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void validateRequestBody(String apiRequestBodyAsJson) {
|
private void validateSaleRequestBody(String apiRequestBodyAsJson) {
|
||||||
final Set<String> requestParameters = new HashSet<>(
|
final Set<String> requestParameters = new HashSet<>(
|
||||||
Arrays.asList(ExternalTransferRequestParameters.SETTLEMENT_DATE, ExternalTransferRequestParameters.OWNER_EXTERNAL_ID,
|
Arrays.asList(ExternalTransferRequestParameters.SETTLEMENT_DATE, ExternalTransferRequestParameters.OWNER_EXTERNAL_ID,
|
||||||
ExternalTransferRequestParameters.TRANSFER_EXTERNAL_ID, ExternalTransferRequestParameters.PURCHASE_PRICE_RATIO,
|
ExternalTransferRequestParameters.TRANSFER_EXTERNAL_ID, ExternalTransferRequestParameters.PURCHASE_PRICE_RATIO,
|
||||||
@@ -248,4 +294,10 @@ public class ExternalAssetOwnersWriteServiceImpl implements ExternalAssetOwnersW
|
|||||||
externalAssetOwner.setExternalId(ExternalIdFactory.produce(externalId));
|
externalAssetOwner.setExternalId(ExternalIdFactory.produce(externalId));
|
||||||
return externalAssetOwnerRepository.saveAndFlush(externalAssetOwner);
|
return externalAssetOwnerRepository.saveAndFlush(externalAssetOwner);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private LoanIdAndExternalIdAndStatus fetchLoanDetails(Long loanId) {
|
||||||
|
Optional<LoanIdAndExternalIdAndStatus> loanIdAndExternalIdAndStatusResult = loanRepository
|
||||||
|
.findLoanIdAndExternalIdAndStatusByLoanId(loanId);
|
||||||
|
return loanIdAndExternalIdAndStatusResult.orElseThrow(() -> new LoanNotFoundException(loanId));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+90
-65
@@ -33,6 +33,7 @@ import java.time.ZoneId;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType;
|
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType;
|
||||||
import org.apache.fineract.infrastructure.core.domain.ActionContext;
|
import org.apache.fineract.infrastructure.core.domain.ActionContext;
|
||||||
import org.apache.fineract.infrastructure.core.domain.FineractPlatformTenant;
|
import org.apache.fineract.infrastructure.core.domain.FineractPlatformTenant;
|
||||||
@@ -80,7 +81,6 @@ public class LoanAccountOwnerTransferBusinessStepTest {
|
|||||||
// given
|
// given
|
||||||
final Loan loanForProcessing = Mockito.mock(Loan.class);
|
final Loan loanForProcessing = Mockito.mock(Loan.class);
|
||||||
Long loanId = 1L;
|
Long loanId = 1L;
|
||||||
LocalDate settlementDate = actualDate;
|
|
||||||
when(loanForProcessing.getId()).thenReturn(loanId);
|
when(loanForProcessing.getId()).thenReturn(loanId);
|
||||||
// when
|
// when
|
||||||
final Loan processedLoan = underTest.execute(loanForProcessing);
|
final Loan processedLoan = underTest.execute(loanForProcessing);
|
||||||
@@ -90,33 +90,13 @@ public class LoanAccountOwnerTransferBusinessStepTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void givenLoanTooManyTransfer() {
|
public void givenLoanTwoTransferButInvalidTransfers() {
|
||||||
// given
|
|
||||||
final Loan loanForProcessing = Mockito.mock(Loan.class);
|
|
||||||
Long loanId = 1L;
|
|
||||||
LocalDate settlementDate = actualDate;
|
|
||||||
when(loanForProcessing.getId()).thenReturn(loanId);
|
|
||||||
ExternalAssetOwnerTransfer firstResponseItem = Mockito.mock(ExternalAssetOwnerTransfer.class);
|
|
||||||
ExternalAssetOwnerTransfer secondResponseItem = Mockito.mock(ExternalAssetOwnerTransfer.class);
|
|
||||||
ExternalAssetOwnerTransfer thirdResponseItem = Mockito.mock(ExternalAssetOwnerTransfer.class);
|
|
||||||
List<ExternalAssetOwnerTransfer> response = List.of(firstResponseItem, secondResponseItem, thirdResponseItem);
|
|
||||||
when(externalAssetOwnerTransferRepository.findAll(any(Specification.class), eq(Sort.by(Sort.Direction.ASC, "id"))))
|
|
||||||
.thenReturn(response);
|
|
||||||
// when
|
|
||||||
IllegalStateException exception = assertThrows(IllegalStateException.class, () -> underTest.execute(loanForProcessing));
|
|
||||||
// then
|
|
||||||
assertEquals("Found too many owner transfers(3) by the settlement date(" + actualDate + ")", exception.getMessage());
|
|
||||||
verify(externalAssetOwnerTransferRepository, times(1)).findAll(any(Specification.class), eq(Sort.by(Sort.Direction.ASC, "id")));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void givenLoanTwoTransferButInvalidSecondTransfer() {
|
|
||||||
// given
|
// given
|
||||||
final Loan loanForProcessing = Mockito.mock(Loan.class);
|
final Loan loanForProcessing = Mockito.mock(Loan.class);
|
||||||
when(loanForProcessing.getId()).thenReturn(1L);
|
when(loanForProcessing.getId()).thenReturn(1L);
|
||||||
ExternalAssetOwnerTransfer firstResponseItem = Mockito.mock(ExternalAssetOwnerTransfer.class);
|
ExternalAssetOwnerTransfer firstResponseItem = Mockito.mock(ExternalAssetOwnerTransfer.class);
|
||||||
ExternalAssetOwnerTransfer secondResponseItem = Mockito.mock(ExternalAssetOwnerTransfer.class);
|
ExternalAssetOwnerTransfer secondResponseItem = Mockito.mock(ExternalAssetOwnerTransfer.class);
|
||||||
|
when(firstResponseItem.getStatus()).thenReturn(ExternalTransferStatus.PENDING);
|
||||||
when(secondResponseItem.getStatus()).thenReturn(ExternalTransferStatus.ACTIVE);
|
when(secondResponseItem.getStatus()).thenReturn(ExternalTransferStatus.ACTIVE);
|
||||||
List<ExternalAssetOwnerTransfer> response = List.of(firstResponseItem, secondResponseItem);
|
List<ExternalAssetOwnerTransfer> response = List.of(firstResponseItem, secondResponseItem);
|
||||||
when(externalAssetOwnerTransferRepository.findAll(any(Specification.class), eq(Sort.by(Sort.Direction.ASC, "id"))))
|
when(externalAssetOwnerTransferRepository.findAll(any(Specification.class), eq(Sort.by(Sort.Direction.ASC, "id"))))
|
||||||
@@ -124,26 +104,7 @@ public class LoanAccountOwnerTransferBusinessStepTest {
|
|||||||
// when
|
// when
|
||||||
IllegalStateException exception = assertThrows(IllegalStateException.class, () -> underTest.execute(loanForProcessing));
|
IllegalStateException exception = assertThrows(IllegalStateException.class, () -> underTest.execute(loanForProcessing));
|
||||||
// then
|
// then
|
||||||
assertEquals("Illegal transfer found. Expected BUYBACK, found: ACTIVE", exception.getMessage());
|
assertEquals("Illegal transfer found. Expected PENDING and BUYBACK, found: PENDING and ACTIVE", exception.getMessage());
|
||||||
verify(externalAssetOwnerTransferRepository, times(1)).findAll(any(Specification.class), eq(Sort.by(Sort.Direction.ASC, "id")));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void givenLoanTwoTransferButInvalidFirstTransfer() {
|
|
||||||
// given
|
|
||||||
final Loan loanForProcessing = Mockito.mock(Loan.class);
|
|
||||||
when(loanForProcessing.getId()).thenReturn(1L);
|
|
||||||
ExternalAssetOwnerTransfer firstResponseItem = Mockito.mock(ExternalAssetOwnerTransfer.class);
|
|
||||||
ExternalAssetOwnerTransfer secondResponseItem = Mockito.mock(ExternalAssetOwnerTransfer.class);
|
|
||||||
when(firstResponseItem.getStatus()).thenReturn(ExternalTransferStatus.BUYBACK);
|
|
||||||
when(secondResponseItem.getStatus()).thenReturn(ExternalTransferStatus.BUYBACK);
|
|
||||||
List<ExternalAssetOwnerTransfer> response = List.of(firstResponseItem, secondResponseItem);
|
|
||||||
when(externalAssetOwnerTransferRepository.findAll(any(Specification.class), eq(Sort.by(Sort.Direction.ASC, "id"))))
|
|
||||||
.thenReturn(response);
|
|
||||||
// when
|
|
||||||
IllegalStateException exception = assertThrows(IllegalStateException.class, () -> underTest.execute(loanForProcessing));
|
|
||||||
// then
|
|
||||||
assertEquals("Illegal transfer found. Expected PENDING or ACTIVE, found: BUYBACK", exception.getMessage());
|
|
||||||
verify(externalAssetOwnerTransferRepository, times(1)).findAll(any(Specification.class), eq(Sort.by(Sort.Direction.ASC, "id")));
|
verify(externalAssetOwnerTransferRepository, times(1)).findAll(any(Specification.class), eq(Sort.by(Sort.Direction.ASC, "id")));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -208,11 +169,12 @@ public class LoanAccountOwnerTransferBusinessStepTest {
|
|||||||
when(loanForProcessing.getId()).thenReturn(1L);
|
when(loanForProcessing.getId()).thenReturn(1L);
|
||||||
ExternalAssetOwnerTransfer firstResponseItem = Mockito.mock(ExternalAssetOwnerTransfer.class);
|
ExternalAssetOwnerTransfer firstResponseItem = Mockito.mock(ExternalAssetOwnerTransfer.class);
|
||||||
ExternalAssetOwnerTransfer secondResponseItem = Mockito.mock(ExternalAssetOwnerTransfer.class);
|
ExternalAssetOwnerTransfer secondResponseItem = Mockito.mock(ExternalAssetOwnerTransfer.class);
|
||||||
when(firstResponseItem.getStatus()).thenReturn(ExternalTransferStatus.ACTIVE);
|
when(firstResponseItem.getStatus()).thenReturn(ExternalTransferStatus.BUYBACK);
|
||||||
when(secondResponseItem.getStatus()).thenReturn(ExternalTransferStatus.BUYBACK);
|
when(firstResponseItem.getEffectiveDateFrom()).thenReturn(actualDate);
|
||||||
List<ExternalAssetOwnerTransfer> response = List.of(firstResponseItem, secondResponseItem);
|
List<ExternalAssetOwnerTransfer> response = List.of(firstResponseItem);
|
||||||
when(externalAssetOwnerTransferRepository.findAll(any(Specification.class), eq(Sort.by(Sort.Direction.ASC, "id"))))
|
when(externalAssetOwnerTransferRepository.findAll(any(Specification.class), eq(Sort.by(Sort.Direction.ASC, "id"))))
|
||||||
.thenReturn(response);
|
.thenReturn(response);
|
||||||
|
when(externalAssetOwnerTransferRepository.findOne(any(Specification.class))).thenReturn(Optional.of(secondResponseItem));
|
||||||
ArgumentCaptor<ExternalAssetOwnerTransfer> externalAssetOwnerTransferArgumentCaptor = ArgumentCaptor
|
ArgumentCaptor<ExternalAssetOwnerTransfer> externalAssetOwnerTransferArgumentCaptor = ArgumentCaptor
|
||||||
.forClass(ExternalAssetOwnerTransfer.class);
|
.forClass(ExternalAssetOwnerTransfer.class);
|
||||||
when(externalAssetOwnerTransferRepository.save(firstResponseItem)).thenReturn(firstResponseItem);
|
when(externalAssetOwnerTransferRepository.save(firstResponseItem)).thenReturn(firstResponseItem);
|
||||||
@@ -221,31 +183,14 @@ public class LoanAccountOwnerTransferBusinessStepTest {
|
|||||||
final Loan processedLoan = underTest.execute(loanForProcessing);
|
final Loan processedLoan = underTest.execute(loanForProcessing);
|
||||||
// then
|
// then
|
||||||
verify(externalAssetOwnerTransferRepository, times(1)).findAll(any(Specification.class), eq(Sort.by(Sort.Direction.ASC, "id")));
|
verify(externalAssetOwnerTransferRepository, times(1)).findAll(any(Specification.class), eq(Sort.by(Sort.Direction.ASC, "id")));
|
||||||
verify(firstResponseItem).setEffectiveDateTo(actualDate);
|
verify(firstResponseItem).setEffectiveDateTo(firstResponseItem.getEffectiveDateFrom());
|
||||||
verify(externalAssetOwnerTransferRepository, times(2)).save(externalAssetOwnerTransferArgumentCaptor.capture());
|
verify(externalAssetOwnerTransferRepository, times(2)).save(externalAssetOwnerTransferArgumentCaptor.capture());
|
||||||
verify(secondResponseItem).setEffectiveDateTo(secondResponseItem.getEffectiveDateFrom());
|
verify(secondResponseItem).setEffectiveDateTo(actualDate);
|
||||||
verify(externalAssetOwnerTransferLoanMappingRepository, times(1)).deleteByLoanIdAndOwnerTransfer(1L, secondResponseItem);
|
verify(externalAssetOwnerTransferLoanMappingRepository, times(1)).deleteByLoanIdAndOwnerTransfer(1L, secondResponseItem);
|
||||||
|
|
||||||
assertEquals(processedLoan, loanForProcessing);
|
assertEquals(processedLoan, loanForProcessing);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void givenLoanOneTransferButInvalidTransfer() {
|
|
||||||
// given
|
|
||||||
final Loan loanForProcessing = Mockito.mock(Loan.class);
|
|
||||||
when(loanForProcessing.getId()).thenReturn(1L);
|
|
||||||
ExternalAssetOwnerTransfer firstResponseItem = Mockito.mock(ExternalAssetOwnerTransfer.class);
|
|
||||||
when(firstResponseItem.getStatus()).thenReturn(ExternalTransferStatus.ACTIVE);
|
|
||||||
List<ExternalAssetOwnerTransfer> response = List.of(firstResponseItem);
|
|
||||||
when(externalAssetOwnerTransferRepository.findAll(any(Specification.class), eq(Sort.by(Sort.Direction.ASC, "id"))))
|
|
||||||
.thenReturn(response);
|
|
||||||
// when
|
|
||||||
IllegalStateException exception = assertThrows(IllegalStateException.class, () -> underTest.execute(loanForProcessing));
|
|
||||||
// then
|
|
||||||
assertEquals("Illegal transfer found. Expected PENDING, found: ACTIVE", exception.getMessage());
|
|
||||||
verify(externalAssetOwnerTransferRepository, times(1)).findAll(any(Specification.class), eq(Sort.by(Sort.Direction.ASC, "id")));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void givenLoanSale() {
|
public void givenLoanSale() {
|
||||||
// given
|
// given
|
||||||
@@ -291,6 +236,86 @@ public class LoanAccountOwnerTransferBusinessStepTest {
|
|||||||
assertEquals(processedLoan, loanForProcessing);
|
assertEquals(processedLoan, loanForProcessing);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenLoanSaleButBalanceIsZero() {
|
||||||
|
// given
|
||||||
|
final Loan loanForProcessing = Mockito.mock(Loan.class);
|
||||||
|
when(loanForProcessing.getId()).thenReturn(1L);
|
||||||
|
ExternalAssetOwnerTransfer firstResponseItem = Mockito.mock(ExternalAssetOwnerTransfer.class);
|
||||||
|
when(firstResponseItem.getStatus()).thenReturn(ExternalTransferStatus.PENDING);
|
||||||
|
List<ExternalAssetOwnerTransfer> response = List.of(firstResponseItem);
|
||||||
|
when(externalAssetOwnerTransferRepository.findAll(any(Specification.class), eq(Sort.by(Sort.Direction.ASC, "id"))))
|
||||||
|
.thenReturn(response);
|
||||||
|
ArgumentCaptor<ExternalAssetOwnerTransfer> externalAssetOwnerTransferArgumentCaptor = ArgumentCaptor
|
||||||
|
.forClass(ExternalAssetOwnerTransfer.class);
|
||||||
|
ExternalAssetOwnerTransfer newTransfer = Mockito.mock(ExternalAssetOwnerTransfer.class);
|
||||||
|
when(externalAssetOwnerTransferRepository.save(any())).thenReturn(firstResponseItem).thenReturn(newTransfer);
|
||||||
|
LoanSummary loanSummary = Mockito.mock(LoanSummary.class);
|
||||||
|
when(loanForProcessing.getLoanSummary()).thenReturn(loanSummary);
|
||||||
|
when(loanSummary.getTotalOutstanding()).thenReturn(BigDecimal.ZERO);
|
||||||
|
when(loanForProcessing.getTotalOverpaid()).thenReturn(BigDecimal.ZERO);
|
||||||
|
// when
|
||||||
|
final Loan processedLoan = underTest.execute(loanForProcessing);
|
||||||
|
// then
|
||||||
|
verify(externalAssetOwnerTransferRepository, times(1)).findAll(any(Specification.class), eq(Sort.by(Sort.Direction.ASC, "id")));
|
||||||
|
verify(firstResponseItem).setEffectiveDateTo(actualDate);
|
||||||
|
verify(externalAssetOwnerTransferRepository, times(2)).save(externalAssetOwnerTransferArgumentCaptor.capture());
|
||||||
|
|
||||||
|
assertEquals(externalAssetOwnerTransferArgumentCaptor.getAllValues().get(0).getOwner(),
|
||||||
|
externalAssetOwnerTransferArgumentCaptor.getAllValues().get(1).getOwner());
|
||||||
|
assertEquals(externalAssetOwnerTransferArgumentCaptor.getAllValues().get(0).getExternalId(),
|
||||||
|
externalAssetOwnerTransferArgumentCaptor.getAllValues().get(1).getExternalId());
|
||||||
|
assertEquals(ExternalTransferStatus.DECLINED, externalAssetOwnerTransferArgumentCaptor.getAllValues().get(1).getStatus());
|
||||||
|
assertEquals(actualDate, externalAssetOwnerTransferArgumentCaptor.getAllValues().get(1).getSettlementDate());
|
||||||
|
assertEquals(externalAssetOwnerTransferArgumentCaptor.getAllValues().get(0).getLoanId(),
|
||||||
|
externalAssetOwnerTransferArgumentCaptor.getAllValues().get(1).getLoanId());
|
||||||
|
assertEquals(externalAssetOwnerTransferArgumentCaptor.getAllValues().get(0).getPurchasePriceRatio(),
|
||||||
|
externalAssetOwnerTransferArgumentCaptor.getAllValues().get(1).getPurchasePriceRatio());
|
||||||
|
assertEquals(actualDate, externalAssetOwnerTransferArgumentCaptor.getAllValues().get(1).getEffectiveDateFrom());
|
||||||
|
assertEquals(actualDate, externalAssetOwnerTransferArgumentCaptor.getAllValues().get(1).getEffectiveDateTo());
|
||||||
|
assertEquals(processedLoan, loanForProcessing);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenLoanSaleButBalanceIsNegative() {
|
||||||
|
// given
|
||||||
|
final Loan loanForProcessing = Mockito.mock(Loan.class);
|
||||||
|
when(loanForProcessing.getId()).thenReturn(1L);
|
||||||
|
ExternalAssetOwnerTransfer firstResponseItem = Mockito.mock(ExternalAssetOwnerTransfer.class);
|
||||||
|
when(firstResponseItem.getStatus()).thenReturn(ExternalTransferStatus.PENDING);
|
||||||
|
List<ExternalAssetOwnerTransfer> response = List.of(firstResponseItem);
|
||||||
|
when(externalAssetOwnerTransferRepository.findAll(any(Specification.class), eq(Sort.by(Sort.Direction.ASC, "id"))))
|
||||||
|
.thenReturn(response);
|
||||||
|
ArgumentCaptor<ExternalAssetOwnerTransfer> externalAssetOwnerTransferArgumentCaptor = ArgumentCaptor
|
||||||
|
.forClass(ExternalAssetOwnerTransfer.class);
|
||||||
|
ExternalAssetOwnerTransfer newTransfer = Mockito.mock(ExternalAssetOwnerTransfer.class);
|
||||||
|
when(externalAssetOwnerTransferRepository.save(any())).thenReturn(firstResponseItem).thenReturn(newTransfer);
|
||||||
|
LoanSummary loanSummary = Mockito.mock(LoanSummary.class);
|
||||||
|
when(loanForProcessing.getLoanSummary()).thenReturn(loanSummary);
|
||||||
|
when(loanSummary.getTotalOutstanding()).thenReturn(BigDecimal.ONE.negate());
|
||||||
|
when(loanForProcessing.getTotalOverpaid()).thenReturn(BigDecimal.ONE.negate());
|
||||||
|
// when
|
||||||
|
final Loan processedLoan = underTest.execute(loanForProcessing);
|
||||||
|
// then
|
||||||
|
verify(externalAssetOwnerTransferRepository, times(1)).findAll(any(Specification.class), eq(Sort.by(Sort.Direction.ASC, "id")));
|
||||||
|
verify(firstResponseItem).setEffectiveDateTo(actualDate);
|
||||||
|
verify(externalAssetOwnerTransferRepository, times(2)).save(externalAssetOwnerTransferArgumentCaptor.capture());
|
||||||
|
|
||||||
|
assertEquals(externalAssetOwnerTransferArgumentCaptor.getAllValues().get(0).getOwner(),
|
||||||
|
externalAssetOwnerTransferArgumentCaptor.getAllValues().get(1).getOwner());
|
||||||
|
assertEquals(externalAssetOwnerTransferArgumentCaptor.getAllValues().get(0).getExternalId(),
|
||||||
|
externalAssetOwnerTransferArgumentCaptor.getAllValues().get(1).getExternalId());
|
||||||
|
assertEquals(ExternalTransferStatus.DECLINED, externalAssetOwnerTransferArgumentCaptor.getAllValues().get(1).getStatus());
|
||||||
|
assertEquals(actualDate, externalAssetOwnerTransferArgumentCaptor.getAllValues().get(1).getSettlementDate());
|
||||||
|
assertEquals(externalAssetOwnerTransferArgumentCaptor.getAllValues().get(0).getLoanId(),
|
||||||
|
externalAssetOwnerTransferArgumentCaptor.getAllValues().get(1).getLoanId());
|
||||||
|
assertEquals(externalAssetOwnerTransferArgumentCaptor.getAllValues().get(0).getPurchasePriceRatio(),
|
||||||
|
externalAssetOwnerTransferArgumentCaptor.getAllValues().get(1).getPurchasePriceRatio());
|
||||||
|
assertEquals(actualDate, externalAssetOwnerTransferArgumentCaptor.getAllValues().get(1).getEffectiveDateFrom());
|
||||||
|
assertEquals(actualDate, externalAssetOwnerTransferArgumentCaptor.getAllValues().get(1).getEffectiveDateTo());
|
||||||
|
assertEquals(processedLoan, loanForProcessing);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetEnumStyledNameSuccessScenario() {
|
public void testGetEnumStyledNameSuccessScenario() {
|
||||||
final String actualEnumName = underTest.getEnumStyledName();
|
final String actualEnumName = underTest.getEnumStyledName();
|
||||||
|
|||||||
+7
-6
@@ -16,16 +16,17 @@
|
|||||||
* specific language governing permissions and limitations
|
* specific language governing permissions and limitations
|
||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
package org.apache.fineract.infrastructure.core.data;
|
package org.apache.fineract.cob.data;
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Data;
|
import lombok.Getter;
|
||||||
import org.apache.fineract.infrastructure.core.domain.ExternalId;
|
import org.apache.fineract.infrastructure.core.domain.ExternalId;
|
||||||
|
|
||||||
@Data
|
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public class LoanIdAndExternalIdData {
|
@Getter
|
||||||
|
public class LoanIdAndExternalIdAndStatus {
|
||||||
|
|
||||||
private Long loanId;
|
Long id;
|
||||||
private ExternalId loanExternalId;
|
ExternalId externalId;
|
||||||
|
Integer loanStatus;
|
||||||
}
|
}
|
||||||
+4
-4
@@ -24,6 +24,7 @@ import java.util.List;
|
|||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import org.apache.fineract.cob.data.LoanCOBParameter;
|
import org.apache.fineract.cob.data.LoanCOBParameter;
|
||||||
import org.apache.fineract.cob.data.LoanIdAndExternalIdAndAccountNo;
|
import org.apache.fineract.cob.data.LoanIdAndExternalIdAndAccountNo;
|
||||||
|
import org.apache.fineract.cob.data.LoanIdAndExternalIdAndStatus;
|
||||||
import org.apache.fineract.cob.data.LoanIdAndLastClosedBusinessDate;
|
import org.apache.fineract.cob.data.LoanIdAndLastClosedBusinessDate;
|
||||||
import org.apache.fineract.infrastructure.core.domain.ExternalId;
|
import org.apache.fineract.infrastructure.core.domain.ExternalId;
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
@@ -86,8 +87,7 @@ public interface LoanRepository extends JpaRepository<Loan, Long>, JpaSpecificat
|
|||||||
|
|
||||||
String FIND_BY_ACCOUNT_NUMBER = "select loan from Loan loan where loan.accountNumber = :accountNumber";
|
String FIND_BY_ACCOUNT_NUMBER = "select loan from Loan loan where loan.accountNumber = :accountNumber";
|
||||||
|
|
||||||
String GET_NON_CLOSED_LOAN_BY_LOAN_ID = "select loan from Loan loan where loan.id = :loanId and loan.loanStatus in (100,200,300,"
|
String FIND_LOAN_ID_AND_EXTERNAL_ID_AND_STATUS = "select new org.apache.fineract.cob.data.LoanIdAndExternalIdAndStatus(loan.id, loan.externalId, loan.loanStatus) from Loan loan where loan.id = :loanId";
|
||||||
+ "303,304)";
|
|
||||||
|
|
||||||
String EXISTS_NON_CLOSED_BY_EXTERNAL_LOAN_ID = "select case when (count (loan) > 0) then 'true' else 'false' end from Loan loan where loan.externalId = :externalLoanId and loan.loanStatus in (100,200,300,303,304)";
|
String EXISTS_NON_CLOSED_BY_EXTERNAL_LOAN_ID = "select case when (count (loan) > 0) then 'true' else 'false' end from Loan loan where loan.externalId = :externalLoanId and loan.loanStatus in (100,200,300,303,304)";
|
||||||
|
|
||||||
@@ -197,8 +197,8 @@ public interface LoanRepository extends JpaRepository<Loan, Long>, JpaSpecificat
|
|||||||
@Query(FIND_BY_ACCOUNT_NUMBER)
|
@Query(FIND_BY_ACCOUNT_NUMBER)
|
||||||
Loan findLoanAccountByAccountNumber(@Param("accountNumber") String accountNumber);
|
Loan findLoanAccountByAccountNumber(@Param("accountNumber") String accountNumber);
|
||||||
|
|
||||||
@Query(GET_NON_CLOSED_LOAN_BY_LOAN_ID)
|
@Query(FIND_LOAN_ID_AND_EXTERNAL_ID_AND_STATUS)
|
||||||
Optional<Loan> getNonClosedLoanIdAndExternalIdByLoanId(@Param("loanId") Long loanId);
|
Optional<LoanIdAndExternalIdAndStatus> findLoanIdAndExternalIdAndStatusByLoanId(@Param("loanId") Long loanId);
|
||||||
|
|
||||||
@Query(EXISTS_NON_CLOSED_BY_EXTERNAL_LOAN_ID)
|
@Query(EXISTS_NON_CLOSED_BY_EXTERNAL_LOAN_ID)
|
||||||
boolean existsNonClosedLoanByExternalLoanId(@Param("externalLoanId") ExternalId externalLoanId);
|
boolean existsNonClosedLoanByExternalLoanId(@Param("externalLoanId") ExternalId externalLoanId);
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
/**
|
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one
|
|
||||||
* or more contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. The ASF licenses this file
|
|
||||||
* to you under the Apache License, Version 2.0 (the
|
|
||||||
* "License"); you may not use this file except in compliance
|
|
||||||
* with the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing,
|
|
||||||
* software distributed under the License is distributed on an
|
|
||||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
||||||
* KIND, either express or implied. See the License for the
|
|
||||||
* specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*/
|
|
||||||
package org.apache.fineract.cob.data;
|
|
||||||
|
|
||||||
import org.apache.fineract.infrastructure.core.domain.ExternalId;
|
|
||||||
|
|
||||||
public interface LoanIdAndExternalId {
|
|
||||||
|
|
||||||
Long getId();
|
|
||||||
|
|
||||||
ExternalId getExternalId();
|
|
||||||
}
|
|
||||||
-7
@@ -24,7 +24,6 @@ import java.util.ArrayList;
|
|||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.apache.fineract.infrastructure.core.config.FineractProperties;
|
import org.apache.fineract.infrastructure.core.config.FineractProperties;
|
||||||
import org.apache.fineract.infrastructure.core.domain.ExternalId;
|
import org.apache.fineract.infrastructure.core.domain.ExternalId;
|
||||||
@@ -264,10 +263,4 @@ public class LoanRepositoryWrapper {
|
|||||||
return repository.findLoanIdByStatusId(statusId);
|
return repository.findLoanIdByStatusId(statusId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Optional<Loan> getNonClosedLoanIdAndExternalIdByLoanId(Long loanId) {
|
|
||||||
if (repository.findById(loanId).isEmpty()) {
|
|
||||||
throw new LoanNotFoundException(loanId);
|
|
||||||
}
|
|
||||||
return repository.getNonClosedLoanIdAndExternalIdByLoanId(loanId);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
-8
@@ -42,7 +42,6 @@ import org.apache.fineract.infrastructure.codes.data.CodeValueData;
|
|||||||
import org.apache.fineract.infrastructure.codes.service.CodeValueReadPlatformService;
|
import org.apache.fineract.infrastructure.codes.service.CodeValueReadPlatformService;
|
||||||
import org.apache.fineract.infrastructure.configuration.domain.ConfigurationDomainService;
|
import org.apache.fineract.infrastructure.configuration.domain.ConfigurationDomainService;
|
||||||
import org.apache.fineract.infrastructure.core.data.EnumOptionData;
|
import org.apache.fineract.infrastructure.core.data.EnumOptionData;
|
||||||
import org.apache.fineract.infrastructure.core.data.LoanIdAndExternalIdData;
|
|
||||||
import org.apache.fineract.infrastructure.core.domain.ExternalId;
|
import org.apache.fineract.infrastructure.core.domain.ExternalId;
|
||||||
import org.apache.fineract.infrastructure.core.domain.JdbcSupport;
|
import org.apache.fineract.infrastructure.core.domain.JdbcSupport;
|
||||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||||
@@ -593,13 +592,6 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService, Loa
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public LoanIdAndExternalIdData getTransferableLoanIdAndExternalId(Long loanId) {
|
|
||||||
Optional<Loan> loan = loanRepositoryWrapper.getNonClosedLoanIdAndExternalIdByLoanId(loanId);
|
|
||||||
return loan.map(value -> new LoanIdAndExternalIdData(value.getId(), value.getExternalId()))
|
|
||||||
.orElseGet(() -> new LoanIdAndExternalIdData(null, null));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Long getLoanIdByLoanExternalId(String externalId) {
|
public Long getLoanIdByLoanExternalId(String externalId) {
|
||||||
ExternalId loanExternalId = ExternalIdFactory.produce(externalId);
|
ExternalId loanExternalId = ExternalIdFactory.produce(externalId);
|
||||||
|
|||||||
+3
@@ -43,12 +43,15 @@ import org.apache.fineract.integrationtests.common.loans.LoanApplicationTestBuil
|
|||||||
import org.apache.fineract.integrationtests.common.loans.LoanCOBCatchUpHelper;
|
import org.apache.fineract.integrationtests.common.loans.LoanCOBCatchUpHelper;
|
||||||
import org.apache.fineract.integrationtests.common.loans.LoanProductTestBuilder;
|
import org.apache.fineract.integrationtests.common.loans.LoanProductTestBuilder;
|
||||||
import org.apache.fineract.integrationtests.common.loans.LoanStatusChecker;
|
import org.apache.fineract.integrationtests.common.loans.LoanStatusChecker;
|
||||||
|
import org.apache.fineract.integrationtests.common.loans.LoanTestLifecycleExtension;
|
||||||
import org.apache.fineract.integrationtests.common.loans.LoanTransactionHelper;
|
import org.apache.fineract.integrationtests.common.loans.LoanTransactionHelper;
|
||||||
import org.apache.fineract.integrationtests.inlinecob.InlineLoanCOBHelper;
|
import org.apache.fineract.integrationtests.inlinecob.InlineLoanCOBHelper;
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
|
|
||||||
|
@ExtendWith(LoanTestLifecycleExtension.class)
|
||||||
public class LoanCOBAccountLockCatchupInlineCOBTest {
|
public class LoanCOBAccountLockCatchupInlineCOBTest {
|
||||||
|
|
||||||
private ResponseSpecification responseSpec;
|
private ResponseSpecification responseSpec;
|
||||||
|
|||||||
+44
@@ -0,0 +1,44 @@
|
|||||||
|
/**
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package org.apache.fineract.integrationtests.common;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import org.apache.fineract.client.models.BusinessStep;
|
||||||
|
import org.apache.fineract.client.models.UpdateBusinessStepConfigRequest;
|
||||||
|
import org.apache.fineract.integrationtests.client.IntegrationTest;
|
||||||
|
|
||||||
|
public class BusinessStepHelper extends IntegrationTest {
|
||||||
|
|
||||||
|
public BusinessStepHelper() {}
|
||||||
|
|
||||||
|
public void updateSteps(String jobName, String... steps) {
|
||||||
|
long order = 0;
|
||||||
|
List<BusinessStep> stepList = new ArrayList<>();
|
||||||
|
for (String step : steps) {
|
||||||
|
order++;
|
||||||
|
BusinessStep businessStep = new BusinessStep();
|
||||||
|
businessStep.stepName(step);
|
||||||
|
businessStep.setOrder(order);
|
||||||
|
stepList.add(businessStep);
|
||||||
|
}
|
||||||
|
ok(fineract().businessStepConfiguration.updateJobBusinessStepConfig(jobName,
|
||||||
|
new UpdateBusinessStepConfigRequest().businessSteps(stepList)));
|
||||||
|
}
|
||||||
|
}
|
||||||
+49
@@ -0,0 +1,49 @@
|
|||||||
|
/**
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package org.apache.fineract.integrationtests.common;
|
||||||
|
|
||||||
|
import org.apache.fineract.client.models.PageExternalTransferData;
|
||||||
|
import org.apache.fineract.client.models.PostInitiateTransferRequest;
|
||||||
|
import org.apache.fineract.client.models.PostInitiateTransferResponse;
|
||||||
|
import org.apache.fineract.integrationtests.client.IntegrationTest;
|
||||||
|
|
||||||
|
public class ExternalAssetOwnerHelper extends IntegrationTest {
|
||||||
|
|
||||||
|
public ExternalAssetOwnerHelper() {}
|
||||||
|
|
||||||
|
public PostInitiateTransferResponse initiateTransferByLoanId(Long loanId, String command, PostInitiateTransferRequest request) {
|
||||||
|
return ok(fineract().externalAssetOwners.transferRequestWithLoanId(loanId, request, command));
|
||||||
|
}
|
||||||
|
|
||||||
|
public PageExternalTransferData retrieveTransferByTransferExternalId(String transferExternalId) {
|
||||||
|
return ok(fineract().externalAssetOwners.getTransfer1(transferExternalId, null, null, 0, 100));
|
||||||
|
}
|
||||||
|
|
||||||
|
public PageExternalTransferData retrieveTransferByLoanExternalId(String loanExternalId) {
|
||||||
|
return ok(fineract().externalAssetOwners.getTransfer1(null, null, loanExternalId, 0, 100));
|
||||||
|
}
|
||||||
|
|
||||||
|
public PageExternalTransferData retrieveTransferByLoanId(Long loanId) {
|
||||||
|
return ok(fineract().externalAssetOwners.getTransfer1(null, loanId, null, 0, 100));
|
||||||
|
}
|
||||||
|
|
||||||
|
public PageExternalTransferData retrieveTransferByLoanId(Long loanId, int offset, int limit) {
|
||||||
|
return ok(fineract().externalAssetOwners.getTransfer1(null, loanId, null, offset, limit));
|
||||||
|
}
|
||||||
|
}
|
||||||
-62
@@ -1,62 +0,0 @@
|
|||||||
/**
|
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one
|
|
||||||
* or more contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. The ASF licenses this file
|
|
||||||
* to you under the Apache License, Version 2.0 (the
|
|
||||||
* "License"); you may not use this file except in compliance
|
|
||||||
* with the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing,
|
|
||||||
* software distributed under the License is distributed on an
|
|
||||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
||||||
* KIND, either express or implied. See the License for the
|
|
||||||
* specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*/
|
|
||||||
package org.apache.fineract.integrationtests.investor.externalassetowner;
|
|
||||||
|
|
||||||
import io.restassured.specification.RequestSpecification;
|
|
||||||
import io.restassured.specification.ResponseSpecification;
|
|
||||||
import org.apache.fineract.client.models.PageExternalTransferData;
|
|
||||||
import org.apache.fineract.integrationtests.client.IntegrationTest;
|
|
||||||
import org.apache.fineract.integrationtests.common.Utils;
|
|
||||||
|
|
||||||
public class ExternalAssetOwnerHelper extends IntegrationTest {
|
|
||||||
|
|
||||||
private final RequestSpecification requestSpec;
|
|
||||||
private final ResponseSpecification responseSpec;
|
|
||||||
|
|
||||||
public ExternalAssetOwnerHelper(final RequestSpecification requestSpec, final ResponseSpecification responseSpec) {
|
|
||||||
this.requestSpec = requestSpec;
|
|
||||||
this.responseSpec = responseSpec;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String initiateTransferByLoanId(Long loanId, String command, String json) {
|
|
||||||
final String INITIATE_TRANSFER_URL = "/fineract-provider/api/v1/external-asset-owners/transfers/loans/" + loanId + "?"
|
|
||||||
+ Utils.TENANT_IDENTIFIER + "&command=" + command;
|
|
||||||
return Utils.performServerPost(requestSpec, responseSpec, INITIATE_TRANSFER_URL, json);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String initiateTransferByLoanExternalId(String loanExternalId, String command, String json) {
|
|
||||||
final String INITIATE_TRANSFER_URL = "/fineract-provider/api/v1/external-asset-owners/transfers/loans/external-id/" + loanExternalId
|
|
||||||
+ "?" + Utils.TENANT_IDENTIFIER + "&command=" + command;
|
|
||||||
return Utils.performServerPost(requestSpec, responseSpec, INITIATE_TRANSFER_URL, json);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String retrieveTransferByTransferExternalId(String transferExternalId) {
|
|
||||||
final String RETRIEVE_TRANSFER_URL = "/fineract-provider/api/v1/external-asset-owners/transfers?" + Utils.TENANT_IDENTIFIER
|
|
||||||
+ "&transferExternalId=" + transferExternalId;
|
|
||||||
return Utils.performServerGet(requestSpec, responseSpec, RETRIEVE_TRANSFER_URL);
|
|
||||||
}
|
|
||||||
|
|
||||||
public PageExternalTransferData retrieveTransferByLoanId(Long loanId) {
|
|
||||||
return ok(fineract().externalAssetOwners.getTransfer1(null, loanId, null, 0, 100));
|
|
||||||
}
|
|
||||||
|
|
||||||
public PageExternalTransferData retrieveTransferByLoanId(Long loanId, int offset, int limit) {
|
|
||||||
return ok(fineract().externalAssetOwners.getTransfer1(null, loanId, null, offset, limit));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+246
-79
@@ -19,65 +19,79 @@
|
|||||||
package org.apache.fineract.integrationtests.investor.externalassetowner;
|
package org.apache.fineract.integrationtests.investor.externalassetowner;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
|
||||||
import com.google.gson.reflect.TypeToken;
|
|
||||||
import io.restassured.builder.RequestSpecBuilder;
|
import io.restassured.builder.RequestSpecBuilder;
|
||||||
import io.restassured.builder.ResponseSpecBuilder;
|
import io.restassured.builder.ResponseSpecBuilder;
|
||||||
import io.restassured.http.ContentType;
|
import io.restassured.http.ContentType;
|
||||||
import io.restassured.path.json.JsonPath;
|
import io.restassured.path.json.JsonPath;
|
||||||
import io.restassured.specification.RequestSpecification;
|
import io.restassured.specification.RequestSpecification;
|
||||||
import io.restassured.specification.ResponseSpecification;
|
import io.restassured.specification.ResponseSpecification;
|
||||||
import java.lang.reflect.Type;
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.UUID;
|
||||||
import org.apache.fineract.client.models.ExternalTransferData;
|
import org.apache.fineract.client.models.ExternalTransferData;
|
||||||
import org.apache.fineract.client.models.PageExternalTransferData;
|
import org.apache.fineract.client.models.PageExternalTransferData;
|
||||||
|
import org.apache.fineract.client.models.PostInitiateTransferRequest;
|
||||||
|
import org.apache.fineract.client.models.PostInitiateTransferResponse;
|
||||||
|
import org.apache.fineract.client.util.CallFailedRuntimeException;
|
||||||
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType;
|
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType;
|
||||||
import org.apache.fineract.integrationtests.common.BusinessDateHelper;
|
import org.apache.fineract.integrationtests.common.BusinessDateHelper;
|
||||||
|
import org.apache.fineract.integrationtests.common.BusinessStepHelper;
|
||||||
import org.apache.fineract.integrationtests.common.ClientHelper;
|
import org.apache.fineract.integrationtests.common.ClientHelper;
|
||||||
import org.apache.fineract.integrationtests.common.CollateralManagementHelper;
|
import org.apache.fineract.integrationtests.common.CollateralManagementHelper;
|
||||||
|
import org.apache.fineract.integrationtests.common.ExternalAssetOwnerHelper;
|
||||||
import org.apache.fineract.integrationtests.common.GlobalConfigurationHelper;
|
import org.apache.fineract.integrationtests.common.GlobalConfigurationHelper;
|
||||||
|
import org.apache.fineract.integrationtests.common.SchedulerJobHelper;
|
||||||
import org.apache.fineract.integrationtests.common.Utils;
|
import org.apache.fineract.integrationtests.common.Utils;
|
||||||
import org.apache.fineract.integrationtests.common.charges.ChargesHelper;
|
import org.apache.fineract.integrationtests.common.charges.ChargesHelper;
|
||||||
import org.apache.fineract.integrationtests.common.loans.LoanApplicationTestBuilder;
|
import org.apache.fineract.integrationtests.common.loans.LoanApplicationTestBuilder;
|
||||||
import org.apache.fineract.integrationtests.common.loans.LoanProductTestBuilder;
|
import org.apache.fineract.integrationtests.common.loans.LoanProductTestBuilder;
|
||||||
import org.apache.fineract.integrationtests.common.loans.LoanStatusChecker;
|
import org.apache.fineract.integrationtests.common.loans.LoanStatusChecker;
|
||||||
|
import org.apache.fineract.integrationtests.common.loans.LoanTestLifecycleExtension;
|
||||||
import org.apache.fineract.integrationtests.common.loans.LoanTransactionHelper;
|
import org.apache.fineract.integrationtests.common.loans.LoanTransactionHelper;
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
|
import org.junit.jupiter.api.BeforeAll;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
|
|
||||||
|
@ExtendWith(LoanTestLifecycleExtension.class)
|
||||||
public class InitiateExternalAssetOwnerTransferTest {
|
public class InitiateExternalAssetOwnerTransferTest {
|
||||||
|
|
||||||
private ResponseSpecification responseSpec;
|
private ResponseSpecification responseSpec;
|
||||||
private ResponseSpecification responseSpecError;
|
|
||||||
private ResponseSpecification responseSpecNotFound;
|
|
||||||
private RequestSpecification requestSpec;
|
private RequestSpecification requestSpec;
|
||||||
private ExternalAssetOwnerHelper externalAssetOwnerHelper;
|
private ExternalAssetOwnerHelper externalAssetOwnerHelper;
|
||||||
private LoanTransactionHelper loanTransactionHelper;
|
private LoanTransactionHelper loanTransactionHelper;
|
||||||
|
private SchedulerJobHelper schedulerJobHelper;
|
||||||
private LocalDate todaysDate;
|
private LocalDate todaysDate;
|
||||||
|
|
||||||
|
@BeforeAll
|
||||||
|
public static void setupInvestorBusinessStep() {
|
||||||
|
new BusinessStepHelper().updateSteps("LOAN_CLOSE_OF_BUSINESS", "APPLY_CHARGE_TO_OVERDUE_LOANS", "LOAN_DELINQUENCY_CLASSIFICATION",
|
||||||
|
"CHECK_LOAN_REPAYMENT_DUE", "CHECK_LOAN_REPAYMENT_OVERDUE", "UPDATE_LOAN_ARREARS_AGING", "ADD_PERIODIC_ACCRUAL_ENTRIES",
|
||||||
|
"EXTERNAL_ASSET_OWNER_TRANSFER");
|
||||||
|
}
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
public void setup() {
|
public void setup() {
|
||||||
Utils.initializeRESTAssured();
|
Utils.initializeRESTAssured();
|
||||||
requestSpec = new RequestSpecBuilder().setContentType(ContentType.JSON).build();
|
requestSpec = new RequestSpecBuilder().setContentType(ContentType.JSON).build();
|
||||||
requestSpec.header("Authorization", "Basic " + Utils.loginIntoServerAndGetBase64EncodedAuthenticationKey());
|
requestSpec.header("Authorization", "Basic " + Utils.loginIntoServerAndGetBase64EncodedAuthenticationKey());
|
||||||
responseSpec = new ResponseSpecBuilder().expectStatusCode(200).build();
|
responseSpec = new ResponseSpecBuilder().expectStatusCode(200).build();
|
||||||
responseSpecError = new ResponseSpecBuilder().expectStatusCode(403).build();
|
externalAssetOwnerHelper = new ExternalAssetOwnerHelper();
|
||||||
responseSpecNotFound = new ResponseSpecBuilder().expectStatusCode(404).build();
|
|
||||||
externalAssetOwnerHelper = new ExternalAssetOwnerHelper(requestSpec, responseSpec);
|
|
||||||
loanTransactionHelper = new LoanTransactionHelper(requestSpec, responseSpec);
|
loanTransactionHelper = new LoanTransactionHelper(requestSpec, responseSpec);
|
||||||
|
schedulerJobHelper = new SchedulerJobHelper(requestSpec);
|
||||||
|
|
||||||
todaysDate = Utils.getLocalDateOfTenant();
|
todaysDate = Utils.getLocalDateOfTenant();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void saleActiveLoanToExternalAssetOwner() {
|
public void saleActiveLoanToExternalAssetOwnerAndBuybackADayLater() {
|
||||||
try {
|
try {
|
||||||
GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec, responseSpec, Boolean.TRUE);
|
GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec, responseSpec, Boolean.TRUE);
|
||||||
|
|
||||||
@@ -110,18 +124,96 @@ public class InitiateExternalAssetOwnerTransferTest {
|
|||||||
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
|
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
|
||||||
LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
|
LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
|
||||||
|
|
||||||
String transferExternalId = "36efeb06-d835-48a1-99eb-09bd1d348c1e";
|
String transferExternalId = UUID.randomUUID().toString();
|
||||||
String saleResponse = externalAssetOwnerHelper.initiateTransferByLoanId(loanID.longValue(), "sale",
|
PostInitiateTransferResponse saleResponse = externalAssetOwnerHelper.initiateTransferByLoanId(loanID.longValue(), "sale",
|
||||||
getSaleRequestJson("04 March 2020", transferExternalId));
|
new PostInitiateTransferRequest().settlementDate("2020-03-02").dateFormat("yyyy-MM-dd").locale("en")
|
||||||
Type type = new TypeToken<Map<String, Object>>() {}.getType();
|
.transferExternalId(transferExternalId).ownerExternalId("1234567890").purchasePriceRatio("1.0"));
|
||||||
Map<String, Object> responseMap = new Gson().fromJson(saleResponse, type);
|
assertEquals(transferExternalId, saleResponse.getResourceExternalId());
|
||||||
assertEquals(responseMap.get("resourceExternalId"), transferExternalId);
|
|
||||||
|
|
||||||
PageExternalTransferData retrieveResponse = externalAssetOwnerHelper.retrieveTransferByLoanId(loanID.longValue());
|
PageExternalTransferData retrieveResponse = externalAssetOwnerHelper.retrieveTransferByLoanId(loanID.longValue());
|
||||||
List<ExternalTransferData> retrieveResponseMap = retrieveResponse.getContent();
|
|
||||||
assertEquals(1, retrieveResponse.getTotalElements());
|
assertEquals(1, retrieveResponse.getNumberOfElements());
|
||||||
assertEquals(retrieveResponseMap.get(0).getTransferExternalId(), transferExternalId);
|
ExternalTransferData externalTransferData = retrieveResponse.getContent().get(0);
|
||||||
assertEquals(retrieveResponseMap.get(0).getStatus(), ExternalTransferData.StatusEnum.PENDING);
|
assertEquals(transferExternalId, externalTransferData.getTransferExternalId());
|
||||||
|
assertEquals(ExternalTransferData.StatusEnum.PENDING, externalTransferData.getStatus());
|
||||||
|
assertEquals(LocalDate.of(2020, 3, 2), externalTransferData.getSettlementDate());
|
||||||
|
assertEquals(LocalDate.of(2020, 3, 2), externalTransferData.getEffectiveFrom());
|
||||||
|
assertEquals(LocalDate.of(9999, 12, 31), externalTransferData.getEffectiveTo());
|
||||||
|
|
||||||
|
BusinessDateHelper.updateBusinessDate(requestSpec, responseSpec, BusinessDateType.BUSINESS_DATE, LocalDate.of(2020, 3, 3));
|
||||||
|
// Run the Loan COB Job
|
||||||
|
final String jobName = "Loan COB";
|
||||||
|
schedulerJobHelper.executeAndAwaitJob(jobName);
|
||||||
|
|
||||||
|
retrieveResponse = externalAssetOwnerHelper.retrieveTransferByLoanId(loanID.longValue());
|
||||||
|
|
||||||
|
assertEquals(2, retrieveResponse.getNumberOfElements());
|
||||||
|
externalTransferData = retrieveResponse.getContent().get(0);
|
||||||
|
assertEquals(transferExternalId, externalTransferData.getTransferExternalId());
|
||||||
|
assertEquals(ExternalTransferData.StatusEnum.PENDING, externalTransferData.getStatus());
|
||||||
|
assertEquals(LocalDate.of(2020, 3, 2), externalTransferData.getSettlementDate());
|
||||||
|
assertEquals(LocalDate.of(2020, 3, 2), externalTransferData.getEffectiveFrom());
|
||||||
|
assertEquals(LocalDate.of(2020, 3, 2), externalTransferData.getEffectiveTo());
|
||||||
|
externalTransferData = retrieveResponse.getContent().get(1);
|
||||||
|
assertEquals(transferExternalId, externalTransferData.getTransferExternalId());
|
||||||
|
assertEquals(ExternalTransferData.StatusEnum.ACTIVE, externalTransferData.getStatus());
|
||||||
|
assertEquals(LocalDate.of(2020, 3, 2), externalTransferData.getSettlementDate());
|
||||||
|
assertEquals(LocalDate.of(2020, 3, 3), externalTransferData.getEffectiveFrom());
|
||||||
|
assertEquals(LocalDate.of(9999, 12, 31), externalTransferData.getEffectiveTo());
|
||||||
|
|
||||||
|
String buybackTransferExternalId = "36efeb06-d835-48a1-99eb-09bd1d348c1e";
|
||||||
|
PostInitiateTransferResponse buybackResponse = externalAssetOwnerHelper.initiateTransferByLoanId(loanID.longValue(), "buyback",
|
||||||
|
new PostInitiateTransferRequest().settlementDate("2020-03-03").dateFormat("yyyy-MM-dd").locale("en")
|
||||||
|
.transferExternalId(buybackTransferExternalId));
|
||||||
|
|
||||||
|
assertEquals(buybackResponse.getResourceExternalId(), buybackTransferExternalId);
|
||||||
|
|
||||||
|
retrieveResponse = externalAssetOwnerHelper.retrieveTransferByLoanId(loanID.longValue());
|
||||||
|
|
||||||
|
assertEquals(3, retrieveResponse.getNumberOfElements());
|
||||||
|
externalTransferData = retrieveResponse.getContent().get(0);
|
||||||
|
assertEquals(transferExternalId, externalTransferData.getTransferExternalId());
|
||||||
|
assertEquals(ExternalTransferData.StatusEnum.PENDING, externalTransferData.getStatus());
|
||||||
|
assertEquals(LocalDate.of(2020, 3, 2), externalTransferData.getSettlementDate());
|
||||||
|
assertEquals(LocalDate.of(2020, 3, 2), externalTransferData.getEffectiveFrom());
|
||||||
|
assertEquals(LocalDate.of(2020, 3, 2), externalTransferData.getEffectiveTo());
|
||||||
|
externalTransferData = retrieveResponse.getContent().get(1);
|
||||||
|
assertEquals(transferExternalId, externalTransferData.getTransferExternalId());
|
||||||
|
assertEquals(ExternalTransferData.StatusEnum.ACTIVE, externalTransferData.getStatus());
|
||||||
|
assertEquals(LocalDate.of(2020, 3, 2), externalTransferData.getSettlementDate());
|
||||||
|
assertEquals(LocalDate.of(2020, 3, 3), externalTransferData.getEffectiveFrom());
|
||||||
|
assertEquals(LocalDate.of(9999, 12, 31), externalTransferData.getEffectiveTo());
|
||||||
|
externalTransferData = retrieveResponse.getContent().get(2);
|
||||||
|
assertEquals(buybackTransferExternalId, externalTransferData.getTransferExternalId());
|
||||||
|
assertEquals(ExternalTransferData.StatusEnum.BUYBACK, externalTransferData.getStatus());
|
||||||
|
assertEquals(LocalDate.of(2020, 3, 3), externalTransferData.getSettlementDate());
|
||||||
|
assertEquals(LocalDate.of(2020, 3, 3), externalTransferData.getEffectiveFrom());
|
||||||
|
assertEquals(LocalDate.of(9999, 12, 31), externalTransferData.getEffectiveTo());
|
||||||
|
|
||||||
|
BusinessDateHelper.updateBusinessDate(requestSpec, responseSpec, BusinessDateType.BUSINESS_DATE, LocalDate.of(2020, 3, 4));
|
||||||
|
|
||||||
|
schedulerJobHelper.executeAndAwaitJob(jobName);
|
||||||
|
|
||||||
|
retrieveResponse = externalAssetOwnerHelper.retrieveTransferByLoanId(loanID.longValue());
|
||||||
|
assertEquals(3, retrieveResponse.getNumberOfElements());
|
||||||
|
externalTransferData = retrieveResponse.getContent().get(0);
|
||||||
|
assertEquals(transferExternalId, externalTransferData.getTransferExternalId());
|
||||||
|
assertEquals(ExternalTransferData.StatusEnum.PENDING, externalTransferData.getStatus());
|
||||||
|
assertEquals(LocalDate.of(2020, 3, 2), externalTransferData.getSettlementDate());
|
||||||
|
assertEquals(LocalDate.of(2020, 3, 2), externalTransferData.getEffectiveFrom());
|
||||||
|
assertEquals(LocalDate.of(2020, 3, 2), externalTransferData.getEffectiveTo());
|
||||||
|
externalTransferData = retrieveResponse.getContent().get(1);
|
||||||
|
assertEquals(transferExternalId, externalTransferData.getTransferExternalId());
|
||||||
|
assertEquals(ExternalTransferData.StatusEnum.ACTIVE, externalTransferData.getStatus());
|
||||||
|
assertEquals(LocalDate.of(2020, 3, 2), externalTransferData.getSettlementDate());
|
||||||
|
assertEquals(LocalDate.of(2020, 3, 3), externalTransferData.getEffectiveFrom());
|
||||||
|
assertEquals(LocalDate.of(2020, 3, 3), externalTransferData.getEffectiveTo());
|
||||||
|
externalTransferData = retrieveResponse.getContent().get(2);
|
||||||
|
assertEquals(buybackTransferExternalId, externalTransferData.getTransferExternalId());
|
||||||
|
assertEquals(ExternalTransferData.StatusEnum.BUYBACK, externalTransferData.getStatus());
|
||||||
|
assertEquals(LocalDate.of(2020, 3, 3), externalTransferData.getSettlementDate());
|
||||||
|
assertEquals(LocalDate.of(2020, 3, 3), externalTransferData.getEffectiveFrom());
|
||||||
|
assertEquals(LocalDate.of(2020, 3, 3), externalTransferData.getEffectiveTo());
|
||||||
} finally {
|
} finally {
|
||||||
requestSpec = new RequestSpecBuilder().setContentType(ContentType.JSON).build();
|
requestSpec = new RequestSpecBuilder().setContentType(ContentType.JSON).build();
|
||||||
requestSpec.header("Authorization", "Basic " + Utils.loginIntoServerAndGetBase64EncodedAuthenticationKey());
|
requestSpec.header("Authorization", "Basic " + Utils.loginIntoServerAndGetBase64EncodedAuthenticationKey());
|
||||||
@@ -165,19 +257,17 @@ public class InitiateExternalAssetOwnerTransferTest {
|
|||||||
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
|
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
|
||||||
LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
|
LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
|
||||||
|
|
||||||
String transferExternalId = "36efeb06-d835-48a1-99eb-09bd1d348c1e";
|
String transferExternalId = UUID.randomUUID().toString();
|
||||||
String saleResponse = externalAssetOwnerHelper.initiateTransferByLoanId(loanID.longValue(), "sale",
|
PostInitiateTransferResponse saleResponse = externalAssetOwnerHelper.initiateTransferByLoanId(loanID.longValue(), "sale",
|
||||||
getSaleRequestJson("04 March 2020", transferExternalId));
|
new PostInitiateTransferRequest().settlementDate("2020-03-02").dateFormat("yyyy-MM-dd").locale("en")
|
||||||
Type type = new TypeToken<Map<String, Object>>() {}.getType();
|
.transferExternalId(transferExternalId).ownerExternalId("1234567890").purchasePriceRatio("1.0"));
|
||||||
Map<String, Object> responseMap = new Gson().fromJson(saleResponse, type);
|
assertEquals(transferExternalId, saleResponse.getResourceExternalId());
|
||||||
assertEquals(responseMap.get("resourceExternalId"), transferExternalId);
|
|
||||||
|
|
||||||
externalAssetOwnerHelper = new ExternalAssetOwnerHelper(requestSpec, responseSpecError);
|
CallFailedRuntimeException exception = assertThrows(CallFailedRuntimeException.class,
|
||||||
String errorResponse = externalAssetOwnerHelper.initiateTransferByLoanId(loanID.longValue(), "sale",
|
() -> externalAssetOwnerHelper.initiateTransferByLoanId(loanID.longValue(), "sale",
|
||||||
getSaleRequestJson("04 March 2020", transferExternalId));
|
new PostInitiateTransferRequest().settlementDate("2020-03-02").dateFormat("yyyy-MM-dd").locale("en")
|
||||||
Map<String, Object> errorResponseMap = new Gson().fromJson(errorResponse, type);
|
.transferExternalId(transferExternalId).ownerExternalId("1234567890").purchasePriceRatio("1.0")));
|
||||||
assertEquals("External asset owner transfer is already in PENDING state for this loan.",
|
assertTrue(exception.getMessage().contains("External asset owner transfer is already in PENDING state for this loan"));
|
||||||
errorResponseMap.get("developerMessage"));
|
|
||||||
} finally {
|
} finally {
|
||||||
requestSpec = new RequestSpecBuilder().setContentType(ContentType.JSON).build();
|
requestSpec = new RequestSpecBuilder().setContentType(ContentType.JSON).build();
|
||||||
requestSpec.header("Authorization", "Basic " + Utils.loginIntoServerAndGetBase64EncodedAuthenticationKey());
|
requestSpec.header("Authorization", "Basic " + Utils.loginIntoServerAndGetBase64EncodedAuthenticationKey());
|
||||||
@@ -226,13 +316,12 @@ public class InitiateExternalAssetOwnerTransferTest {
|
|||||||
|
|
||||||
loanTransactionHelper.makeRepayment("04 March 2020", 16000.0f, loanID);
|
loanTransactionHelper.makeRepayment("04 March 2020", 16000.0f, loanID);
|
||||||
|
|
||||||
externalAssetOwnerHelper = new ExternalAssetOwnerHelper(requestSpec, responseSpecError);
|
|
||||||
String transferExternalId = "36efeb06-d835-48a1-99eb-09bd1d348c1e";
|
String transferExternalId = "36efeb06-d835-48a1-99eb-09bd1d348c1e";
|
||||||
String saleResponse = externalAssetOwnerHelper.initiateTransferByLoanId(loanID.longValue(), "sale",
|
CallFailedRuntimeException exception = assertThrows(CallFailedRuntimeException.class,
|
||||||
getSaleRequestJson("05 March 2020", transferExternalId));
|
() -> externalAssetOwnerHelper.initiateTransferByLoanId(loanID.longValue(), "sale",
|
||||||
Type type = new TypeToken<Map<String, Object>>() {}.getType();
|
new PostInitiateTransferRequest().settlementDate("2020-03-02").dateFormat("yyyy-MM-dd").locale("en")
|
||||||
Map<String, Object> errorResponseMap = new Gson().fromJson(saleResponse, type);
|
.transferExternalId(transferExternalId).ownerExternalId("1234567890").purchasePriceRatio("1.0")));
|
||||||
assertEquals("Loan is not in active status", errorResponseMap.get("developerMessage"));
|
assertTrue(exception.getMessage().contains("Loan is not in active status"));
|
||||||
} finally {
|
} finally {
|
||||||
requestSpec = new RequestSpecBuilder().setContentType(ContentType.JSON).build();
|
requestSpec = new RequestSpecBuilder().setContentType(ContentType.JSON).build();
|
||||||
requestSpec.header("Authorization", "Basic " + Utils.loginIntoServerAndGetBase64EncodedAuthenticationKey());
|
requestSpec.header("Authorization", "Basic " + Utils.loginIntoServerAndGetBase64EncodedAuthenticationKey());
|
||||||
@@ -278,58 +367,147 @@ public class InitiateExternalAssetOwnerTransferTest {
|
|||||||
LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
|
LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
|
||||||
|
|
||||||
String transferExternalId = "36efeb06-d835-48a1-99eb-09bd1d348c1e";
|
String transferExternalId = "36efeb06-d835-48a1-99eb-09bd1d348c1e";
|
||||||
String saleResponse = externalAssetOwnerHelper.initiateTransferByLoanId(loanID.longValue(), "sale",
|
PostInitiateTransferResponse saleResponse = externalAssetOwnerHelper.initiateTransferByLoanId(loanID.longValue(), "sale",
|
||||||
getSaleRequestJson("04 March 2020", transferExternalId));
|
new PostInitiateTransferRequest().settlementDate("2020-03-02").dateFormat("yyyy-MM-dd").locale("en")
|
||||||
Type type = new TypeToken<Map<String, Object>>() {}.getType();
|
.transferExternalId(transferExternalId).ownerExternalId("1234567890").purchasePriceRatio("1.0"));
|
||||||
Map<String, Object> responseMap = new Gson().fromJson(saleResponse, type);
|
assertEquals(transferExternalId, saleResponse.getResourceExternalId());
|
||||||
assertEquals(responseMap.get("resourceExternalId"), transferExternalId);
|
|
||||||
|
|
||||||
String buybackTransferExternalId = "36efeb06-d835-48a1-99eb-09bd1d348c1e";
|
PostInitiateTransferResponse buybackResponse = externalAssetOwnerHelper.initiateTransferByLoanId(loanID.longValue(), "buyback",
|
||||||
String buybackResponse = externalAssetOwnerHelper.initiateTransferByLoanId(loanID.longValue(), "buyback",
|
new PostInitiateTransferRequest().settlementDate("2020-03-02").dateFormat("yyyy-MM-dd").locale("en")
|
||||||
getSaleRequestJson("04 March 2020", buybackTransferExternalId));
|
.transferExternalId(transferExternalId));
|
||||||
Map<String, Object> buybackResponseMap = new Gson().fromJson(buybackResponse, type);
|
|
||||||
assertEquals(buybackResponseMap.get("resourceExternalId"), buybackTransferExternalId);
|
|
||||||
|
|
||||||
PageExternalTransferData retrieveResponse = externalAssetOwnerHelper.retrieveTransferByLoanId(loanID.longValue(), 0, 1);
|
assertEquals(buybackResponse.getResourceExternalId(), transferExternalId);
|
||||||
List<ExternalTransferData> retrieveResponseMap = retrieveResponse.getContent();
|
|
||||||
|
|
||||||
assertEquals(2, retrieveResponse.getTotalElements());
|
PageExternalTransferData retrieveResponse = externalAssetOwnerHelper.retrieveTransferByLoanId(loanID.longValue());
|
||||||
assertEquals(1, retrieveResponse.getNumberOfElements());
|
assertEquals(2, retrieveResponse.getNumberOfElements());
|
||||||
assertEquals(retrieveResponseMap.get(0).getTransferExternalId(), transferExternalId);
|
ExternalTransferData externalTransferData = retrieveResponse.getContent().get(0);
|
||||||
assertEquals(retrieveResponseMap.get(0).getStatus(), ExternalTransferData.StatusEnum.PENDING);
|
assertEquals(transferExternalId, externalTransferData.getTransferExternalId());
|
||||||
|
assertEquals(ExternalTransferData.StatusEnum.PENDING, externalTransferData.getStatus());
|
||||||
|
assertEquals(LocalDate.of(2020, 3, 2), externalTransferData.getSettlementDate());
|
||||||
|
assertEquals(LocalDate.of(2020, 3, 2), externalTransferData.getEffectiveFrom());
|
||||||
|
assertEquals(LocalDate.of(9999, 12, 31), externalTransferData.getEffectiveTo());
|
||||||
|
externalTransferData = retrieveResponse.getContent().get(1);
|
||||||
|
assertEquals(transferExternalId, externalTransferData.getTransferExternalId());
|
||||||
|
assertEquals(ExternalTransferData.StatusEnum.BUYBACK, externalTransferData.getStatus());
|
||||||
|
assertEquals(LocalDate.of(2020, 3, 2), externalTransferData.getSettlementDate());
|
||||||
|
assertEquals(LocalDate.of(2020, 3, 2), externalTransferData.getEffectiveFrom());
|
||||||
|
assertEquals(LocalDate.of(9999, 12, 31), externalTransferData.getEffectiveTo());
|
||||||
|
|
||||||
retrieveResponse = externalAssetOwnerHelper.retrieveTransferByLoanId(loanID.longValue(), 1, 1);
|
BusinessDateHelper.updateBusinessDate(requestSpec, responseSpec, BusinessDateType.BUSINESS_DATE, LocalDate.of(2020, 3, 3));
|
||||||
retrieveResponseMap = retrieveResponse.getContent();
|
final String jobName = "Loan COB";
|
||||||
|
schedulerJobHelper.executeAndAwaitJob(jobName);
|
||||||
|
|
||||||
assertEquals(2, retrieveResponse.getTotalElements());
|
retrieveResponse = externalAssetOwnerHelper.retrieveTransferByLoanId(loanID.longValue());
|
||||||
assertEquals(1, retrieveResponse.getNumberOfElements());
|
assertEquals(4, retrieveResponse.getNumberOfElements());
|
||||||
assertEquals(retrieveResponseMap.get(0).getTransferExternalId(), buybackTransferExternalId);
|
externalTransferData = retrieveResponse.getContent().get(0);
|
||||||
assertEquals(retrieveResponseMap.get(0).getStatus(), ExternalTransferData.StatusEnum.BUYBACK);
|
assertEquals(transferExternalId, externalTransferData.getTransferExternalId());
|
||||||
|
assertEquals(ExternalTransferData.StatusEnum.PENDING, externalTransferData.getStatus());
|
||||||
|
assertEquals(LocalDate.of(2020, 3, 2), externalTransferData.getSettlementDate());
|
||||||
|
assertEquals(LocalDate.of(2020, 3, 2), externalTransferData.getEffectiveFrom());
|
||||||
|
assertEquals(LocalDate.of(2020, 3, 2), externalTransferData.getEffectiveTo());
|
||||||
|
externalTransferData = retrieveResponse.getContent().get(1);
|
||||||
|
assertEquals(transferExternalId, externalTransferData.getTransferExternalId());
|
||||||
|
assertEquals(ExternalTransferData.StatusEnum.BUYBACK, externalTransferData.getStatus());
|
||||||
|
assertEquals(LocalDate.of(2020, 3, 2), externalTransferData.getSettlementDate());
|
||||||
|
assertEquals(LocalDate.of(2020, 3, 2), externalTransferData.getEffectiveFrom());
|
||||||
|
assertEquals(LocalDate.of(2020, 3, 2), externalTransferData.getEffectiveTo());
|
||||||
|
externalTransferData = retrieveResponse.getContent().get(2);
|
||||||
|
assertEquals(transferExternalId, externalTransferData.getTransferExternalId());
|
||||||
|
assertEquals(ExternalTransferData.StatusEnum.CANCELLED, externalTransferData.getStatus());
|
||||||
|
assertEquals(LocalDate.of(2020, 3, 2), externalTransferData.getSettlementDate());
|
||||||
|
assertEquals(LocalDate.of(2020, 3, 2), externalTransferData.getEffectiveFrom());
|
||||||
|
assertEquals(LocalDate.of(2020, 3, 2), externalTransferData.getEffectiveTo());
|
||||||
|
externalTransferData = retrieveResponse.getContent().get(3);
|
||||||
|
assertEquals(transferExternalId, externalTransferData.getTransferExternalId());
|
||||||
|
assertEquals(ExternalTransferData.StatusEnum.CANCELLED, externalTransferData.getStatus());
|
||||||
|
assertEquals(LocalDate.of(2020, 3, 2), externalTransferData.getSettlementDate());
|
||||||
|
assertEquals(LocalDate.of(2020, 3, 2), externalTransferData.getEffectiveFrom());
|
||||||
|
assertEquals(LocalDate.of(2020, 3, 2), externalTransferData.getEffectiveTo());
|
||||||
} finally {
|
} finally {
|
||||||
requestSpec = new RequestSpecBuilder().setContentType(ContentType.JSON).build();
|
requestSpec = new RequestSpecBuilder().setContentType(ContentType.JSON).build();
|
||||||
requestSpec.header("Authorization", "Basic " + Utils.loginIntoServerAndGetBase64EncodedAuthenticationKey());
|
requestSpec.header("Authorization", "Basic " + Utils.loginIntoServerAndGetBase64EncodedAuthenticationKey());
|
||||||
requestSpec.header("Fineract-Platform-TenantId", "default");
|
requestSpec.header("Fineract-Platform-TenantId", "default");
|
||||||
responseSpec = new ResponseSpecBuilder().expectStatusCode(200).build();
|
responseSpec = new ResponseSpecBuilder().expectStatusCode(200).build();
|
||||||
|
BusinessDateHelper.updateBusinessDate(requestSpec, responseSpec, BusinessDateType.BUSINESS_DATE, todaysDate);
|
||||||
GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec, responseSpec, Boolean.FALSE);
|
GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec, responseSpec, Boolean.FALSE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getNotFoundErrorIfTheLoanDoesNotExistWithTheGivenID() {
|
public void saleAndBuybackMultipleTimes() {
|
||||||
try {
|
try {
|
||||||
GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec, responseSpec, Boolean.TRUE);
|
GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec, responseSpec, Boolean.TRUE);
|
||||||
|
|
||||||
BusinessDateHelper.updateBusinessDate(requestSpec, responseSpec, BusinessDateType.BUSINESS_DATE, LocalDate.of(2020, 3, 2));
|
BusinessDateHelper.updateBusinessDate(requestSpec, responseSpec, BusinessDateType.BUSINESS_DATE, LocalDate.of(2020, 3, 2));
|
||||||
GlobalConfigurationHelper.updateValueForGlobalConfiguration(requestSpec, responseSpec, "10", "0");
|
GlobalConfigurationHelper.updateValueForGlobalConfiguration(requestSpec, responseSpec, "10", "0");
|
||||||
|
|
||||||
externalAssetOwnerHelper = new ExternalAssetOwnerHelper(requestSpec, responseSpecNotFound);
|
final Integer clientID = ClientHelper.createClient(requestSpec, responseSpec);
|
||||||
|
Assertions.assertNotNull(clientID);
|
||||||
|
|
||||||
|
Integer overdueFeeChargeId = ChargesHelper.createCharges(requestSpec, responseSpec,
|
||||||
|
ChargesHelper.getLoanOverdueFeeJSONWithCalculationTypePercentage("1"));
|
||||||
|
Assertions.assertNotNull(overdueFeeChargeId);
|
||||||
|
|
||||||
|
final Integer loanProductID = createLoanProduct(overdueFeeChargeId.toString());
|
||||||
|
Assertions.assertNotNull(loanProductID);
|
||||||
|
HashMap loanStatusHashMap;
|
||||||
|
|
||||||
|
final Integer loanID = applyForLoanApplication(clientID.toString(), loanProductID.toString(), null, "10 January 2020");
|
||||||
|
|
||||||
|
Assertions.assertNotNull(loanID);
|
||||||
|
|
||||||
|
loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(requestSpec, responseSpec, loanID);
|
||||||
|
LoanStatusChecker.verifyLoanIsPending(loanStatusHashMap);
|
||||||
|
|
||||||
|
loanStatusHashMap = loanTransactionHelper.approveLoan("01 March 2020", loanID);
|
||||||
|
LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap);
|
||||||
|
|
||||||
|
String loanDetails = loanTransactionHelper.getLoanDetails(requestSpec, responseSpec, loanID);
|
||||||
|
loanStatusHashMap = loanTransactionHelper.disburseLoanWithNetDisbursalAmount("02 March 2020", loanID,
|
||||||
|
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
|
||||||
|
LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
|
||||||
|
|
||||||
String transferExternalId = "36efeb06-d835-48a1-99eb-09bd1d348c1e";
|
String transferExternalId = "36efeb06-d835-48a1-99eb-09bd1d348c1e";
|
||||||
String nonExistingLoanExternalID = "NonExistingLoanExternalID";
|
PostInitiateTransferResponse saleResponse = externalAssetOwnerHelper.initiateTransferByLoanId(loanID.longValue(), "sale",
|
||||||
String saleResponse = externalAssetOwnerHelper.initiateTransferByLoanExternalId(nonExistingLoanExternalID, "sale",
|
new PostInitiateTransferRequest().settlementDate("2020-03-04").dateFormat("yyyy-MM-dd").locale("en")
|
||||||
getSaleRequestJson("05 March 2020", transferExternalId));
|
.transferExternalId(transferExternalId).ownerExternalId("1234567890").purchasePriceRatio("1.0"));
|
||||||
Type type = new TypeToken<Map<String, Object>>() {}.getType();
|
|
||||||
Map<String, Object> errorResponseMap = new Gson().fromJson(saleResponse, type);
|
assertEquals(transferExternalId, saleResponse.getResourceExternalId());
|
||||||
assertEquals("The requested resource is not available.", errorResponseMap.get("developerMessage"));
|
|
||||||
|
String buybackTransferExternalId = "36efeb06-d835-48a1-99eb-09bd1d348c1e";
|
||||||
|
PostInitiateTransferResponse buybackResponse = externalAssetOwnerHelper.initiateTransferByLoanId(loanID.longValue(), "buyback",
|
||||||
|
new PostInitiateTransferRequest().settlementDate("2020-03-04").dateFormat("yyyy-MM-dd").locale("en")
|
||||||
|
.transferExternalId(buybackTransferExternalId));
|
||||||
|
|
||||||
|
assertEquals(buybackResponse.getResourceExternalId(), buybackTransferExternalId);
|
||||||
|
PageExternalTransferData retrieveResponse = externalAssetOwnerHelper.retrieveTransferByLoanId(loanID.longValue());
|
||||||
|
assertEquals(2, retrieveResponse.getNumberOfElements());
|
||||||
|
ExternalTransferData externalTransferData = retrieveResponse.getContent().get(0);
|
||||||
|
assertEquals(transferExternalId, externalTransferData.getTransferExternalId());
|
||||||
|
assertEquals(ExternalTransferData.StatusEnum.PENDING, externalTransferData.getStatus());
|
||||||
|
assertEquals(LocalDate.of(2020, 3, 4), externalTransferData.getSettlementDate());
|
||||||
|
assertEquals(LocalDate.of(2020, 3, 2), externalTransferData.getEffectiveFrom());
|
||||||
|
assertEquals(LocalDate.of(9999, 12, 31), externalTransferData.getEffectiveTo());
|
||||||
|
externalTransferData = retrieveResponse.getContent().get(1);
|
||||||
|
assertEquals(transferExternalId, externalTransferData.getTransferExternalId());
|
||||||
|
assertEquals(ExternalTransferData.StatusEnum.BUYBACK, externalTransferData.getStatus());
|
||||||
|
assertEquals(LocalDate.of(2020, 3, 4), externalTransferData.getSettlementDate());
|
||||||
|
assertEquals(LocalDate.of(2020, 3, 2), externalTransferData.getEffectiveFrom());
|
||||||
|
assertEquals(LocalDate.of(9999, 12, 31), externalTransferData.getEffectiveTo());
|
||||||
|
|
||||||
|
CallFailedRuntimeException exception = assertThrows(CallFailedRuntimeException.class,
|
||||||
|
() -> externalAssetOwnerHelper.initiateTransferByLoanId(loanID.longValue(), "sale",
|
||||||
|
new PostInitiateTransferRequest().settlementDate("2020-03-04").dateFormat("yyyy-MM-dd").locale("en")
|
||||||
|
.transferExternalId(transferExternalId).ownerExternalId("1234567890").purchasePriceRatio("1.0")));
|
||||||
|
|
||||||
|
assertTrue(exception.getMessage().contains("This loan cannot be sold, there is already an in progress transfer"));
|
||||||
|
|
||||||
|
CallFailedRuntimeException exception2 = assertThrows(CallFailedRuntimeException.class,
|
||||||
|
() -> externalAssetOwnerHelper.initiateTransferByLoanId(loanID.longValue(), "buyback",
|
||||||
|
new PostInitiateTransferRequest().settlementDate("2020-03-04").dateFormat("yyyy-MM-dd").locale("en")
|
||||||
|
.transferExternalId(buybackTransferExternalId)));
|
||||||
|
assertTrue(exception2.getMessage()
|
||||||
|
.contains("This loan cannot be bought back, external asset owner buyback transfer is already in progress"));
|
||||||
} finally {
|
} finally {
|
||||||
requestSpec = new RequestSpecBuilder().setContentType(ContentType.JSON).build();
|
requestSpec = new RequestSpecBuilder().setContentType(ContentType.JSON).build();
|
||||||
requestSpec.header("Authorization", "Basic " + Utils.loginIntoServerAndGetBase64EncodedAuthenticationKey());
|
requestSpec.header("Authorization", "Basic " + Utils.loginIntoServerAndGetBase64EncodedAuthenticationKey());
|
||||||
@@ -378,15 +556,4 @@ public class InitiateExternalAssetOwnerTransferTest {
|
|||||||
return collateral;
|
return collateral;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getSaleRequestJson(String date, String transferExternalId) {
|
|
||||||
final HashMap<String, String> map = new HashMap<>();
|
|
||||||
map.put("settlementDate", date);
|
|
||||||
map.put("ownerExternalId", "1234567890987654321");
|
|
||||||
map.put("transferExternalId", transferExternalId);
|
|
||||||
map.put("purchasePriceRatio", "1.234");
|
|
||||||
map.put("dateFormat", "dd MMMM yyyy");
|
|
||||||
map.put("locale", "en");
|
|
||||||
return new Gson().toJson(map);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user