FINERACT-1760: Enhanced external id support for loan
This commit is contained in:
+3
-1
@@ -42,7 +42,9 @@ import org.apache.fineract.infrastructure.bulkimport.importhandler.helper.DateSe
|
|||||||
import org.apache.fineract.infrastructure.bulkimport.importhandler.helper.EnumOptionDataValueSerializer;
|
import org.apache.fineract.infrastructure.bulkimport.importhandler.helper.EnumOptionDataValueSerializer;
|
||||||
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
|
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
|
||||||
import org.apache.fineract.infrastructure.core.data.EnumOptionData;
|
import org.apache.fineract.infrastructure.core.data.EnumOptionData;
|
||||||
|
import org.apache.fineract.infrastructure.core.domain.ExternalId;
|
||||||
import org.apache.fineract.infrastructure.core.serialization.GoogleGsonSerializerHelper;
|
import org.apache.fineract.infrastructure.core.serialization.GoogleGsonSerializerHelper;
|
||||||
|
import org.apache.fineract.infrastructure.core.service.ExternalIdFactory;
|
||||||
import org.apache.fineract.portfolio.loanaccount.data.DisbursementData;
|
import org.apache.fineract.portfolio.loanaccount.data.DisbursementData;
|
||||||
import org.apache.fineract.portfolio.loanaccount.data.LoanAccountData;
|
import org.apache.fineract.portfolio.loanaccount.data.LoanAccountData;
|
||||||
import org.apache.fineract.portfolio.loanaccount.data.LoanApprovalData;
|
import org.apache.fineract.portfolio.loanaccount.data.LoanApprovalData;
|
||||||
@@ -140,7 +142,7 @@ public class LoanImportHandler implements ImportHandler {
|
|||||||
|
|
||||||
private LoanAccountData readLoan(final Workbook workbook, final Row row, final List<String> statuses, final String locale,
|
private LoanAccountData readLoan(final Workbook workbook, final Row row, final List<String> statuses, final String locale,
|
||||||
final String dateFormat) {
|
final String dateFormat) {
|
||||||
String externalId = ImportHandlerUtils.readAsString(LoanConstants.EXTERNAL_ID_COL, row);
|
ExternalId externalId = ExternalIdFactory.produce(ImportHandlerUtils.readAsString(LoanConstants.EXTERNAL_ID_COL, row));
|
||||||
String status = ImportHandlerUtils.readAsString(LoanConstants.STATUS_COL, row);
|
String status = ImportHandlerUtils.readAsString(LoanConstants.STATUS_COL, row);
|
||||||
String productName = ImportHandlerUtils.readAsString(LoanConstants.PRODUCT_COL, row);
|
String productName = ImportHandlerUtils.readAsString(LoanConstants.PRODUCT_COL, row);
|
||||||
Long productId = ImportHandlerUtils.getIdByName(workbook.getSheet(TemplatePopulateImportConstants.PRODUCT_SHEET_NAME), productName);
|
Long productId = ImportHandlerUtils.getIdByName(workbook.getSheet(TemplatePopulateImportConstants.PRODUCT_SHEET_NAME), productName);
|
||||||
|
|||||||
+1
-1
@@ -47,7 +47,7 @@ public class LoanDelinquencyRangeChangeBusinessEventSerializer extends AbstractB
|
|||||||
LoanAccountData data = service.retrieveOne(event.get().getId());
|
LoanAccountData data = service.retrieveOne(event.get().getId());
|
||||||
Long id = data.getId();
|
Long id = data.getId();
|
||||||
String accountNumber = data.getAccountNo();
|
String accountNumber = data.getAccountNo();
|
||||||
String externalId = data.getExternalId();
|
String externalId = data.getExternalId().getValue();
|
||||||
DelinquencyRangeDataV1 delinquencyRange = mapper.map(data.getDelinquencyRange());
|
DelinquencyRangeDataV1 delinquencyRange = mapper.map(data.getDelinquencyRange());
|
||||||
return new LoanAccountDelinquencyRangeDataV1(id, accountNumber, externalId, delinquencyRange);
|
return new LoanAccountDelinquencyRangeDataV1(id, accountNumber, externalId, delinquencyRange);
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -48,7 +48,7 @@ public class LoanRepaymentBusinessEventSerializer extends AbstractBusinessEventS
|
|||||||
Loan loan = repaymentInstallment.getLoan();
|
Loan loan = repaymentInstallment.getLoan();
|
||||||
Long id = loan.getId();
|
Long id = loan.getId();
|
||||||
String accountNo = loan.getAccountNumber();
|
String accountNo = loan.getAccountNumber();
|
||||||
String externalId = loan.getExternalId();
|
String externalId = loan.getExternalId().getValue();
|
||||||
String dueDate = dataTimeMapper.mapLocalDate(repaymentInstallment.getDueDate());
|
String dueDate = dataTimeMapper.mapLocalDate(repaymentInstallment.getDueDate());
|
||||||
MonetaryCurrency loanCurrency = loan.getCurrency();
|
MonetaryCurrency loanCurrency = loan.getCurrency();
|
||||||
CurrencyDataV1 currency = CurrencyDataV1.newBuilder().setCode(loanCurrency.getCode())
|
CurrencyDataV1 currency = CurrencyDataV1.newBuilder().setCode(loanCurrency.getCode())
|
||||||
|
|||||||
+2
-1
@@ -163,7 +163,8 @@ public class DelinquencyWritePlatformServiceImpl implements DelinquencyWritePlat
|
|||||||
final CollectionData collectionData = loanDelinquencyDomainService.getOverdueCollectionData(loan);
|
final CollectionData collectionData = loanDelinquencyDomainService.getOverdueCollectionData(loan);
|
||||||
changes = lookUpDelinquencyRange(loan, delinquencyBucket, collectionData.getDelinquentDays());
|
changes = lookUpDelinquencyRange(loan, delinquencyBucket, collectionData.getDelinquentDays());
|
||||||
}
|
}
|
||||||
return new CommandProcessingResultBuilder().withCommandId(command.commandId()).withEntityId(loan.getId()).with(changes).build();
|
return new CommandProcessingResultBuilder().withCommandId(command.commandId()).withEntityId(loan.getId())
|
||||||
|
.withEntityExternalId(loan.getExternalId()).with(changes).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+1
-1
@@ -560,7 +560,7 @@ public class LoanChargesApiResource {
|
|||||||
Long resolvedLoanId = loanId;
|
Long resolvedLoanId = loanId;
|
||||||
if (resolvedLoanId == null) {
|
if (resolvedLoanId == null) {
|
||||||
loanExternalId.throwExceptionIfEmpty();
|
loanExternalId.throwExceptionIfEmpty();
|
||||||
resolvedLoanId = this.loanReadPlatformService.retrieveLoanIdByExternalId(loanExternalId.getValue());
|
resolvedLoanId = this.loanReadPlatformService.retrieveLoanIdByExternalId(loanExternalId);
|
||||||
if (resolvedLoanId == null) {
|
if (resolvedLoanId == null) {
|
||||||
throw new LoanNotFoundException(loanExternalId);
|
throw new LoanNotFoundException(loanExternalId);
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -587,7 +587,7 @@ public class LoanTransactionsApiResource {
|
|||||||
Long resolvedLoanId = loanId;
|
Long resolvedLoanId = loanId;
|
||||||
if (resolvedLoanId == null) {
|
if (resolvedLoanId == null) {
|
||||||
loanExternalId.throwExceptionIfEmpty();
|
loanExternalId.throwExceptionIfEmpty();
|
||||||
resolvedLoanId = this.loanReadPlatformService.retrieveLoanIdByExternalId(loanExternalId.getValue());
|
resolvedLoanId = this.loanReadPlatformService.retrieveLoanIdByExternalId(loanExternalId);
|
||||||
if (resolvedLoanId == null) {
|
if (resolvedLoanId == null) {
|
||||||
throw new LoanNotFoundException(loanExternalId);
|
throw new LoanNotFoundException(loanExternalId);
|
||||||
}
|
}
|
||||||
|
|||||||
+504
-354
@@ -73,11 +73,13 @@ import org.apache.fineract.infrastructure.core.api.JsonQuery;
|
|||||||
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
|
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
|
||||||
import org.apache.fineract.infrastructure.core.data.EnumOptionData;
|
import org.apache.fineract.infrastructure.core.data.EnumOptionData;
|
||||||
import org.apache.fineract.infrastructure.core.data.UploadRequest;
|
import org.apache.fineract.infrastructure.core.data.UploadRequest;
|
||||||
|
import org.apache.fineract.infrastructure.core.domain.ExternalId;
|
||||||
import org.apache.fineract.infrastructure.core.exception.UnrecognizedQueryParamException;
|
import org.apache.fineract.infrastructure.core.exception.UnrecognizedQueryParamException;
|
||||||
import org.apache.fineract.infrastructure.core.serialization.ApiRequestJsonSerializationSettings;
|
import org.apache.fineract.infrastructure.core.serialization.ApiRequestJsonSerializationSettings;
|
||||||
import org.apache.fineract.infrastructure.core.serialization.DefaultToApiJsonSerializer;
|
import org.apache.fineract.infrastructure.core.serialization.DefaultToApiJsonSerializer;
|
||||||
import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
|
import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
|
||||||
import org.apache.fineract.infrastructure.core.service.CommandParameterUtil;
|
import org.apache.fineract.infrastructure.core.service.CommandParameterUtil;
|
||||||
|
import org.apache.fineract.infrastructure.core.service.ExternalIdFactory;
|
||||||
import org.apache.fineract.infrastructure.core.service.Page;
|
import org.apache.fineract.infrastructure.core.service.Page;
|
||||||
import org.apache.fineract.infrastructure.core.service.SearchParameters;
|
import org.apache.fineract.infrastructure.core.service.SearchParameters;
|
||||||
import org.apache.fineract.infrastructure.dataqueries.api.DataTableApiConstant;
|
import org.apache.fineract.infrastructure.dataqueries.api.DataTableApiConstant;
|
||||||
@@ -127,6 +129,7 @@ import org.apache.fineract.portfolio.loanaccount.data.PaidInAdvanceData;
|
|||||||
import org.apache.fineract.portfolio.loanaccount.data.RepaymentScheduleRelatedLoanData;
|
import org.apache.fineract.portfolio.loanaccount.data.RepaymentScheduleRelatedLoanData;
|
||||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanStatus;
|
import org.apache.fineract.portfolio.loanaccount.domain.LoanStatus;
|
||||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanTermVariationType;
|
import org.apache.fineract.portfolio.loanaccount.domain.LoanTermVariationType;
|
||||||
|
import org.apache.fineract.portfolio.loanaccount.exception.LoanNotFoundException;
|
||||||
import org.apache.fineract.portfolio.loanaccount.exception.LoanTemplateTypeRequiredException;
|
import org.apache.fineract.portfolio.loanaccount.exception.LoanTemplateTypeRequiredException;
|
||||||
import org.apache.fineract.portfolio.loanaccount.exception.NotSupportedLoanTemplateTypeException;
|
import org.apache.fineract.portfolio.loanaccount.exception.NotSupportedLoanTemplateTypeException;
|
||||||
import org.apache.fineract.portfolio.loanaccount.guarantor.data.GuarantorData;
|
import org.apache.fineract.portfolio.loanaccount.guarantor.data.GuarantorData;
|
||||||
@@ -282,24 +285,12 @@ public class LoansApiResource {
|
|||||||
@Path("{loanId}/template")
|
@Path("{loanId}/template")
|
||||||
@Consumes({ MediaType.APPLICATION_JSON })
|
@Consumes({ MediaType.APPLICATION_JSON })
|
||||||
@Produces({ MediaType.APPLICATION_JSON })
|
@Produces({ MediaType.APPLICATION_JSON })
|
||||||
public String retrieveApprovalTemplate(@PathParam("loanId") @Parameter(description = "loanId") final Long loanId,
|
@ApiResponses({
|
||||||
|
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = LoansApiResourceSwagger.GetLoansApprovalTemplateResponse.class))) })
|
||||||
|
public String retrieveApprovalTemplate(@PathParam("loanId") @Parameter(description = "loanId", required = true) final Long loanId,
|
||||||
@QueryParam("templateType") @Parameter(description = "templateType") final String templateType,
|
@QueryParam("templateType") @Parameter(description = "templateType") final String templateType,
|
||||||
@Context final UriInfo uriInfo) {
|
@Context final UriInfo uriInfo) {
|
||||||
|
return retrieveApprovalTemplate(loanId, null, templateType, uriInfo);
|
||||||
this.context.authenticatedUser().validateHasReadPermission(RESOURCE_NAME_FOR_PERMISSIONS);
|
|
||||||
|
|
||||||
LoanApprovalData loanApprovalTemplate = null;
|
|
||||||
|
|
||||||
if (templateType == null) {
|
|
||||||
final String errorMsg = "Loan template type must be provided";
|
|
||||||
throw new LoanTemplateTypeRequiredException(errorMsg);
|
|
||||||
} else if (templateType.equals("approval")) {
|
|
||||||
loanApprovalTemplate = this.loanReadPlatformService.retrieveApprovalTemplate(loanId);
|
|
||||||
}
|
|
||||||
|
|
||||||
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
|
||||||
return this.loanApprovalDataToApiJsonSerializer.serialize(settings, loanApprovalTemplate, LOAN_APPROVAL_DATA_PARAMETERS);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
@@ -376,7 +367,7 @@ public class LoansApiResource {
|
|||||||
calendarOptions = this.loanReadPlatformService.retrieveCalendars(groupId);
|
calendarOptions = this.loanReadPlatformService.retrieveCalendars(groupId);
|
||||||
newLoanAccount = newLoanAccount == null ? loanAccountGroupData
|
newLoanAccount = newLoanAccount == null ? loanAccountGroupData
|
||||||
: LoanAccountData.populateGroupDefaults(newLoanAccount, loanAccountGroupData);
|
: LoanAccountData.populateGroupDefaults(newLoanAccount, loanAccountGroupData);
|
||||||
accountLinkingOptions = getaccountLinkingOptions(newLoanAccount, clientId, groupId);
|
accountLinkingOptions = getAccountLinkingOptions(newLoanAccount, clientId, groupId);
|
||||||
|
|
||||||
} else if (templateType.equals("jlgbulk")) {
|
} else if (templateType.equals("jlgbulk")) {
|
||||||
// get group details along with members in that group
|
// get group details along with members in that group
|
||||||
@@ -393,7 +384,7 @@ public class LoansApiResource {
|
|||||||
for (ClientData clientData : members) {
|
for (ClientData clientData : members) {
|
||||||
Integer loanCounter = this.loanReadPlatformService.retriveLoanCounter(clientData.getId(), productId);
|
Integer loanCounter = this.loanReadPlatformService.retriveLoanCounter(clientData.getId(), productId);
|
||||||
memberLoanCycle.put(clientData.getId(), loanCounter);
|
memberLoanCycle.put(clientData.getId(), loanCounter);
|
||||||
accountLinkingOptions.addAll(getaccountLinkingOptions(newLoanAccount, clientData.getId(), groupId));
|
accountLinkingOptions.addAll(getAccountLinkingOptions(newLoanAccount, clientData.getId(), groupId));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -408,7 +399,7 @@ public class LoansApiResource {
|
|||||||
allowedLoanOfficers = this.loanReadPlatformService.retrieveAllowedLoanOfficers(officeId, staffInSelectedOfficeOnly);
|
allowedLoanOfficers = this.loanReadPlatformService.retrieveAllowedLoanOfficers(officeId, staffInSelectedOfficeOnly);
|
||||||
|
|
||||||
if (clientId != null) {
|
if (clientId != null) {
|
||||||
accountLinkingOptions = getaccountLinkingOptions(newLoanAccount, clientId, groupId);
|
accountLinkingOptions = getAccountLinkingOptions(newLoanAccount, clientId, groupId);
|
||||||
}
|
}
|
||||||
|
|
||||||
// add product options, allowed loan officers and calendar options
|
// add product options, allowed loan officers and calendar options
|
||||||
@@ -424,7 +415,7 @@ public class LoansApiResource {
|
|||||||
return this.toApiJsonSerializer.serialize(settings, newLoanAccount, LOAN_DATA_PARAMETERS);
|
return this.toApiJsonSerializer.serialize(settings, newLoanAccount, LOAN_DATA_PARAMETERS);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Collection<PortfolioAccountData> getaccountLinkingOptions(final LoanAccountData newLoanAccount, final Long clientId,
|
private Collection<PortfolioAccountData> getAccountLinkingOptions(final LoanAccountData newLoanAccount, final Long clientId,
|
||||||
final Long groupId) {
|
final Long groupId) {
|
||||||
final CurrencyData currencyData = newLoanAccount.getCurrency();
|
final CurrencyData currencyData = newLoanAccount.getCurrency();
|
||||||
String currencyCode = null;
|
String currencyCode = null;
|
||||||
@@ -450,289 +441,14 @@ public class LoansApiResource {
|
|||||||
+ "loans/1?fields=id,principal,annualInterestRate&associations=repaymentSchedule,transactions")
|
+ "loans/1?fields=id,principal,annualInterestRate&associations=repaymentSchedule,transactions")
|
||||||
@ApiResponses({
|
@ApiResponses({
|
||||||
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = LoansApiResourceSwagger.GetLoansLoanIdResponse.class))) })
|
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = LoansApiResourceSwagger.GetLoansLoanIdResponse.class))) })
|
||||||
public String retrieveLoan(@PathParam("loanId") @Parameter(description = "loanId") final Long loanId,
|
public String retrieveLoan(@PathParam("loanId") @Parameter(description = "loanId", required = true) final Long loanId,
|
||||||
@DefaultValue("false") @QueryParam("staffInSelectedOfficeOnly") @Parameter(description = "staffInSelectedOfficeOnly") final boolean staffInSelectedOfficeOnly,
|
@DefaultValue("false") @QueryParam("staffInSelectedOfficeOnly") @Parameter(description = "staffInSelectedOfficeOnly") final boolean staffInSelectedOfficeOnly,
|
||||||
@DefaultValue("all") @QueryParam("associations") @Parameter(in = ParameterIn.QUERY, name = "associations", description = "Loan object relations to be included in the response", required = false, examples = {
|
@DefaultValue("all") @QueryParam("associations") @Parameter(in = ParameterIn.QUERY, name = "associations", description = "Loan object relations to be included in the response", required = false, examples = {
|
||||||
@ExampleObject(value = "all"), @ExampleObject(value = "repaymentSchedule,transactions") }) final String associations,
|
@ExampleObject(value = "all"), @ExampleObject(value = "repaymentSchedule,transactions") }) final String associations,
|
||||||
@QueryParam("exclude") @Parameter(in = ParameterIn.QUERY, name = "exclude", description = "Optional Loan object relation list to be filtered in the response", required = false, example = "guarantors,futureSchedule") final String exclude,
|
@QueryParam("exclude") @Parameter(in = ParameterIn.QUERY, name = "exclude", description = "Optional Loan object relation list to be filtered in the response", required = false, example = "guarantors,futureSchedule") final String exclude,
|
||||||
@QueryParam("fields") @Parameter(in = ParameterIn.QUERY, name = "fields", description = "Optional Loan attribute list to be in the response", required = false, example = "id,principal,annualInterestRate") final String fields,
|
@QueryParam("fields") @Parameter(in = ParameterIn.QUERY, name = "fields", description = "Optional Loan attribute list to be in the response", required = false, example = "id,principal,annualInterestRate") final String fields,
|
||||||
@Context final UriInfo uriInfo) {
|
@Context final UriInfo uriInfo) {
|
||||||
this.context.authenticatedUser().validateHasReadPermission(RESOURCE_NAME_FOR_PERMISSIONS);
|
return retrieveLoan(loanId, null, staffInSelectedOfficeOnly, exclude, uriInfo);
|
||||||
|
|
||||||
LoanAccountData loanBasicDetails = this.loanReadPlatformService.retrieveOne(loanId);
|
|
||||||
if (loanBasicDetails.isInterestRecalculationEnabled()) {
|
|
||||||
Collection<CalendarData> interestRecalculationCalendarDatas = this.calendarReadPlatformService.retrieveCalendarsByEntity(
|
|
||||||
loanBasicDetails.getInterestRecalculationDetailId(), CalendarEntityType.LOAN_RECALCULATION_REST_DETAIL.getValue(),
|
|
||||||
null);
|
|
||||||
CalendarData calendarData = null;
|
|
||||||
if (!CollectionUtils.isEmpty(interestRecalculationCalendarDatas)) {
|
|
||||||
calendarData = interestRecalculationCalendarDatas.iterator().next();
|
|
||||||
}
|
|
||||||
|
|
||||||
Collection<CalendarData> interestRecalculationCompoundingCalendarDatas = this.calendarReadPlatformService
|
|
||||||
.retrieveCalendarsByEntity(loanBasicDetails.getInterestRecalculationDetailId(),
|
|
||||||
CalendarEntityType.LOAN_RECALCULATION_COMPOUNDING_DETAIL.getValue(), null);
|
|
||||||
CalendarData compoundingCalendarData = null;
|
|
||||||
if (!CollectionUtils.isEmpty(interestRecalculationCompoundingCalendarDatas)) {
|
|
||||||
compoundingCalendarData = interestRecalculationCompoundingCalendarDatas.iterator().next();
|
|
||||||
}
|
|
||||||
loanBasicDetails = LoanAccountData.withInterestRecalculationCalendarData(loanBasicDetails, calendarData,
|
|
||||||
compoundingCalendarData);
|
|
||||||
}
|
|
||||||
if (loanBasicDetails.getRepaymentFrequencyType() != null
|
|
||||||
&& loanBasicDetails.getRepaymentFrequencyType().getId().intValue() == PeriodFrequencyType.MONTHS.getValue()) {
|
|
||||||
Collection<CalendarData> loanCalendarDatas = this.calendarReadPlatformService.retrieveCalendarsByEntity(loanId,
|
|
||||||
CalendarEntityType.LOANS.getValue(), null);
|
|
||||||
CalendarData calendarData = null;
|
|
||||||
if (!CollectionUtils.isEmpty(loanCalendarDatas)) {
|
|
||||||
calendarData = loanCalendarDatas.iterator().next();
|
|
||||||
}
|
|
||||||
if (calendarData != null) {
|
|
||||||
loanBasicDetails = LoanAccountData.withLoanCalendarData(loanBasicDetails, calendarData);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Collection<InterestRatePeriodData> interestRatesPeriods = this.loanReadPlatformService
|
|
||||||
.retrieveLoanInterestRatePeriodData(loanBasicDetails);
|
|
||||||
Collection<LoanTransactionData> loanRepayments = null;
|
|
||||||
LoanScheduleData repaymentSchedule = null;
|
|
||||||
Collection<LoanChargeData> charges = null;
|
|
||||||
Collection<GuarantorData> guarantors = null;
|
|
||||||
CalendarData meeting = null;
|
|
||||||
Collection<NoteData> notes = null;
|
|
||||||
PortfolioAccountData linkedAccount = null;
|
|
||||||
Collection<DisbursementData> disbursementData = null;
|
|
||||||
Collection<LoanTermVariationsData> emiAmountVariations = null;
|
|
||||||
Collection<LoanCollateralResponseData> loanCollateralManagements;
|
|
||||||
Collection<LoanCollateralManagementData> loanCollateralManagementData = new ArrayList<>();
|
|
||||||
CollectionData collectionData = CollectionData.template();
|
|
||||||
|
|
||||||
final Set<String> mandatoryResponseParameters = new HashSet<>();
|
|
||||||
final Set<String> associationParameters = ApiParameterHelper.extractAssociationsForResponseIfProvided(uriInfo.getQueryParameters());
|
|
||||||
final Collection<LoanTransactionData> currentLoanRepayments = this.loanReadPlatformService.retrieveLoanTransactions(loanId);
|
|
||||||
if (!associationParameters.isEmpty()) {
|
|
||||||
if (associationParameters.contains(DataTableApiConstant.allAssociateParamName)) {
|
|
||||||
associationParameters.addAll(Arrays.asList(DataTableApiConstant.repaymentScheduleAssociateParamName,
|
|
||||||
DataTableApiConstant.futureScheduleAssociateParamName, DataTableApiConstant.originalScheduleAssociateParamName,
|
|
||||||
DataTableApiConstant.transactionsAssociateParamName, DataTableApiConstant.chargesAssociateParamName,
|
|
||||||
DataTableApiConstant.guarantorsAssociateParamName, DataTableApiConstant.collateralAssociateParamName,
|
|
||||||
DataTableApiConstant.notesAssociateParamName, DataTableApiConstant.linkedAccountAssociateParamName,
|
|
||||||
DataTableApiConstant.multiDisburseDetailsAssociateParamName, DataTableApiConstant.collectionAssociateParamName));
|
|
||||||
}
|
|
||||||
|
|
||||||
ApiParameterHelper.excludeAssociationsForResponseIfProvided(exclude, associationParameters);
|
|
||||||
|
|
||||||
if (associationParameters.contains(DataTableApiConstant.guarantorsAssociateParamName)) {
|
|
||||||
mandatoryResponseParameters.add(DataTableApiConstant.guarantorsAssociateParamName);
|
|
||||||
guarantors = this.guarantorReadPlatformService.retrieveGuarantorsForLoan(loanId);
|
|
||||||
if (CollectionUtils.isEmpty(guarantors)) {
|
|
||||||
guarantors = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (associationParameters.contains(DataTableApiConstant.transactionsAssociateParamName)) {
|
|
||||||
mandatoryResponseParameters.add(DataTableApiConstant.transactionsAssociateParamName);
|
|
||||||
if (!CollectionUtils.isEmpty(currentLoanRepayments)) {
|
|
||||||
loanRepayments = currentLoanRepayments;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (associationParameters.contains(DataTableApiConstant.multiDisburseDetailsAssociateParamName)
|
|
||||||
|| associationParameters.contains(DataTableApiConstant.repaymentScheduleAssociateParamName)) {
|
|
||||||
mandatoryResponseParameters.add(DataTableApiConstant.multiDisburseDetailsAssociateParamName);
|
|
||||||
disbursementData = this.loanReadPlatformService.retrieveLoanDisbursementDetails(loanId);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (associationParameters.contains(DataTableApiConstant.emiAmountVariationsAssociateParamName)
|
|
||||||
|| associationParameters.contains(DataTableApiConstant.repaymentScheduleAssociateParamName)) {
|
|
||||||
mandatoryResponseParameters.add(DataTableApiConstant.emiAmountVariationsAssociateParamName);
|
|
||||||
emiAmountVariations = this.loanReadPlatformService.retrieveLoanTermVariations(loanId,
|
|
||||||
LoanTermVariationType.EMI_AMOUNT.getValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (associationParameters.contains(DataTableApiConstant.repaymentScheduleAssociateParamName)) {
|
|
||||||
mandatoryResponseParameters.add(DataTableApiConstant.repaymentScheduleAssociateParamName);
|
|
||||||
final RepaymentScheduleRelatedLoanData repaymentScheduleRelatedData = loanBasicDetails.getTimeline()
|
|
||||||
.repaymentScheduleRelatedData(loanBasicDetails.getCurrency(), loanBasicDetails.getPrincipal(),
|
|
||||||
loanBasicDetails.getApprovedPrincipal(), loanBasicDetails.getInArrearsTolerance(),
|
|
||||||
loanBasicDetails.getFeeChargesAtDisbursementCharged());
|
|
||||||
repaymentSchedule = this.loanReadPlatformService.retrieveRepaymentSchedule(loanId, repaymentScheduleRelatedData,
|
|
||||||
disbursementData, loanBasicDetails.isInterestRecalculationEnabled(),
|
|
||||||
loanBasicDetails.getSummary() != null ? loanBasicDetails.getSummary().getFeeChargesPaid() : BigDecimal.ZERO);
|
|
||||||
|
|
||||||
if (associationParameters.contains(DataTableApiConstant.futureScheduleAssociateParamName)
|
|
||||||
&& loanBasicDetails.isInterestRecalculationEnabled()) {
|
|
||||||
mandatoryResponseParameters.add(DataTableApiConstant.futureScheduleAssociateParamName);
|
|
||||||
this.calculationPlatformService.updateFutureSchedule(repaymentSchedule, loanId);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (associationParameters.contains(DataTableApiConstant.originalScheduleAssociateParamName)
|
|
||||||
&& loanBasicDetails.isInterestRecalculationEnabled()
|
|
||||||
&& LoanStatus.fromInt(loanBasicDetails.getStatus().getId().intValue()).isActive()) {
|
|
||||||
mandatoryResponseParameters.add(DataTableApiConstant.originalScheduleAssociateParamName);
|
|
||||||
LoanScheduleData loanScheduleData = this.loanScheduleHistoryReadPlatformService.retrieveRepaymentArchiveSchedule(loanId,
|
|
||||||
repaymentScheduleRelatedData, disbursementData);
|
|
||||||
loanBasicDetails = LoanAccountData.withOriginalSchedule(loanBasicDetails, loanScheduleData);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (associationParameters.contains(DataTableApiConstant.chargesAssociateParamName)) {
|
|
||||||
mandatoryResponseParameters.add(DataTableApiConstant.chargesAssociateParamName);
|
|
||||||
charges = this.loanChargeReadPlatformService.retrieveLoanCharges(loanId);
|
|
||||||
if (CollectionUtils.isEmpty(charges)) {
|
|
||||||
charges = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (associationParameters.contains(DataTableApiConstant.collateralAssociateParamName)) {
|
|
||||||
mandatoryResponseParameters.add(DataTableApiConstant.collateralAssociateParamName);
|
|
||||||
loanCollateralManagements = this.loanCollateralManagementReadPlatformService.getLoanCollateralResponseDataList(loanId);
|
|
||||||
for (LoanCollateralResponseData loanCollateralManagement : loanCollateralManagements) {
|
|
||||||
loanCollateralManagementData.add(loanCollateralManagement.toCommand());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (associationParameters.contains(DataTableApiConstant.meetingAssociateParamName)) {
|
|
||||||
mandatoryResponseParameters.add(DataTableApiConstant.meetingAssociateParamName);
|
|
||||||
meeting = this.calendarReadPlatformService.retrieveLoanCalendar(loanId);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (associationParameters.contains(DataTableApiConstant.notesAssociateParamName)) {
|
|
||||||
mandatoryResponseParameters.add(DataTableApiConstant.notesAssociateParamName);
|
|
||||||
notes = this.noteReadPlatformService.retrieveNotesByResource(loanId, NoteType.LOAN.getValue());
|
|
||||||
if (CollectionUtils.isEmpty(notes)) {
|
|
||||||
notes = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (associationParameters.contains(DataTableApiConstant.linkedAccountAssociateParamName)) {
|
|
||||||
mandatoryResponseParameters.add(DataTableApiConstant.linkedAccountAssociateParamName);
|
|
||||||
linkedAccount = this.accountAssociationsReadPlatformService.retriveLoanLinkedAssociation(loanId);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (associationParameters.contains(DataTableApiConstant.collectionAssociateParamName)) {
|
|
||||||
mandatoryResponseParameters.add(DataTableApiConstant.collectionAssociateParamName);
|
|
||||||
if (loanBasicDetails.isActive()) {
|
|
||||||
collectionData = this.delinquencyReadPlatformService.calculateLoanCollectionData(loanId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Collection<LoanProductData> productOptions = null;
|
|
||||||
LoanProductData product;
|
|
||||||
Collection<EnumOptionData> loanTermFrequencyTypeOptions = null;
|
|
||||||
Collection<EnumOptionData> repaymentFrequencyTypeOptions = null;
|
|
||||||
Collection<EnumOptionData> repaymentFrequencyNthDayTypeOptions = null;
|
|
||||||
Collection<EnumOptionData> repaymentFrequencyDayOfWeekTypeOptions = null;
|
|
||||||
Collection<TransactionProcessingStrategyData> repaymentStrategyOptions = null;
|
|
||||||
Collection<EnumOptionData> interestRateFrequencyTypeOptions = null;
|
|
||||||
Collection<EnumOptionData> amortizationTypeOptions = null;
|
|
||||||
Collection<EnumOptionData> interestTypeOptions = null;
|
|
||||||
Collection<EnumOptionData> interestCalculationPeriodTypeOptions = null;
|
|
||||||
Collection<FundData> fundOptions = null;
|
|
||||||
Collection<StaffData> allowedLoanOfficers = null;
|
|
||||||
Collection<ChargeData> chargeOptions = null;
|
|
||||||
ChargeData chargeTemplate = null;
|
|
||||||
Collection<CodeValueData> loanPurposeOptions = null;
|
|
||||||
Collection<CodeValueData> loanCollateralOptions = null;
|
|
||||||
Collection<CalendarData> calendarOptions = null;
|
|
||||||
Collection<PortfolioAccountData> accountLinkingOptions = null;
|
|
||||||
PaidInAdvanceData paidInAdvanceTemplate;
|
|
||||||
Collection<LoanAccountSummaryData> clientActiveLoanOptions = null;
|
|
||||||
|
|
||||||
final boolean template = ApiParameterHelper.template(uriInfo.getQueryParameters());
|
|
||||||
if (template) {
|
|
||||||
productOptions = this.loanProductReadPlatformService.retrieveAllLoanProductsForLookup();
|
|
||||||
product = this.loanProductReadPlatformService.retrieveLoanProduct(loanBasicDetails.getLoanProductId());
|
|
||||||
loanBasicDetails.setProduct(product);
|
|
||||||
loanTermFrequencyTypeOptions = this.dropdownReadPlatformService.retrieveLoanTermFrequencyTypeOptions();
|
|
||||||
repaymentFrequencyTypeOptions = this.dropdownReadPlatformService.retrieveRepaymentFrequencyTypeOptions();
|
|
||||||
repaymentFrequencyNthDayTypeOptions = this.dropdownReadPlatformService.retrieveRepaymentFrequencyOptionsForNthDayOfMonth();
|
|
||||||
repaymentFrequencyDayOfWeekTypeOptions = this.dropdownReadPlatformService.retrieveRepaymentFrequencyOptionsForDaysOfWeek();
|
|
||||||
interestRateFrequencyTypeOptions = this.dropdownReadPlatformService.retrieveInterestRateFrequencyTypeOptions();
|
|
||||||
|
|
||||||
amortizationTypeOptions = this.dropdownReadPlatformService.retrieveLoanAmortizationTypeOptions();
|
|
||||||
if (product.isLinkedToFloatingInterestRates()) {
|
|
||||||
interestTypeOptions = Collections.singletonList(interestType(InterestMethod.DECLINING_BALANCE));
|
|
||||||
} else {
|
|
||||||
interestTypeOptions = this.dropdownReadPlatformService.retrieveLoanInterestTypeOptions();
|
|
||||||
}
|
|
||||||
interestCalculationPeriodTypeOptions = this.dropdownReadPlatformService.retrieveLoanInterestRateCalculatedInPeriodOptions();
|
|
||||||
|
|
||||||
fundOptions = this.fundReadPlatformService.retrieveAllFunds();
|
|
||||||
repaymentStrategyOptions = this.dropdownReadPlatformService.retrieveTransactionProcessingStrategies();
|
|
||||||
if (product.getMultiDisburseLoan()) {
|
|
||||||
chargeOptions = this.chargeReadPlatformService.retrieveLoanAccountApplicableCharges(loanId,
|
|
||||||
new ChargeTimeType[] { ChargeTimeType.OVERDUE_INSTALLMENT });
|
|
||||||
} else {
|
|
||||||
chargeOptions = this.chargeReadPlatformService.retrieveLoanAccountApplicableCharges(loanId,
|
|
||||||
new ChargeTimeType[] { ChargeTimeType.OVERDUE_INSTALLMENT, ChargeTimeType.TRANCHE_DISBURSEMENT });
|
|
||||||
}
|
|
||||||
chargeTemplate = this.loanChargeReadPlatformService.retrieveLoanChargeTemplate();
|
|
||||||
|
|
||||||
Long officeId = loanBasicDetails.getClientOfficeId();
|
|
||||||
|
|
||||||
if (officeId == null && loanBasicDetails.getGroup() != null) {
|
|
||||||
officeId = loanBasicDetails.getGroup().getOfficeId();
|
|
||||||
}
|
|
||||||
allowedLoanOfficers = this.loanReadPlatformService.retrieveAllowedLoanOfficers(officeId, staffInSelectedOfficeOnly);
|
|
||||||
|
|
||||||
loanPurposeOptions = this.codeValueReadPlatformService.retrieveCodeValuesByCode("LoanPurpose");
|
|
||||||
loanCollateralOptions = this.codeValueReadPlatformService.retrieveCodeValuesByCode("LoanCollateral");
|
|
||||||
final CurrencyData currencyData = loanBasicDetails.getCurrency();
|
|
||||||
String currencyCode = null;
|
|
||||||
if (currencyData != null) {
|
|
||||||
currencyCode = currencyData.getCode();
|
|
||||||
}
|
|
||||||
final long[] accountStatus = { SavingsAccountStatusType.ACTIVE.getValue() };
|
|
||||||
PortfolioAccountDTO portfolioAccountDTO = new PortfolioAccountDTO(PortfolioAccountType.SAVINGS.getValue(),
|
|
||||||
loanBasicDetails.getClientId(), currencyCode, accountStatus, DepositAccountType.SAVINGS_DEPOSIT.getValue());
|
|
||||||
accountLinkingOptions = this.portfolioAccountReadPlatformService.retrieveAllForLookup(portfolioAccountDTO);
|
|
||||||
|
|
||||||
if (!associationParameters.contains(DataTableApiConstant.linkedAccountAssociateParamName)) {
|
|
||||||
mandatoryResponseParameters.add(DataTableApiConstant.linkedAccountAssociateParamName);
|
|
||||||
linkedAccount = this.accountAssociationsReadPlatformService.retriveLoanLinkedAssociation(loanId);
|
|
||||||
}
|
|
||||||
if (loanBasicDetails.getGroup() != null && loanBasicDetails.getGroup().getId() != null) {
|
|
||||||
calendarOptions = this.loanReadPlatformService.retrieveCalendars(loanBasicDetails.getGroup().getId());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (loanBasicDetails.getProduct().isCanUseForTopup() && loanBasicDetails.getClientId() != null) {
|
|
||||||
clientActiveLoanOptions = this.accountDetailsReadPlatformService
|
|
||||||
.retrieveClientActiveLoanAccountSummary(loanBasicDetails.getClientId());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Collection<ChargeData> overdueCharges = this.chargeReadPlatformService
|
|
||||||
.retrieveLoanProductCharges(loanBasicDetails.getLoanProductId(), ChargeTimeType.OVERDUE_INSTALLMENT);
|
|
||||||
|
|
||||||
paidInAdvanceTemplate = this.loanReadPlatformService.retrieveTotalPaidInAdvance(loanId);
|
|
||||||
|
|
||||||
// Get rates from Loan
|
|
||||||
boolean isRatesEnabled = this.configurationDomainService.isSubRatesEnabled();
|
|
||||||
List<RateData> rates = null;
|
|
||||||
if (isRatesEnabled) {
|
|
||||||
rates = this.rateReadService.retrieveLoanRates(loanId);
|
|
||||||
}
|
|
||||||
|
|
||||||
// updating summary with transaction amounts summary
|
|
||||||
if (loanBasicDetails.getSummary() != null) {
|
|
||||||
loanBasicDetails
|
|
||||||
.setSummary(LoanSummaryData.withTransactionAmountsSummary(loanBasicDetails.getSummary(), currentLoanRepayments));
|
|
||||||
}
|
|
||||||
|
|
||||||
final LoanAccountData loanAccount = LoanAccountData.associationsAndTemplate(loanBasicDetails, repaymentSchedule, loanRepayments,
|
|
||||||
charges, loanCollateralManagementData, guarantors, meeting, productOptions, loanTermFrequencyTypeOptions,
|
|
||||||
repaymentFrequencyTypeOptions, repaymentFrequencyNthDayTypeOptions, repaymentFrequencyDayOfWeekTypeOptions,
|
|
||||||
repaymentStrategyOptions, interestRateFrequencyTypeOptions, amortizationTypeOptions, interestTypeOptions,
|
|
||||||
interestCalculationPeriodTypeOptions, fundOptions, chargeOptions, chargeTemplate, allowedLoanOfficers, loanPurposeOptions,
|
|
||||||
loanCollateralOptions, calendarOptions, notes, accountLinkingOptions, linkedAccount, disbursementData, emiAmountVariations,
|
|
||||||
overdueCharges, paidInAdvanceTemplate, interestRatesPeriods, clientActiveLoanOptions, rates, isRatesEnabled,
|
|
||||||
collectionData);
|
|
||||||
|
|
||||||
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters(),
|
|
||||||
mandatoryResponseParameters);
|
|
||||||
return this.toApiJsonSerializer.serialize(settings, loanAccount, LOAN_DATA_PARAMETERS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
@@ -807,20 +523,10 @@ public class LoansApiResource {
|
|||||||
@RequestBody(required = true, content = @Content(schema = @Schema(implementation = LoansApiResourceSwagger.PutLoansLoanIdRequest.class)))
|
@RequestBody(required = true, content = @Content(schema = @Schema(implementation = LoansApiResourceSwagger.PutLoansLoanIdRequest.class)))
|
||||||
@ApiResponses({
|
@ApiResponses({
|
||||||
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = LoansApiResourceSwagger.PutLoansLoanIdResponse.class))) })
|
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = LoansApiResourceSwagger.PutLoansLoanIdResponse.class))) })
|
||||||
public String modifyLoanApplication(@PathParam("loanId") @Parameter(description = "loanId") final Long loanId,
|
public String modifyLoanApplication(@PathParam("loanId") @Parameter(description = "loanId", required = true) final Long loanId,
|
||||||
@QueryParam("command") @Parameter(description = "command") final String commandParam,
|
@QueryParam("command") @Parameter(description = "command") final String commandParam,
|
||||||
@Parameter(hidden = true) final String apiRequestBodyAsJson) {
|
@Parameter(hidden = true) final String apiRequestBodyAsJson) {
|
||||||
|
return modifyLoanApplication(loanId, null, commandParam, apiRequestBodyAsJson);
|
||||||
final CommandWrapperBuilder builder = new CommandWrapperBuilder().withJson(apiRequestBodyAsJson);
|
|
||||||
CommandWrapper commandRequest = null;
|
|
||||||
if (CommandParameterUtil.is(commandParam, LoanApiConstants.MARK_AS_FRAUD_COMMAND)) {
|
|
||||||
commandRequest = builder.markAsFraud(loanId).build();
|
|
||||||
} else {
|
|
||||||
commandRequest = builder.updateLoanApplication(loanId).build();
|
|
||||||
}
|
|
||||||
|
|
||||||
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
|
||||||
return this.toApiJsonSerializer.serialize(result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@DELETE
|
@DELETE
|
||||||
@@ -830,13 +536,8 @@ public class LoansApiResource {
|
|||||||
@Operation(summary = "Delete a Loan Application", description = "Note: Only loans in \"Submitted and awaiting approval\" status can be deleted.")
|
@Operation(summary = "Delete a Loan Application", description = "Note: Only loans in \"Submitted and awaiting approval\" status can be deleted.")
|
||||||
@ApiResponses({
|
@ApiResponses({
|
||||||
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = LoansApiResourceSwagger.DeleteLoansLoanIdResponse.class))) })
|
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = LoansApiResourceSwagger.DeleteLoansLoanIdResponse.class))) })
|
||||||
public String deleteLoanApplication(@PathParam("loanId") @Parameter(description = "loanId") final Long loanId) {
|
public String deleteLoanApplication(@PathParam("loanId") @Parameter(description = "loanId", required = true) final Long loanId) {
|
||||||
|
return deleteLoanApplication(loanId, null);
|
||||||
final CommandWrapper commandRequest = new CommandWrapperBuilder().deleteLoanApplication(loanId).build();
|
|
||||||
|
|
||||||
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
|
||||||
|
|
||||||
return this.toApiJsonSerializer.serialize(result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@POST
|
@POST
|
||||||
@@ -858,44 +559,10 @@ public class LoansApiResource {
|
|||||||
@RequestBody(required = true, content = @Content(schema = @Schema(implementation = LoansApiResourceSwagger.PostLoansLoanIdRequest.class)))
|
@RequestBody(required = true, content = @Content(schema = @Schema(implementation = LoansApiResourceSwagger.PostLoansLoanIdRequest.class)))
|
||||||
@ApiResponses({
|
@ApiResponses({
|
||||||
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = LoansApiResourceSwagger.PostLoansLoanIdResponse.class))) })
|
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = LoansApiResourceSwagger.PostLoansLoanIdResponse.class))) })
|
||||||
public String stateTransitions(@PathParam("loanId") @Parameter(description = "loanId") final Long loanId,
|
public String stateTransitions(@PathParam("loanId") @Parameter(description = "loanId", required = true) final Long loanId,
|
||||||
@QueryParam("command") @Parameter(description = "command") final String commandParam,
|
@QueryParam("command") @Parameter(description = "command") final String commandParam,
|
||||||
@Parameter(hidden = true) final String apiRequestBodyAsJson) {
|
@Parameter(hidden = true) final String apiRequestBodyAsJson) {
|
||||||
|
return stateTransitions(loanId, null, commandParam, apiRequestBodyAsJson);
|
||||||
final CommandWrapperBuilder builder = new CommandWrapperBuilder().withJson(apiRequestBodyAsJson);
|
|
||||||
CommandWrapper commandRequest = null;
|
|
||||||
if (CommandParameterUtil.is(commandParam, "reject")) {
|
|
||||||
commandRequest = builder.rejectLoanApplication(loanId).build();
|
|
||||||
} else if (CommandParameterUtil.is(commandParam, "withdrawnByApplicant")) {
|
|
||||||
commandRequest = builder.withdrawLoanApplication(loanId).build();
|
|
||||||
} else if (CommandParameterUtil.is(commandParam, "approve")) {
|
|
||||||
commandRequest = builder.approveLoanApplication(loanId).build();
|
|
||||||
} else if (CommandParameterUtil.is(commandParam, "disburse")) {
|
|
||||||
commandRequest = builder.disburseLoanApplication(loanId).build();
|
|
||||||
} else if (CommandParameterUtil.is(commandParam, "disburseToSavings")) {
|
|
||||||
commandRequest = builder.disburseLoanToSavingsApplication(loanId).build();
|
|
||||||
} else if (CommandParameterUtil.is(commandParam, "undoapproval")) {
|
|
||||||
commandRequest = builder.undoLoanApplicationApproval(loanId).build();
|
|
||||||
} else if (CommandParameterUtil.is(commandParam, "undodisbursal")) {
|
|
||||||
commandRequest = builder.undoLoanApplicationDisbursal(loanId).build();
|
|
||||||
} else if (CommandParameterUtil.is(commandParam, "undolastdisbursal")) {
|
|
||||||
commandRequest = builder.undoLastDisbursalLoanApplication(loanId).build();
|
|
||||||
} else if (CommandParameterUtil.is(commandParam, "assignloanofficer")) {
|
|
||||||
commandRequest = builder.assignLoanOfficer(loanId).build();
|
|
||||||
} else if (CommandParameterUtil.is(commandParam, "unassignloanofficer")) {
|
|
||||||
commandRequest = builder.unassignLoanOfficer(loanId).build();
|
|
||||||
} else if (CommandParameterUtil.is(commandParam, "recoverGuarantees")) {
|
|
||||||
commandRequest = new CommandWrapperBuilder().recoverFromGuarantor(loanId).build();
|
|
||||||
} else if (CommandParameterUtil.is(commandParam, "assigndelinquency")) {
|
|
||||||
commandRequest = builder.assignDelinquency(loanId).build();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (commandRequest == null) {
|
|
||||||
throw new UnrecognizedQueryParamException("command", commandParam);
|
|
||||||
}
|
|
||||||
CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
|
||||||
|
|
||||||
return this.toApiJsonSerializer.serialize(result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
@@ -1001,12 +668,495 @@ public class LoansApiResource {
|
|||||||
@Operation(summary = "Retrieve the Loan Delinquency Tag history using the Loan Id", description = "")
|
@Operation(summary = "Retrieve the Loan Delinquency Tag history using the Loan Id", description = "")
|
||||||
@ApiResponses({
|
@ApiResponses({
|
||||||
@ApiResponse(responseCode = "200", description = "OK", content = @Content(array = @ArraySchema(schema = @Schema(implementation = DelinquencyApiResourceSwagger.GetDelinquencyTagHistoryResponse.class)))) })
|
@ApiResponse(responseCode = "200", description = "OK", content = @Content(array = @ArraySchema(schema = @Schema(implementation = DelinquencyApiResourceSwagger.GetDelinquencyTagHistoryResponse.class)))) })
|
||||||
public String getDelinquencyTagHistory(@PathParam("loanId") @Parameter(description = "loanId") final Long loanId,
|
public String getDelinquencyTagHistory(@PathParam("loanId") @Parameter(description = "loanId", required = true) final Long loanId,
|
||||||
@Context final UriInfo uriInfo) {
|
@Context final UriInfo uriInfo) {
|
||||||
|
return getDelinquencyTagHistory(loanId, null, uriInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
// External id related APIs
|
||||||
|
@GET
|
||||||
|
@Path("external-id/{loanExternalId}/template")
|
||||||
|
@Consumes({ MediaType.APPLICATION_JSON })
|
||||||
|
@Produces({ MediaType.APPLICATION_JSON })
|
||||||
|
@ApiResponses({
|
||||||
|
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = LoansApiResourceSwagger.GetLoansApprovalTemplateResponse.class))) })
|
||||||
|
public String retrieveApprovalTemplate(
|
||||||
|
@PathParam("loanExternalId") @Parameter(description = "loanExternalId", required = true) final String loanExternalId,
|
||||||
|
@QueryParam("templateType") @Parameter(description = "templateType") final String templateType,
|
||||||
|
@Context final UriInfo uriInfo) {
|
||||||
|
return retrieveApprovalTemplate(null, loanExternalId, templateType, uriInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("external-id/{loanExternalId}")
|
||||||
|
@Consumes({ MediaType.APPLICATION_JSON })
|
||||||
|
@Produces({ MediaType.APPLICATION_JSON })
|
||||||
|
@Operation(summary = "Retrieve a Loan", description = "Note: template=true parameter doesn't apply to this resource."
|
||||||
|
+ "Example Requests:\n" + "\n" + "loans/external-id/7dd80a7c-ycba-a446-t378-91eb6f53e854\n" + "\n" + "\n"
|
||||||
|
+ "loans/external-id/7dd80a7c-ycba-a446-t378-91eb6f53e854?fields=id,principal,annualInterestRate\n" + "\n" + "\n"
|
||||||
|
+ "loans/external-id/7dd80a7c-ycba-a446-t378-91eb6f53e854?associations=all\n" + "\n"
|
||||||
|
+ "loans/external-id/7dd80a7c-ycba-a446-t378-91eb6f53e854?associations=all&exclude=guarantors\n" + "\n" + "\n"
|
||||||
|
+ "loans/external-id/7dd80a7c-ycba-a446-t378-91eb6f53e854?fields=id,principal,annualInterestRate&associations=repaymentSchedule,transactions")
|
||||||
|
@ApiResponses({
|
||||||
|
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = LoansApiResourceSwagger.GetLoansLoanIdResponse.class))) })
|
||||||
|
public String retrieveLoan(
|
||||||
|
@PathParam("loanExternalId") @Parameter(description = "loanExternalId", required = true) final String loanExternalId,
|
||||||
|
@DefaultValue("false") @QueryParam("staffInSelectedOfficeOnly") @Parameter(description = "staffInSelectedOfficeOnly") final boolean staffInSelectedOfficeOnly,
|
||||||
|
@DefaultValue("all") @QueryParam("associations") @Parameter(in = ParameterIn.QUERY, name = "associations", description = "Loan object relations to be included in the response", required = false, examples = {
|
||||||
|
@ExampleObject(value = "all"), @ExampleObject(value = "repaymentSchedule,transactions") }) final String associations,
|
||||||
|
@QueryParam("exclude") @Parameter(in = ParameterIn.QUERY, name = "exclude", description = "Optional Loan object relation list to be filtered in the response", required = false, example = "guarantors,futureSchedule") final String exclude,
|
||||||
|
@QueryParam("fields") @Parameter(in = ParameterIn.QUERY, name = "fields", description = "Optional Loan attribute list to be in the response", required = false, example = "id,principal,annualInterestRate") final String fields,
|
||||||
|
@Context final UriInfo uriInfo) {
|
||||||
|
return retrieveLoan(null, loanExternalId, staffInSelectedOfficeOnly, exclude, uriInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PUT
|
||||||
|
@Path("external-id/{loanExternalId}")
|
||||||
|
@Consumes({ MediaType.APPLICATION_JSON })
|
||||||
|
@Produces({ MediaType.APPLICATION_JSON })
|
||||||
|
@Operation(summary = "Modify a loan application", description = "Loan application can only be modified when in 'Submitted and pending approval' state. Once the application is approved, the details cannot be changed using this method.")
|
||||||
|
@RequestBody(required = true, content = @Content(schema = @Schema(implementation = LoansApiResourceSwagger.PutLoansLoanIdRequest.class)))
|
||||||
|
@ApiResponses({
|
||||||
|
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = LoansApiResourceSwagger.PutLoansLoanIdResponse.class))) })
|
||||||
|
public String modifyLoanApplication(
|
||||||
|
@PathParam("loanExternalId") @Parameter(description = "loanExternalId", required = true) final String loanExternalId,
|
||||||
|
@QueryParam("command") @Parameter(description = "command") final String commandParam,
|
||||||
|
@Parameter(hidden = true) final String apiRequestBodyAsJson) {
|
||||||
|
return modifyLoanApplication(null, loanExternalId, commandParam, apiRequestBodyAsJson);
|
||||||
|
}
|
||||||
|
|
||||||
|
@DELETE
|
||||||
|
@Path("external-id/{loanExternalId}")
|
||||||
|
@Consumes({ MediaType.APPLICATION_JSON })
|
||||||
|
@Produces({ MediaType.APPLICATION_JSON })
|
||||||
|
@Operation(summary = "Delete a Loan Application", description = "Note: Only loans in \"Submitted and awaiting approval\" status can be deleted.")
|
||||||
|
@ApiResponses({
|
||||||
|
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = LoansApiResourceSwagger.DeleteLoansLoanIdResponse.class))) })
|
||||||
|
public String deleteLoanApplication(
|
||||||
|
@PathParam("loanExternalId") @Parameter(description = "loanExternalId", required = true) final String loanExternalId) {
|
||||||
|
return deleteLoanApplication(null, loanExternalId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@POST
|
||||||
|
@Path("external-id/{loanExternalId}")
|
||||||
|
@Consumes({ MediaType.APPLICATION_JSON })
|
||||||
|
@Produces({ MediaType.APPLICATION_JSON })
|
||||||
|
@Operation(summary = "Approve Loan Application | Recover Loan Guarantee | Undo Loan Application Approval | Assign a Loan Officer | Unassign a Loan Officer | Reject Loan Application | Applicant Withdraws from Loan Application | Disburse Loan Disburse Loan To Savings Account | Undo Loan Disbursal", description = "Approve Loan Application:\n"
|
||||||
|
+ "Mandatory Fields: approvedOnDate\n" + "Optional Fields: approvedLoanAmount and expectedDisbursementDate\n"
|
||||||
|
+ "Approves the loan application\n\n" + "Recover Loan Guarantee:\n" + "Recovers the loan guarantee\n\n"
|
||||||
|
+ "Undo Loan Application Approval:\n" + "Undoes the Loan Application Approval\n\n" + "Assign a Loan Officer:\n"
|
||||||
|
+ "Allows you to assign Loan Officer for existing Loan.\n\n" + "Unassign a Loan Officer:\n"
|
||||||
|
+ "Allows you to unassign the Loan Officer.\n\n" + "Reject Loan Application:\n" + "Mandatory Fields: rejectedOnDate\n"
|
||||||
|
+ "Allows you to reject the loan application\n\n" + "Applicant Withdraws from Loan Application:\n"
|
||||||
|
+ "Mandatory Fields: withdrawnOnDate\n" + "Allows the applicant to withdraw the loan application\n\n" + "Disburse Loan:\n"
|
||||||
|
+ "Mandatory Fields: actualDisbursementDate\n" + "Optional Fields: transactionAmount and fixedEmiAmount\n"
|
||||||
|
+ "Disburses the Loan\n\n" + "Disburse Loan To Savings Account:\n" + "Mandatory Fields: actualDisbursementDate\n"
|
||||||
|
+ "Optional Fields: transactionAmount and fixedEmiAmount\n" + "Disburses the loan to Saving Account\n\n"
|
||||||
|
+ "Undo Loan Disbursal:\n" + "Undoes the Loan Disbursal\n" + "Showing request and response for Assign a Loan Officer")
|
||||||
|
@RequestBody(required = true, content = @Content(schema = @Schema(implementation = LoansApiResourceSwagger.PostLoansLoanIdRequest.class)))
|
||||||
|
@ApiResponses({
|
||||||
|
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = LoansApiResourceSwagger.PostLoansLoanIdResponse.class))) })
|
||||||
|
public String stateTransitions(
|
||||||
|
@PathParam("loanExternalId") @Parameter(description = "loanExternalId", required = true) final String loanExternalId,
|
||||||
|
@QueryParam("command") @Parameter(description = "command") final String commandParam,
|
||||||
|
@Parameter(hidden = true) final String apiRequestBodyAsJson) {
|
||||||
|
return stateTransitions(null, loanExternalId, commandParam, apiRequestBodyAsJson);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("external-id/{loanExternalId}/delinquencytags")
|
||||||
|
@Consumes({ MediaType.TEXT_HTML, MediaType.APPLICATION_JSON })
|
||||||
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
@Operation(summary = "Retrieve the Loan Delinquency Tag history using the Loan Id", description = "")
|
||||||
|
@ApiResponses({
|
||||||
|
@ApiResponse(responseCode = "200", description = "OK", content = @Content(array = @ArraySchema(schema = @Schema(implementation = DelinquencyApiResourceSwagger.GetDelinquencyTagHistoryResponse.class)))) })
|
||||||
|
public String getDelinquencyTagHistory(
|
||||||
|
@PathParam("loanExternalId") @Parameter(description = "loanExternalId", required = true) final String loanExternalId,
|
||||||
|
@Context final UriInfo uriInfo) {
|
||||||
|
return getDelinquencyTagHistory(null, loanExternalId, uriInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String retrieveApprovalTemplate(final Long loanId, final String loanExternalIdStr, final String templateType,
|
||||||
|
final UriInfo uriInfo) {
|
||||||
|
this.context.authenticatedUser().validateHasReadPermission(RESOURCE_NAME_FOR_PERMISSIONS);
|
||||||
|
LoanApprovalData loanApprovalTemplate = null;
|
||||||
|
ExternalId loanExternalId = ExternalIdFactory.produce(loanExternalIdStr);
|
||||||
|
Long resolvedLoanId = getResolvedLoanId(loanId, loanExternalId);
|
||||||
|
if (templateType == null) {
|
||||||
|
final String errorMsg = "Loan template type must be provided";
|
||||||
|
throw new LoanTemplateTypeRequiredException(errorMsg);
|
||||||
|
} else if (templateType.equals("approval")) {
|
||||||
|
loanApprovalTemplate = this.loanReadPlatformService.retrieveApprovalTemplate(resolvedLoanId);
|
||||||
|
}
|
||||||
|
|
||||||
|
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
||||||
|
return this.loanApprovalDataToApiJsonSerializer.serialize(settings, loanApprovalTemplate, LOAN_APPROVAL_DATA_PARAMETERS);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String retrieveLoan(final Long loanId, final String loanExternalIdStr, boolean staffInSelectedOfficeOnly, final String exclude,
|
||||||
|
final UriInfo uriInfo) {
|
||||||
|
this.context.authenticatedUser().validateHasReadPermission(RESOURCE_NAME_FOR_PERMISSIONS);
|
||||||
|
ExternalId loanExternalId = ExternalIdFactory.produce(loanExternalIdStr);
|
||||||
|
Long resolvedLoanId = getResolvedLoanId(loanId, loanExternalId);
|
||||||
|
LoanAccountData loanBasicDetails = this.loanReadPlatformService.retrieveOne(resolvedLoanId);
|
||||||
|
if (loanBasicDetails.isInterestRecalculationEnabled()) {
|
||||||
|
Collection<CalendarData> interestRecalculationCalendarDatas = this.calendarReadPlatformService.retrieveCalendarsByEntity(
|
||||||
|
loanBasicDetails.getInterestRecalculationDetailId(), CalendarEntityType.LOAN_RECALCULATION_REST_DETAIL.getValue(),
|
||||||
|
null);
|
||||||
|
CalendarData calendarData = null;
|
||||||
|
if (!CollectionUtils.isEmpty(interestRecalculationCalendarDatas)) {
|
||||||
|
calendarData = interestRecalculationCalendarDatas.iterator().next();
|
||||||
|
}
|
||||||
|
|
||||||
|
Collection<CalendarData> interestRecalculationCompoundingCalendarDatas = this.calendarReadPlatformService
|
||||||
|
.retrieveCalendarsByEntity(loanBasicDetails.getInterestRecalculationDetailId(),
|
||||||
|
CalendarEntityType.LOAN_RECALCULATION_COMPOUNDING_DETAIL.getValue(), null);
|
||||||
|
CalendarData compoundingCalendarData = null;
|
||||||
|
if (!CollectionUtils.isEmpty(interestRecalculationCompoundingCalendarDatas)) {
|
||||||
|
compoundingCalendarData = interestRecalculationCompoundingCalendarDatas.iterator().next();
|
||||||
|
}
|
||||||
|
loanBasicDetails = LoanAccountData.withInterestRecalculationCalendarData(loanBasicDetails, calendarData,
|
||||||
|
compoundingCalendarData);
|
||||||
|
}
|
||||||
|
if (loanBasicDetails.getRepaymentFrequencyType() != null
|
||||||
|
&& loanBasicDetails.getRepaymentFrequencyType().getId().intValue() == PeriodFrequencyType.MONTHS.getValue()) {
|
||||||
|
Collection<CalendarData> loanCalendarDatas = this.calendarReadPlatformService.retrieveCalendarsByEntity(resolvedLoanId,
|
||||||
|
CalendarEntityType.LOANS.getValue(), null);
|
||||||
|
CalendarData calendarData = null;
|
||||||
|
if (!CollectionUtils.isEmpty(loanCalendarDatas)) {
|
||||||
|
calendarData = loanCalendarDatas.iterator().next();
|
||||||
|
}
|
||||||
|
if (calendarData != null) {
|
||||||
|
loanBasicDetails = LoanAccountData.withLoanCalendarData(loanBasicDetails, calendarData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Collection<InterestRatePeriodData> interestRatesPeriods = this.loanReadPlatformService
|
||||||
|
.retrieveLoanInterestRatePeriodData(loanBasicDetails);
|
||||||
|
Collection<LoanTransactionData> loanRepayments = null;
|
||||||
|
LoanScheduleData repaymentSchedule = null;
|
||||||
|
Collection<LoanChargeData> charges = null;
|
||||||
|
Collection<GuarantorData> guarantors = null;
|
||||||
|
CalendarData meeting = null;
|
||||||
|
Collection<NoteData> notes = null;
|
||||||
|
PortfolioAccountData linkedAccount = null;
|
||||||
|
Collection<DisbursementData> disbursementData = null;
|
||||||
|
Collection<LoanTermVariationsData> emiAmountVariations = null;
|
||||||
|
Collection<LoanCollateralResponseData> loanCollateralManagements;
|
||||||
|
Collection<LoanCollateralManagementData> loanCollateralManagementData = new ArrayList<>();
|
||||||
|
CollectionData collectionData = CollectionData.template();
|
||||||
|
|
||||||
|
final Set<String> mandatoryResponseParameters = new HashSet<>();
|
||||||
|
final Set<String> associationParameters = ApiParameterHelper.extractAssociationsForResponseIfProvided(uriInfo.getQueryParameters());
|
||||||
|
final Collection<LoanTransactionData> currentLoanRepayments = this.loanReadPlatformService.retrieveLoanTransactions(resolvedLoanId);
|
||||||
|
if (!associationParameters.isEmpty()) {
|
||||||
|
if (associationParameters.contains(DataTableApiConstant.allAssociateParamName)) {
|
||||||
|
associationParameters.addAll(Arrays.asList(DataTableApiConstant.repaymentScheduleAssociateParamName,
|
||||||
|
DataTableApiConstant.futureScheduleAssociateParamName, DataTableApiConstant.originalScheduleAssociateParamName,
|
||||||
|
DataTableApiConstant.transactionsAssociateParamName, DataTableApiConstant.chargesAssociateParamName,
|
||||||
|
DataTableApiConstant.guarantorsAssociateParamName, DataTableApiConstant.collateralAssociateParamName,
|
||||||
|
DataTableApiConstant.notesAssociateParamName, DataTableApiConstant.linkedAccountAssociateParamName,
|
||||||
|
DataTableApiConstant.multiDisburseDetailsAssociateParamName, DataTableApiConstant.collectionAssociateParamName));
|
||||||
|
}
|
||||||
|
|
||||||
|
ApiParameterHelper.excludeAssociationsForResponseIfProvided(exclude, associationParameters);
|
||||||
|
|
||||||
|
if (associationParameters.contains(DataTableApiConstant.guarantorsAssociateParamName)) {
|
||||||
|
mandatoryResponseParameters.add(DataTableApiConstant.guarantorsAssociateParamName);
|
||||||
|
guarantors = this.guarantorReadPlatformService.retrieveGuarantorsForLoan(resolvedLoanId);
|
||||||
|
if (CollectionUtils.isEmpty(guarantors)) {
|
||||||
|
guarantors = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (associationParameters.contains(DataTableApiConstant.transactionsAssociateParamName)) {
|
||||||
|
mandatoryResponseParameters.add(DataTableApiConstant.transactionsAssociateParamName);
|
||||||
|
if (!CollectionUtils.isEmpty(currentLoanRepayments)) {
|
||||||
|
loanRepayments = currentLoanRepayments;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (associationParameters.contains(DataTableApiConstant.multiDisburseDetailsAssociateParamName)
|
||||||
|
|| associationParameters.contains(DataTableApiConstant.repaymentScheduleAssociateParamName)) {
|
||||||
|
mandatoryResponseParameters.add(DataTableApiConstant.multiDisburseDetailsAssociateParamName);
|
||||||
|
disbursementData = this.loanReadPlatformService.retrieveLoanDisbursementDetails(resolvedLoanId);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (associationParameters.contains(DataTableApiConstant.emiAmountVariationsAssociateParamName)
|
||||||
|
|| associationParameters.contains(DataTableApiConstant.repaymentScheduleAssociateParamName)) {
|
||||||
|
mandatoryResponseParameters.add(DataTableApiConstant.emiAmountVariationsAssociateParamName);
|
||||||
|
emiAmountVariations = this.loanReadPlatformService.retrieveLoanTermVariations(resolvedLoanId,
|
||||||
|
LoanTermVariationType.EMI_AMOUNT.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (associationParameters.contains(DataTableApiConstant.repaymentScheduleAssociateParamName)) {
|
||||||
|
mandatoryResponseParameters.add(DataTableApiConstant.repaymentScheduleAssociateParamName);
|
||||||
|
final RepaymentScheduleRelatedLoanData repaymentScheduleRelatedData = loanBasicDetails.getTimeline()
|
||||||
|
.repaymentScheduleRelatedData(loanBasicDetails.getCurrency(), loanBasicDetails.getPrincipal(),
|
||||||
|
loanBasicDetails.getApprovedPrincipal(), loanBasicDetails.getInArrearsTolerance(),
|
||||||
|
loanBasicDetails.getFeeChargesAtDisbursementCharged());
|
||||||
|
repaymentSchedule = this.loanReadPlatformService.retrieveRepaymentSchedule(resolvedLoanId, repaymentScheduleRelatedData,
|
||||||
|
disbursementData, loanBasicDetails.isInterestRecalculationEnabled(),
|
||||||
|
loanBasicDetails.getSummary() != null ? loanBasicDetails.getSummary().getFeeChargesPaid() : BigDecimal.ZERO);
|
||||||
|
|
||||||
|
if (associationParameters.contains(DataTableApiConstant.futureScheduleAssociateParamName)
|
||||||
|
&& loanBasicDetails.isInterestRecalculationEnabled()) {
|
||||||
|
mandatoryResponseParameters.add(DataTableApiConstant.futureScheduleAssociateParamName);
|
||||||
|
this.calculationPlatformService.updateFutureSchedule(repaymentSchedule, resolvedLoanId);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (associationParameters.contains(DataTableApiConstant.originalScheduleAssociateParamName)
|
||||||
|
&& loanBasicDetails.isInterestRecalculationEnabled()
|
||||||
|
&& LoanStatus.fromInt(loanBasicDetails.getStatus().getId().intValue()).isActive()) {
|
||||||
|
mandatoryResponseParameters.add(DataTableApiConstant.originalScheduleAssociateParamName);
|
||||||
|
LoanScheduleData loanScheduleData = this.loanScheduleHistoryReadPlatformService
|
||||||
|
.retrieveRepaymentArchiveSchedule(resolvedLoanId, repaymentScheduleRelatedData, disbursementData);
|
||||||
|
loanBasicDetails = LoanAccountData.withOriginalSchedule(loanBasicDetails, loanScheduleData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (associationParameters.contains(DataTableApiConstant.chargesAssociateParamName)) {
|
||||||
|
mandatoryResponseParameters.add(DataTableApiConstant.chargesAssociateParamName);
|
||||||
|
charges = this.loanChargeReadPlatformService.retrieveLoanCharges(resolvedLoanId);
|
||||||
|
if (CollectionUtils.isEmpty(charges)) {
|
||||||
|
charges = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (associationParameters.contains(DataTableApiConstant.collateralAssociateParamName)) {
|
||||||
|
mandatoryResponseParameters.add(DataTableApiConstant.collateralAssociateParamName);
|
||||||
|
loanCollateralManagements = this.loanCollateralManagementReadPlatformService
|
||||||
|
.getLoanCollateralResponseDataList(resolvedLoanId);
|
||||||
|
for (LoanCollateralResponseData loanCollateralManagement : loanCollateralManagements) {
|
||||||
|
loanCollateralManagementData.add(loanCollateralManagement.toCommand());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (associationParameters.contains(DataTableApiConstant.meetingAssociateParamName)) {
|
||||||
|
mandatoryResponseParameters.add(DataTableApiConstant.meetingAssociateParamName);
|
||||||
|
meeting = this.calendarReadPlatformService.retrieveLoanCalendar(resolvedLoanId);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (associationParameters.contains(DataTableApiConstant.notesAssociateParamName)) {
|
||||||
|
mandatoryResponseParameters.add(DataTableApiConstant.notesAssociateParamName);
|
||||||
|
notes = this.noteReadPlatformService.retrieveNotesByResource(resolvedLoanId, NoteType.LOAN.getValue());
|
||||||
|
if (CollectionUtils.isEmpty(notes)) {
|
||||||
|
notes = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (associationParameters.contains(DataTableApiConstant.linkedAccountAssociateParamName)) {
|
||||||
|
mandatoryResponseParameters.add(DataTableApiConstant.linkedAccountAssociateParamName);
|
||||||
|
linkedAccount = this.accountAssociationsReadPlatformService.retriveLoanLinkedAssociation(resolvedLoanId);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (associationParameters.contains(DataTableApiConstant.collectionAssociateParamName)) {
|
||||||
|
mandatoryResponseParameters.add(DataTableApiConstant.collectionAssociateParamName);
|
||||||
|
if (loanBasicDetails.isActive()) {
|
||||||
|
collectionData = this.delinquencyReadPlatformService.calculateLoanCollectionData(resolvedLoanId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Collection<LoanProductData> productOptions = null;
|
||||||
|
LoanProductData product;
|
||||||
|
Collection<EnumOptionData> loanTermFrequencyTypeOptions = null;
|
||||||
|
Collection<EnumOptionData> repaymentFrequencyTypeOptions = null;
|
||||||
|
Collection<EnumOptionData> repaymentFrequencyNthDayTypeOptions = null;
|
||||||
|
Collection<EnumOptionData> repaymentFrequencyDayOfWeekTypeOptions = null;
|
||||||
|
Collection<TransactionProcessingStrategyData> repaymentStrategyOptions = null;
|
||||||
|
Collection<EnumOptionData> interestRateFrequencyTypeOptions = null;
|
||||||
|
Collection<EnumOptionData> amortizationTypeOptions = null;
|
||||||
|
Collection<EnumOptionData> interestTypeOptions = null;
|
||||||
|
Collection<EnumOptionData> interestCalculationPeriodTypeOptions = null;
|
||||||
|
Collection<FundData> fundOptions = null;
|
||||||
|
Collection<StaffData> allowedLoanOfficers = null;
|
||||||
|
Collection<ChargeData> chargeOptions = null;
|
||||||
|
ChargeData chargeTemplate = null;
|
||||||
|
Collection<CodeValueData> loanPurposeOptions = null;
|
||||||
|
Collection<CodeValueData> loanCollateralOptions = null;
|
||||||
|
Collection<CalendarData> calendarOptions = null;
|
||||||
|
Collection<PortfolioAccountData> accountLinkingOptions = null;
|
||||||
|
PaidInAdvanceData paidInAdvanceTemplate;
|
||||||
|
Collection<LoanAccountSummaryData> clientActiveLoanOptions = null;
|
||||||
|
|
||||||
|
final boolean template = ApiParameterHelper.template(uriInfo.getQueryParameters());
|
||||||
|
if (template) {
|
||||||
|
productOptions = this.loanProductReadPlatformService.retrieveAllLoanProductsForLookup();
|
||||||
|
product = this.loanProductReadPlatformService.retrieveLoanProduct(loanBasicDetails.getLoanProductId());
|
||||||
|
loanBasicDetails.setProduct(product);
|
||||||
|
loanTermFrequencyTypeOptions = this.dropdownReadPlatformService.retrieveLoanTermFrequencyTypeOptions();
|
||||||
|
repaymentFrequencyTypeOptions = this.dropdownReadPlatformService.retrieveRepaymentFrequencyTypeOptions();
|
||||||
|
repaymentFrequencyNthDayTypeOptions = this.dropdownReadPlatformService.retrieveRepaymentFrequencyOptionsForNthDayOfMonth();
|
||||||
|
repaymentFrequencyDayOfWeekTypeOptions = this.dropdownReadPlatformService.retrieveRepaymentFrequencyOptionsForDaysOfWeek();
|
||||||
|
interestRateFrequencyTypeOptions = this.dropdownReadPlatformService.retrieveInterestRateFrequencyTypeOptions();
|
||||||
|
|
||||||
|
amortizationTypeOptions = this.dropdownReadPlatformService.retrieveLoanAmortizationTypeOptions();
|
||||||
|
if (product.isLinkedToFloatingInterestRates()) {
|
||||||
|
interestTypeOptions = Collections.singletonList(interestType(InterestMethod.DECLINING_BALANCE));
|
||||||
|
} else {
|
||||||
|
interestTypeOptions = this.dropdownReadPlatformService.retrieveLoanInterestTypeOptions();
|
||||||
|
}
|
||||||
|
interestCalculationPeriodTypeOptions = this.dropdownReadPlatformService.retrieveLoanInterestRateCalculatedInPeriodOptions();
|
||||||
|
|
||||||
|
fundOptions = this.fundReadPlatformService.retrieveAllFunds();
|
||||||
|
repaymentStrategyOptions = this.dropdownReadPlatformService.retrieveTransactionProcessingStrategies();
|
||||||
|
if (product.getMultiDisburseLoan()) {
|
||||||
|
chargeOptions = this.chargeReadPlatformService.retrieveLoanAccountApplicableCharges(resolvedLoanId,
|
||||||
|
new ChargeTimeType[] { ChargeTimeType.OVERDUE_INSTALLMENT });
|
||||||
|
} else {
|
||||||
|
chargeOptions = this.chargeReadPlatformService.retrieveLoanAccountApplicableCharges(resolvedLoanId,
|
||||||
|
new ChargeTimeType[] { ChargeTimeType.OVERDUE_INSTALLMENT, ChargeTimeType.TRANCHE_DISBURSEMENT });
|
||||||
|
}
|
||||||
|
chargeTemplate = this.loanChargeReadPlatformService.retrieveLoanChargeTemplate();
|
||||||
|
|
||||||
|
Long officeId = loanBasicDetails.getClientOfficeId();
|
||||||
|
|
||||||
|
if (officeId == null && loanBasicDetails.getGroup() != null) {
|
||||||
|
officeId = loanBasicDetails.getGroup().getOfficeId();
|
||||||
|
}
|
||||||
|
allowedLoanOfficers = this.loanReadPlatformService.retrieveAllowedLoanOfficers(officeId, staffInSelectedOfficeOnly);
|
||||||
|
|
||||||
|
loanPurposeOptions = this.codeValueReadPlatformService.retrieveCodeValuesByCode("LoanPurpose");
|
||||||
|
loanCollateralOptions = this.codeValueReadPlatformService.retrieveCodeValuesByCode("LoanCollateral");
|
||||||
|
final CurrencyData currencyData = loanBasicDetails.getCurrency();
|
||||||
|
String currencyCode = null;
|
||||||
|
if (currencyData != null) {
|
||||||
|
currencyCode = currencyData.getCode();
|
||||||
|
}
|
||||||
|
final long[] accountStatus = { SavingsAccountStatusType.ACTIVE.getValue() };
|
||||||
|
PortfolioAccountDTO portfolioAccountDTO = new PortfolioAccountDTO(PortfolioAccountType.SAVINGS.getValue(),
|
||||||
|
loanBasicDetails.getClientId(), currencyCode, accountStatus, DepositAccountType.SAVINGS_DEPOSIT.getValue());
|
||||||
|
accountLinkingOptions = this.portfolioAccountReadPlatformService.retrieveAllForLookup(portfolioAccountDTO);
|
||||||
|
|
||||||
|
if (!associationParameters.contains(DataTableApiConstant.linkedAccountAssociateParamName)) {
|
||||||
|
mandatoryResponseParameters.add(DataTableApiConstant.linkedAccountAssociateParamName);
|
||||||
|
linkedAccount = this.accountAssociationsReadPlatformService.retriveLoanLinkedAssociation(resolvedLoanId);
|
||||||
|
}
|
||||||
|
if (loanBasicDetails.getGroup() != null && loanBasicDetails.getGroup().getId() != null) {
|
||||||
|
calendarOptions = this.loanReadPlatformService.retrieveCalendars(loanBasicDetails.getGroup().getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (loanBasicDetails.getProduct().isCanUseForTopup() && loanBasicDetails.getClientId() != null) {
|
||||||
|
clientActiveLoanOptions = this.accountDetailsReadPlatformService
|
||||||
|
.retrieveClientActiveLoanAccountSummary(loanBasicDetails.getClientId());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Collection<ChargeData> overdueCharges = this.chargeReadPlatformService
|
||||||
|
.retrieveLoanProductCharges(loanBasicDetails.getLoanProductId(), ChargeTimeType.OVERDUE_INSTALLMENT);
|
||||||
|
|
||||||
|
paidInAdvanceTemplate = this.loanReadPlatformService.retrieveTotalPaidInAdvance(resolvedLoanId);
|
||||||
|
|
||||||
|
// Get rates from Loan
|
||||||
|
boolean isRatesEnabled = this.configurationDomainService.isSubRatesEnabled();
|
||||||
|
List<RateData> rates = null;
|
||||||
|
if (isRatesEnabled) {
|
||||||
|
rates = this.rateReadService.retrieveLoanRates(resolvedLoanId);
|
||||||
|
}
|
||||||
|
|
||||||
|
// updating summary with transaction amounts summary
|
||||||
|
if (loanBasicDetails.getSummary() != null) {
|
||||||
|
loanBasicDetails
|
||||||
|
.setSummary(LoanSummaryData.withTransactionAmountsSummary(loanBasicDetails.getSummary(), currentLoanRepayments));
|
||||||
|
}
|
||||||
|
|
||||||
|
final LoanAccountData loanAccount = LoanAccountData.associationsAndTemplate(loanBasicDetails, repaymentSchedule, loanRepayments,
|
||||||
|
charges, loanCollateralManagementData, guarantors, meeting, productOptions, loanTermFrequencyTypeOptions,
|
||||||
|
repaymentFrequencyTypeOptions, repaymentFrequencyNthDayTypeOptions, repaymentFrequencyDayOfWeekTypeOptions,
|
||||||
|
repaymentStrategyOptions, interestRateFrequencyTypeOptions, amortizationTypeOptions, interestTypeOptions,
|
||||||
|
interestCalculationPeriodTypeOptions, fundOptions, chargeOptions, chargeTemplate, allowedLoanOfficers, loanPurposeOptions,
|
||||||
|
loanCollateralOptions, calendarOptions, notes, accountLinkingOptions, linkedAccount, disbursementData, emiAmountVariations,
|
||||||
|
overdueCharges, paidInAdvanceTemplate, interestRatesPeriods, clientActiveLoanOptions, rates, isRatesEnabled,
|
||||||
|
collectionData);
|
||||||
|
|
||||||
|
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters(),
|
||||||
|
mandatoryResponseParameters);
|
||||||
|
return this.toApiJsonSerializer.serialize(settings, loanAccount, LOAN_DATA_PARAMETERS);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String modifyLoanApplication(final Long loanId, final String loanExternalIdStr, final String commandParam,
|
||||||
|
final String apiRequestBodyAsJson) {
|
||||||
|
final CommandWrapperBuilder builder = new CommandWrapperBuilder().withJson(apiRequestBodyAsJson);
|
||||||
|
CommandWrapper commandRequest;
|
||||||
|
ExternalId loanExternalId = ExternalIdFactory.produce(loanExternalIdStr);
|
||||||
|
Long resolvedLoanId = getResolvedLoanId(loanId, loanExternalId);
|
||||||
|
if (CommandParameterUtil.is(commandParam, LoanApiConstants.MARK_AS_FRAUD_COMMAND)) {
|
||||||
|
commandRequest = builder.markAsFraud(resolvedLoanId).build();
|
||||||
|
} else {
|
||||||
|
commandRequest = builder.updateLoanApplication(resolvedLoanId).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
||||||
|
return this.toApiJsonSerializer.serialize(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String deleteLoanApplication(final Long loanId, final String loanExternalIdStr) {
|
||||||
|
ExternalId loanExternalId = ExternalIdFactory.produce(loanExternalIdStr);
|
||||||
|
Long resolvedLoanId = getResolvedLoanId(loanId, loanExternalId);
|
||||||
|
final CommandWrapper commandRequest = new CommandWrapperBuilder().deleteLoanApplication(resolvedLoanId).build();
|
||||||
|
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
||||||
|
return this.toApiJsonSerializer.serialize(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String stateTransitions(final Long loanId, final String loanExternalIdStr, final String commandParam,
|
||||||
|
final String apiRequestBodyAsJson) {
|
||||||
|
ExternalId loanExternalId = ExternalIdFactory.produce(loanExternalIdStr);
|
||||||
|
Long resolvedLoanId = getResolvedLoanId(loanId, loanExternalId);
|
||||||
|
final CommandWrapperBuilder builder = new CommandWrapperBuilder().withJson(apiRequestBodyAsJson);
|
||||||
|
CommandWrapper commandRequest = null;
|
||||||
|
if (CommandParameterUtil.is(commandParam, "reject")) {
|
||||||
|
commandRequest = builder.rejectLoanApplication(resolvedLoanId).build();
|
||||||
|
} else if (CommandParameterUtil.is(commandParam, "withdrawnByApplicant")) {
|
||||||
|
commandRequest = builder.withdrawLoanApplication(resolvedLoanId).build();
|
||||||
|
} else if (CommandParameterUtil.is(commandParam, "approve")) {
|
||||||
|
commandRequest = builder.approveLoanApplication(resolvedLoanId).build();
|
||||||
|
} else if (CommandParameterUtil.is(commandParam, "disburse")) {
|
||||||
|
commandRequest = builder.disburseLoanApplication(resolvedLoanId).build();
|
||||||
|
} else if (CommandParameterUtil.is(commandParam, "disburseToSavings")) {
|
||||||
|
commandRequest = builder.disburseLoanToSavingsApplication(resolvedLoanId).build();
|
||||||
|
} else if (CommandParameterUtil.is(commandParam, "undoapproval")) {
|
||||||
|
commandRequest = builder.undoLoanApplicationApproval(resolvedLoanId).build();
|
||||||
|
} else if (CommandParameterUtil.is(commandParam, "undodisbursal")) {
|
||||||
|
commandRequest = builder.undoLoanApplicationDisbursal(resolvedLoanId).build();
|
||||||
|
} else if (CommandParameterUtil.is(commandParam, "undolastdisbursal")) {
|
||||||
|
commandRequest = builder.undoLastDisbursalLoanApplication(resolvedLoanId).build();
|
||||||
|
} else if (CommandParameterUtil.is(commandParam, "assignloanofficer")) {
|
||||||
|
commandRequest = builder.assignLoanOfficer(resolvedLoanId).build();
|
||||||
|
} else if (CommandParameterUtil.is(commandParam, "unassignloanofficer")) {
|
||||||
|
commandRequest = builder.unassignLoanOfficer(resolvedLoanId).build();
|
||||||
|
} else if (CommandParameterUtil.is(commandParam, "recoverGuarantees")) {
|
||||||
|
commandRequest = new CommandWrapperBuilder().recoverFromGuarantor(resolvedLoanId).build();
|
||||||
|
} else if (CommandParameterUtil.is(commandParam, "assigndelinquency")) {
|
||||||
|
commandRequest = builder.assignDelinquency(resolvedLoanId).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (commandRequest == null) {
|
||||||
|
throw new UnrecognizedQueryParamException("command", commandParam);
|
||||||
|
}
|
||||||
|
CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
||||||
|
|
||||||
|
return this.toApiJsonSerializer.serialize(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getDelinquencyTagHistory(final Long loanId, final String loanExternalIdStr, final UriInfo uriInfo) {
|
||||||
context.authenticatedUser().validateHasReadPermission("DELINQUENCY_TAGS");
|
context.authenticatedUser().validateHasReadPermission("DELINQUENCY_TAGS");
|
||||||
|
ExternalId loanExternalId = ExternalIdFactory.produce(loanExternalIdStr);
|
||||||
|
Long resolvedLoanId = getResolvedLoanId(loanId, loanExternalId);
|
||||||
final Collection<LoanDelinquencyTagHistoryData> loanDelinquencyTagHistoryData = this.delinquencyReadPlatformService
|
final Collection<LoanDelinquencyTagHistoryData> loanDelinquencyTagHistoryData = this.delinquencyReadPlatformService
|
||||||
.retrieveDelinquencyRangeHistory(loanId);
|
.retrieveDelinquencyRangeHistory(resolvedLoanId);
|
||||||
return this.jsonSerializerTagHistory.serialize(loanDelinquencyTagHistoryData);
|
return this.jsonSerializerTagHistory.serialize(loanDelinquencyTagHistoryData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Long getResolvedLoanId(final Long loanId, final ExternalId loanExternalId) {
|
||||||
|
Long resolvedLoanId = loanId;
|
||||||
|
if (resolvedLoanId == null) {
|
||||||
|
loanExternalId.throwExceptionIfEmpty();
|
||||||
|
resolvedLoanId = this.loanReadPlatformService.retrieveLoanIdByExternalId(loanExternalId);
|
||||||
|
if (resolvedLoanId == null) {
|
||||||
|
throw new LoanNotFoundException(loanExternalId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return resolvedLoanId;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+28
@@ -32,6 +32,19 @@ final class LoansApiResourceSwagger {
|
|||||||
|
|
||||||
private LoansApiResourceSwagger() {}
|
private LoansApiResourceSwagger() {}
|
||||||
|
|
||||||
|
@Schema(description = "GetLoansApprovalTemplateResponse")
|
||||||
|
public static final class GetLoansApprovalTemplateResponse {
|
||||||
|
|
||||||
|
private GetLoansApprovalTemplateResponse() {}
|
||||||
|
|
||||||
|
@Schema(example = "[2012, 4, 3]")
|
||||||
|
public LocalDate approvalDate;
|
||||||
|
@Schema(example = "200.000000")
|
||||||
|
public Double approvalAmount;
|
||||||
|
@Schema(example = "200.000000")
|
||||||
|
public Double netDisbursalAmount;
|
||||||
|
}
|
||||||
|
|
||||||
@Schema(description = "GetLoansTemplateResponse")
|
@Schema(description = "GetLoansTemplateResponse")
|
||||||
public static final class GetLoansTemplateResponse {
|
public static final class GetLoansTemplateResponse {
|
||||||
|
|
||||||
@@ -935,6 +948,8 @@ final class LoansApiResourceSwagger {
|
|||||||
|
|
||||||
@Schema(example = "1")
|
@Schema(example = "1")
|
||||||
public Long id;
|
public Long id;
|
||||||
|
@Schema(example = "95174ff9-1a75-4d72-a413-6f9b1cb988b7")
|
||||||
|
public String externalId;
|
||||||
@Schema(example = "000000001")
|
@Schema(example = "000000001")
|
||||||
public Long accountNo;
|
public Long accountNo;
|
||||||
public GetLoansLoanIdStatus status;
|
public GetLoansLoanIdStatus status;
|
||||||
@@ -1302,6 +1317,8 @@ final class LoansApiResourceSwagger {
|
|||||||
public Integer loanId;
|
public Integer loanId;
|
||||||
@Schema(example = "1")
|
@Schema(example = "1")
|
||||||
public Integer resourceId;
|
public Integer resourceId;
|
||||||
|
@Schema(example = "95174ff9-1a75-4d72-a413-6f9b1cb988b7")
|
||||||
|
public String resourceExternalId;
|
||||||
public PutLoansLoanIdChanges changes;
|
public PutLoansLoanIdChanges changes;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1318,6 +1335,8 @@ final class LoansApiResourceSwagger {
|
|||||||
public Integer loanId;
|
public Integer loanId;
|
||||||
@Schema(example = "1")
|
@Schema(example = "1")
|
||||||
public Integer resourceId;
|
public Integer resourceId;
|
||||||
|
@Schema(example = "95174ff9-1a75-4d72-a413-6f9b1cb988b7")
|
||||||
|
public String resourceExternalId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Schema(description = "PostLoansLoanIdRequest")
|
@Schema(description = "PostLoansLoanIdRequest")
|
||||||
@@ -1339,6 +1358,9 @@ final class LoansApiResourceSwagger {
|
|||||||
public Integer toLoanOfficerId;
|
public Integer toLoanOfficerId;
|
||||||
@Schema(example = "02 September 2014")
|
@Schema(example = "02 September 2014")
|
||||||
public String assignmentDate;
|
public String assignmentDate;
|
||||||
|
|
||||||
|
@Schema(example = "02 September 2014")
|
||||||
|
public String unassignedDate;
|
||||||
@Schema(example = "en")
|
@Schema(example = "en")
|
||||||
public String locale;
|
public String locale;
|
||||||
@Schema(example = "dd MMMM yyyy")
|
@Schema(example = "dd MMMM yyyy")
|
||||||
@@ -1361,6 +1383,10 @@ final class LoansApiResourceSwagger {
|
|||||||
public String approvedLoanAmount;
|
public String approvedLoanAmount;
|
||||||
@Schema(example = "28 June 2022")
|
@Schema(example = "28 June 2022")
|
||||||
public String expectedDisbursementDate;
|
public String expectedDisbursementDate;
|
||||||
|
@Schema(example = "28 June 2022")
|
||||||
|
public String rejectedOnDate;
|
||||||
|
@Schema(example = "28 June 2022")
|
||||||
|
public String withdrawnOnDate;
|
||||||
@Schema(description = "List of PostLoansLoanIdDisbursementData")
|
@Schema(description = "List of PostLoansLoanIdDisbursementData")
|
||||||
public List<PostLoansLoanIdDisbursementData> disbursementData;
|
public List<PostLoansLoanIdDisbursementData> disbursementData;
|
||||||
}
|
}
|
||||||
@@ -1422,6 +1448,8 @@ final class LoansApiResourceSwagger {
|
|||||||
public Integer loanId;
|
public Integer loanId;
|
||||||
@Schema(example = "3")
|
@Schema(example = "3")
|
||||||
public Integer resourceId;
|
public Integer resourceId;
|
||||||
|
@Schema(example = "95174ff9-1a75-4d72-a413-6f9b1cb988b7")
|
||||||
|
public String resourceExternalId;
|
||||||
@Schema(description = "PostLoansLoanIdChanges")
|
@Schema(description = "PostLoansLoanIdChanges")
|
||||||
public PostLoansLoanIdChanges changes;
|
public PostLoansLoanIdChanges changes;
|
||||||
}
|
}
|
||||||
|
|||||||
+21
-19
@@ -33,6 +33,7 @@ import lombok.NoArgsConstructor;
|
|||||||
import lombok.experimental.Accessors;
|
import lombok.experimental.Accessors;
|
||||||
import org.apache.fineract.infrastructure.codes.data.CodeValueData;
|
import org.apache.fineract.infrastructure.codes.data.CodeValueData;
|
||||||
import org.apache.fineract.infrastructure.core.data.EnumOptionData;
|
import org.apache.fineract.infrastructure.core.data.EnumOptionData;
|
||||||
|
import org.apache.fineract.infrastructure.core.domain.ExternalId;
|
||||||
import org.apache.fineract.infrastructure.dataqueries.data.DatatableData;
|
import org.apache.fineract.infrastructure.dataqueries.data.DatatableData;
|
||||||
import org.apache.fineract.organisation.monetary.data.CurrencyData;
|
import org.apache.fineract.organisation.monetary.data.CurrencyData;
|
||||||
import org.apache.fineract.organisation.staff.data.StaffData;
|
import org.apache.fineract.organisation.staff.data.StaffData;
|
||||||
@@ -65,7 +66,7 @@ public class LoanAccountData {
|
|||||||
// identity
|
// identity
|
||||||
private Long id;
|
private Long id;
|
||||||
private String accountNo;
|
private String accountNo;
|
||||||
private String externalId;
|
private ExternalId externalId = ExternalId.empty();
|
||||||
|
|
||||||
// status
|
// status
|
||||||
private LoanStatusEnumData status;
|
private LoanStatusEnumData status;
|
||||||
@@ -260,7 +261,7 @@ public class LoanAccountData {
|
|||||||
EnumOptionData amortizationEnumOption, EnumOptionData interestMethodEnum, EnumOptionData interestCalculationPeriodTypeEnum,
|
EnumOptionData amortizationEnumOption, EnumOptionData interestMethodEnum, EnumOptionData interestCalculationPeriodTypeEnum,
|
||||||
BigDecimal inArrearsTolerance, String transactionProcessingStrategyCode, Integer graceOnPrincipalPayment,
|
BigDecimal inArrearsTolerance, String transactionProcessingStrategyCode, Integer graceOnPrincipalPayment,
|
||||||
Integer graceOnInterestPayment, Integer graceOnInterestCharged, LocalDate interestChargedFromDate,
|
Integer graceOnInterestPayment, Integer graceOnInterestCharged, LocalDate interestChargedFromDate,
|
||||||
LocalDate repaymentsStartingFromDate, Integer rowIndex, String externalId, Long groupId, Collection<LoanChargeData> charges,
|
LocalDate repaymentsStartingFromDate, Integer rowIndex, ExternalId externalId, Long groupId, Collection<LoanChargeData> charges,
|
||||||
String linkAccountId, String locale, String dateFormat, List<LoanCollateralManagementData> loanCollateralManagementData) {
|
String linkAccountId, String locale, String dateFormat, List<LoanCollateralManagementData> loanCollateralManagementData) {
|
||||||
|
|
||||||
return new LoanAccountData().setLoanType(loanTypeEnumOption).setClientId(clientId).setProductId(productId)
|
return new LoanAccountData().setLoanType(loanTypeEnumOption).setClientId(clientId).setProductId(productId)
|
||||||
@@ -285,7 +286,7 @@ public class LoanAccountData {
|
|||||||
EnumOptionData interestMethodEnum, EnumOptionData interestCalculationPeriodEnum, BigDecimal arrearsTolerance,
|
EnumOptionData interestMethodEnum, EnumOptionData interestCalculationPeriodEnum, BigDecimal arrearsTolerance,
|
||||||
String transactionProcessingStrategyCode, Integer graceOnPrincipalPayment, Integer graceOnInterestPayment,
|
String transactionProcessingStrategyCode, Integer graceOnPrincipalPayment, Integer graceOnInterestPayment,
|
||||||
Integer graceOnInterestCharged, LocalDate interestChargedFromDate, LocalDate repaymentsStartingFromDate, Integer rowIndex,
|
Integer graceOnInterestCharged, LocalDate interestChargedFromDate, LocalDate repaymentsStartingFromDate, Integer rowIndex,
|
||||||
String externalId, String linkAccountId, String locale, String dateFormat) {
|
ExternalId externalId, String linkAccountId, String locale, String dateFormat) {
|
||||||
|
|
||||||
return new LoanAccountData().setLoanType(loanTypeEnumOption).setGroupId(groupIdforGroupLoan).setProductId(productId)
|
return new LoanAccountData().setLoanType(loanTypeEnumOption).setGroupId(groupIdforGroupLoan).setProductId(productId)
|
||||||
.setLoanOfficerId(loanOfficerId).setSubmittedOnDate(submittedOnDate).setFundId(fundId).setPrincipal(principal)
|
.setLoanOfficerId(loanOfficerId).setSubmittedOnDate(submittedOnDate).setFundId(fundId).setPrincipal(principal)
|
||||||
@@ -626,22 +627,23 @@ public class LoanAccountData {
|
|||||||
* Used to send back loan account data with the basic details coming from query.
|
* Used to send back loan account data with the basic details coming from query.
|
||||||
*/
|
*/
|
||||||
public static LoanAccountData basicLoanDetails(final Long id, final String accountNo, final LoanStatusEnumData status,
|
public static LoanAccountData basicLoanDetails(final Long id, final String accountNo, final LoanStatusEnumData status,
|
||||||
final String externalId, final Long clientId, final String clientAccountNo, final String clientName, final Long clientOfficeId,
|
final ExternalId externalId, final Long clientId, final String clientAccountNo, final String clientName,
|
||||||
final String clientExternalId, final GroupGeneralData group, final EnumOptionData loanType, final Long loanProductId,
|
final Long clientOfficeId, final String clientExternalId, final GroupGeneralData group, final EnumOptionData loanType,
|
||||||
final String loanProductName, final String loanProductDescription, final boolean isLoanProductLinkedToFloatingRate,
|
final Long loanProductId, final String loanProductName, final String loanProductDescription,
|
||||||
final Long fundId, final String fundName, final Long loanPurposeId, final String loanPurposeName, final Long loanOfficerId,
|
final boolean isLoanProductLinkedToFloatingRate, final Long fundId, final String fundName, final Long loanPurposeId,
|
||||||
final String loanOfficerName, final CurrencyData currencyData, final BigDecimal proposedPrincipal, final BigDecimal principal,
|
final String loanPurposeName, final Long loanOfficerId, final String loanOfficerName, final CurrencyData currencyData,
|
||||||
final BigDecimal approvedPrincipal, final BigDecimal netDisbursalAmount, final BigDecimal totalOverpaid,
|
final BigDecimal proposedPrincipal, final BigDecimal principal, final BigDecimal approvedPrincipal,
|
||||||
final BigDecimal inArrearsTolerance, final Integer termFrequency, final EnumOptionData termPeriodFrequencyType,
|
final BigDecimal netDisbursalAmount, final BigDecimal totalOverpaid, final BigDecimal inArrearsTolerance,
|
||||||
final Integer numberOfRepayments, final Integer repaymentEvery, final EnumOptionData repaymentFrequencyType,
|
final Integer termFrequency, final EnumOptionData termPeriodFrequencyType, final Integer numberOfRepayments,
|
||||||
EnumOptionData repaymentFrequencyNthDayType, EnumOptionData repaymentFrequencyDayOfWeekType, final String transactionStrategy,
|
final Integer repaymentEvery, final EnumOptionData repaymentFrequencyType, EnumOptionData repaymentFrequencyNthDayType,
|
||||||
final String transactionStrategyName, final EnumOptionData amortizationType, final BigDecimal interestRatePerPeriod,
|
EnumOptionData repaymentFrequencyDayOfWeekType, final String transactionStrategy, final String transactionStrategyName,
|
||||||
final EnumOptionData interestRateFrequencyType, final BigDecimal annualInterestRate, final EnumOptionData interestType,
|
final EnumOptionData amortizationType, final BigDecimal interestRatePerPeriod, final EnumOptionData interestRateFrequencyType,
|
||||||
final boolean isFloatingInterestRate, final BigDecimal interestRateDifferential,
|
final BigDecimal annualInterestRate, final EnumOptionData interestType, final boolean isFloatingInterestRate,
|
||||||
final EnumOptionData interestCalculationPeriodType, Boolean allowPartialPeriodInterestCalcualtion,
|
final BigDecimal interestRateDifferential, final EnumOptionData interestCalculationPeriodType,
|
||||||
final LocalDate expectedFirstRepaymentOnDate, final Integer graceOnPrincipalPayment,
|
Boolean allowPartialPeriodInterestCalcualtion, final LocalDate expectedFirstRepaymentOnDate,
|
||||||
final Integer recurringMoratoriumOnPrincipalPeriods, final Integer graceOnInterestPayment, final Integer graceOnInterestCharged,
|
final Integer graceOnPrincipalPayment, final Integer recurringMoratoriumOnPrincipalPeriods,
|
||||||
final LocalDate interestChargedFromDate, final LoanApplicationTimelineData timeline, final LoanSummaryData loanSummary,
|
final Integer graceOnInterestPayment, final Integer graceOnInterestCharged, final LocalDate interestChargedFromDate,
|
||||||
|
final LoanApplicationTimelineData timeline, final LoanSummaryData loanSummary,
|
||||||
final BigDecimal feeChargesDueAtDisbursementCharged, final Boolean syncDisbursementWithMeeting, final Integer loanCounter,
|
final BigDecimal feeChargesDueAtDisbursementCharged, final Boolean syncDisbursementWithMeeting, final Integer loanCounter,
|
||||||
final Integer loanProductCounter, final Boolean multiDisburseLoan, Boolean canDefineInstallmentAmount,
|
final Integer loanProductCounter, final Boolean multiDisburseLoan, Boolean canDefineInstallmentAmount,
|
||||||
final BigDecimal fixedEmiAmont, final BigDecimal outstandingLoanBalance, final Boolean inArrears,
|
final BigDecimal fixedEmiAmont, final BigDecimal outstandingLoanBalance, final Boolean inArrears,
|
||||||
|
|||||||
+11
-10
@@ -38,7 +38,7 @@ public class LoanTransactionData {
|
|||||||
|
|
||||||
private final Long id;
|
private final Long id;
|
||||||
private final Long loanId;
|
private final Long loanId;
|
||||||
private final String externalLoanId;
|
private final ExternalId externalLoanId;
|
||||||
private final Long officeId;
|
private final Long officeId;
|
||||||
private final String officeName;
|
private final String officeName;
|
||||||
|
|
||||||
@@ -115,7 +115,7 @@ public class LoanTransactionData {
|
|||||||
this.type = null;
|
this.type = null;
|
||||||
this.id = null;
|
this.id = null;
|
||||||
this.loanId = null;
|
this.loanId = null;
|
||||||
this.externalLoanId = null;
|
this.externalLoanId = ExternalId.empty();
|
||||||
this.officeId = null;
|
this.officeId = null;
|
||||||
this.officeName = null;
|
this.officeName = null;
|
||||||
this.currency = null;
|
this.currency = null;
|
||||||
@@ -163,7 +163,7 @@ public class LoanTransactionData {
|
|||||||
this.locale = locale;
|
this.locale = locale;
|
||||||
this.id = null;
|
this.id = null;
|
||||||
this.loanId = null;
|
this.loanId = null;
|
||||||
this.externalLoanId = null;
|
this.externalLoanId = ExternalId.empty();
|
||||||
this.officeId = null;
|
this.officeId = null;
|
||||||
this.officeName = null;
|
this.officeName = null;
|
||||||
this.type = null;
|
this.type = null;
|
||||||
@@ -216,7 +216,7 @@ public class LoanTransactionData {
|
|||||||
final BigDecimal netDisbursalAmount, final BigDecimal principalPortion, final BigDecimal interestPortion,
|
final BigDecimal netDisbursalAmount, final BigDecimal principalPortion, final BigDecimal interestPortion,
|
||||||
final BigDecimal feeChargesPortion, final BigDecimal penaltyChargesPortion, final BigDecimal overpaymentPortion,
|
final BigDecimal feeChargesPortion, final BigDecimal penaltyChargesPortion, final BigDecimal overpaymentPortion,
|
||||||
final ExternalId externalId, final AccountTransferData transfer, BigDecimal fixedEmiAmount, BigDecimal outstandingLoanBalance,
|
final ExternalId externalId, final AccountTransferData transfer, BigDecimal fixedEmiAmount, BigDecimal outstandingLoanBalance,
|
||||||
final BigDecimal unrecognizedIncomePortion, final boolean manuallyReversed, Long loanId, String externalLoanId) {
|
final BigDecimal unrecognizedIncomePortion, final boolean manuallyReversed, Long loanId, ExternalId externalLoanId) {
|
||||||
this(id, officeId, officeName, transactionType, paymentDetailData, currency, date, amount, netDisbursalAmount, principalPortion,
|
this(id, officeId, officeName, transactionType, paymentDetailData, currency, date, amount, netDisbursalAmount, principalPortion,
|
||||||
interestPortion, feeChargesPortion, penaltyChargesPortion, overpaymentPortion, unrecognizedIncomePortion, null, externalId,
|
interestPortion, feeChargesPortion, penaltyChargesPortion, overpaymentPortion, unrecognizedIncomePortion, null, externalId,
|
||||||
transfer, fixedEmiAmount, outstandingLoanBalance, manuallyReversed, loanId, externalLoanId);
|
transfer, fixedEmiAmount, outstandingLoanBalance, manuallyReversed, loanId, externalLoanId);
|
||||||
@@ -228,7 +228,7 @@ public class LoanTransactionData {
|
|||||||
final BigDecimal feeChargesPortion, final BigDecimal penaltyChargesPortion, final BigDecimal overpaymentPortion,
|
final BigDecimal feeChargesPortion, final BigDecimal penaltyChargesPortion, final BigDecimal overpaymentPortion,
|
||||||
BigDecimal unrecognizedIncomePortion, final Collection<PaymentTypeData> paymentTypeOptions, final ExternalId externalId,
|
BigDecimal unrecognizedIncomePortion, final Collection<PaymentTypeData> paymentTypeOptions, final ExternalId externalId,
|
||||||
final AccountTransferData transfer, final BigDecimal fixedEmiAmount, BigDecimal outstandingLoanBalance,
|
final AccountTransferData transfer, final BigDecimal fixedEmiAmount, BigDecimal outstandingLoanBalance,
|
||||||
boolean manuallyReversed, Long loanId, String externalLoanId) {
|
boolean manuallyReversed, Long loanId, ExternalId externalLoanId) {
|
||||||
this(id, externalLoanId, officeId, officeName, transactionType, paymentDetailData, currency, date, amount, netDisbursalAmount,
|
this(id, externalLoanId, officeId, officeName, transactionType, paymentDetailData, currency, date, amount, netDisbursalAmount,
|
||||||
principalPortion, interestPortion, feeChargesPortion, penaltyChargesPortion, overpaymentPortion, unrecognizedIncomePortion,
|
principalPortion, interestPortion, feeChargesPortion, penaltyChargesPortion, overpaymentPortion, unrecognizedIncomePortion,
|
||||||
paymentTypeOptions, externalId, transfer, fixedEmiAmount, outstandingLoanBalance, null, manuallyReversed,
|
paymentTypeOptions, externalId, transfer, fixedEmiAmount, outstandingLoanBalance, null, manuallyReversed,
|
||||||
@@ -241,14 +241,14 @@ public class LoanTransactionData {
|
|||||||
final BigDecimal feeChargesPortion, final BigDecimal penaltyChargesPortion, final BigDecimal overpaymentPortion,
|
final BigDecimal feeChargesPortion, final BigDecimal penaltyChargesPortion, final BigDecimal overpaymentPortion,
|
||||||
final BigDecimal unrecognizedIncomePortion, final ExternalId externalId, final AccountTransferData transfer,
|
final BigDecimal unrecognizedIncomePortion, final ExternalId externalId, final AccountTransferData transfer,
|
||||||
BigDecimal fixedEmiAmount, BigDecimal outstandingLoanBalance, LocalDate submittedOnDate, final boolean manuallyReversed,
|
BigDecimal fixedEmiAmount, BigDecimal outstandingLoanBalance, LocalDate submittedOnDate, final boolean manuallyReversed,
|
||||||
final ExternalId reversalExternalId, final LocalDate reversedOnDate, Long loanId, String externalLoanId) {
|
final ExternalId reversalExternalId, final LocalDate reversedOnDate, Long loanId, ExternalId externalLoanId) {
|
||||||
this(id, externalLoanId, officeId, officeName, transactionType, paymentDetailData, currency, date, amount, netDisbursalAmount,
|
this(id, externalLoanId, officeId, officeName, transactionType, paymentDetailData, currency, date, amount, netDisbursalAmount,
|
||||||
principalPortion, interestPortion, feeChargesPortion, penaltyChargesPortion, overpaymentPortion, unrecognizedIncomePortion,
|
principalPortion, interestPortion, feeChargesPortion, penaltyChargesPortion, overpaymentPortion, unrecognizedIncomePortion,
|
||||||
null, externalId, transfer, fixedEmiAmount, outstandingLoanBalance, submittedOnDate, manuallyReversed, reversalExternalId,
|
null, externalId, transfer, fixedEmiAmount, outstandingLoanBalance, submittedOnDate, manuallyReversed, reversalExternalId,
|
||||||
reversedOnDate, loanId);
|
reversedOnDate, loanId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public LoanTransactionData(final Long id, final String externalLoanId, final Long officeId, final String officeName,
|
public LoanTransactionData(final Long id, final ExternalId externalLoanId, final Long officeId, final String officeName,
|
||||||
final LoanTransactionEnumData transactionType, final PaymentDetailData paymentDetailData, final CurrencyData currency,
|
final LoanTransactionEnumData transactionType, final PaymentDetailData paymentDetailData, final CurrencyData currency,
|
||||||
final LocalDate date, final BigDecimal amount, final BigDecimal netDisbursalAmount, final BigDecimal principalPortion,
|
final LocalDate date, final BigDecimal amount, final BigDecimal netDisbursalAmount, final BigDecimal principalPortion,
|
||||||
final BigDecimal interestPortion, final BigDecimal feeChargesPortion, final BigDecimal penaltyChargesPortion,
|
final BigDecimal interestPortion, final BigDecimal feeChargesPortion, final BigDecimal penaltyChargesPortion,
|
||||||
@@ -288,7 +288,8 @@ public class LoanTransactionData {
|
|||||||
public LoanTransactionData(Long id, LoanTransactionEnumData transactionType, LocalDate date, BigDecimal totalAmount,
|
public LoanTransactionData(Long id, LoanTransactionEnumData transactionType, LocalDate date, BigDecimal totalAmount,
|
||||||
BigDecimal netDisbursalAmount, BigDecimal principalPortion, BigDecimal interestPortion, BigDecimal feeChargesPortion,
|
BigDecimal netDisbursalAmount, BigDecimal principalPortion, BigDecimal interestPortion, BigDecimal feeChargesPortion,
|
||||||
BigDecimal penaltyChargesPortion, BigDecimal overpaymentPortion, BigDecimal unrecognizedIncomePortion,
|
BigDecimal penaltyChargesPortion, BigDecimal overpaymentPortion, BigDecimal unrecognizedIncomePortion,
|
||||||
BigDecimal outstandingLoanBalance, final boolean manuallyReversed, ExternalId externalId, Long loanId, String externalLoanId) {
|
BigDecimal outstandingLoanBalance, final boolean manuallyReversed, ExternalId externalId, Long loanId,
|
||||||
|
ExternalId externalLoanId) {
|
||||||
this(id, externalLoanId, null, null, transactionType, null, null, date, totalAmount, netDisbursalAmount, principalPortion,
|
this(id, externalLoanId, null, null, transactionType, null, null, date, totalAmount, netDisbursalAmount, principalPortion,
|
||||||
interestPortion, feeChargesPortion, penaltyChargesPortion, overpaymentPortion, unrecognizedIncomePortion, null, externalId,
|
interestPortion, feeChargesPortion, penaltyChargesPortion, overpaymentPortion, unrecognizedIncomePortion, null, externalId,
|
||||||
null, null, outstandingLoanBalance, null, manuallyReversed, ExternalId.empty(), null, loanId);
|
null, null, outstandingLoanBalance, null, manuallyReversed, ExternalId.empty(), null, loanId);
|
||||||
@@ -300,7 +301,7 @@ public class LoanTransactionData {
|
|||||||
final LocalDate possibleNextRepaymentDate) {
|
final LocalDate possibleNextRepaymentDate) {
|
||||||
final Long id = null;
|
final Long id = null;
|
||||||
final Long loanId = null;
|
final Long loanId = null;
|
||||||
final String externalLoanId = null;
|
final ExternalId externalLoanId = ExternalId.empty();
|
||||||
final Long officeId = null;
|
final Long officeId = null;
|
||||||
final String officeName = null;
|
final String officeName = null;
|
||||||
final PaymentDetailData paymentDetailData = null;
|
final PaymentDetailData paymentDetailData = null;
|
||||||
@@ -331,7 +332,7 @@ public class LoanTransactionData {
|
|||||||
BigDecimal unrecognizedIncomePortion, Collection<PaymentTypeData> paymentOptions, final AccountTransferData transfer,
|
BigDecimal unrecognizedIncomePortion, Collection<PaymentTypeData> paymentOptions, final AccountTransferData transfer,
|
||||||
final ExternalId externalId, final BigDecimal fixedEmiAmount, BigDecimal outstandingLoanBalance,
|
final ExternalId externalId, final BigDecimal fixedEmiAmount, BigDecimal outstandingLoanBalance,
|
||||||
final LocalDate submittedOnDate, final boolean manuallyReversed, final LocalDate possibleNextRepaymentDate, Long loanId,
|
final LocalDate submittedOnDate, final boolean manuallyReversed, final LocalDate possibleNextRepaymentDate, Long loanId,
|
||||||
String externalLoanId) {
|
ExternalId externalLoanId) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.loanId = loanId;
|
this.loanId = loanId;
|
||||||
this.externalLoanId = externalLoanId;
|
this.externalLoanId = externalLoanId;
|
||||||
|
|||||||
+13
-8
@@ -69,6 +69,7 @@ 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.JsonParserHelper;
|
import org.apache.fineract.infrastructure.core.serialization.JsonParserHelper;
|
||||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||||
|
import org.apache.fineract.infrastructure.core.service.ExternalIdFactory;
|
||||||
import org.apache.fineract.infrastructure.security.service.RandomPasswordGenerator;
|
import org.apache.fineract.infrastructure.security.service.RandomPasswordGenerator;
|
||||||
import org.apache.fineract.organisation.holiday.domain.Holiday;
|
import org.apache.fineract.organisation.holiday.domain.Holiday;
|
||||||
import org.apache.fineract.organisation.holiday.service.HolidayUtil;
|
import org.apache.fineract.organisation.holiday.service.HolidayUtil;
|
||||||
@@ -194,7 +195,7 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom {
|
|||||||
private String accountNumber;
|
private String accountNumber;
|
||||||
|
|
||||||
@Column(name = "external_id")
|
@Column(name = "external_id")
|
||||||
private String externalId;
|
private ExternalId externalId;
|
||||||
|
|
||||||
@ManyToOne
|
@ManyToOne
|
||||||
@JoinColumn(name = "client_id", nullable = true)
|
@JoinColumn(name = "client_id", nullable = true)
|
||||||
@@ -1440,10 +1441,14 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom {
|
|||||||
this.createStandingInstructionAtDisbursement = valueAsInput;
|
this.createStandingInstructionAtDisbursement = valueAsInput;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (command.isChangeInStringParameterNamed(EXTERNAL_ID, this.externalId)) {
|
if (command.isChangeInStringParameterNamed(EXTERNAL_ID, this.externalId.getValue())) {
|
||||||
final String newValue = command.stringValueOfParameterNamed(EXTERNAL_ID);
|
final String newValue = command.stringValueOfParameterNamed(EXTERNAL_ID);
|
||||||
actualChanges.put(EXTERNAL_ID, newValue);
|
ExternalId externalId = ExternalIdFactory.produce(newValue);
|
||||||
this.externalId = StringUtils.defaultIfEmpty(newValue, null);
|
if (externalId.isEmpty() && TemporaryConfigurationServiceContainer.isExternalIdAutoGenerationEnabled()) {
|
||||||
|
externalId = ExternalId.generate();
|
||||||
|
}
|
||||||
|
actualChanges.put(EXTERNAL_ID, externalId);
|
||||||
|
this.externalId = externalId;
|
||||||
}
|
}
|
||||||
|
|
||||||
// add clientId, groupId and loanType changes to actual changes
|
// add clientId, groupId and loanType changes to actual changes
|
||||||
@@ -2055,7 +2060,7 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void loanApplicationSubmittal(final LoanScheduleModel loanSchedule, final LoanApplicationTerms loanApplicationTerms,
|
public void loanApplicationSubmittal(final LoanScheduleModel loanSchedule, final LoanApplicationTerms loanApplicationTerms,
|
||||||
final LoanLifecycleStateMachine lifecycleStateMachine, final LocalDate submittedOn, final String externalId,
|
final LoanLifecycleStateMachine lifecycleStateMachine, final LocalDate submittedOn, final ExternalId externalId,
|
||||||
final boolean allowTransactionsOnHoliday, final List<Holiday> holidays, final WorkingDays workingDays,
|
final boolean allowTransactionsOnHoliday, final List<Holiday> holidays, final WorkingDays workingDays,
|
||||||
final boolean allowTransactionsOnNonWorkingDay) {
|
final boolean allowTransactionsOnNonWorkingDay) {
|
||||||
|
|
||||||
@@ -3793,7 +3798,7 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom {
|
|||||||
final LocalDate writtenOffOnLocalDate = command.localDateValueOfParameterNamed(TRANSACTION_DATE);
|
final LocalDate writtenOffOnLocalDate = command.localDateValueOfParameterNamed(TRANSACTION_DATE);
|
||||||
final String txnExternalId = command.stringValueOfParameterNamedAllowingNull(EXTERNAL_ID);
|
final String txnExternalId = command.stringValueOfParameterNamedAllowingNull(EXTERNAL_ID);
|
||||||
|
|
||||||
ExternalId externalId = StringUtils.isBlank(txnExternalId) ? ExternalId.empty() : new ExternalId(txnExternalId);
|
ExternalId externalId = ExternalIdFactory.produce(txnExternalId);
|
||||||
|
|
||||||
if (externalId.isEmpty() && TemporaryConfigurationServiceContainer.isExternalIdAutoGenerationEnabled()) {
|
if (externalId.isEmpty() && TemporaryConfigurationServiceContainer.isExternalIdAutoGenerationEnabled()) {
|
||||||
externalId = ExternalId.generate();
|
externalId = ExternalId.generate();
|
||||||
@@ -3887,7 +3892,7 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom {
|
|||||||
final LocalDate closureDate = command.localDateValueOfParameterNamed(TRANSACTION_DATE);
|
final LocalDate closureDate = command.localDateValueOfParameterNamed(TRANSACTION_DATE);
|
||||||
final String txnExternalId = command.stringValueOfParameterNamedAllowingNull(EXTERNAL_ID);
|
final String txnExternalId = command.stringValueOfParameterNamedAllowingNull(EXTERNAL_ID);
|
||||||
|
|
||||||
ExternalId externalId = StringUtils.isBlank(txnExternalId) ? ExternalId.empty() : new ExternalId(txnExternalId);
|
ExternalId externalId = ExternalIdFactory.produce(txnExternalId);
|
||||||
if (externalId.isEmpty() && TemporaryConfigurationServiceContainer.isExternalIdAutoGenerationEnabled()) {
|
if (externalId.isEmpty() && TemporaryConfigurationServiceContainer.isExternalIdAutoGenerationEnabled()) {
|
||||||
externalId = ExternalId.generate();
|
externalId = ExternalId.generate();
|
||||||
}
|
}
|
||||||
@@ -6033,7 +6038,7 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom {
|
|||||||
return this.accountNumber;
|
return this.accountNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getExternalId() {
|
public ExternalId getExternalId() {
|
||||||
return this.externalId;
|
return this.externalId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-1
@@ -83,7 +83,8 @@ public interface LoanAccountDomainService {
|
|||||||
|
|
||||||
void saveLoanWithDataIntegrityViolationChecks(Loan loan);
|
void saveLoanWithDataIntegrityViolationChecks(Loan loan);
|
||||||
|
|
||||||
Map<String, Object> foreCloseLoan(Loan loan, LocalDate foreClourseDate, String noteText, ExternalId externalId);
|
LoanTransaction foreCloseLoan(Loan loan, LocalDate foreClourseDate, String noteText, ExternalId externalId,
|
||||||
|
Map<String, Object> changes);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Disables all standing instructions linked to a closed loan
|
* Disables all standing instructions linked to a closed loan
|
||||||
|
|||||||
+3
-6
@@ -22,7 +22,6 @@ import java.math.BigDecimal;
|
|||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@@ -708,11 +707,10 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, Object> foreCloseLoan(final Loan loan, final LocalDate foreClosureDate, final String noteText,
|
public LoanTransaction foreCloseLoan(final Loan loan, final LocalDate foreClosureDate, final String noteText,
|
||||||
final ExternalId externalId) {
|
final ExternalId externalId, Map<String, Object> changes) {
|
||||||
businessEventNotifierService.notifyPreBusinessEvent(new LoanForeClosurePreBusinessEvent(loan));
|
businessEventNotifierService.notifyPreBusinessEvent(new LoanForeClosurePreBusinessEvent(loan));
|
||||||
MonetaryCurrency currency = loan.getCurrency();
|
MonetaryCurrency currency = loan.getCurrency();
|
||||||
final Map<String, Object> changes = new LinkedHashMap<>();
|
|
||||||
List<LoanTransaction> newTransactions = new ArrayList<>();
|
List<LoanTransaction> newTransactions = new ArrayList<>();
|
||||||
|
|
||||||
final List<Long> existingTransactionIds = new ArrayList<>();
|
final List<Long> existingTransactionIds = new ArrayList<>();
|
||||||
@@ -808,8 +806,7 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
|
|||||||
postJournalEntries(loan, existingTransactionIds, existingReversedTransactionIds, false);
|
postJournalEntries(loan, existingTransactionIds, existingReversedTransactionIds, false);
|
||||||
businessEventNotifierService.notifyPostBusinessEvent(new LoanBalanceChangedBusinessEvent(loan));
|
businessEventNotifierService.notifyPostBusinessEvent(new LoanBalanceChangedBusinessEvent(loan));
|
||||||
businessEventNotifierService.notifyPostBusinessEvent(new LoanForeClosurePostBusinessEvent(payment));
|
businessEventNotifierService.notifyPostBusinessEvent(new LoanForeClosurePostBusinessEvent(payment));
|
||||||
return changes;
|
return payment;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+3
-2
@@ -21,6 +21,7 @@ package org.apache.fineract.portfolio.loanaccount.domain;
|
|||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import org.apache.fineract.infrastructure.core.domain.ExternalId;
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||||
import org.springframework.data.jpa.repository.Query;
|
import org.springframework.data.jpa.repository.Query;
|
||||||
@@ -167,13 +168,13 @@ 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);
|
||||||
|
|
||||||
boolean existsByExternalId(@Param("externalId") String externalId);
|
boolean existsByExternalId(@Param("externalId") ExternalId externalId);
|
||||||
|
|
||||||
@Query(FIND_ALL_NON_CLOSED)
|
@Query(FIND_ALL_NON_CLOSED)
|
||||||
List<Long> findAllNonClosedLoanIds();
|
List<Long> findAllNonClosedLoanIds();
|
||||||
|
|
||||||
@Query(FIND_ID_BY_EXTERNAL_ID)
|
@Query(FIND_ID_BY_EXTERNAL_ID)
|
||||||
Long findIdByExternalId(@Param("externalId") String externalId);
|
Long findIdByExternalId(@Param("externalId") ExternalId externalId);
|
||||||
|
|
||||||
@Query(FIND_ALL_NON_CLOSED_ONE_DAY_BEHIND)
|
@Query(FIND_ALL_NON_CLOSED_ONE_DAY_BEHIND)
|
||||||
List<Long> findAllNonClosedLoanIdsOneDayBehind(@Param("last_closed_business_date") LocalDate businessDate);
|
List<Long> findAllNonClosedLoanIdsOneDayBehind(@Param("last_closed_business_date") LocalDate businessDate);
|
||||||
|
|||||||
+3
-2
@@ -23,6 +23,7 @@ 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 org.apache.fineract.infrastructure.core.domain.ExternalId;
|
||||||
import org.apache.fineract.portfolio.loanaccount.exception.LoanNotFoundException;
|
import org.apache.fineract.portfolio.loanaccount.exception.LoanNotFoundException;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.data.repository.query.Param;
|
import org.springframework.data.repository.query.Param;
|
||||||
@@ -238,7 +239,7 @@ public class LoanRepositoryWrapper {
|
|||||||
return this.repository.findNonClosedLoanByAccountNumber(accountNumber);
|
return this.repository.findNonClosedLoanByAccountNumber(accountNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean existLoanByExternalId(final String externalId) {
|
public boolean existLoanByExternalId(final ExternalId externalId) {
|
||||||
return this.repository.existsByExternalId(externalId);
|
return this.repository.existsByExternalId(externalId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -252,7 +253,7 @@ public class LoanRepositoryWrapper {
|
|||||||
return loan;
|
return loan;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Long findIdByExternalId(String externalId) {
|
public Long findIdByExternalId(ExternalId externalId) {
|
||||||
return this.repository.findIdByExternalId(externalId);
|
return this.repository.findIdByExternalId(externalId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+12
-2
@@ -48,10 +48,12 @@ 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.domain.ExternalId;
|
||||||
import org.apache.fineract.infrastructure.core.exception.GeneralPlatformDomainRuleException;
|
import org.apache.fineract.infrastructure.core.exception.GeneralPlatformDomainRuleException;
|
||||||
import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException;
|
import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException;
|
||||||
import org.apache.fineract.infrastructure.core.exception.PlatformDataIntegrityException;
|
import org.apache.fineract.infrastructure.core.exception.PlatformDataIntegrityException;
|
||||||
import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
|
import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
|
||||||
|
import org.apache.fineract.infrastructure.core.service.ExternalIdFactory;
|
||||||
import org.apache.fineract.infrastructure.dataqueries.data.EntityTables;
|
import org.apache.fineract.infrastructure.dataqueries.data.EntityTables;
|
||||||
import org.apache.fineract.infrastructure.dataqueries.data.StatusEnum;
|
import org.apache.fineract.infrastructure.dataqueries.data.StatusEnum;
|
||||||
import org.apache.fineract.infrastructure.dataqueries.service.EntityDatatableChecksWritePlatformService;
|
import org.apache.fineract.infrastructure.dataqueries.service.EntityDatatableChecksWritePlatformService;
|
||||||
@@ -217,8 +219,9 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
|
|||||||
this.fromApiJsonDeserializer.validateForCreate(command.json(), isMeetingMandatoryForJLGLoans, loanProduct);
|
this.fromApiJsonDeserializer.validateForCreate(command.json(), isMeetingMandatoryForJLGLoans, loanProduct);
|
||||||
|
|
||||||
// Validate If the externalId is already registered
|
// Validate If the externalId is already registered
|
||||||
final String externalId = this.fromJsonHelper.extractStringNamed("externalId", command.parsedJson());
|
final String externalIdStr = this.fromJsonHelper.extractStringNamed("externalId", command.parsedJson());
|
||||||
if (StringUtils.isNotBlank(externalId)) {
|
ExternalId externalId = ExternalIdFactory.produce(externalIdStr);
|
||||||
|
if (!externalId.isEmpty()) {
|
||||||
final boolean existByExternalId = this.loanRepositoryWrapper.existLoanByExternalId(externalId);
|
final boolean existByExternalId = this.loanRepositoryWrapper.existLoanByExternalId(externalId);
|
||||||
if (existByExternalId) {
|
if (existByExternalId) {
|
||||||
throw new GeneralPlatformDomainRuleException("error.msg.loan.with.externalId.already.used",
|
throw new GeneralPlatformDomainRuleException("error.msg.loan.with.externalId.already.used",
|
||||||
@@ -518,6 +521,7 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
|
|||||||
return new CommandProcessingResultBuilder() //
|
return new CommandProcessingResultBuilder() //
|
||||||
.withCommandId(command.commandId()) //
|
.withCommandId(command.commandId()) //
|
||||||
.withEntityId(newLoanApplication.getId()) //
|
.withEntityId(newLoanApplication.getId()) //
|
||||||
|
.withEntityExternalId(newLoanApplication.getExternalId()) //
|
||||||
.withOfficeId(newLoanApplication.getOfficeId()) //
|
.withOfficeId(newLoanApplication.getOfficeId()) //
|
||||||
.withClientId(newLoanApplication.getClientId()) //
|
.withClientId(newLoanApplication.getClientId()) //
|
||||||
.withGroupId(newLoanApplication.getGroupId()) //
|
.withGroupId(newLoanApplication.getGroupId()) //
|
||||||
@@ -1165,6 +1169,7 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
|
|||||||
|
|
||||||
return new CommandProcessingResultBuilder() //
|
return new CommandProcessingResultBuilder() //
|
||||||
.withEntityId(loanId) //
|
.withEntityId(loanId) //
|
||||||
|
.withEntityExternalId(existingLoanApplication.getExternalId()) //
|
||||||
.withOfficeId(existingLoanApplication.getOfficeId()) //
|
.withOfficeId(existingLoanApplication.getOfficeId()) //
|
||||||
.withClientId(existingLoanApplication.getClientId()) //
|
.withClientId(existingLoanApplication.getClientId()) //
|
||||||
.withGroupId(existingLoanApplication.getGroupId()) //
|
.withGroupId(existingLoanApplication.getGroupId()) //
|
||||||
@@ -1239,6 +1244,7 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
|
|||||||
|
|
||||||
return new CommandProcessingResultBuilder() //
|
return new CommandProcessingResultBuilder() //
|
||||||
.withEntityId(loanId) //
|
.withEntityId(loanId) //
|
||||||
|
.withEntityExternalId(loan.getExternalId()) //
|
||||||
.withOfficeId(loan.getOfficeId()) //
|
.withOfficeId(loan.getOfficeId()) //
|
||||||
.withClientId(loan.getClientId()) //
|
.withClientId(loan.getClientId()) //
|
||||||
.withGroupId(loan.getGroupId()) //
|
.withGroupId(loan.getGroupId()) //
|
||||||
@@ -1408,6 +1414,7 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
|
|||||||
return new CommandProcessingResultBuilder() //
|
return new CommandProcessingResultBuilder() //
|
||||||
.withCommandId(command.commandId()) //
|
.withCommandId(command.commandId()) //
|
||||||
.withEntityId(loan.getId()) //
|
.withEntityId(loan.getId()) //
|
||||||
|
.withEntityExternalId(loan.getExternalId()) //
|
||||||
.withOfficeId(loan.getOfficeId()) //
|
.withOfficeId(loan.getOfficeId()) //
|
||||||
.withClientId(loan.getClientId()) //
|
.withClientId(loan.getClientId()) //
|
||||||
.withGroupId(loan.getGroupId()) //
|
.withGroupId(loan.getGroupId()) //
|
||||||
@@ -1486,6 +1493,7 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
|
|||||||
return new CommandProcessingResultBuilder() //
|
return new CommandProcessingResultBuilder() //
|
||||||
.withCommandId(command.commandId()) //
|
.withCommandId(command.commandId()) //
|
||||||
.withEntityId(loan.getId()) //
|
.withEntityId(loan.getId()) //
|
||||||
|
.withEntityExternalId(loan.getExternalId()) //
|
||||||
.withOfficeId(loan.getOfficeId()) //
|
.withOfficeId(loan.getOfficeId()) //
|
||||||
.withClientId(loan.getClientId()) //
|
.withClientId(loan.getClientId()) //
|
||||||
.withGroupId(loan.getGroupId()) //
|
.withGroupId(loan.getGroupId()) //
|
||||||
@@ -1554,6 +1562,7 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
|
|||||||
return new CommandProcessingResultBuilder() //
|
return new CommandProcessingResultBuilder() //
|
||||||
.withCommandId(command.commandId()) //
|
.withCommandId(command.commandId()) //
|
||||||
.withEntityId(loan.getId()) //
|
.withEntityId(loan.getId()) //
|
||||||
|
.withEntityExternalId(loan.getExternalId()) //
|
||||||
.withOfficeId(loan.getOfficeId()) //
|
.withOfficeId(loan.getOfficeId()) //
|
||||||
.withClientId(loan.getClientId()) //
|
.withClientId(loan.getClientId()) //
|
||||||
.withGroupId(loan.getGroupId()) //
|
.withGroupId(loan.getGroupId()) //
|
||||||
@@ -1605,6 +1614,7 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
|
|||||||
return new CommandProcessingResultBuilder() //
|
return new CommandProcessingResultBuilder() //
|
||||||
.withCommandId(command.commandId()) //
|
.withCommandId(command.commandId()) //
|
||||||
.withEntityId(loan.getId()) //
|
.withEntityId(loan.getId()) //
|
||||||
|
.withEntityExternalId(loan.getExternalId()) //
|
||||||
.withOfficeId(loan.getOfficeId()) //
|
.withOfficeId(loan.getOfficeId()) //
|
||||||
.withClientId(loan.getClientId()) //
|
.withClientId(loan.getClientId()) //
|
||||||
.withGroupId(loan.getGroupId()) //
|
.withGroupId(loan.getGroupId()) //
|
||||||
|
|||||||
+5
-1
@@ -33,7 +33,9 @@ import org.apache.fineract.infrastructure.codes.domain.CodeValueRepositoryWrappe
|
|||||||
import org.apache.fineract.infrastructure.configuration.domain.ConfigurationDomainService;
|
import org.apache.fineract.infrastructure.configuration.domain.ConfigurationDomainService;
|
||||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||||
import org.apache.fineract.infrastructure.core.data.EnumOptionData;
|
import org.apache.fineract.infrastructure.core.data.EnumOptionData;
|
||||||
|
import org.apache.fineract.infrastructure.core.domain.ExternalId;
|
||||||
import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
|
import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
|
||||||
|
import org.apache.fineract.infrastructure.core.service.ExternalIdFactory;
|
||||||
import org.apache.fineract.organisation.holiday.domain.Holiday;
|
import org.apache.fineract.organisation.holiday.domain.Holiday;
|
||||||
import org.apache.fineract.organisation.holiday.domain.HolidayRepository;
|
import org.apache.fineract.organisation.holiday.domain.HolidayRepository;
|
||||||
import org.apache.fineract.organisation.holiday.domain.HolidayStatusType;
|
import org.apache.fineract.organisation.holiday.domain.HolidayStatusType;
|
||||||
@@ -107,6 +109,7 @@ public class LoanAssembler {
|
|||||||
private final LoanUtilService loanUtilService;
|
private final LoanUtilService loanUtilService;
|
||||||
private final RateAssembler rateAssembler;
|
private final RateAssembler rateAssembler;
|
||||||
private final LoanLifecycleStateMachine defaultLoanLifecycleStateMachine;
|
private final LoanLifecycleStateMachine defaultLoanLifecycleStateMachine;
|
||||||
|
private final ExternalIdFactory externalIdFactory;
|
||||||
|
|
||||||
public Loan assembleFrom(final Long accountId) {
|
public Loan assembleFrom(final Long accountId) {
|
||||||
final Loan loanAccount = this.loanRepository.findOneWithNotFoundDetection(accountId, true);
|
final Loan loanAccount = this.loanRepository.findOneWithNotFoundDetection(accountId, true);
|
||||||
@@ -287,7 +290,8 @@ public class LoanAssembler {
|
|||||||
loanApplication.updateTransactionProcessingStrategy(transactionProcessingStrategyCode, transactionProcessingStrategyName);
|
loanApplication.updateTransactionProcessingStrategy(transactionProcessingStrategyCode, transactionProcessingStrategyName);
|
||||||
}
|
}
|
||||||
|
|
||||||
final String externalId = this.fromApiJsonHelper.extractStringNamed("externalId", element);
|
final String externalIdStr = this.fromApiJsonHelper.extractStringNamed("externalId", element);
|
||||||
|
ExternalId externalId = externalIdFactory.create(externalIdStr);
|
||||||
final LocalDate submittedOnDate = this.fromApiJsonHelper.extractLocalDateNamed("submittedOnDate", element);
|
final LocalDate submittedOnDate = this.fromApiJsonHelper.extractLocalDateNamed("submittedOnDate", element);
|
||||||
|
|
||||||
if (loanApplication == null) {
|
if (loanApplication == null) {
|
||||||
|
|||||||
+2
-1
@@ -631,7 +631,8 @@ public class LoanChargeWritePlatformServiceImpl implements LoanChargeWritePlatfo
|
|||||||
.withCommandId(command.commandId()) //
|
.withCommandId(command.commandId()) //
|
||||||
.withEntityId(loanChargeId) //
|
.withEntityId(loanChargeId) //
|
||||||
.withEntityExternalId(loanCharge.getExternalId()) //
|
.withEntityExternalId(loanCharge.getExternalId()) //
|
||||||
.withSubEntityId(loanTransaction.getId()).withSubEntityExternalId(loanTransaction.getExternalId())
|
.withSubEntityId(loanTransaction.getId()) //
|
||||||
|
.withSubEntityExternalId(loanTransaction.getExternalId()) //
|
||||||
.withOfficeId(loan.getOfficeId()) //
|
.withOfficeId(loan.getOfficeId()) //
|
||||||
.withClientId(loan.getClientId()) //
|
.withClientId(loan.getClientId()) //
|
||||||
.withGroupId(loan.getGroupId()) //
|
.withGroupId(loan.getGroupId()) //
|
||||||
|
|||||||
+1
-1
@@ -158,5 +158,5 @@ public interface LoanReadPlatformService {
|
|||||||
|
|
||||||
Long retrieveLoanTransactionIdByExternalId(ExternalId externalId);
|
Long retrieveLoanTransactionIdByExternalId(ExternalId externalId);
|
||||||
|
|
||||||
Long retrieveLoanIdByExternalId(String externalId);
|
Long retrieveLoanIdByExternalId(ExternalId externalId);
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-7
@@ -696,7 +696,8 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
|||||||
|
|
||||||
final Long id = rs.getLong("id");
|
final Long id = rs.getLong("id");
|
||||||
final String accountNo = rs.getString("accountNo");
|
final String accountNo = rs.getString("accountNo");
|
||||||
final String externalId = rs.getString("externalId");
|
final String externalIdStr = rs.getString("externalId");
|
||||||
|
final ExternalId externalId = ExternalIdFactory.produce(externalIdStr);
|
||||||
|
|
||||||
final Long clientId = JdbcSupport.getLong(rs, "clientId");
|
final Long clientId = JdbcSupport.getLong(rs, "clientId");
|
||||||
final String clientAccountNo = rs.getString("clientAccountNo");
|
final String clientAccountNo = rs.getString("clientAccountNo");
|
||||||
@@ -1345,7 +1346,8 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
|||||||
|
|
||||||
final Long id = rs.getLong("id");
|
final Long id = rs.getLong("id");
|
||||||
final Long loanId = rs.getLong("loanId");
|
final Long loanId = rs.getLong("loanId");
|
||||||
final String externalLoanId = rs.getString("externalLoanId");
|
final String externalLoanIdStr = rs.getString("externalLoanId");
|
||||||
|
final ExternalId externalLoanId = ExternalIdFactory.produce(externalLoanIdStr);
|
||||||
final Long officeId = rs.getLong("officeId");
|
final Long officeId = rs.getLong("officeId");
|
||||||
final String officeName = rs.getString("officeName");
|
final String officeName = rs.getString("officeName");
|
||||||
final int transactionTypeInt = JdbcSupport.getInteger(rs, "transactionType");
|
final int transactionTypeInt = JdbcSupport.getInteger(rs, "transactionType");
|
||||||
@@ -2033,7 +2035,8 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
|||||||
|
|
||||||
final Long id = rs.getLong("id");
|
final Long id = rs.getLong("id");
|
||||||
final Long loanId = rs.getLong("loanId");
|
final Long loanId = rs.getLong("loanId");
|
||||||
final String externalLoanId = rs.getString("externalLoanId");
|
final String externalLoanIdStr = rs.getString("externalLoanId");
|
||||||
|
final ExternalId externalLoanId = ExternalIdFactory.produce(externalLoanIdStr);
|
||||||
final int transactionTypeInt = JdbcSupport.getInteger(rs, "transactionType");
|
final int transactionTypeInt = JdbcSupport.getInteger(rs, "transactionType");
|
||||||
final LoanTransactionEnumData transactionType = LoanEnumerations.transactionType(transactionTypeInt);
|
final LoanTransactionEnumData transactionType = LoanEnumerations.transactionType(transactionTypeInt);
|
||||||
|
|
||||||
@@ -2186,7 +2189,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
|||||||
|
|
||||||
private LoanTransactionData retrieveRefundTemplate(Long loanId, LoanTransactionType loanTransactionType,
|
private LoanTransactionData retrieveRefundTemplate(Long loanId, LoanTransactionType loanTransactionType,
|
||||||
Collection<PaymentTypeData> paymentOptions, MonetaryCurrency currency, BigDecimal transactionAmount, BigDecimal netDisbursal,
|
Collection<PaymentTypeData> paymentOptions, MonetaryCurrency currency, BigDecimal transactionAmount, BigDecimal netDisbursal,
|
||||||
String externalLoanId) {
|
ExternalId externalLoanId) {
|
||||||
|
|
||||||
final ApplicationCurrency applicationCurrency = this.applicationCurrencyRepository.findOneWithNotFoundDetection(currency);
|
final ApplicationCurrency applicationCurrency = this.applicationCurrencyRepository.findOneWithNotFoundDetection(currency);
|
||||||
|
|
||||||
@@ -2365,7 +2368,6 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
|||||||
final BigDecimal netDisbursalAmount = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "netDisbursalAmount");
|
final BigDecimal netDisbursalAmount = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "netDisbursalAmount");
|
||||||
final Long id = null;
|
final Long id = null;
|
||||||
final Long loanId = null;
|
final Long loanId = null;
|
||||||
final String externalLoanId = null;
|
|
||||||
final Long officeId = null;
|
final Long officeId = null;
|
||||||
final String officeName = null;
|
final String officeName = null;
|
||||||
boolean manuallyReversed = false;
|
boolean manuallyReversed = false;
|
||||||
@@ -2374,7 +2376,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
|||||||
final BigDecimal fixedEmiAmount = null;
|
final BigDecimal fixedEmiAmount = null;
|
||||||
return new LoanTransactionData(id, officeId, officeName, transactionType, paymentDetailData, currencyData, date, totalDue,
|
return new LoanTransactionData(id, officeId, officeName, transactionType, paymentDetailData, currencyData, date, totalDue,
|
||||||
netDisbursalAmount, principalPortion, interestDue, feeDue, penaltyDue, overPaymentPortion, ExternalId.empty(), transfer,
|
netDisbursalAmount, principalPortion, interestDue, feeDue, penaltyDue, overPaymentPortion, ExternalId.empty(), transfer,
|
||||||
fixedEmiAmount, outstandingLoanBalance, unrecognizedIncomePortion, manuallyReversed, loanId, externalLoanId);
|
fixedEmiAmount, outstandingLoanBalance, unrecognizedIncomePortion, manuallyReversed, loanId, ExternalId.empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -2419,7 +2421,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Long retrieveLoanIdByExternalId(String externalId) {
|
public Long retrieveLoanIdByExternalId(ExternalId externalId) {
|
||||||
return loanRepositoryWrapper.findIdByExternalId(externalId);
|
return loanRepositoryWrapper.findIdByExternalId(externalId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+21
-6
@@ -18,6 +18,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.apache.fineract.portfolio.loanaccount.service;
|
package org.apache.fineract.portfolio.loanaccount.service;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
import com.google.gson.JsonArray;
|
import com.google.gson.JsonArray;
|
||||||
import com.google.gson.JsonElement;
|
import com.google.gson.JsonElement;
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
@@ -506,11 +507,13 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
businessEventNotifierService.notifyPostBusinessEvent(new LoanDisbursalBusinessEvent(loan));
|
businessEventNotifierService.notifyPostBusinessEvent(new LoanDisbursalBusinessEvent(loan));
|
||||||
|
|
||||||
Long entityId = loan.getId();
|
Long entityId = loan.getId();
|
||||||
ExternalId externalId = ExternalId.empty();
|
ExternalId externalId = loan.getExternalId();
|
||||||
|
|
||||||
// During a disbursement, the entityId should be the disbursement transaction id
|
// During a disbursement, the entityId should be the disbursement transaction id
|
||||||
if (!isAccountTransfer) {
|
if (!isAccountTransfer) {
|
||||||
LoanTransaction disbursalTransaction = loan.getLoanTransactions().get(loan.getLoanTransactions().size() - 1);
|
// If accounting is not periodic accrual, the last transaction might be the accrual not the disbursement
|
||||||
|
LoanTransaction disbursalTransaction = Lists.reverse(loan.getLoanTransactions()).stream()
|
||||||
|
.filter(e -> LoanTransactionType.DISBURSEMENT.equals(e.getTypeOf())).findFirst().orElseThrow();
|
||||||
entityId = disbursalTransaction.getId();
|
entityId = disbursalTransaction.getId();
|
||||||
externalId = disbursalTransaction.getExternalId();
|
externalId = disbursalTransaction.getExternalId();
|
||||||
businessEventNotifierService.notifyPostBusinessEvent(new LoanDisbursalTransactionBusinessEvent(disbursalTransaction));
|
businessEventNotifierService.notifyPostBusinessEvent(new LoanDisbursalTransactionBusinessEvent(disbursalTransaction));
|
||||||
@@ -859,6 +862,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
return new CommandProcessingResultBuilder() //
|
return new CommandProcessingResultBuilder() //
|
||||||
.withCommandId(command.commandId()) //
|
.withCommandId(command.commandId()) //
|
||||||
.withEntityId(loan.getId()) //
|
.withEntityId(loan.getId()) //
|
||||||
|
.withEntityExternalId(loan.getExternalId()) //
|
||||||
.withOfficeId(loan.getOfficeId()) //
|
.withOfficeId(loan.getOfficeId()) //
|
||||||
.withClientId(loan.getClientId()) //
|
.withClientId(loan.getClientId()) //
|
||||||
.withGroupId(loan.getGroupId()) //
|
.withGroupId(loan.getGroupId()) //
|
||||||
@@ -1556,6 +1560,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
result = new CommandProcessingResultBuilder() //
|
result = new CommandProcessingResultBuilder() //
|
||||||
.withCommandId(command.commandId()) //
|
.withCommandId(command.commandId()) //
|
||||||
.withEntityId(loanId) //
|
.withEntityId(loanId) //
|
||||||
|
.withEntityExternalId(loan.getExternalId()) //
|
||||||
.withOfficeId(loan.getOfficeId()) //
|
.withOfficeId(loan.getOfficeId()) //
|
||||||
.withClientId(loan.getClientId()) //
|
.withClientId(loan.getClientId()) //
|
||||||
.withGroupId(loan.getGroupId()) //
|
.withGroupId(loan.getGroupId()) //
|
||||||
@@ -1616,6 +1621,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
return new CommandProcessingResultBuilder() //
|
return new CommandProcessingResultBuilder() //
|
||||||
.withCommandId(command.commandId()) //
|
.withCommandId(command.commandId()) //
|
||||||
.withEntityId(loanId) //
|
.withEntityId(loanId) //
|
||||||
|
.withEntityExternalId(loan.getExternalId()) //
|
||||||
.withOfficeId(loan.getOfficeId()) //
|
.withOfficeId(loan.getOfficeId()) //
|
||||||
.withClientId(loan.getClientId()) //
|
.withClientId(loan.getClientId()) //
|
||||||
.withGroupId(loan.getGroupId()) //
|
.withGroupId(loan.getGroupId()) //
|
||||||
@@ -1785,6 +1791,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
return new CommandProcessingResultBuilder() //
|
return new CommandProcessingResultBuilder() //
|
||||||
.withCommandId(command.commandId()) //
|
.withCommandId(command.commandId()) //
|
||||||
.withEntityId(loanId) //
|
.withEntityId(loanId) //
|
||||||
|
.withEntityExternalId(loan.getExternalId()) //
|
||||||
.withOfficeId(loan.getOfficeId()) //
|
.withOfficeId(loan.getOfficeId()) //
|
||||||
.withClientId(loan.getClientId()) //
|
.withClientId(loan.getClientId()) //
|
||||||
.withGroupId(loan.getGroupId()) //
|
.withGroupId(loan.getGroupId()) //
|
||||||
@@ -1862,6 +1869,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
return new CommandProcessingResultBuilder() //
|
return new CommandProcessingResultBuilder() //
|
||||||
.withCommandId(command.commandId()) //
|
.withCommandId(command.commandId()) //
|
||||||
.withEntityId(loanId) //
|
.withEntityId(loanId) //
|
||||||
|
.withEntityExternalId(loan.getExternalId()) //
|
||||||
.withOfficeId(loan.getOfficeId()) //
|
.withOfficeId(loan.getOfficeId()) //
|
||||||
.withClientId(loan.getClientId()) //
|
.withClientId(loan.getClientId()) //
|
||||||
.withGroupId(loan.getGroupId()) //
|
.withGroupId(loan.getGroupId()) //
|
||||||
@@ -2353,7 +2361,8 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
public CommandProcessingResult recoverFromGuarantor(final Long loanId) {
|
public CommandProcessingResult recoverFromGuarantor(final Long loanId) {
|
||||||
final Loan loan = this.loanAssembler.assembleFrom(loanId);
|
final Loan loan = this.loanAssembler.assembleFrom(loanId);
|
||||||
this.guarantorDomainService.transferFundsFromGuarantor(loan);
|
this.guarantorDomainService.transferFundsFromGuarantor(loan);
|
||||||
return new CommandProcessingResultBuilder().withLoanId(loanId).build();
|
return new CommandProcessingResultBuilder().withLoanId(loanId).withEntityId(loanId).withEntityExternalId(loan.getExternalId())
|
||||||
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
@@ -2476,6 +2485,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
return new CommandProcessingResultBuilder() //
|
return new CommandProcessingResultBuilder() //
|
||||||
.withCommandId(command.commandId()) //
|
.withCommandId(command.commandId()) //
|
||||||
.withEntityId(loan.getId()) //
|
.withEntityId(loan.getId()) //
|
||||||
|
.withEntityExternalId(loan.getExternalId()) //
|
||||||
.withOfficeId(loan.getOfficeId()) //
|
.withOfficeId(loan.getOfficeId()) //
|
||||||
.withClientId(loan.getClientId()) //
|
.withClientId(loan.getClientId()) //
|
||||||
.withGroupId(loan.getGroupId()) //
|
.withGroupId(loan.getGroupId()) //
|
||||||
@@ -2585,6 +2595,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
return new CommandProcessingResultBuilder() //
|
return new CommandProcessingResultBuilder() //
|
||||||
.withCommandId(command.commandId()) //
|
.withCommandId(command.commandId()) //
|
||||||
.withEntityId(loan.getId()) //
|
.withEntityId(loan.getId()) //
|
||||||
|
.withEntityExternalId(loan.getExternalId()) //
|
||||||
.withOfficeId(loan.getOfficeId()) //
|
.withOfficeId(loan.getOfficeId()) //
|
||||||
.withClientId(loan.getClientId()) //
|
.withClientId(loan.getClientId()) //
|
||||||
.withGroupId(loan.getGroupId()) //
|
.withGroupId(loan.getGroupId()) //
|
||||||
@@ -2603,7 +2614,9 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
final ExternalId externalId = externalIdFactory.createFromCommand(command, LoanApiConstants.externalIdParameterName);
|
final ExternalId externalId = externalIdFactory.createFromCommand(command, LoanApiConstants.externalIdParameterName);
|
||||||
this.loanEventApiJsonValidator.validateLoanForeclosure(command.json());
|
this.loanEventApiJsonValidator.validateLoanForeclosure(command.json());
|
||||||
final Map<String, Object> changes = new LinkedHashMap<>();
|
final Map<String, Object> changes = new LinkedHashMap<>();
|
||||||
changes.put("transactionDate", transactionDate);
|
// Got changed to match with the rest of the APIs
|
||||||
|
changes.put("dateFormat", command.dateFormat());
|
||||||
|
changes.put("transactionDate", command.stringValueOfParameterNamed(LoanApiConstants.transactionDateParamName));
|
||||||
changes.put("externalId", externalId);
|
changes.put("externalId", externalId);
|
||||||
|
|
||||||
String noteText = this.fromApiJsonHelper.extractStringNamed(LoanApiConstants.noteParamName, element);
|
String noteText = this.fromApiJsonHelper.extractStringNamed(LoanApiConstants.noteParamName, element);
|
||||||
@@ -2619,12 +2632,14 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
this.loanScheduleHistoryWritePlatformService.createAndSaveLoanScheduleArchive(loan.getRepaymentScheduleInstallments(), loan,
|
this.loanScheduleHistoryWritePlatformService.createAndSaveLoanScheduleArchive(loan.getRepaymentScheduleInstallments(), loan,
|
||||||
loanRescheduleRequest);
|
loanRescheduleRequest);
|
||||||
|
|
||||||
final Map<String, Object> modifications = this.loanAccountDomainService.foreCloseLoan(loan, transactionDate, noteText, externalId);
|
LoanTransaction foreclosureTransaction = this.loanAccountDomainService.foreCloseLoan(loan, transactionDate, noteText, externalId,
|
||||||
changes.putAll(modifications);
|
changes);
|
||||||
|
|
||||||
final CommandProcessingResultBuilder commandProcessingResultBuilder = new CommandProcessingResultBuilder();
|
final CommandProcessingResultBuilder commandProcessingResultBuilder = new CommandProcessingResultBuilder();
|
||||||
return commandProcessingResultBuilder //
|
return commandProcessingResultBuilder //
|
||||||
.withLoanId(loanId) //
|
.withLoanId(loanId) //
|
||||||
|
.withEntityId(foreclosureTransaction.getId()) //
|
||||||
|
.withEntityExternalId(foreclosureTransaction.getExternalId()) //
|
||||||
.with(changes) //
|
.with(changes) //
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-1
@@ -37,6 +37,7 @@ import org.apache.fineract.avro.loan.v1.RepaymentDueDataV1;
|
|||||||
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType;
|
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType;
|
||||||
import org.apache.fineract.infrastructure.core.domain.FineractPlatformTenant;
|
import org.apache.fineract.infrastructure.core.domain.FineractPlatformTenant;
|
||||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||||
|
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.infrastructure.event.business.domain.loan.repayment.LoanRepaymentDueBusinessEvent;
|
import org.apache.fineract.infrastructure.event.business.domain.loan.repayment.LoanRepaymentDueBusinessEvent;
|
||||||
import org.apache.fineract.infrastructure.event.external.service.serialization.mapper.support.AvroDateTimeMapper;
|
import org.apache.fineract.infrastructure.event.external.service.serialization.mapper.support.AvroDateTimeMapper;
|
||||||
@@ -87,7 +88,7 @@ public class LoanRepaymentBusinessEventSerializerTest {
|
|||||||
|
|
||||||
when(loanForProcessing.getId()).thenReturn(1L);
|
when(loanForProcessing.getId()).thenReturn(1L);
|
||||||
when(loanForProcessing.getAccountNumber()).thenReturn("0001");
|
when(loanForProcessing.getAccountNumber()).thenReturn("0001");
|
||||||
when(loanForProcessing.getExternalId()).thenReturn("externalId");
|
when(loanForProcessing.getExternalId()).thenReturn(ExternalIdFactory.produce("externalId"));
|
||||||
when(loanForProcessing.getLoanSummary()).thenReturn(loanSummary);
|
when(loanForProcessing.getLoanSummary()).thenReturn(loanSummary);
|
||||||
when(loanSummary.getTotalOutstanding()).thenReturn(BigDecimal.valueOf(0.0));
|
when(loanSummary.getTotalOutstanding()).thenReturn(BigDecimal.valueOf(0.0));
|
||||||
when(loanForProcessing.getCurrency()).thenReturn(loanCurrency);
|
when(loanForProcessing.getCurrency()).thenReturn(loanCurrency);
|
||||||
|
|||||||
+247
-1
@@ -31,18 +31,29 @@ import io.restassured.specification.ResponseSpecification;
|
|||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.time.format.DateTimeFormatterBuilder;
|
import java.time.format.DateTimeFormatterBuilder;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
import org.apache.fineract.client.models.BusinessDateRequest;
|
||||||
import org.apache.fineract.client.models.DeleteLoansLoanIdChargesChargeIdResponse;
|
import org.apache.fineract.client.models.DeleteLoansLoanIdChargesChargeIdResponse;
|
||||||
|
import org.apache.fineract.client.models.DeleteLoansLoanIdResponse;
|
||||||
|
import org.apache.fineract.client.models.GetDelinquencyRangesResponse;
|
||||||
|
import org.apache.fineract.client.models.GetDelinquencyTagHistoryResponse;
|
||||||
|
import org.apache.fineract.client.models.GetLoansApprovalTemplateResponse;
|
||||||
import org.apache.fineract.client.models.GetLoansLoanIdChargesChargeIdResponse;
|
import org.apache.fineract.client.models.GetLoansLoanIdChargesChargeIdResponse;
|
||||||
import org.apache.fineract.client.models.GetLoansLoanIdChargesTemplateResponse;
|
import org.apache.fineract.client.models.GetLoansLoanIdChargesTemplateResponse;
|
||||||
|
import org.apache.fineract.client.models.GetLoansLoanIdResponse;
|
||||||
import org.apache.fineract.client.models.GetLoansLoanIdTransactionsTransactionIdResponse;
|
import org.apache.fineract.client.models.GetLoansLoanIdTransactionsTransactionIdResponse;
|
||||||
import org.apache.fineract.client.models.PostClientsResponse;
|
import org.apache.fineract.client.models.PostClientsResponse;
|
||||||
|
import org.apache.fineract.client.models.PostDelinquencyBucketResponse;
|
||||||
|
import org.apache.fineract.client.models.PostDelinquencyRangeResponse;
|
||||||
import org.apache.fineract.client.models.PostLoansLoanIdChargesChargeIdRequest;
|
import org.apache.fineract.client.models.PostLoansLoanIdChargesChargeIdRequest;
|
||||||
import org.apache.fineract.client.models.PostLoansLoanIdChargesChargeIdResponse;
|
import org.apache.fineract.client.models.PostLoansLoanIdChargesChargeIdResponse;
|
||||||
import org.apache.fineract.client.models.PostLoansLoanIdChargesRequest;
|
import org.apache.fineract.client.models.PostLoansLoanIdChargesRequest;
|
||||||
import org.apache.fineract.client.models.PostLoansLoanIdChargesResponse;
|
import org.apache.fineract.client.models.PostLoansLoanIdChargesResponse;
|
||||||
|
import org.apache.fineract.client.models.PostLoansLoanIdRequest;
|
||||||
|
import org.apache.fineract.client.models.PostLoansLoanIdResponse;
|
||||||
import org.apache.fineract.client.models.PostLoansLoanIdTransactionsRequest;
|
import org.apache.fineract.client.models.PostLoansLoanIdTransactionsRequest;
|
||||||
import org.apache.fineract.client.models.PostLoansLoanIdTransactionsResponse;
|
import org.apache.fineract.client.models.PostLoansLoanIdTransactionsResponse;
|
||||||
import org.apache.fineract.client.models.PostLoansLoanIdTransactionsTransactionIdRequest;
|
import org.apache.fineract.client.models.PostLoansLoanIdTransactionsTransactionIdRequest;
|
||||||
@@ -50,8 +61,12 @@ import org.apache.fineract.client.models.PutChargeTransactionChangesRequest;
|
|||||||
import org.apache.fineract.client.models.PutChargeTransactionChangesResponse;
|
import org.apache.fineract.client.models.PutChargeTransactionChangesResponse;
|
||||||
import org.apache.fineract.client.models.PutLoansLoanIdChargesChargeIdRequest;
|
import org.apache.fineract.client.models.PutLoansLoanIdChargesChargeIdRequest;
|
||||||
import org.apache.fineract.client.models.PutLoansLoanIdChargesChargeIdResponse;
|
import org.apache.fineract.client.models.PutLoansLoanIdChargesChargeIdResponse;
|
||||||
|
import org.apache.fineract.client.models.PutLoansLoanIdRequest;
|
||||||
|
import org.apache.fineract.client.models.PutLoansLoanIdResponse;
|
||||||
import org.apache.fineract.client.util.CallFailedRuntimeException;
|
import org.apache.fineract.client.util.CallFailedRuntimeException;
|
||||||
|
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType;
|
||||||
import org.apache.fineract.integrationtests.client.IntegrationTest;
|
import org.apache.fineract.integrationtests.client.IntegrationTest;
|
||||||
|
import org.apache.fineract.integrationtests.common.BusinessDateHelper;
|
||||||
import org.apache.fineract.integrationtests.common.ClientHelper;
|
import org.apache.fineract.integrationtests.common.ClientHelper;
|
||||||
import org.apache.fineract.integrationtests.common.GlobalConfigurationHelper;
|
import org.apache.fineract.integrationtests.common.GlobalConfigurationHelper;
|
||||||
import org.apache.fineract.integrationtests.common.Utils;
|
import org.apache.fineract.integrationtests.common.Utils;
|
||||||
@@ -61,6 +76,9 @@ 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.LoanTransactionHelper;
|
import org.apache.fineract.integrationtests.common.loans.LoanTransactionHelper;
|
||||||
|
import org.apache.fineract.integrationtests.common.organisation.StaffHelper;
|
||||||
|
import org.apache.fineract.integrationtests.common.products.DelinquencyBucketsHelper;
|
||||||
|
import org.apache.fineract.integrationtests.common.products.DelinquencyRangesHelper;
|
||||||
import org.apache.fineract.integrationtests.common.savings.SavingsAccountHelper;
|
import org.apache.fineract.integrationtests.common.savings.SavingsAccountHelper;
|
||||||
import org.junit.jupiter.api.BeforeAll;
|
import org.junit.jupiter.api.BeforeAll;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
@@ -827,13 +845,241 @@ public class ExternalIdSupportIntegrationTest extends IntegrationTest {
|
|||||||
assertTrue(exception.getMessage().contains("error.msg.loanCharge.external.id.invalid"));
|
assertTrue(exception.getMessage().contains("error.msg.loanCharge.external.id.invalid"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void loan() {
|
||||||
|
GlobalConfigurationHelper.updateEnabledFlagForGlobalConfiguration(requestSpec, responseSpec, 50, true);
|
||||||
|
GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec, responseSpec, Boolean.TRUE);
|
||||||
|
new BusinessDateHelper().updateBusinessDate(new BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName())
|
||||||
|
.date("2022.10.10").dateFormat("yyyy.MM.dd").locale("en"));
|
||||||
|
try {
|
||||||
|
ArrayList<Integer> rangeIds = new ArrayList<>();
|
||||||
|
// First Range
|
||||||
|
String jsonRange = DelinquencyRangesHelper.getAsJSON(1, 3);
|
||||||
|
PostDelinquencyRangeResponse delinquencyRangeResponse = DelinquencyRangesHelper.createDelinquencyRange(requestSpec,
|
||||||
|
responseSpec, jsonRange);
|
||||||
|
rangeIds.add(delinquencyRangeResponse.getResourceId());
|
||||||
|
jsonRange = DelinquencyRangesHelper.getAsJSON(4, 60);
|
||||||
|
|
||||||
|
GetDelinquencyRangesResponse range = DelinquencyRangesHelper.getDelinquencyRange(requestSpec, responseSpec,
|
||||||
|
delinquencyRangeResponse.getResourceId());
|
||||||
|
|
||||||
|
// Second Range
|
||||||
|
delinquencyRangeResponse = DelinquencyRangesHelper.createDelinquencyRange(requestSpec, responseSpec, jsonRange);
|
||||||
|
rangeIds.add(delinquencyRangeResponse.getResourceId());
|
||||||
|
|
||||||
|
String jsonBucket = DelinquencyBucketsHelper.getAsJSON(rangeIds);
|
||||||
|
PostDelinquencyBucketResponse delinquencyBucketResponse = DelinquencyBucketsHelper.createDelinquencyBucket(requestSpec,
|
||||||
|
responseSpec, jsonBucket);
|
||||||
|
|
||||||
|
final String loanProductJSON = new LoanProductTestBuilder().withPrincipal("1000").withRepaymentTypeAsMonth()
|
||||||
|
.withRepaymentAfterEvery("1").withNumberOfRepayments("1").withRepaymentTypeAsMonth().withinterestRatePerPeriod("0")
|
||||||
|
.withInterestRateFrequencyTypeAsMonths().withAmortizationTypeAsEqualPrincipalPayment()
|
||||||
|
.withInterestTypeAsDecliningBalance().withAccountingRuleAsNone()
|
||||||
|
.withInterestCalculationPeriodTypeAsRepaymentPeriod(true).withDaysInMonth("30").withDaysInYear("365")
|
||||||
|
.withMoratorium("0", "0").withDelinquencyBucket(delinquencyBucketResponse.getResourceId())
|
||||||
|
.withInArrearsTolerance("1001").withMultiDisburse().withDisallowExpectedDisbursements(true).build(null);
|
||||||
|
final Integer loanProductID = this.loanTransactionHelper.getLoanProductId(loanProductJSON);
|
||||||
|
|
||||||
|
final PostClientsResponse client = clientHelper.createClient(ClientHelper.defaultClientCreationRequest());
|
||||||
|
|
||||||
|
String loanExternalIdStr = UUID.randomUUID().toString();
|
||||||
|
final HashMap loan = applyForLoanApplication(client.getClientId().intValue(), loanProductID, loanExternalIdStr);
|
||||||
|
Integer loanId = (Integer) loan.get("resourceId");
|
||||||
|
String resourceExternalId = (String) loan.get("resourceExternalId");
|
||||||
|
assertEquals(loanExternalIdStr, resourceExternalId);
|
||||||
|
|
||||||
|
LocalDate actualDate = LocalDate.of(2022, 10, 10);
|
||||||
|
|
||||||
|
GetLoansApprovalTemplateResponse loanApprovalResult = this.loanTransactionHelper.getLoanApprovalTemplate(loanExternalIdStr);
|
||||||
|
assertEquals(actualDate, loanApprovalResult.getApprovalDate());
|
||||||
|
assertEquals(1000.0, loanApprovalResult.getApprovalAmount());
|
||||||
|
assertEquals(1000.0, loanApprovalResult.getNetDisbursalAmount());
|
||||||
|
|
||||||
|
GetLoansLoanIdResponse loanDetailsResult = this.loanTransactionHelper.getLoanDetails(loanExternalIdStr);
|
||||||
|
assertEquals(loanExternalIdStr, loanDetailsResult.getExternalId());
|
||||||
|
|
||||||
|
this.loanTransactionHelper.approveLoan("02 September 2022", loanId);
|
||||||
|
String txnExternalIdStr = UUID.randomUUID().toString();
|
||||||
|
final HashMap disbursedLoanResult = this.loanTransactionHelper.disburseLoan("03 September 2022", loanId, "1000",
|
||||||
|
txnExternalIdStr);
|
||||||
|
|
||||||
|
// Check whether the provided external id was retrieved
|
||||||
|
assertEquals(txnExternalIdStr, disbursedLoanResult.get("resourceExternalId"));
|
||||||
|
|
||||||
|
String txnExternalIdStr2 = UUID.randomUUID().toString();
|
||||||
|
final HashMap disbursedLoanResult2 = this.loanTransactionHelper.disburseLoan("04 September 2022", loanId, "1000",
|
||||||
|
txnExternalIdStr2);
|
||||||
|
|
||||||
|
// Check whether the provided external id was retrieved
|
||||||
|
assertEquals(txnExternalIdStr2, disbursedLoanResult2.get("resourceExternalId"));
|
||||||
|
|
||||||
|
PutLoansLoanIdResponse markLoanAsFraudResult = this.loanTransactionHelper.modifyLoanApplication(loanExternalIdStr,
|
||||||
|
"markAsFraud", new PutLoansLoanIdRequest().fraud(true));
|
||||||
|
assertEquals(loanExternalIdStr, markLoanAsFraudResult.getResourceExternalId());
|
||||||
|
|
||||||
|
List<GetDelinquencyTagHistoryResponse> delinquencyTagHistoryResponseResult = this.loanTransactionHelper
|
||||||
|
.getLoanDelinquencyTags(loanExternalIdStr);
|
||||||
|
assertEquals(1, delinquencyTagHistoryResponseResult.size());
|
||||||
|
assertEquals((long) loanId, delinquencyTagHistoryResponseResult.get(0).getLoanId());
|
||||||
|
|
||||||
|
String loanExternalIdStr2 = UUID.randomUUID().toString();
|
||||||
|
applyForLoanApplication(client.getClientId().intValue(), loanProductID, loanExternalIdStr2);
|
||||||
|
|
||||||
|
PutLoansLoanIdResponse modifyLoanApplicationResult = this.loanTransactionHelper.modifyLoanApplication(loanExternalIdStr2,
|
||||||
|
"modify",
|
||||||
|
new PutLoansLoanIdRequest().submittedOnDate("31 August 2022").dateFormat("dd MMMM yyyy").locale("en")
|
||||||
|
.loanType("individual").productId(loanProductID).clientId(client.getClientId()).interestType(0)
|
||||||
|
.interestCalculationPeriodType(1).interestRatePerPeriod(0).isEqualAmortization(false).loanTermFrequency(30)
|
||||||
|
.loanTermFrequencyType(0).maxOutstandingLoanBalance(10000L).numberOfRepayments(1).principal(10000L)
|
||||||
|
.repaymentEvery(30).repaymentFrequencyType(0).transactionProcessingStrategyCode("mifos-standard-strategy")
|
||||||
|
.expectedDisbursementDate("2 September 2022").amortizationType(1));
|
||||||
|
|
||||||
|
assertEquals(loanExternalIdStr2, modifyLoanApplicationResult.getResourceExternalId());
|
||||||
|
DeleteLoansLoanIdResponse deleteLoanApplicationResult = this.loanTransactionHelper.deleteLoanApplication(loanExternalIdStr2);
|
||||||
|
assertEquals(loanExternalIdStr2, deleteLoanApplicationResult.getResourceExternalId());
|
||||||
|
|
||||||
|
String loanExternalIdStr3 = UUID.randomUUID().toString();
|
||||||
|
applyForLoanApplication(client.getClientId().intValue(), loanProductID, loanExternalIdStr3);
|
||||||
|
PostLoansLoanIdResponse result = this.loanTransactionHelper.rejectLoan(loanExternalIdStr3,
|
||||||
|
new PostLoansLoanIdRequest().rejectedOnDate("2 September 2022").locale("en").dateFormat("dd MMMM yyyy"));
|
||||||
|
assertEquals(loanExternalIdStr3, result.getResourceExternalId());
|
||||||
|
|
||||||
|
String loanExternalIdStr4 = UUID.randomUUID().toString();
|
||||||
|
applyForLoanApplication(client.getClientId().intValue(), loanProductID, loanExternalIdStr4);
|
||||||
|
result = this.loanTransactionHelper.withdrawnByApplicantLoan(loanExternalIdStr4,
|
||||||
|
new PostLoansLoanIdRequest().withdrawnOnDate("2 September 2022").locale("en").dateFormat("dd MMMM yyyy"));
|
||||||
|
assertEquals(loanExternalIdStr4, result.getResourceExternalId());
|
||||||
|
|
||||||
|
String loanExternalIdStr5 = UUID.randomUUID().toString();
|
||||||
|
applyForLoanApplication(client.getClientId().intValue(), loanProductID, loanExternalIdStr5);
|
||||||
|
this.loanTransactionHelper.approveLoan(loanExternalIdStr5, new PostLoansLoanIdRequest().approvedOnDate("2 September 2022")
|
||||||
|
.approvedLoanAmount("1000").expectedDisbursementDate("2 September 2022").locale("en").dateFormat("dd MMMM yyyy"));
|
||||||
|
result = this.loanTransactionHelper.disburseLoan(loanExternalIdStr5, new PostLoansLoanIdRequest()
|
||||||
|
.actualDisbursementDate("2 September 2022").transactionAmount("1000").locale("en").dateFormat("dd MMMM yyyy"));
|
||||||
|
// It's commented out for now, till it got fixed to return the loan externalId as well
|
||||||
|
// assertEquals(loanExternalIdStr5, result.getResourceExternalId());
|
||||||
|
|
||||||
|
String loanExternalIdStr6 = UUID.randomUUID().toString();
|
||||||
|
applyForLoanApplication(client.getClientId().intValue(), loanProductID, loanExternalIdStr6);
|
||||||
|
this.loanTransactionHelper.approveLoan(loanExternalIdStr6, new PostLoansLoanIdRequest().approvedOnDate("2 September 2022")
|
||||||
|
.approvedLoanAmount("1000").expectedDisbursementDate("2 September 2022").locale("en").dateFormat("dd MMMM yyyy"));
|
||||||
|
result = this.loanTransactionHelper.undoApprovalLoan(loanExternalIdStr6, new PostLoansLoanIdRequest());
|
||||||
|
assertEquals(loanExternalIdStr6, result.getResourceExternalId());
|
||||||
|
|
||||||
|
final Integer savingsId = SavingsAccountHelper.openSavingsAccount(this.requestSpec, this.responseSpec,
|
||||||
|
client.getClientId().intValue(), "10000.0");
|
||||||
|
|
||||||
|
String loanExternalIdStr7 = UUID.randomUUID().toString();
|
||||||
|
applyForLoanApplication(client.getClientId().intValue(), loanProductID, loanExternalIdStr7, savingsId.toString());
|
||||||
|
this.loanTransactionHelper.approveLoan(loanExternalIdStr7, new PostLoansLoanIdRequest().approvedOnDate("2 September 2022")
|
||||||
|
.approvedLoanAmount("1000").expectedDisbursementDate("2 September 2022").locale("en").dateFormat("dd MMMM yyyy"));
|
||||||
|
result = this.loanTransactionHelper.disburseToSavingsLoan(loanExternalIdStr7, new PostLoansLoanIdRequest()
|
||||||
|
.actualDisbursementDate("2 September 2022").transactionAmount("1000").locale("en").dateFormat("dd MMMM yyyy"));
|
||||||
|
assertEquals(loanExternalIdStr7, result.getResourceExternalId());
|
||||||
|
|
||||||
|
String loanExternalIdStr8 = UUID.randomUUID().toString();
|
||||||
|
applyForLoanApplication(client.getClientId().intValue(), loanProductID, loanExternalIdStr8);
|
||||||
|
this.loanTransactionHelper.approveLoan(loanExternalIdStr8, new PostLoansLoanIdRequest().approvedOnDate("2 September 2022")
|
||||||
|
.approvedLoanAmount("1000").expectedDisbursementDate("2 September 2022").locale("en").dateFormat("dd MMMM yyyy"));
|
||||||
|
this.loanTransactionHelper.disburseLoan(loanExternalIdStr8, new PostLoansLoanIdRequest()
|
||||||
|
.actualDisbursementDate("2 September 2022").transactionAmount("1000").locale("en").dateFormat("dd MMMM yyyy"));
|
||||||
|
result = this.loanTransactionHelper.undoDisbursalLoan(loanExternalIdStr8, new PostLoansLoanIdRequest());
|
||||||
|
assertEquals(loanExternalIdStr8, result.getResourceExternalId());
|
||||||
|
|
||||||
|
String loanExternalIdStr9 = UUID.randomUUID().toString();
|
||||||
|
applyForLoanApplication(client.getClientId().intValue(), loanProductID, loanExternalIdStr9);
|
||||||
|
this.loanTransactionHelper.approveLoan(loanExternalIdStr9, new PostLoansLoanIdRequest().approvedOnDate("2 September 2022")
|
||||||
|
.approvedLoanAmount("1000").expectedDisbursementDate("2 September 2022").locale("en").dateFormat("dd MMMM yyyy"));
|
||||||
|
this.loanTransactionHelper.disburseLoan(loanExternalIdStr9, new PostLoansLoanIdRequest()
|
||||||
|
.actualDisbursementDate("2 September 2022").transactionAmount("1000").locale("en").dateFormat("dd MMMM yyyy"));
|
||||||
|
this.loanTransactionHelper.disburseLoan(loanExternalIdStr9, new PostLoansLoanIdRequest()
|
||||||
|
.actualDisbursementDate("3 September 2022").transactionAmount("1000").locale("en").dateFormat("dd MMMM yyyy"));
|
||||||
|
result = this.loanTransactionHelper.undoLastDisbursalLoan(loanExternalIdStr9, new PostLoansLoanIdRequest());
|
||||||
|
assertEquals(loanExternalIdStr9, result.getResourceExternalId());
|
||||||
|
|
||||||
|
Integer loanOfficerId = StaffHelper.createStaff(this.requestSpec, this.responseSpec);
|
||||||
|
String loanExternalIdStr10 = UUID.randomUUID().toString();
|
||||||
|
applyForLoanApplication(client.getClientId().intValue(), loanProductID, loanExternalIdStr10);
|
||||||
|
result = this.loanTransactionHelper.assignLoanOfficerLoan(loanExternalIdStr10, new PostLoansLoanIdRequest()
|
||||||
|
.assignmentDate("2 September 2022").locale("en").dateFormat("dd MMMM yyyy").toLoanOfficerId(loanOfficerId));
|
||||||
|
assertEquals(loanExternalIdStr10, result.getResourceExternalId());
|
||||||
|
result = this.loanTransactionHelper.unassignLoanOfficerLoan(loanExternalIdStr10,
|
||||||
|
new PostLoansLoanIdRequest().unassignedDate("2 September 2022").locale("en").dateFormat("dd MMMM yyyy"));
|
||||||
|
assertEquals(loanExternalIdStr10, result.getResourceExternalId());
|
||||||
|
|
||||||
|
String loanExternalIdStr11 = UUID.randomUUID().toString();
|
||||||
|
applyForLoanApplication(client.getClientId().intValue(), loanProductID, loanExternalIdStr11);
|
||||||
|
result = this.loanTransactionHelper.recoverGuaranteesLoan(loanExternalIdStr11, new PostLoansLoanIdRequest());
|
||||||
|
assertEquals(loanExternalIdStr11, result.getResourceExternalId());
|
||||||
|
|
||||||
|
String loanExternalIdStr12 = UUID.randomUUID().toString();
|
||||||
|
applyForLoanApplication(client.getClientId().intValue(), loanProductID, loanExternalIdStr12);
|
||||||
|
result = this.loanTransactionHelper.assignDelinquencyLoan(loanExternalIdStr12, new PostLoansLoanIdRequest());
|
||||||
|
assertEquals(loanExternalIdStr12, result.getResourceExternalId());
|
||||||
|
|
||||||
|
String loanExternalIdStr13 = UUID.randomUUID().toString();
|
||||||
|
applyForLoanApplication(client.getClientId().intValue(), loanProductID, loanExternalIdStr13);
|
||||||
|
result = this.loanTransactionHelper.approveLoan(loanExternalIdStr13,
|
||||||
|
new PostLoansLoanIdRequest().approvedOnDate("2 September 2022").approvedLoanAmount("1000")
|
||||||
|
.expectedDisbursementDate("2 September 2022").locale("en").dateFormat("dd MMMM yyyy"));
|
||||||
|
assertEquals(loanExternalIdStr13, result.getResourceExternalId());
|
||||||
|
|
||||||
|
PostLoansLoanIdTransactionsResponse closeRescheduleResult = this.loanTransactionHelper.closeRescheduledLoan(loanExternalIdStr13,
|
||||||
|
new PostLoansLoanIdTransactionsRequest().transactionDate("2 September 2022").locale("en").dateFormat("dd MMMM yyyy"));
|
||||||
|
assertEquals(loanExternalIdStr13, closeRescheduleResult.getResourceExternalId());
|
||||||
|
|
||||||
|
String loanExternalIdStr14 = UUID.randomUUID().toString();
|
||||||
|
applyForLoanApplication(client.getClientId().intValue(), loanProductID, loanExternalIdStr14);
|
||||||
|
String transactionExternalId = UUID.randomUUID().toString();
|
||||||
|
result = this.loanTransactionHelper.approveLoan(loanExternalIdStr14,
|
||||||
|
new PostLoansLoanIdRequest().approvedOnDate("2 September 2022").approvedLoanAmount("1000")
|
||||||
|
.expectedDisbursementDate("2 September 2022").locale("en").dateFormat("dd MMMM yyyy"));
|
||||||
|
assertEquals(loanExternalIdStr14, result.getResourceExternalId());
|
||||||
|
this.loanTransactionHelper.disburseLoan(loanExternalIdStr14, new PostLoansLoanIdRequest()
|
||||||
|
.actualDisbursementDate("2 September 2022").transactionAmount("1000").locale("en").dateFormat("dd MMMM yyyy"));
|
||||||
|
PostLoansLoanIdTransactionsResponse closeResult = this.loanTransactionHelper.closeLoan(loanExternalIdStr14,
|
||||||
|
new PostLoansLoanIdTransactionsRequest().transactionDate("3 September 2022").locale("en").dateFormat("dd MMMM yyyy")
|
||||||
|
.externalId(transactionExternalId));
|
||||||
|
assertEquals(transactionExternalId, closeResult.getResourceExternalId());
|
||||||
|
|
||||||
|
String loanExternalIdStr15 = UUID.randomUUID().toString();
|
||||||
|
String transactionExternalId2 = UUID.randomUUID().toString();
|
||||||
|
applyForLoanApplication(client.getClientId().intValue(), loanProductID, loanExternalIdStr15);
|
||||||
|
result = this.loanTransactionHelper.approveLoan(loanExternalIdStr15,
|
||||||
|
new PostLoansLoanIdRequest().approvedOnDate("2 September 2022").approvedLoanAmount("1000")
|
||||||
|
.expectedDisbursementDate("2 September 2022").locale("en").dateFormat("dd MMMM yyyy"));
|
||||||
|
this.loanTransactionHelper.disburseLoan(loanExternalIdStr15, new PostLoansLoanIdRequest()
|
||||||
|
.actualDisbursementDate("2 September 2022").transactionAmount("1000").locale("en").dateFormat("dd MMMM yyyy"));
|
||||||
|
assertEquals(loanExternalIdStr15, result.getResourceExternalId());
|
||||||
|
PostLoansLoanIdTransactionsResponse forecloseResult = this.loanTransactionHelper.forecloseLoan(loanExternalIdStr15,
|
||||||
|
new PostLoansLoanIdTransactionsRequest().transactionDate("2 September 2022").locale("en").dateFormat("dd MMMM yyyy")
|
||||||
|
.externalId(transactionExternalId2));
|
||||||
|
assertEquals(transactionExternalId2, forecloseResult.getResourceExternalId());
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec, responseSpec, Boolean.FALSE);
|
||||||
|
GlobalConfigurationHelper.updateEnabledFlagForGlobalConfiguration(requestSpec, responseSpec, 50, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private HashMap applyForLoanApplication(final Integer clientID, final Integer loanProductID, final String externalId,
|
||||||
|
final String linkAccountId) {
|
||||||
|
final String loanApplicationJSON = new LoanApplicationTestBuilder().withPrincipal("1000").withLoanTermFrequency("1")
|
||||||
|
.withLoanTermFrequencyAsMonths().withNumberOfRepayments("1").withRepaymentEveryAfter("1")
|
||||||
|
.withRepaymentFrequencyTypeAsMonths().withInterestRatePerPeriod("0").withInterestTypeAsFlatBalance()
|
||||||
|
.withAmortizationTypeAsEqualPrincipalPayments().withInterestCalculationPeriodTypeSameAsRepaymentPeriod()
|
||||||
|
.withExpectedDisbursementDate("03 September 2022").withSubmittedOnDate("01 September 2022").withLoanType("individual")
|
||||||
|
.withExternalId(externalId).build(clientID.toString(), loanProductID.toString(), linkAccountId);
|
||||||
|
return (HashMap) this.loanTransactionHelper.createLoanAccount(loanApplicationJSON, "");
|
||||||
|
}
|
||||||
|
|
||||||
private HashMap applyForLoanApplication(final Integer clientID, final Integer loanProductID, final String externalId) {
|
private HashMap applyForLoanApplication(final Integer clientID, final Integer loanProductID, final String externalId) {
|
||||||
final String loanApplicationJSON = new LoanApplicationTestBuilder().withPrincipal("1000").withLoanTermFrequency("1")
|
final String loanApplicationJSON = new LoanApplicationTestBuilder().withPrincipal("1000").withLoanTermFrequency("1")
|
||||||
.withLoanTermFrequencyAsMonths().withNumberOfRepayments("1").withRepaymentEveryAfter("1")
|
.withLoanTermFrequencyAsMonths().withNumberOfRepayments("1").withRepaymentEveryAfter("1")
|
||||||
.withRepaymentFrequencyTypeAsMonths().withInterestRatePerPeriod("0").withInterestTypeAsFlatBalance()
|
.withRepaymentFrequencyTypeAsMonths().withInterestRatePerPeriod("0").withInterestTypeAsFlatBalance()
|
||||||
.withAmortizationTypeAsEqualPrincipalPayments().withInterestCalculationPeriodTypeSameAsRepaymentPeriod()
|
.withAmortizationTypeAsEqualPrincipalPayments().withInterestCalculationPeriodTypeSameAsRepaymentPeriod()
|
||||||
.withExpectedDisbursementDate("03 September 2022").withSubmittedOnDate("01 September 2022").withLoanType("individual")
|
.withExpectedDisbursementDate("03 September 2022").withSubmittedOnDate("01 September 2022").withLoanType("individual")
|
||||||
.withExternalId(externalId).build(clientID.toString(), loanProductID.toString(), null);
|
.withInArrearsTolerance("1001").withExternalId(externalId).build(clientID.toString(), loanProductID.toString(), null);
|
||||||
return (HashMap) this.loanTransactionHelper.createLoanAccount(loanApplicationJSON, "");
|
return (HashMap) this.loanTransactionHelper.createLoanAccount(loanApplicationJSON, "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+20
@@ -79,6 +79,8 @@ public class LoanApplicationTestBuilder {
|
|||||||
private List<Map<String, Object>> approvalFormData = null;
|
private List<Map<String, Object>> approvalFormData = null;
|
||||||
private String fixedPrincipalPercentagePerInstallment;
|
private String fixedPrincipalPercentagePerInstallment;
|
||||||
private String interestChargedFromDate;
|
private String interestChargedFromDate;
|
||||||
|
private String linkAccountId;
|
||||||
|
private String inArrearsTolerance;
|
||||||
|
|
||||||
public String build(final String clientID, final String groupID, final String loanProductId, final String savingsID) {
|
public String build(final String clientID, final String groupID, final String loanProductId, final String savingsID) {
|
||||||
final HashMap<String, Object> map = new HashMap<>();
|
final HashMap<String, Object> map = new HashMap<>();
|
||||||
@@ -169,6 +171,14 @@ public class LoanApplicationTestBuilder {
|
|||||||
map.put("linkAccountId", savingsID);
|
map.put("linkAccountId", savingsID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.linkAccountId != null) {
|
||||||
|
map.put("linkAccountId", this.linkAccountId);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.inArrearsTolerance != null) {
|
||||||
|
map.put("inArrearsTolerance", this.inArrearsTolerance);
|
||||||
|
}
|
||||||
|
|
||||||
if (graceOnPrincipalPayment != null) {
|
if (graceOnPrincipalPayment != null) {
|
||||||
map.put("graceOnPrincipalPayment", graceOnPrincipalPayment);
|
map.put("graceOnPrincipalPayment", graceOnPrincipalPayment);
|
||||||
}
|
}
|
||||||
@@ -210,6 +220,11 @@ public class LoanApplicationTestBuilder {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public LoanApplicationTestBuilder withLinkedAccount(String linkAccountId) {
|
||||||
|
this.linkAccountId = linkAccountId;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public LoanApplicationTestBuilder withLoanTermFrequencyAsMonths() {
|
public LoanApplicationTestBuilder withLoanTermFrequencyAsMonths() {
|
||||||
this.loanTermFrequencyType = MONTHS;
|
this.loanTermFrequencyType = MONTHS;
|
||||||
return this;
|
return this;
|
||||||
@@ -398,4 +413,9 @@ public class LoanApplicationTestBuilder {
|
|||||||
this.interestChargedFromDate = interestChargedFromDate;
|
this.interestChargedFromDate = interestChargedFromDate;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public LoanApplicationTestBuilder withInArrearsTolerance(String amount) {
|
||||||
|
this.inArrearsTolerance = amount;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+10
@@ -136,6 +136,7 @@ public class LoanProductTestBuilder {
|
|||||||
private String fixedPrincipalPercentagePerInstallment;
|
private String fixedPrincipalPercentagePerInstallment;
|
||||||
private String installmentAmountInMultiplesOf;
|
private String installmentAmountInMultiplesOf;
|
||||||
private boolean canDefineInstallmentAmount;
|
private boolean canDefineInstallmentAmount;
|
||||||
|
private Integer delinquencyBucketId;
|
||||||
|
|
||||||
public String build(final String chargeId) {
|
public String build(final String chargeId) {
|
||||||
final HashMap<String, Object> map = build(chargeId, null);
|
final HashMap<String, Object> map = build(chargeId, null);
|
||||||
@@ -254,6 +255,10 @@ public class LoanProductTestBuilder {
|
|||||||
map.put("delinquencyBucketId", delinquencyBucketId);
|
map.put("delinquencyBucketId", delinquencyBucketId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.delinquencyBucketId != null) {
|
||||||
|
map.put("delinquencyBucketId", this.delinquencyBucketId);
|
||||||
|
}
|
||||||
|
|
||||||
if (this.feeToIncomeAccountMappings != null) {
|
if (this.feeToIncomeAccountMappings != null) {
|
||||||
map.put("feeToIncomeAccountMappings", this.feeToIncomeAccountMappings);
|
map.put("feeToIncomeAccountMappings", this.feeToIncomeAccountMappings);
|
||||||
}
|
}
|
||||||
@@ -269,6 +274,11 @@ public class LoanProductTestBuilder {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public LoanProductTestBuilder withDelinquencyBucket(Integer delinquencyBucketId) {
|
||||||
|
this.delinquencyBucketId = delinquencyBucketId;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public LoanProductTestBuilder withMinPrincipal(final String minPrincipal) {
|
public LoanProductTestBuilder withMinPrincipal(final String minPrincipal) {
|
||||||
this.minPrincipal = minPrincipal;
|
this.minPrincipal = minPrincipal;
|
||||||
return this;
|
return this;
|
||||||
|
|||||||
+84
@@ -43,8 +43,10 @@ import javax.ws.rs.core.HttpHeaders;
|
|||||||
import javax.ws.rs.core.MediaType;
|
import javax.ws.rs.core.MediaType;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.fineract.client.models.DeleteLoansLoanIdChargesChargeIdResponse;
|
import org.apache.fineract.client.models.DeleteLoansLoanIdChargesChargeIdResponse;
|
||||||
|
import org.apache.fineract.client.models.DeleteLoansLoanIdResponse;
|
||||||
import org.apache.fineract.client.models.GetDelinquencyTagHistoryResponse;
|
import org.apache.fineract.client.models.GetDelinquencyTagHistoryResponse;
|
||||||
import org.apache.fineract.client.models.GetLoanProductsProductIdResponse;
|
import org.apache.fineract.client.models.GetLoanProductsProductIdResponse;
|
||||||
|
import org.apache.fineract.client.models.GetLoansApprovalTemplateResponse;
|
||||||
import org.apache.fineract.client.models.GetLoansLoanIdChargesChargeIdResponse;
|
import org.apache.fineract.client.models.GetLoansLoanIdChargesChargeIdResponse;
|
||||||
import org.apache.fineract.client.models.GetLoansLoanIdChargesTemplateResponse;
|
import org.apache.fineract.client.models.GetLoansLoanIdChargesTemplateResponse;
|
||||||
import org.apache.fineract.client.models.GetLoansLoanIdCollectionData;
|
import org.apache.fineract.client.models.GetLoansLoanIdCollectionData;
|
||||||
@@ -59,6 +61,7 @@ import org.apache.fineract.client.models.PostLoansLoanIdChargesChargeIdRequest;
|
|||||||
import org.apache.fineract.client.models.PostLoansLoanIdChargesChargeIdResponse;
|
import org.apache.fineract.client.models.PostLoansLoanIdChargesChargeIdResponse;
|
||||||
import org.apache.fineract.client.models.PostLoansLoanIdChargesRequest;
|
import org.apache.fineract.client.models.PostLoansLoanIdChargesRequest;
|
||||||
import org.apache.fineract.client.models.PostLoansLoanIdChargesResponse;
|
import org.apache.fineract.client.models.PostLoansLoanIdChargesResponse;
|
||||||
|
import org.apache.fineract.client.models.PostLoansLoanIdRequest;
|
||||||
import org.apache.fineract.client.models.PostLoansLoanIdResponse;
|
import org.apache.fineract.client.models.PostLoansLoanIdResponse;
|
||||||
import org.apache.fineract.client.models.PostLoansLoanIdTransactionsRequest;
|
import org.apache.fineract.client.models.PostLoansLoanIdTransactionsRequest;
|
||||||
import org.apache.fineract.client.models.PostLoansLoanIdTransactionsResponse;
|
import org.apache.fineract.client.models.PostLoansLoanIdTransactionsResponse;
|
||||||
@@ -67,6 +70,7 @@ import org.apache.fineract.client.models.PutChargeTransactionChangesRequest;
|
|||||||
import org.apache.fineract.client.models.PutChargeTransactionChangesResponse;
|
import org.apache.fineract.client.models.PutChargeTransactionChangesResponse;
|
||||||
import org.apache.fineract.client.models.PutLoansLoanIdChargesChargeIdRequest;
|
import org.apache.fineract.client.models.PutLoansLoanIdChargesChargeIdRequest;
|
||||||
import org.apache.fineract.client.models.PutLoansLoanIdChargesChargeIdResponse;
|
import org.apache.fineract.client.models.PutLoansLoanIdChargesChargeIdResponse;
|
||||||
|
import org.apache.fineract.client.models.PutLoansLoanIdRequest;
|
||||||
import org.apache.fineract.client.models.PutLoansLoanIdResponse;
|
import org.apache.fineract.client.models.PutLoansLoanIdResponse;
|
||||||
import org.apache.fineract.client.util.JSON;
|
import org.apache.fineract.client.util.JSON;
|
||||||
import org.apache.fineract.integrationtests.client.IntegrationTest;
|
import org.apache.fineract.integrationtests.client.IntegrationTest;
|
||||||
@@ -178,6 +182,11 @@ public class LoanTransactionHelper extends IntegrationTest {
|
|||||||
return GSON.fromJson(response, PutLoansLoanIdResponse.class);
|
return GSON.fromJson(response, PutLoansLoanIdResponse.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public PutLoansLoanIdResponse modifyLoanApplication(final String loanExternalId, final String command,
|
||||||
|
final PutLoansLoanIdRequest request) {
|
||||||
|
return ok(fineract().loans.modifyLoanApplication1(loanExternalId, request, command));
|
||||||
|
}
|
||||||
|
|
||||||
public ArrayList getLoanRepaymentSchedule(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
|
public ArrayList getLoanRepaymentSchedule(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
|
||||||
final Integer loanID) {
|
final Integer loanID) {
|
||||||
final String URL = "/fineract-provider/api/v1/loans/" + loanID + "?associations=repaymentSchedule&" + Utils.TENANT_IDENTIFIER;
|
final String URL = "/fineract-provider/api/v1/loans/" + loanID + "?associations=repaymentSchedule&" + Utils.TENANT_IDENTIFIER;
|
||||||
@@ -920,6 +929,10 @@ public class LoanTransactionHelper extends IntegrationTest {
|
|||||||
return ok(fineract().loans.retrieveLoan(loanId, false, "all", null, null));
|
return ok(fineract().loans.retrieveLoan(loanId, false, "all", null, null));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public GetLoansLoanIdResponse getLoanDetails(final String loanExternalId) {
|
||||||
|
return ok(fineract().loans.retrieveLoan1(loanExternalId, false, "all", null, null));
|
||||||
|
}
|
||||||
|
|
||||||
public GetLoansLoanIdTransactionsTransactionIdResponse getLoanTransaction(final Integer loanId, final Integer txnId) {
|
public GetLoansLoanIdTransactionsTransactionIdResponse getLoanTransaction(final Integer loanId, final Integer txnId) {
|
||||||
final String GET_LOAN_CHARGES_URL = "/fineract-provider/api/v1/loans/" + loanId + "/transactions/" + txnId + "?"
|
final String GET_LOAN_CHARGES_URL = "/fineract-provider/api/v1/loans/" + loanId + "/transactions/" + txnId + "?"
|
||||||
+ Utils.TENANT_IDENTIFIER;
|
+ Utils.TENANT_IDENTIFIER;
|
||||||
@@ -1626,4 +1639,75 @@ public class LoanTransactionHelper extends IntegrationTest {
|
|||||||
fineract().loanTransactions.retrieveTransactionTemplate1(loanExternalIdStr, command, dateFormat, transactionDate, locale));
|
fineract().loanTransactions.retrieveTransactionTemplate1(loanExternalIdStr, command, dateFormat, transactionDate, locale));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public GetLoansApprovalTemplateResponse getLoanApprovalTemplate(String loanExternalIdStr) {
|
||||||
|
return ok(fineract().loans.retrieveApprovalTemplate1(loanExternalIdStr, "approval"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public DeleteLoansLoanIdResponse deleteLoanApplication(String loanExternalId) {
|
||||||
|
return ok(fineract().loans.deleteLoanApplication1(loanExternalId));
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<GetDelinquencyTagHistoryResponse> getLoanDelinquencyTags(String loanExternalId) {
|
||||||
|
return ok(fineract().loans.getDelinquencyTagHistory1(loanExternalId));
|
||||||
|
}
|
||||||
|
|
||||||
|
public PostLoansLoanIdResponse approveLoan(String loanExternalId, PostLoansLoanIdRequest request) {
|
||||||
|
return ok(fineract().loans.stateTransitions1(loanExternalId, request, "approve"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public PostLoansLoanIdResponse rejectLoan(String loanExternalId, PostLoansLoanIdRequest request) {
|
||||||
|
return ok(fineract().loans.stateTransitions1(loanExternalId, request, "reject"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public PostLoansLoanIdResponse withdrawnByApplicantLoan(String loanExternalId, PostLoansLoanIdRequest request) {
|
||||||
|
return ok(fineract().loans.stateTransitions1(loanExternalId, request, "withdrawnByApplicant"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public PostLoansLoanIdResponse disburseLoan(String loanExternalId, PostLoansLoanIdRequest request) {
|
||||||
|
return ok(fineract().loans.stateTransitions1(loanExternalId, request, "disburse"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public PostLoansLoanIdResponse disburseToSavingsLoan(String loanExternalId, PostLoansLoanIdRequest request) {
|
||||||
|
return ok(fineract().loans.stateTransitions1(loanExternalId, request, "disburseToSavings"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public PostLoansLoanIdResponse undoApprovalLoan(String loanExternalId, PostLoansLoanIdRequest request) {
|
||||||
|
return ok(fineract().loans.stateTransitions1(loanExternalId, request, "undoapproval"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public PostLoansLoanIdResponse undoDisbursalLoan(String loanExternalId, PostLoansLoanIdRequest request) {
|
||||||
|
return ok(fineract().loans.stateTransitions1(loanExternalId, request, "undodisbursal"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public PostLoansLoanIdResponse undoLastDisbursalLoan(String loanExternalId, PostLoansLoanIdRequest request) {
|
||||||
|
return ok(fineract().loans.stateTransitions1(loanExternalId, request, "undolastdisbursal"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public PostLoansLoanIdResponse assignLoanOfficerLoan(String loanExternalId, PostLoansLoanIdRequest request) {
|
||||||
|
return ok(fineract().loans.stateTransitions1(loanExternalId, request, "assignloanofficer"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public PostLoansLoanIdResponse unassignLoanOfficerLoan(String loanExternalId, PostLoansLoanIdRequest request) {
|
||||||
|
return ok(fineract().loans.stateTransitions1(loanExternalId, request, "unassignloanofficer"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public PostLoansLoanIdResponse recoverGuaranteesLoan(String loanExternalId, PostLoansLoanIdRequest request) {
|
||||||
|
return ok(fineract().loans.stateTransitions1(loanExternalId, request, "recoverGuarantees"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public PostLoansLoanIdResponse assignDelinquencyLoan(String loanExternalId, PostLoansLoanIdRequest request) {
|
||||||
|
return ok(fineract().loans.stateTransitions1(loanExternalId, request, "assigndelinquency"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public PostLoansLoanIdTransactionsResponse closeRescheduledLoan(String loanExternalId, PostLoansLoanIdTransactionsRequest request) {
|
||||||
|
return ok(fineract().loanTransactions.executeLoanTransaction1(loanExternalId, request, "close-rescheduled"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public PostLoansLoanIdTransactionsResponse closeLoan(String loanExternalId, PostLoansLoanIdTransactionsRequest request) {
|
||||||
|
return ok(fineract().loanTransactions.executeLoanTransaction1(loanExternalId, request, "close"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public PostLoansLoanIdTransactionsResponse forecloseLoan(String loanExternalId, PostLoansLoanIdTransactionsRequest request) {
|
||||||
|
return ok(fineract().loanTransactions.executeLoanTransaction1(loanExternalId, request, "foreclosure"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user