diff --git a/fineract-provider/src/main/java/org/apache/fineract/organisation/prequalification/service/PrequalificationReadPlatformService.java b/fineract-provider/src/main/java/org/apache/fineract/organisation/prequalification/service/PrequalificationReadPlatformService.java index acff1d94f53..963cad6825a 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/organisation/prequalification/service/PrequalificationReadPlatformService.java +++ b/fineract-provider/src/main/java/org/apache/fineract/organisation/prequalification/service/PrequalificationReadPlatformService.java @@ -38,5 +38,7 @@ public interface PrequalificationReadPlatformService { Collection retrievePrequalificationGroupsMappings(Long groupId); + Collection retrieveGroupByPrequalificationId(Long prequalificationId); + Collection retrievePrequalificationIndividualMappings(Long clientId); } diff --git a/fineract-provider/src/main/java/org/apache/fineract/organisation/prequalification/service/PrequalificationReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/organisation/prequalification/service/PrequalificationReadPlatformServiceImpl.java index 455a4367c20..4dad1ee5774 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/organisation/prequalification/service/PrequalificationReadPlatformServiceImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/organisation/prequalification/service/PrequalificationReadPlatformServiceImpl.java @@ -257,6 +257,14 @@ public Collection retrievePrequalificationGroupsMappi return prequalificationGroups; } + @Override + public Collection retrieveGroupByPrequalificationId(Long prequalificationId) { + final String sql = "select " + this.mappingsMapper.schema() + " where PG.id = ? "; + Collection prequalificationGroups = this.jdbcTemplate.query(sql, this.mappingsMapper, + new Object[] { prequalificationId }); + return prequalificationGroups; + } + @Override public Collection retrievePrequalificationIndividualMappings(final Long clientId) { final String sql = "select " + this.prequalificationIndividualMappingsMapper.schema() + " WHERE mc.id = ? AND mpg.status = 600"; @@ -562,7 +570,7 @@ private static final class PrequalificationsGroupMappingsMapper implements RowMa PrequalificationsGroupMappingsMapper() { this.schema = " PG.id AS id, PG.prequalification_number AS prequalificationNumber, PG.group_name AS groupName, " - + "PG.status, LP.name AS productName, " + "PG.created_at, AU.firstname, AU.lastname " + + "PG.status, LP.name AS productName, " + "PG.created_at, AU.firstname, AU.lastname, MG.id AS groupId " + "from m_group_prequalification_relationship GR " + "inner join m_group MG on MG.id = GR.group_id " + "inner join m_prequalification_group PG on PG.id = GR.prequalification_id " + "inner join m_product_loan LP on LP.id = PG.product_id " + "INNER JOIN m_appuser AU ON AU.id = PG.added_by " + ""; @@ -577,13 +585,14 @@ public GroupPrequalificationData mapRow(final ResultSet rs, final int rowNum) th final Integer statusEnum = JdbcSupport.getInteger(rs, "status"); final EnumOptionData status = PreQualificationsEnumerations.status(statusEnum); final Long id = JdbcSupport.getLong(rs, "id"); + final Long groupId = JdbcSupport.getLong(rs, "groupId"); final String prequalificationNumber = rs.getString("prequalificationNumber"); String groupName = rs.getString("groupName"); final String productName = rs.getString("productName"); final LocalDate createdAt = JdbcSupport.getLocalDate(rs, "created_at"); final String addedBy = rs.getString("firstname") + " " + rs.getString("lastname"); return GroupPrequalificationData.simpeGroupData(id, prequalificationNumber, status, groupName, productName, addedBy, createdAt, - null); + groupId); } } diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/service/LoanScheduleAssembler.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/service/LoanScheduleAssembler.java index 0d3f78da3ee..b65a31901fe 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/service/LoanScheduleAssembler.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/service/LoanScheduleAssembler.java @@ -293,15 +293,18 @@ private LoanApplicationTerms assembleLoanApplicationTermsFrom(final JsonElement numberOfDays = configurationDomainService.retreivePeroidInNumberOfDaysForSkipMeetingDate().intValue(); } } - if ((loanType.isJLGAccount() || loanType.isGroupAccount()) && calendar != null) { - validateRepaymentsStartDateWithMeetingDates(calculatedRepaymentsStartingFromDate, calendar, isSkipMeetingOnFirstDay, - numberOfDays); - - /* - * If disbursement is synced on meeting, make sure disbursement date is on a meeting date - */ - if (synchDisbursement != null && synchDisbursement.booleanValue()) { - validateDisbursementDateWithMeetingDates(expectedDisbursementDate, calendar, isSkipMeetingOnFirstDay, numberOfDays); + final boolean isMeetingMandatoryForJLGLoans = this.configurationDomainService.isMeetingMandatoryForJLGLoans(); + if (Boolean.TRUE.equals(isMeetingMandatoryForJLGLoans)) { + if ((loanType.isJLGAccount() || loanType.isGroupAccount()) && calendar != null) { + validateRepaymentsStartDateWithMeetingDates(calculatedRepaymentsStartingFromDate, calendar, isSkipMeetingOnFirstDay, + numberOfDays); + + /* + * If disbursement is synced on meeting, make sure disbursement date is on a meeting date + */ + if (synchDisbursement != null && synchDisbursement.booleanValue()) { + validateDisbursementDateWithMeetingDates(expectedDisbursementDate, calendar, isSkipMeetingOnFirstDay, numberOfDays); + } } } diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/serialization/LoanApplicationCommandFromApiJsonHelper.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/serialization/LoanApplicationCommandFromApiJsonHelper.java index 28def244703..58a99407b36 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/serialization/LoanApplicationCommandFromApiJsonHelper.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/serialization/LoanApplicationCommandFromApiJsonHelper.java @@ -124,8 +124,9 @@ public final class LoanApplicationCommandFromApiJsonHelper { LoanApiConstants.relativeNumberParamName, LoanApiConstants.yearsInCommunityParamName, LoanApiConstants.PREQUALIFICATION_ID, LoanApiConstants.cupoIdParameterName, LoanApiConstants.externalLoansParamName, LoanApiConstants.CASE_ID, LoanApiConstants.paymentCapacityParamName, LoanApiConstants.facilitatorParamName, LoanApiConstants.maidenNameParamName, - LoanApiConstants.politicallyExposedParamName, LoanApiConstants.otherIncomeParamName, LoanApiConstants.currentLoansParamName, LoanApiConstants.dateOfBirthParamName, - LoanApiConstants.businessActivityParamName, LoanApiConstants.LOAN_ADDITIONAL_DATA, "borrowerCycle", "isBulkImport")); + LoanApiConstants.politicallyExposedParamName, LoanApiConstants.otherIncomeParamName, LoanApiConstants.currentLoansParamName, + LoanApiConstants.dateOfBirthParamName, LoanApiConstants.businessActivityParamName, LoanApiConstants.LOAN_ADDITIONAL_DATA, + "borrowerCycle", "isBulkImport")); private final FromJsonHelper fromApiJsonHelper; private final CalculateLoanScheduleQueryFromApiJsonHelper apiJsonHelper; diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanApplicationWritePlatformServiceJpaRepositoryImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanApplicationWritePlatformServiceJpaRepositoryImpl.java index fe108218cce..b554c604619 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanApplicationWritePlatformServiceJpaRepositoryImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanApplicationWritePlatformServiceJpaRepositoryImpl.java @@ -75,13 +75,14 @@ import org.apache.fineract.organisation.bankcheque.domain.BankChequeStatus; import org.apache.fineract.organisation.bankcheque.domain.Cheque; import org.apache.fineract.organisation.bankcheque.domain.ChequeBatchRepositoryWrapper; +import org.apache.fineract.organisation.prequalification.data.GroupPrequalificationData; import org.apache.fineract.organisation.prequalification.data.LoanAdditionalData; import org.apache.fineract.organisation.prequalification.domain.LoanAdditionProperties; import org.apache.fineract.organisation.prequalification.domain.LoanAdditionalPropertiesRepository; import org.apache.fineract.organisation.prequalification.domain.PrequalificationGroup; import org.apache.fineract.organisation.prequalification.domain.PrequalificationGroupRepositoryWrapper; import org.apache.fineract.organisation.prequalification.exception.PrequalificationNotProvidedException; -import org.apache.fineract.organisation.prequalification.service.BureauValidationWritePlatformServiceImpl; +import org.apache.fineract.organisation.prequalification.service.PrequalificationReadPlatformService; import org.apache.fineract.organisation.staff.domain.Staff; import org.apache.fineract.portfolio.account.domain.AccountAssociationType; import org.apache.fineract.portfolio.account.domain.AccountAssociations; @@ -133,7 +134,6 @@ import org.apache.fineract.portfolio.loanaccount.domain.LoanCollateralManagement; import org.apache.fineract.portfolio.loanaccount.domain.LoanDisbursementDetails; import org.apache.fineract.portfolio.loanaccount.domain.LoanLifecycleStateMachine; -import org.apache.fineract.portfolio.loanaccount.domain.LoanRepaymentScheduleInstallmentRepository; import org.apache.fineract.portfolio.loanaccount.domain.LoanRepaymentScheduleTransactionProcessorFactory; import org.apache.fineract.portfolio.loanaccount.domain.LoanRepository; import org.apache.fineract.portfolio.loanaccount.domain.LoanRepositoryWrapper; @@ -171,7 +171,6 @@ import org.apache.fineract.portfolio.savings.data.GroupSavingsIndividualMonitoringAccountData; import org.apache.fineract.portfolio.savings.domain.SavingsAccount; import org.apache.fineract.portfolio.savings.domain.SavingsAccountAssembler; -import org.apache.fineract.portfolio.savings.domain.SavingsAccountRepositoryWrapper; import org.apache.fineract.portfolio.savings.service.GSIMReadPlatformService; import org.apache.fineract.portfolio.savings.service.SavingsAccountWritePlatformService; import org.apache.fineract.useradministration.domain.AppUser; @@ -244,11 +243,9 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa private BitaCoraMasterRepository bitaCoraMasterRepository; private final SavingsAccountWritePlatformService savingsAccountWritePlatformService; - - private final SavingsAccountRepositoryWrapper savingsAccountRepositoryWrapper; private final AppUserRepository appUserRepository; - private final BureauValidationWritePlatformServiceImpl bureauValidationWritePlatformService; private final LoanAdditionalPropertiesRepository loanAdditionalPropertiesRepository; + private final PrequalificationReadPlatformService prequalificationReadPlatformService; @Autowired public LoanApplicationWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, final FromJsonHelper fromJsonHelper, @@ -264,7 +261,6 @@ public LoanApplicationWritePlatformServiceJpaRepositoryImpl(final PlatformSecuri final LoanRepaymentScheduleTransactionProcessorFactory loanRepaymentScheduleTransactionProcessorFactory, final CalendarRepository calendarRepository, final CalendarInstanceRepository calendarInstanceRepository, final SavingsAccountAssembler savingsAccountAssembler, final AccountAssociationsRepository accountAssociationsRepository, - final LoanRepaymentScheduleInstallmentRepository repaymentScheduleInstallmentRepository, final LoanReadPlatformService loanReadPlatformService, final AccountNumberFormatRepositoryWrapper accountNumberFormatRepository, final BusinessEventNotifierService businessEventNotifierService, final ConfigurationDomainService configurationDomainService, final LoanScheduleAssembler loanScheduleAssembler, final LoanUtilService loanUtilService, @@ -281,10 +277,9 @@ public LoanApplicationWritePlatformServiceJpaRepositoryImpl(final PlatformSecuri ChequeBatchRepositoryWrapper chequeBatchRepositoryWrapper, PrequalificationGroupRepositoryWrapper prequalificationGroupRepositoryWrapper, final SavingsAccountWritePlatformService savingsAccountWritePlatformService, - final SavingsAccountRepositoryWrapper savingsAccountRepositoryWrapper, - final BureauValidationWritePlatformServiceImpl bureauValidationWritePlatformService, final LoanAdditionalPropertiesRepository loanAdditionalPropertiesRepository, - final GroupLoanAdditionalsRepository groupLoanAdditionalsRepository) { + final GroupLoanAdditionalsRepository groupLoanAdditionalsRepository, + PrequalificationReadPlatformService prequalificationReadPlatformService) { this.context = context; this.fromJsonHelper = fromJsonHelper; this.loanApplicationTransitionApiJsonValidator = loanApplicationTransitionApiJsonValidator; @@ -332,11 +327,10 @@ public LoanApplicationWritePlatformServiceJpaRepositoryImpl(final PlatformSecuri this.chequeBatchRepositoryWrapper = chequeBatchRepositoryWrapper; this.prequalificationGroupRepositoryWrapper = prequalificationGroupRepositoryWrapper; this.savingsAccountWritePlatformService = savingsAccountWritePlatformService; - this.savingsAccountRepositoryWrapper = savingsAccountRepositoryWrapper; this.groupLoanAdditionalsRepository = groupLoanAdditionalsRepository; this.appUserRepository = appUserRepository; - this.bureauValidationWritePlatformService = bureauValidationWritePlatformService; this.loanAdditionalPropertiesRepository = loanAdditionalPropertiesRepository; + this.prequalificationReadPlatformService = prequalificationReadPlatformService; } private LoanLifecycleStateMachine defaultLoanLifecycleStateMachine() { @@ -524,6 +518,16 @@ public CommandProcessingResult submitApplication(final JsonCommand command) { final PrequalificationGroup prequalificationGroup = newLoanApplication.getPrequalificationGroup(); if (prequalificationGroup != null && prequalificationGroup.isPrequalificationTypeGroup()) { + Collection prequalificationDataList = this.prequalificationReadPlatformService + .retrieveGroupByPrequalificationId(prequalificationGroup.getId()); + if (!CollectionUtils.isEmpty(prequalificationDataList)) { + GroupPrequalificationData prequalificationData = new ArrayList<>(prequalificationDataList).get(0); + final Long prequalificationGroupId = prequalificationData.getGroupId(); + if (prequalificationGroupId != null) { + final Group groupPrequalification = this.groupRepository.findOneWithNotFoundDetection(prequalificationGroupId); + newLoanApplication.updateGroup(groupPrequalification); + } + } GroupLoanAdditionals groupLoanAdditionals = GroupLoanAdditionals.assembleFromJson(command, newLoanApplication, facilitator); addExternalLoans(groupLoanAdditionals, command); this.groupLoanAdditionalsRepository.save(groupLoanAdditionals); @@ -1489,7 +1493,21 @@ public CommandProcessingResult modifyApplication(final Long loanId, final JsonCo officeSpecificLoanProductValidation(existingLoanApplication.getLoanProduct().getId(), OfficeId); } + if (prequalificationGroup.isPrequalificationTypeGroup()) { + Collection prequalificationDataList = this.prequalificationReadPlatformService + .retrieveGroupByPrequalificationId(prequalificationGroup.getId()); + if (!CollectionUtils.isEmpty(prequalificationDataList)) { + GroupPrequalificationData prequalificationData = new ArrayList<>(prequalificationDataList).get(0); + final Long prequalificationGroupId = prequalificationData.getGroupId(); + if (prequalificationGroupId != null) { + final Group groupPrequalification = this.groupRepository.findOneWithNotFoundDetection(prequalificationGroupId); + existingLoanApplication.updateGroup(groupPrequalification); + } + } + } + if (prequalificationGroup.isPrequalificationTypeIndividual()) { + existingLoanApplication.updateGroup(null); final JsonElement loanAdditionalDataJson = command.jsonElement(LoanApiConstants.LOAN_ADDITIONAL_DATA); if (loanAdditionalDataJson != null && loanAdditionalDataJson.isJsonObject()) { this.fromApiJsonDeserializer.validateLoanAdditionalData(command); @@ -2562,8 +2580,11 @@ public CommandProcessingResult approveApplication(final Long loanId, final JsonC numberOfDays = configurationDomainService.retreivePeroidInNumberOfDaysForSkipMeetingDate().intValue(); } } - this.loanScheduleAssembler.validateDisbursementDateWithMeetingDates(expectedDisbursementDate, calendar, - isSkipRepaymentOnFirstMonth, numberOfDays); + final boolean isMeetingMandatoryForJLGLoans = this.configurationDomainService.isMeetingMandatoryForJLGLoans(); + if (Boolean.TRUE.equals(isMeetingMandatoryForJLGLoans)) { + this.loanScheduleAssembler.validateDisbursementDateWithMeetingDates(expectedDisbursementDate, calendar, + isSkipRepaymentOnFirstMonth, numberOfDays); + } } diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java index 4b62eb0a061..6176d45c58d 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java @@ -2847,8 +2847,8 @@ public GroupLoanAdditionalData mapRow(ResultSet rs, int rowNum) throws SQLExcept .requestedValue(requestedValue).groupAuthorizedValue(groupAuthorizedValue) .facilitatorProposedValue(facilitatorProposedValue).proposedFee(proposedFee) .agencyAuthorizedAmount(agencyAuthorizedAmount).authorizedFee(authorizedFee).totalIncome(totalIncome) - .totalExpenditures(totalExpenditures).availableMonthly(availableMonthly).facValue(facValue).debtLevel(debtLevel).dateOfBirth(dateOfBirth) - .build(); + .totalExpenditures(totalExpenditures).availableMonthly(availableMonthly).facValue(facValue).debtLevel(debtLevel) + .dateOfBirth(dateOfBirth).build(); return additionalGroupLoanData; } diff --git a/fineract-provider/src/main/resources/db/changelog/tenant/changelog-tenant.xml b/fineract-provider/src/main/resources/db/changelog/tenant/changelog-tenant.xml index dea0a8095ff..6e5b08854dc 100644 --- a/fineract-provider/src/main/resources/db/changelog/tenant/changelog-tenant.xml +++ b/fineract-provider/src/main/resources/db/changelog/tenant/changelog-tenant.xml @@ -134,4 +134,5 @@ + diff --git a/fineract-provider/src/main/resources/db/changelog/tenant/parts/0117_FBR_506_Reporte_de_Cobranzas_y_Saldos_por_Financista.xml b/fineract-provider/src/main/resources/db/changelog/tenant/parts/0117_FBR_506_Reporte_de_Cobranzas_y_Saldos_por_Financista.xml new file mode 100644 index 00000000000..e0a5cdf4789 --- /dev/null +++ b/fineract-provider/src/main/resources/db/changelog/tenant/parts/0117_FBR_506_Reporte_de_Cobranzas_y_Saldos_por_Financista.xml @@ -0,0 +1,138 @@ + + + + + + + + + + + + + + + + + + + + + + +