in fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/api/LoansApiResource.java [884:1170]
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 = loanBasicDetails.withInterestRecalculationCalendarData(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 = loanBasicDetails.setMeeting(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;
List<LoanTermVariationsData> emiAmountVariations = null;
List<LoanTermVariationsData> loanTermVariations = null;
Collection<LoanCollateralResponseData> loanCollateralManagements;
Collection<LoanCollateralManagementData> loanCollateralManagementData = new ArrayList<>();
CollectionData collectionData = this.delinquencyReadPlatformService.calculateLoanCollectionData(resolvedLoanId);
final Set<String> mandatoryResponseParameters = new HashSet<>();
final Set<String> associationParameters = ApiParameterHelper.extractAssociationsForResponseIfProvided(uriInfo.getQueryParameters());
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,
DataTableApiConstant.loanTermVariationsAssociateParamName));
}
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);
loanRepayments = this.loanReadPlatformService.retrieveLoanTransactions(resolvedLoanId);
}
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.loanTermVariationsRepository.findLoanTermVariationsByLoanIdAndTermType(resolvedLoanId,
LoanTermVariationType.EMI_AMOUNT.getValue());
}
if (associationParameters.contains(DataTableApiConstant.loanTermVariationsAssociateParamName)) {
mandatoryResponseParameters.add(DataTableApiConstant.loanTermVariationsAssociateParamName);
loanTermVariations = this.loanTermVariationsRepository.findLoanTermVariationsByLoanId(resolvedLoanId);
}
if (associationParameters.contains(DataTableApiConstant.repaymentScheduleAssociateParamName)) {
mandatoryResponseParameters.add(DataTableApiConstant.repaymentScheduleAssociateParamName);
final RepaymentScheduleRelatedLoanData repaymentScheduleRelatedData = new RepaymentScheduleRelatedLoanData(
loanBasicDetails.getTimeline().getExpectedDisbursementDate(),
loanBasicDetails.getTimeline().getActualDisbursementDate(), loanBasicDetails.getCurrency(),
loanBasicDetails.getPrincipal(), loanBasicDetails.getInArrearsTolerance(),
loanBasicDetails.getFeeChargesAtDisbursementCharged());
repaymentSchedule = this.loanReadPlatformService.retrieveRepaymentSchedule(resolvedLoanId, repaymentScheduleRelatedData,
disbursementData, loanBasicDetails.isInterestRecalculationEnabled(),
LoanScheduleType.fromEnumOptionData(loanBasicDetails.getLoanScheduleType()));
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,
LoanScheduleType.fromEnumOptionData(loanBasicDetails.getLoanScheduleType()));
loanBasicDetails = loanBasicDetails.setOriginalSchedule(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);
}
}
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) {
LoanSummaryDataProvider loanSummaryDataProvider = loanSummaryProviderDelegate
.resolveLoanSummaryDataProvider(loanBasicDetails.getTransactionProcessingStrategyCode());
loanBasicDetails.setSummary(
loanSummaryDataProvider.withTransactionAmountsSummary(loanBasicDetails.getId(), loanBasicDetails.getSummary(),
repaymentSchedule, loanSummaryBalancesRepository.retrieveLoanSummaryBalancesByTransactionType(
loanBasicDetails.getId(), LoanApiConstants.LOAN_SUMMARY_TRANSACTION_TYPES)));
}
final LoanAccountData loanAccount = loanBasicDetails.associationsAndTemplate(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,
LoanScheduleType.getValuesAsEnumOptionDataList(), LoanScheduleProcessingType.getValuesAsEnumOptionDataList(),
loanTermVariations, ApiFacingEnum.getValuesAsStringEnumOptionDataList(DaysInYearCustomStrategyType.class),
ApiFacingEnum.getValuesAsStringEnumOptionDataList(LoanCapitalizedIncomeCalculationType.class),
ApiFacingEnum.getValuesAsStringEnumOptionDataList(LoanCapitalizedIncomeStrategy.class),
ApiFacingEnum.getValuesAsStringEnumOptionDataList(LoanCapitalizedIncomeType.class));
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters(),
mandatoryResponseParameters);
return this.toApiJsonSerializer.serialize(settings, loanAccount, LOAN_DATA_PARAMETERS);
}