From 6a5b2b18b9f410cb9b852112f3c6361ee4c440fe Mon Sep 17 00:00:00 2001 From: Pramod Nuthakki Date: Mon, 29 Jul 2013 11:22:29 +0530 Subject: [PATCH 01/11] added condition to call scheduler's standby --- .../infrastructure/jobs/service/JobRegisterServiceImpl.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/jobs/service/JobRegisterServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/jobs/service/JobRegisterServiceImpl.java index 0c1b4db2c..c395cfd71 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/jobs/service/JobRegisterServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/jobs/service/JobRegisterServiceImpl.java @@ -195,6 +195,9 @@ public class JobRegisterServiceImpl implements JobRegisterService { JobDetail jobDetail = createJobDetail(scheduledJobDetails); Trigger trigger = createTrigger(scheduledJobDetails, jobDetail); Scheduler scheduler = getScheduler(scheduledJobDetails); + if (!this.schedulerStatus.get(ThreadLocalContextUtil.getTenant().getId()) && !scheduler.isInStandbyMode()) { + scheduler.standby(); + } scheduler.scheduleJob(jobDetail, trigger); scheduledJobDetails.updateJobKey(getJobKeyAsString(jobDetail.getKey())); scheduledJobDetails.updateNextRunTime(trigger.getNextFireTime()); From 328f225072b663aba3a336a6beeffb7d381438a2 Mon Sep 17 00:00:00 2001 From: mifoscontributer Date: Tue, 30 Jul 2013 16:13:31 +0530 Subject: [PATCH 02/11] Validating Expected disbursal date for holiday or nonworking day --- .../holiday/domain/HolidayRepository.java | 4 ++-- .../portfolio/loanaccount/domain/Loan.java | 8 ++++++++ ...icationWritePlatformServiceJpaRepositoryImpl.java | 6 ++++-- .../portfolio/loanaccount/service/LoanAssembler.java | 12 +++++++++++- 4 files changed, 25 insertions(+), 5 deletions(-) diff --git a/mifosng-provider/src/main/java/org/mifosplatform/organisation/holiday/domain/HolidayRepository.java b/mifosng-provider/src/main/java/org/mifosplatform/organisation/holiday/domain/HolidayRepository.java index 478b0cc53..11a0b84c7 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/organisation/holiday/domain/HolidayRepository.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/organisation/holiday/domain/HolidayRepository.java @@ -15,8 +15,8 @@ import org.springframework.data.repository.query.Param; public interface HolidayRepository extends JpaRepository, JpaSpecificationExecutor { - @Query("select holiday from Holiday holiday, IN(holiday.offices) office where holiday.fromDate >= :fromDate and office.id = :officeId") - List findByOfficeIdAndGreaterThanDate(@Param("officeId") Long officeId, @Param("fromDate") Date fromDate); + @Query("select holiday from Holiday holiday, IN(holiday.offices) office where (holiday.fromDate >= :date OR :date <= holiday.toDate) and office.id = :officeId") + List findByOfficeIdAndGreaterThanDate(@Param("officeId") Long officeId, @Param("date") Date date); @Query("from Holiday holiday where holiday.processed = false") List findUnprocessed(); diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/Loan.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/Loan.java index 0fa3cf8f3..2a57c9a72 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/Loan.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/Loan.java @@ -2509,4 +2509,12 @@ public class Loan extends AbstractPersistable { return this.termPeriodFrequencyType; } + public void validateExpectedDisbursementForHolidayAndNonWorkingDay(WorkingDays workingDays, boolean isHolidayEnabled, + List holidays) { + // validate if disbursement date is a holiday or a non-working day + validateDisbursementDateIsOnNonWorkingDay(workingDays); + validateDisbursementDateIsOnHoliday(isHolidayEnabled, holidays); + + } + } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanApplicationWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanApplicationWritePlatformServiceJpaRepositoryImpl.java index 2a9024112..b64a0b515 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanApplicationWritePlatformServiceJpaRepositoryImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanApplicationWritePlatformServiceJpaRepositoryImpl.java @@ -224,6 +224,10 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa final Map changes = existingLoanApplication.loanApplicationModification(command, possiblyModifedLoanCharges, possiblyModifedLoanCollateralItems, this.aprCalculator); + if (changes.containsKey("expectedDisbursementDate")) { + this.loanAssembler.validateExpectedDisbursementForHolidayAndNonWorkingDay(existingLoanApplication); + } + final String clientIdParamName = "clientId"; if (changes.containsKey(clientIdParamName)) { final Long clientId = command.longValueOfParameterNamed(clientIdParamName); @@ -245,8 +249,6 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa } validateSubmittedOnDate(existingLoanApplication); - // validate min and maximum constraints - this.fromApiJsonDeserializer.validateForModify(command.json()); final LoanProductRelatedDetail productRelatedDetail = existingLoanApplication.repaymentScheduleDetail(); this.fromApiJsonDeserializer.validateLoanTermAndRepaidEveryValues(existingLoanApplication.getTermFrequency(), existingLoanApplication.getTermPeriodFrequencyType(), productRelatedDetail.getNumberOfRepayments(), productRelatedDetail.getRepayEvery(), diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanAssembler.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanAssembler.java index cf04003f3..40c1c1e4d 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanAssembler.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanAssembler.java @@ -22,8 +22,8 @@ import org.mifosplatform.organisation.staff.domain.Staff; import org.mifosplatform.organisation.staff.domain.StaffRepository; import org.mifosplatform.organisation.staff.exception.StaffNotFoundException; import org.mifosplatform.organisation.staff.exception.StaffRoleException; -import org.mifosplatform.organisation.workingdays.domain.WorkingDaysRepositoryWrapper; import org.mifosplatform.organisation.workingdays.domain.WorkingDays; +import org.mifosplatform.organisation.workingdays.domain.WorkingDaysRepositoryWrapper; import org.mifosplatform.portfolio.client.domain.Client; import org.mifosplatform.portfolio.client.domain.ClientRepositoryWrapper; import org.mifosplatform.portfolio.collateral.domain.LoanCollateral; @@ -238,4 +238,14 @@ public class LoanAssembler { } return strategy; } + + public void validateExpectedDisbursementForHolidayAndNonWorkingDay(final Loan loanApplication) { + + final boolean isHolidayEnabled = this.configurationDomainService.isRescheduleRepaymentsOnHolidaysEnabled(); + final List holidays = this.holidayRepository.findByOfficeIdAndGreaterThanDate(loanApplication.getOfficeId(), + loanApplication.getExpectedDisbursedOnLocalDate().toDate()); + final WorkingDays workingDays = this.workingDaysRepository.findOne(); + + loanApplication.validateExpectedDisbursementForHolidayAndNonWorkingDay(workingDays,isHolidayEnabled,holidays); + } } \ No newline at end of file From 33345378d4d00834f6d76fd14213615268653c62 Mon Sep 17 00:00:00 2001 From: mifoscontributer Date: Wed, 31 Jul 2013 18:33:31 +0530 Subject: [PATCH 03/11] Retrieve writeoff date for writtenoff loan --- .../data/LoanApplicationTimelineData.java | 18 ++++++++++++++++-- .../portfolio/loanaccount/domain/Loan.java | 4 +++- .../service/LoanReadPlatformServiceImpl.java | 6 ++++-- ...nWritePlatformServiceJpaRepositoryImpl.java | 4 ++-- 4 files changed, 25 insertions(+), 7 deletions(-) diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/data/LoanApplicationTimelineData.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/data/LoanApplicationTimelineData.java index 61fcc6e98..15d922a38 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/data/LoanApplicationTimelineData.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/data/LoanApplicationTimelineData.java @@ -39,6 +39,10 @@ public class LoanApplicationTimelineData { private final String disbursedByFirstname; private final String disbursedByLastname; private final LocalDate expectedMaturityDate; + private final LocalDate writeOffOnDate; + private final String writeOffByUsername; + private final String writeOffByFirstname; + private final String writeOffByLastname; public static LoanApplicationTimelineData templateDefault(final LocalDate expectedDisbursementDate) { @@ -67,12 +71,17 @@ public class LoanApplicationTimelineData { final String closedByFirstname = null; final String closedByLastname = null; final LocalDate expectedMaturityDate = null; + final LocalDate writeOffOnDate = null; + final String writeOffByUsername = null; + final String writeOffByFirstname = null; + final String writeOffByLastname = null; return new LoanApplicationTimelineData(submittedOnDate, submittedByUsername, submittedByFirstname, submittedByLastname, rejectedOnDate, rejectedByUsername, rejectedByFirstname, rejectedByLastname, withdrawnOnDate, withdrawnByUsername, withdrawnByFirstname, withdrawnByLastname, approvedOnDate, approvedByUsername, approvedByFirstname, approvedByLastname, expectedDisbursementDate, actualDisbursementDate, disbursedByUsername, disbursedByFirstname, disbursedByLastname, - closedOnDate, closedByUsername, closedByFirstname, closedByLastname, expectedMaturityDate); + closedOnDate, closedByUsername, closedByFirstname, closedByLastname, expectedMaturityDate, writeOffOnDate, + writeOffByUsername, writeOffByFirstname, writeOffByLastname); } public LoanApplicationTimelineData(final LocalDate submittedOnDate, final String submittedByUsername, @@ -83,7 +92,8 @@ public class LoanApplicationTimelineData { final String approvedByFirstname, final String approvedByLastname, final LocalDate expectedDisbursementDate, final LocalDate actualDisbursementDate, final String disbursedByUsername, final String disbursedByFirstname, final String disbursedByLastname, final LocalDate closedOnDate, final String closedByUsername, final String closedByFirstname, - final String closedByLastname, final LocalDate expectedMaturityDate) { + final String closedByLastname, final LocalDate expectedMaturityDate, final LocalDate writeOffOnDate, + final String writeOffByUsername, final String writeOffByFirstname, final String writeOffByLastname) { this.submittedOnDate = submittedOnDate; this.submittedByUsername = submittedByUsername; this.submittedByFirstname = submittedByFirstname; @@ -106,6 +116,10 @@ public class LoanApplicationTimelineData { this.disbursedByFirstname = disbursedByFirstname; this.disbursedByLastname = disbursedByLastname; this.expectedMaturityDate = expectedMaturityDate; + this.writeOffOnDate = writeOffOnDate; + this.writeOffByUsername = writeOffByUsername; + this.writeOffByFirstname = writeOffByFirstname; + this.writeOffByLastname = writeOffByLastname; } public RepaymentScheduleRelatedLoanData repaymentScheduleRelatedData(final CurrencyData currency, final BigDecimal principal, diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/Loan.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/Loan.java index 2a57c9a72..b30e73209 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/Loan.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/Loan.java @@ -1815,7 +1815,8 @@ public class Loan extends AbstractPersistable { } public LoanTransaction closeAsWrittenOff(final JsonCommand command, final LoanLifecycleStateMachine loanLifecycleStateMachine, - final Map changes, final List existingTransactionIds, final List existingReversedTransactionIds) { + final Map changes, final List existingTransactionIds, final List existingReversedTransactionIds, + final AppUser currentUser) { final LoanStatus statusEnum = loanLifecycleStateMachine.transition(LoanEvent.WRITE_OFF_OUTSTANDING, LoanStatus.fromInt(this.loanStatus)); @@ -1832,6 +1833,7 @@ public class Loan extends AbstractPersistable { this.closedOnDate = writtenOffOnLocalDate.toDate(); this.writtenOffOnDate = writtenOffOnLocalDate.toDate(); + this.closedBy = currentUser; changes.put("closedOnDate", command.stringValueOfParameterNamed("transactionDate")); changes.put("writtenOffOnDate", command.stringValueOfParameterNamed("transactionDate")); diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java index 1d749797a..71301f921 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java @@ -398,7 +398,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService { + " l.withdrawnon_date as withdrawnOnDate, wbu.username as withdrawnByUsername, wbu.firstname as withdrawnByFirstname, wbu.lastname as withdrawnByLastname," + " l.approvedon_date as approvedOnDate, abu.username as approvedByUsername, abu.firstname as approvedByFirstname, abu.lastname as approvedByLastname," + " l.expected_disbursedon_date as expectedDisbursementDate, l.disbursedon_date as actualDisbursementDate, dbu.username as disbursedByUsername, dbu.firstname as disbursedByFirstname, dbu.lastname as disbursedByLastname," - + " l.closedon_date as closedOnDate, cbu.username as closedByUsername, cbu.firstname as closedByFirstname, cbu.lastname as closedByLastname," + + " l.closedon_date as closedOnDate, cbu.username as closedByUsername, cbu.firstname as closedByFirstname, cbu.lastname as closedByLastname, l.writtenoffon_date as writtenOffOnDate, " + " l.expected_firstrepaymenton_date as expectedFirstRepaymentOnDate, l.interest_calculated_from_date as interestChargedFromDate, l.expected_maturedon_date as expectedMaturityDate, " + " l.principal_amount as principal, l.arrearstolerance_amount as inArrearsTolerance, l.number_of_repayments as numberOfRepayments, l.repay_every as repaymentEvery," + " l.grace_on_principal_periods as graceOnPrincipalPayment, l.grace_on_interest_periods as graceOnInterestPayment, l.grace_interest_free_periods as graceOnInterestCharged," @@ -538,6 +538,8 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService { final String closedByFirstname = rs.getString("closedByFirstname"); final String closedByLastname = rs.getString("closedByLastname"); + final LocalDate writtenOffOnDate = JdbcSupport.getLocalDate(rs, "writtenOffOnDate"); + final LocalDate expectedMaturityDate = JdbcSupport.getLocalDate(rs, "expectedMaturityDate"); final LoanApplicationTimelineData timeline = new LoanApplicationTimelineData(submittedOnDate, submittedByUsername, @@ -545,7 +547,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService { withdrawnOnDate, withdrawnByUsername, withdrawnByFirstname, withdrawnByLastname, approvedOnDate, approvedByUsername, approvedByFirstname, approvedByLastname, expectedDisbursementDate, actualDisbursementDate, disbursedByUsername, disbursedByFirstname, disbursedByLastname, closedOnDate, closedByUsername, closedByFirstname, closedByLastname, - expectedMaturityDate); + expectedMaturityDate, writtenOffOnDate, closedByUsername, closedByFirstname, closedByLastname); final BigDecimal principal = rs.getBigDecimal("principal"); final BigDecimal totalOverpaid = rs.getBigDecimal("totalOverpaid"); diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java index 0376b2258..5e594427d 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java @@ -607,7 +607,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf @Transactional @Override public CommandProcessingResult writeOff(final Long loanId, final JsonCommand command) { - context.authenticatedUser(); + final AppUser currentUser = this.context.authenticatedUser(); this.loanEventApiJsonValidator.validateTransactionWithNoAmount(command.json()); @@ -622,7 +622,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf final List existingTransactionIds = new ArrayList(); final List existingReversedTransactionIds = new ArrayList(); final LoanTransaction writeoff = loan.closeAsWrittenOff(command, defaultLoanLifecycleStateMachine(), changes, - existingTransactionIds, existingReversedTransactionIds); + existingTransactionIds, existingReversedTransactionIds, currentUser); this.loanTransactionRepository.save(writeoff); this.loanRepository.save(loan); From 538039e9bdf05e4a321aba965ef440ab278e2c1a Mon Sep 17 00:00:00 2001 From: mifoscontributer Date: Thu, 1 Aug 2013 12:23:00 +0530 Subject: [PATCH 04/11] mifosx-538 global search functionality query fix --- .../portfolio/search/service/SearchReadPlatformServiceImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/search/service/SearchReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/search/service/SearchReadPlatformServiceImpl.java index cd80e94b0..fb6edb452 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/search/service/SearchReadPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/search/service/SearchReadPlatformServiceImpl.java @@ -52,7 +52,7 @@ public class SearchReadPlatformServiceImpl implements SearchReadPlatformService public String searchSchema(final SearchConditions searchConditions) { - String union = " union all "; + String union = " union "; String clientExactMatchSql = " (select 'CLIENT' as entityType, c.id as entityId, c.display_name as entityName, c.external_id as entityExternalId, c.account_no as entityAccountNo " + " , c.office_id as parentId, o.name as parentName " + " from m_client c join m_office o on o.id = c.office_id where o.hierarchy like :hierarchy and (c.account_no like :search or c.display_name like :search or c.external_id like :search)) "; From 6f5e79b387ffacde90c68112ba88f98e4918ae20 Mon Sep 17 00:00:00 2001 From: mifoscontributer Date: Mon, 5 Aug 2013 13:03:14 +0530 Subject: [PATCH 05/11] MIFOSX-589 check edit transaction transactiondate for holiday or nonworking day --- .../mifosplatform/portfolio/loanaccount/domain/Loan.java | 6 +++++- .../service/LoanWritePlatformServiceJpaRepositoryImpl.java | 7 ++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/Loan.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/Loan.java index b30e73209..a5beb1e8c 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/Loan.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/Loan.java @@ -1739,7 +1739,11 @@ public class Loan extends AbstractPersistable { public ChangedTransactionDetail adjustExistingTransaction(final LoanTransaction newTransactionDetail, final LoanLifecycleStateMachine loanLifecycleStateMachine, final LoanTransaction transactionForAdjustment, - final List existingTransactionIds, final List existingReversedTransactionIds) { + final List existingTransactionIds, final List existingReversedTransactionIds, final boolean isHolidayEnabled, + final List holidays, final WorkingDays workingDays) { + + validateRepaymentDateIsOnHoliday(newTransactionDetail.getTransactionDate(), isHolidayEnabled, holidays); + validateRepaymentDateIsOnNonWorkingDay(newTransactionDetail.getTransactionDate(), workingDays); ChangedTransactionDetail changedTransactionDetail = null; diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java index 5e594427d..9f7a8ed3b 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java @@ -486,8 +486,13 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf newTransactionDetail = LoanTransaction.waiver(loan, transactionAmountAsMoney, transactionDate); } + final boolean isHolidayEnabled = this.configurationDomainService.isRescheduleRepaymentsOnHolidaysEnabled(); + final List holidays = this.holidayRepository.findByOfficeIdAndGreaterThanDate(loan.getOfficeId(), transactionDate.toDate()); + final WorkingDays workingDays = this.workingDaysRepository.findOne(); + final ChangedTransactionDetail changedTransactionDetail = loan.adjustExistingTransaction(newTransactionDetail, - defaultLoanLifecycleStateMachine(), transactionToAdjust, existingTransactionIds, existingReversedTransactionIds); + defaultLoanLifecycleStateMachine(), transactionToAdjust, existingTransactionIds, existingReversedTransactionIds, + isHolidayEnabled, holidays, workingDays); if (newTransactionDetail.isGreaterThanZero(loan.getPrincpal().getCurrency())) { if (paymentDetail != null) { From 13c5c5c050bf155c6b401a9843ec30990052baf5 Mon Sep 17 00:00:00 2001 From: mifoscontributer Date: Mon, 5 Aug 2013 15:37:30 +0530 Subject: [PATCH 06/11] MIFSOX-428 Api fix for edit user --- .../domain/JpaUserDomainService.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/mifosng-provider/src/main/java/org/mifosplatform/useradministration/domain/JpaUserDomainService.java b/mifosng-provider/src/main/java/org/mifosplatform/useradministration/domain/JpaUserDomainService.java index 366e996e3..6ed40691a 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/useradministration/domain/JpaUserDomainService.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/useradministration/domain/JpaUserDomainService.java @@ -29,7 +29,7 @@ public class JpaUserDomainService implements UserDomainService { @Transactional @Override - public void create(final AppUser appUser , final Boolean sendPasswordToEmail) { + public void create(final AppUser appUser, final Boolean sendPasswordToEmail) { generateKeyUsedForPasswordSalting(appUser); @@ -40,11 +40,11 @@ public class JpaUserDomainService implements UserDomainService { this.userRepository.save(appUser); - if (sendPasswordToEmail.booleanValue()){ - final EmailDetail emailDetail = new EmailDetail(appUser.getFirstname(), appUser.getFirstname(), appUser.getEmail(), - appUser.getUsername()); + if (sendPasswordToEmail.booleanValue()) { + final EmailDetail emailDetail = new EmailDetail(appUser.getOffice().getName(), appUser.getFirstname(), appUser.getEmail(), + appUser.getUsername()); - this.emailService.sendToUserAccount(emailDetail, unencodedPassword); + this.emailService.sendToUserAccount(emailDetail, unencodedPassword); } } From 327880473293c07fb82be9363f55d29547cdf9f9 Mon Sep 17 00:00:00 2001 From: mifoscontributer Date: Tue, 6 Aug 2013 12:38:41 +0530 Subject: [PATCH 07/11] Add configuration settings for holidays and non_workingdays --- ...ettings_for_holiday_and_non_workingday.sql | 2 + .../domain/ConfigurationDomainService.java | 2 + .../domain/ConfigurationDomainServiceJpa.java | 19 ++++- .../portfolio/loanaccount/domain/Loan.java | 70 +++++++++++-------- .../loanaccount/service/LoanAssembler.java | 10 ++- ...WritePlatformServiceJpaRepositoryImpl.java | 24 +++++-- 6 files changed, 84 insertions(+), 43 deletions(-) create mode 100644 mifosng-db/migrations/core_db/V92__configuration_settings_for_holiday_and_non_workingday.sql diff --git a/mifosng-db/migrations/core_db/V92__configuration_settings_for_holiday_and_non_workingday.sql b/mifosng-db/migrations/core_db/V92__configuration_settings_for_holiday_and_non_workingday.sql new file mode 100644 index 000000000..0b84ea2b0 --- /dev/null +++ b/mifosng-db/migrations/core_db/V92__configuration_settings_for_holiday_and_non_workingday.sql @@ -0,0 +1,2 @@ +INSERT INTO `c_configuration` (`name`, `enabled`) VALUES ('allow-transactions-on-holiday', 0); +INSERT INTO `c_configuration` (`name`, `enabled`) VALUES ('allow-transactions-on-non_workingday', 0); \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/domain/ConfigurationDomainService.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/domain/ConfigurationDomainService.java index 7bd6f8cf6..a343385c4 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/domain/ConfigurationDomainService.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/domain/ConfigurationDomainService.java @@ -11,4 +11,6 @@ public interface ConfigurationDomainService { boolean isAmazonS3Enabled(); boolean isRescheduleFutureRepaymentsEnabled(); boolean isRescheduleRepaymentsOnHolidaysEnabled(); + boolean allowTransactionsOnHolidayEnabled(); + boolean allowTransactionsOnNonWorkingDayEnabled(); } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/domain/ConfigurationDomainServiceJpa.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/domain/ConfigurationDomainServiceJpa.java index 8adcffe12..c32cf223c 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/domain/ConfigurationDomainServiceJpa.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/domain/ConfigurationDomainServiceJpa.java @@ -63,6 +63,21 @@ public class ConfigurationDomainServiceJpa implements ConfigurationDomainService if (property == null) { throw new GlobalConfigurationPropertyNotFoundException(holidaysConfigurationProperty); } return property.isEnabled(); } - - + + @Override + public boolean allowTransactionsOnHolidayEnabled() { + final String allowTransactionsOnHolidayProperty = "allow-transactions-on-holiday"; + final GlobalConfigurationProperty property = this.globalConfigurationRepository.findOneByName(allowTransactionsOnHolidayProperty); + if (property == null) { throw new GlobalConfigurationPropertyNotFoundException(allowTransactionsOnHolidayProperty); } + return property.isEnabled(); + } + + @Override + public boolean allowTransactionsOnNonWorkingDayEnabled() { + final String allowTransactionsOnNonWorkingDayProperty = "allow-transactions-on-non_workingday"; + final GlobalConfigurationProperty property = this.globalConfigurationRepository.findOneByName(allowTransactionsOnNonWorkingDayProperty); + if (property == null) { throw new GlobalConfigurationPropertyNotFoundException(allowTransactionsOnNonWorkingDayProperty); } + return property.isEnabled(); + } + } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/Loan.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/Loan.java index a5beb1e8c..863813f9f 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/Loan.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/Loan.java @@ -1075,8 +1075,8 @@ public class Loan extends AbstractPersistable { public void loanApplicationSubmittal(final AppUser currentUser, final LoanScheduleModel loanSchedule, final LoanApplicationTerms loanApplicationTerms, final LoanLifecycleStateMachine lifecycleStateMachine, - final LocalDate submittedOn, final String externalId, final boolean isHolidayEnabled, final List holidays, - final WorkingDays workingDays) { + final LocalDate submittedOn, final String externalId, final boolean allowTransactionsOnHoliday, final List holidays, + final WorkingDays workingDays, final boolean allowTransactionsOnNonWorkingDay) { updateLoanSchedule(loanSchedule); @@ -1125,8 +1125,8 @@ public class Loan extends AbstractPersistable { } //validate if disbursement date is a holiday or a non-working day - validateDisbursementDateIsOnNonWorkingDay(workingDays); - validateDisbursementDateIsOnHoliday(isHolidayEnabled, holidays); + validateDisbursementDateIsOnNonWorkingDay(workingDays, allowTransactionsOnNonWorkingDay); + validateDisbursementDateIsOnHoliday(allowTransactionsOnHoliday, holidays); } private LocalDate determineExpectedMaturityDate() { @@ -1317,7 +1317,8 @@ public class Loan extends AbstractPersistable { public Map disburse(final LoanScheduleGeneratorFactory loanScheduleFactory, final AppUser currentUser, final JsonCommand command, final ApplicationCurrency currency, final List existingTransactionIds, final List existingReversedTransactionIds, final Map actualChanges, final PaymentDetail paymentDetail, - final LocalDate calculatedRepaymentsStartingFromDate, final boolean isHolidayEnabled, final List holidays, final WorkingDays workingDays) { + final LocalDate calculatedRepaymentsStartingFromDate, final boolean isHolidayEnabled, final List holidays, + final WorkingDays workingDays, final boolean allowTransactionsOnHoliday, final boolean allowTransactionsOnNonWorkingDay) { updateLoanToPreDisbursalState(); @@ -1341,8 +1342,8 @@ public class Loan extends AbstractPersistable { actualChanges.put("actualDisbursementDate", command.stringValueOfParameterNamed("actualDisbursementDate")); //validate if disbursement date is a holiday or a non-working day - validateDisbursementDateIsOnNonWorkingDay(workingDays); - validateDisbursementDateIsOnHoliday(isHolidayEnabled, holidays); + validateDisbursementDateIsOnNonWorkingDay(workingDays, allowTransactionsOnNonWorkingDay); + validateDisbursementDateIsOnHoliday(allowTransactionsOnHoliday, holidays); handleDisbursementTransaction(paymentDetail, actualDisbursementDate); @@ -1514,11 +1515,11 @@ public class Loan extends AbstractPersistable { public ChangedTransactionDetail makeRepayment(final LoanTransaction repaymentTransaction, final LoanLifecycleStateMachine loanLifecycleStateMachine, final List existingTransactionIds, - final List existingReversedTransactionIds, final boolean isHolidayEnabled, final List holidays, - final WorkingDays workingDays) { + final List existingReversedTransactionIds, final boolean allowTransactionsOnHoliday, final List holidays, + final WorkingDays workingDays, final boolean allowTransactionsOnNonWorkingDay) { - validateRepaymentDateIsOnHoliday(repaymentTransaction.getTransactionDate(), isHolidayEnabled, holidays); - validateRepaymentDateIsOnNonWorkingDay(repaymentTransaction.getTransactionDate(), workingDays); + validateRepaymentDateIsOnHoliday(repaymentTransaction.getTransactionDate(), allowTransactionsOnHoliday, holidays); + validateRepaymentDateIsOnNonWorkingDay(repaymentTransaction.getTransactionDate(), workingDays, allowTransactionsOnNonWorkingDay); existingTransactionIds.addAll(findExistingTransactionIds()); existingReversedTransactionIds.addAll(findExistingReversedTransactionIds()); @@ -1739,11 +1740,12 @@ public class Loan extends AbstractPersistable { public ChangedTransactionDetail adjustExistingTransaction(final LoanTransaction newTransactionDetail, final LoanLifecycleStateMachine loanLifecycleStateMachine, final LoanTransaction transactionForAdjustment, - final List existingTransactionIds, final List existingReversedTransactionIds, final boolean isHolidayEnabled, - final List holidays, final WorkingDays workingDays) { + final List existingTransactionIds, final List existingReversedTransactionIds, + final boolean allowTransactionsOnHoliday, final List holidays, final WorkingDays workingDays, + final boolean allowTransactionsOnNonWorkingDay) { - validateRepaymentDateIsOnHoliday(newTransactionDetail.getTransactionDate(), isHolidayEnabled, holidays); - validateRepaymentDateIsOnNonWorkingDay(newTransactionDetail.getTransactionDate(), workingDays); + validateRepaymentDateIsOnHoliday(newTransactionDetail.getTransactionDate(), allowTransactionsOnHoliday, holidays); + validateRepaymentDateIsOnNonWorkingDay(newTransactionDetail.getTransactionDate(), workingDays, allowTransactionsOnNonWorkingDay); ChangedTransactionDetail changedTransactionDetail = null; @@ -2446,15 +2448,17 @@ public class Loan extends AbstractPersistable { } } - private void validateDisbursementDateIsOnNonWorkingDay(final WorkingDays workingDays) { - if(!WorkingDaysUtil.isWorkingDay(workingDays, getDisbursementDate())){ - final String errorMessage = "Expected disbursement date cannot be on a non working day"; - throw new LoanApplicationDateException("disbursement.date.on.non.working.day", errorMessage, getExpectedDisbursedOnLocalDate()); + private void validateDisbursementDateIsOnNonWorkingDay(final WorkingDays workingDays, final boolean allowTransactionsOnNonWorkingDay) { + if (!allowTransactionsOnNonWorkingDay) { + if(!WorkingDaysUtil.isWorkingDay(workingDays, getDisbursementDate())){ + final String errorMessage = "Expected disbursement date cannot be on a non working day"; + throw new LoanApplicationDateException("disbursement.date.on.non.working.day", errorMessage, getExpectedDisbursedOnLocalDate()); + } } } - private void validateDisbursementDateIsOnHoliday(final boolean isHolidayEnabled, final List holidays) { - if (isHolidayEnabled) { + private void validateDisbursementDateIsOnHoliday(final boolean allowTransactionsOnHoliday, final List holidays) { + if (!allowTransactionsOnHoliday) { if (HolidayUtil.isHoliday(getDisbursementDate(), holidays)) { final String errorMessage = "Expected disbursement date cannot be on a holiday"; throw new LoanApplicationDateException("disbursement.date.on.holiday", errorMessage, @@ -2463,15 +2467,19 @@ public class Loan extends AbstractPersistable { } } - private void validateRepaymentDateIsOnNonWorkingDay(final LocalDate repaymentDate, final WorkingDays workingDays) { - if(!WorkingDaysUtil.isWorkingDay(workingDays, repaymentDate)){ - final String errorMessage = "Repayment date cannot be on a non working day"; - throw new LoanApplicationDateException("repayment.date.on.non.working.day", errorMessage, repaymentDate); + private void validateRepaymentDateIsOnNonWorkingDay(final LocalDate repaymentDate, final WorkingDays workingDays, + final boolean allowTransactionsOnNonWorkingDay) { + if (!allowTransactionsOnNonWorkingDay) { + if (!WorkingDaysUtil.isWorkingDay(workingDays, repaymentDate)) { + final String errorMessage = "Repayment date cannot be on a non working day"; + throw new LoanApplicationDateException("repayment.date.on.non.working.day", errorMessage, repaymentDate); + } } } - private void validateRepaymentDateIsOnHoliday(final LocalDate repaymentDate, final boolean isHolidayEnabled, final List holidays) { - if (isHolidayEnabled) { + private void validateRepaymentDateIsOnHoliday(final LocalDate repaymentDate, final boolean allowTransactionsOnHoliday, + final List holidays) { + if (!allowTransactionsOnHoliday) { if (HolidayUtil.isHoliday(repaymentDate, holidays)) { final String errorMessage = "Repayment date cannot be on a holiday"; throw new LoanApplicationDateException("repayment.date.on.holiday", errorMessage, repaymentDate); @@ -2515,11 +2523,11 @@ public class Loan extends AbstractPersistable { return this.termPeriodFrequencyType; } - public void validateExpectedDisbursementForHolidayAndNonWorkingDay(WorkingDays workingDays, boolean isHolidayEnabled, - List holidays) { + public void validateExpectedDisbursementForHolidayAndNonWorkingDay(final WorkingDays workingDays, + final boolean allowTransactionsOnHoliday, final List holidays, final boolean allowTransactionsOnNonWorkingDay) { // validate if disbursement date is a holiday or a non-working day - validateDisbursementDateIsOnNonWorkingDay(workingDays); - validateDisbursementDateIsOnHoliday(isHolidayEnabled, holidays); + validateDisbursementDateIsOnNonWorkingDay(workingDays, allowTransactionsOnNonWorkingDay); + validateDisbursementDateIsOnHoliday(allowTransactionsOnHoliday, holidays); } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanAssembler.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanAssembler.java index 40c1c1e4d..553dae611 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanAssembler.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanAssembler.java @@ -190,9 +190,11 @@ public class LoanAssembler { final boolean isHolidayEnabled = this.configurationDomainService.isRescheduleRepaymentsOnHolidaysEnabled(); final List holidays = this.holidayRepository.findByOfficeIdAndGreaterThanDate(loanApplication.getOfficeId(), loanApplicationTerms.getExpectedDisbursementDate().toDate()); final WorkingDays workingDays = this.workingDaysRepository.findOne(); + final boolean allowTransactionsOnNonWorkingDay = this.configurationDomainService.allowTransactionsOnNonWorkingDayEnabled(); + final boolean allowTransactionsOnHoliday = this.configurationDomainService.allowTransactionsOnHolidayEnabled(); final LoanScheduleModel loanScheduleModel = this.loanScheduleAssembler.assembleLoanScheduleFrom(loanApplicationTerms, isHolidayEnabled, holidays, workingDays, element); loanApplication.loanApplicationSubmittal(currentUser, loanScheduleModel, loanApplicationTerms, defaultLoanLifecycleStateMachine(), - submittedOnDate, externalId, isHolidayEnabled, holidays, workingDays); + submittedOnDate, externalId, allowTransactionsOnHoliday, holidays, workingDays, allowTransactionsOnNonWorkingDay); return loanApplication; } @@ -241,11 +243,13 @@ public class LoanAssembler { public void validateExpectedDisbursementForHolidayAndNonWorkingDay(final Loan loanApplication) { - final boolean isHolidayEnabled = this.configurationDomainService.isRescheduleRepaymentsOnHolidaysEnabled(); + final boolean allowTransactionsOnHoliday = this.configurationDomainService.allowTransactionsOnHolidayEnabled(); final List holidays = this.holidayRepository.findByOfficeIdAndGreaterThanDate(loanApplication.getOfficeId(), loanApplication.getExpectedDisbursedOnLocalDate().toDate()); final WorkingDays workingDays = this.workingDaysRepository.findOne(); + final boolean allowTransactionsOnNonWorkingDay = this.configurationDomainService.allowTransactionsOnNonWorkingDayEnabled(); - loanApplication.validateExpectedDisbursementForHolidayAndNonWorkingDay(workingDays,isHolidayEnabled,holidays); + loanApplication.validateExpectedDisbursementForHolidayAndNonWorkingDay(workingDays, allowTransactionsOnHoliday, holidays, + allowTransactionsOnNonWorkingDay); } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java index 9f7a8ed3b..d94b4f9bf 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java @@ -191,10 +191,13 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf final boolean isHolidayEnabled = this.configurationDomainService.isRescheduleRepaymentsOnHolidaysEnabled(); final List holidays = this.holidayRepository.findByOfficeIdAndGreaterThanDate(loan.getOfficeId(), actualDisbursementDate.toDate()); final WorkingDays workingDays = this.workingDaysRepository.findOne(); + final boolean allowTransactionsOnHoliday = this.configurationDomainService.allowTransactionsOnHolidayEnabled(); + final boolean allowTransactionsOnNonWorkingDay = this.configurationDomainService.allowTransactionsOnNonWorkingDayEnabled(); updateLoanCounters(loan, actualDisbursementDate); loan.disburse(this.loanScheduleFactory, currentUser, command, applicationCurrency, existingTransactionIds, - existingReversedTransactionIds, changes, paymentDetail, calculatedRepaymentsStartingFromDate, isHolidayEnabled, holidays, workingDays); + existingReversedTransactionIds, changes, paymentDetail, calculatedRepaymentsStartingFromDate, isHolidayEnabled, holidays, + workingDays, allowTransactionsOnHoliday, allowTransactionsOnNonWorkingDay); if (!changes.isEmpty()) { this.loanRepository.save(loan); @@ -281,9 +284,13 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf final boolean isHolidayEnabled = this.configurationDomainService.isRescheduleRepaymentsOnHolidaysEnabled(); final List holidays = this.holidayRepository.findByOfficeIdAndGreaterThanDate(loan.getOfficeId(), actualDisbursementDate.toDate()); final WorkingDays workingDays = this.workingDaysRepository.findOne(); + final boolean allowTransactionsOnHoliday = this.configurationDomainService.allowTransactionsOnHolidayEnabled(); + final boolean allowTransactionsOnNonWorkingDay = this.configurationDomainService.allowTransactionsOnNonWorkingDayEnabled(); + updateLoanCounters(loan, actualDisbursementDate); loan.disburse(this.loanScheduleFactory, currentUser, command, applicationCurrency, existingTransactionIds, - existingReversedTransactionIds, changes, paymentDetail, firstRepaymentOnDate, isHolidayEnabled, holidays, workingDays); + existingReversedTransactionIds, changes, paymentDetail, firstRepaymentOnDate, isHolidayEnabled, holidays, workingDays, + allowTransactionsOnHoliday, allowTransactionsOnNonWorkingDay); if (!changes.isEmpty()) { this.loanRepository.save(loan); @@ -394,12 +401,14 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf final Money repaymentAmount = Money.of(loan.getCurrency(), transactionAmount); final LoanTransaction newRepaymentTransaction = LoanTransaction.repayment(repaymentAmount, paymentDetail, transactionDate); - final boolean isHolidayEnabled = this.configurationDomainService.isRescheduleRepaymentsOnHolidaysEnabled(); + final boolean allowTransactionsOnHoliday = this.configurationDomainService.allowTransactionsOnHolidayEnabled(); final List holidays = this.holidayRepository.findByOfficeIdAndGreaterThanDate(loan.getOfficeId(), transactionDate.toDate()); final WorkingDays workingDays = this.workingDaysRepository.findOne(); - + final boolean allowTransactionsOnNonWorkingDay = this.configurationDomainService.allowTransactionsOnNonWorkingDayEnabled(); + final ChangedTransactionDetail changedTransactionDetail = loan.makeRepayment(newRepaymentTransaction, - defaultLoanLifecycleStateMachine(), existingTransactionIds, existingReversedTransactionIds, isHolidayEnabled, holidays, workingDays); + defaultLoanLifecycleStateMachine(), existingTransactionIds, existingReversedTransactionIds, allowTransactionsOnHoliday, + holidays, workingDays, allowTransactionsOnNonWorkingDay); this.loanTransactionRepository.save(newRepaymentTransaction); @@ -486,13 +495,14 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf newTransactionDetail = LoanTransaction.waiver(loan, transactionAmountAsMoney, transactionDate); } - final boolean isHolidayEnabled = this.configurationDomainService.isRescheduleRepaymentsOnHolidaysEnabled(); + final boolean allowTransactionsOnHoliday = this.configurationDomainService.allowTransactionsOnHolidayEnabled(); final List holidays = this.holidayRepository.findByOfficeIdAndGreaterThanDate(loan.getOfficeId(), transactionDate.toDate()); final WorkingDays workingDays = this.workingDaysRepository.findOne(); + final boolean allowTransactionsOnNonWorkingDay = this.configurationDomainService.allowTransactionsOnNonWorkingDayEnabled(); final ChangedTransactionDetail changedTransactionDetail = loan.adjustExistingTransaction(newTransactionDetail, defaultLoanLifecycleStateMachine(), transactionToAdjust, existingTransactionIds, existingReversedTransactionIds, - isHolidayEnabled, holidays, workingDays); + allowTransactionsOnHoliday, holidays, workingDays, allowTransactionsOnNonWorkingDay); if (newTransactionDetail.isGreaterThanZero(loan.getPrincpal().getCurrency())) { if (paymentDetail != null) { From 94e711873861d4149ca102d973d19e7c3b6b1362 Mon Sep 17 00:00:00 2001 From: mifoscontributer Date: Wed, 7 Aug 2013 10:39:52 +0530 Subject: [PATCH 08/11] MIFOSX-554 Adjust repaymentdate for frequent meeting changes --- .../calendar/service/CalendarHelper.java | 53 +++++++++++-------- .../portfolio/loanaccount/domain/Loan.java | 51 ++++++++++++++---- 2 files changed, 74 insertions(+), 30 deletions(-) diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/service/CalendarHelper.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/service/CalendarHelper.java index 6c3f1e37d..df8a4634c 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/service/CalendarHelper.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/service/CalendarHelper.java @@ -312,30 +312,41 @@ public class CalendarHelper { public static LocalDate getNewRepaymentMeetingDate(final String recurringRule, final LocalDate seedDate, final LocalDate oldRepaymentDate, final Integer loanRepaymentInterval, final String frequency, final WorkingDays workingDays){ final Recur recur = CalendarHelper.getICalRecur(recurringRule); if (recur == null) { return null; } - if(isValidRecurringDate(recur, seedDate, oldRepaymentDate)){ return oldRepaymentDate; } - /* Recurring dates should follow loanRepaymentInterval. - e.g. The weekly meeting will have interval of 1, if the loan product with fortnightly frequency will have interval of 2, - to generate right set of meeting dates reset interval same as loan repayment interval. - */ - recur.setInterval(loanRepaymentInterval); - - /*Recurring dates should follow loanRepayment frequency. - //e.g. daily meeting frequency should support all loan products with any type of frequency. - to generate right set of meeting dates reset frequency same as loan repayment frequency. - */ - if(recur.getFrequency().equals(Recur.DAILY)){ - recur.setFrequency(frequency); - } - - LocalDate newRepaymentDate = getNextRecurringDate(recur, seedDate, oldRepaymentDate); - LocalDate nextRepaymentDate = getNextRecurringDate(recur, seedDate, newRepaymentDate); - - newRepaymentDate = WorkingDaysUtil.getOffSetDateIfNonWorkingDay(newRepaymentDate, nextRepaymentDate, workingDays); - - return newRepaymentDate; + return getNextRepaymentMeetingDate(recurringRule, seedDate, oldRepaymentDate, loanRepaymentInterval, frequency, workingDays); + } + + public static LocalDate getNextRepaymentMeetingDate(final String recurringRule, final LocalDate seedDate, final LocalDate repaymentDate, final Integer loanRepaymentInterval, final String frequency, final WorkingDays workingDays){ + + final Recur recur = CalendarHelper.getICalRecur(recurringRule); + if (recur == null) { return null; } + LocalDate tmpDate = repaymentDate; + if(isValidRecurringDate(recur, seedDate, repaymentDate)){ + tmpDate = repaymentDate.plusDays(1); + } + /* Recurring dates should follow loanRepaymentInterval. + * + e.g. The weekly meeting will have interval of 1, if the loan product with fortnightly frequency will have interval of 2, + to generate right set of meeting dates reset interval same as loan repayment interval. + */ + recur.setInterval(loanRepaymentInterval); + + /*Recurring dates should follow loanRepayment frequency. + //e.g. daily meeting frequency should support all loan products with any type of frequency. + to generate right set of meeting dates reset frequency same as loan repayment frequency. + */ + if(recur.getFrequency().equals(Recur.DAILY)){ + recur.setFrequency(frequency); + } + + LocalDate newRepaymentDate = getNextRecurringDate(recur, seedDate, tmpDate); + LocalDate nextRepaymentDate = getNextRecurringDate(recur, seedDate, newRepaymentDate); + + newRepaymentDate = WorkingDaysUtil.getOffSetDateIfNonWorkingDay(newRepaymentDate, nextRepaymentDate, workingDays); + + return newRepaymentDate; } public static boolean isFrequencySame(final String oldRRule, final String newRRule) { diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/Loan.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/Loan.java index 863813f9f..fc69b1dd5 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/Loan.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/Loan.java @@ -2395,23 +2395,33 @@ public class Loan extends AbstractPersistable { public void updateLoanRepaymentScheduleDates(final LocalDate meetingStartDate, final String recuringRule, final boolean isHolidayEnabled, final List holidays, final WorkingDays workingDays) { - //update repayment dates of repayment schedule installaments - LocalDate tmpFromDate = this.getDisbursementDate();//first repayment's from date is same as disbursement date. + + LocalDate tmpFromDate = this.getDisbursementDate(); + final PeriodFrequencyType repaymentPeriodFrequencyType = this.loanRepaymentScheduleDetail.getRepaymentPeriodFrequencyType(); + final Integer loanRepaymentInterval = this.loanRepaymentScheduleDetail.getRepayEvery(); + final String frequency = CalendarHelper.getMeetingFrequencyFromPeriodFrequencyType(repaymentPeriodFrequencyType); + LocalDate newRepaymentDate = null; for (LoanRepaymentScheduleInstallment loanRepaymentScheduleInstallment : this.repaymentScheduleInstallments) { final LocalDate oldDueDate = loanRepaymentScheduleInstallment.getDueDate(); // FIXME: AA this won't update repayment dates before current date. if (oldDueDate.isAfter(meetingStartDate) && oldDueDate.isAfter(DateUtils.getLocalDateOfTenant())) { - final PeriodFrequencyType repaymentPeriodFrequencyType = this.loanRepaymentScheduleDetail.getRepaymentPeriodFrequencyType(); - final String frequency = CalendarHelper.getMeetingFrequencyFromPeriodFrequencyType(repaymentPeriodFrequencyType); - final Integer loanRepaymentInterval = this.loanRepaymentScheduleDetail.getRepayEvery(); - // reset repayment date with new meeting date - newRepaymentDate = CalendarHelper.getNewRepaymentMeetingDate(recuringRule, meetingStartDate, oldDueDate, loanRepaymentInterval, frequency, workingDays); - if(isHolidayEnabled){ + newRepaymentDate = CalendarHelper.getNewRepaymentMeetingDate(recuringRule, meetingStartDate, oldDueDate, + loanRepaymentInterval, frequency, workingDays); + + final LocalDate maxDateLimitForNewRepayment = getMaxDateLimitForNewRepayment(repaymentPeriodFrequencyType, + loanRepaymentInterval, tmpFromDate); + + if (newRepaymentDate.isAfter(maxDateLimitForNewRepayment)) { + newRepaymentDate = CalendarHelper.getNextRepaymentMeetingDate(recuringRule, meetingStartDate, tmpFromDate, + loanRepaymentInterval, frequency, workingDays); + } + + if (isHolidayEnabled) { newRepaymentDate = HolidayUtil.getRepaymentRescheduleDateToIfHoliday(newRepaymentDate, holidays); } - + loanRepaymentScheduleInstallment.updateDueDate(newRepaymentDate); // reset from date to get actual daysInPeriod loanRepaymentScheduleInstallment.updateFromDate(tmpFromDate); @@ -2423,6 +2433,29 @@ public class Loan extends AbstractPersistable { } } + private LocalDate getMaxDateLimitForNewRepayment(final PeriodFrequencyType periodFrequencyType, final Integer loanRepaymentInterval, + final LocalDate startDate) { + LocalDate dueRepaymentPeriodDate = startDate; + final Integer repaidEvery = 2*loanRepaymentInterval; + switch (periodFrequencyType) { + case DAYS: + dueRepaymentPeriodDate = startDate.plusDays(repaidEvery); + break; + case WEEKS: + dueRepaymentPeriodDate = startDate.plusWeeks(repaidEvery); + break; + case MONTHS: + dueRepaymentPeriodDate = startDate.plusMonths(repaidEvery); + break; + case YEARS: + dueRepaymentPeriodDate = startDate.plusYears(repaidEvery); + break; + case INVALID: + break; + } + return dueRepaymentPeriodDate.minusDays(1);//get 2n-1 range date from startDate + } + public void applyHolidayToRepaymentScheduleDates(final Holiday holiday) { // first repayment's from date is same as disbursement date. LocalDate tmpFromDate = this.getDisbursementDate(); From 57eecb4b1b763cfa21d59e58c80f3af52bfca446 Mon Sep 17 00:00:00 2001 From: mifoscontributer Date: Fri, 9 Aug 2013 13:39:27 +0530 Subject: [PATCH 09/11] Validation check for loans and savings for client or group status --- .../exception/ClientNotActiveException.java | 11 ++++++ .../ClientReadPlatformServiceImpl.java | 5 +-- ...WritePlatformServiceJpaRepositoryImpl.java | 9 +++++ .../portfolio/group/domain/Group.java | 4 +++ .../portfolio/group/domain/GroupLevel.java | 4 +++ .../exception/CenterNotActiveException.java | 11 ++++++ ....java => GroupAccountExistsException.java} | 4 +-- .../exception/GroupNotActiveException.java | 11 ++++++ ...WritePlatformServiceJpaRepositoryImpl.java | 24 +++++++++++-- .../portfolio/loanaccount/domain/Loan.java | 4 +++ ...WritePlatformServiceJpaRepositoryImpl.java | 35 ++++++++++++++++++- .../loanaccount/service/LoanAssembler.java | 8 +++++ ...WritePlatformServiceJpaRepositoryImpl.java | 31 ++++++++++++++++ .../savings/domain/SavingsAccount.java | 8 +++++ .../domain/SavingsAccountAssembler.java | 9 +++++ .../domain/SavingsAccountRepository.java | 3 ++ ...WritePlatformServiceJpaRepositoryImpl.java | 22 ++++++++++++ ...WritePlatformServiceJpaRepositoryImpl.java | 29 ++++++++++++++- 18 files changed, 223 insertions(+), 9 deletions(-) create mode 100644 mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/exception/ClientNotActiveException.java create mode 100644 mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/exception/CenterNotActiveException.java rename mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/exception/{GroupLoanExistsException.java => GroupAccountExistsException.java} (67%) create mode 100644 mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/exception/GroupNotActiveException.java diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/exception/ClientNotActiveException.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/exception/ClientNotActiveException.java new file mode 100644 index 000000000..8f2a8479c --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/exception/ClientNotActiveException.java @@ -0,0 +1,11 @@ +package org.mifosplatform.portfolio.client.exception; + +import org.mifosplatform.infrastructure.core.exception.AbstractPlatformDomainRuleException; + +public class ClientNotActiveException extends AbstractPlatformDomainRuleException { + + public ClientNotActiveException(final Long clientId) { + super("error.msg.client.not.active.exception", "The Client with id `" + clientId + "` is not active", clientId); + } + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientReadPlatformServiceImpl.java index 6d9ea0746..0492bba20 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientReadPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientReadPlatformServiceImpl.java @@ -263,7 +263,7 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService public ClientMembersOfGroupMapper() { final StringBuilder sqlBuilder = new StringBuilder(200); - sqlBuilder.append("c.id as id, c.account_no as accountNo, c.external_id as externalId, "); + sqlBuilder.append("c.id as id, c.account_no as accountNo, c.external_id as externalId, c.status_enum as statusEnum, "); sqlBuilder.append("c.office_id as officeId, o.name as officeName, "); sqlBuilder.append("c.firstname as firstname, c.middlename as middlename, c.lastname as lastname, "); sqlBuilder.append("c.fullname as fullname, c.display_name as displayName, "); @@ -286,7 +286,8 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService final String accountNo = rs.getString("accountNo"); - final EnumOptionData status = null; + final Integer statusEnum = JdbcSupport.getInteger(rs, "statusEnum"); + final EnumOptionData status = ClientEnumerations.status(statusEnum); final Long officeId = JdbcSupport.getLong(rs, "officeId"); final Long id = JdbcSupport.getLong(rs, "id"); diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientWritePlatformServiceJpaRepositoryImpl.java index 01f0bd45c..bd7270965 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientWritePlatformServiceJpaRepositoryImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientWritePlatformServiceJpaRepositoryImpl.java @@ -359,6 +359,9 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP } else if (loanStatus.isPendingApproval()) { final String errorMessage = "Client cannot be closed because of non-closed loans."; throw new InvalidClientStateTransitionException("close", "loan.non-closed", errorMessage); + } else if (loanStatus.isAwaitingDisbursal()) { + final String errorMessage = "Client cannot be closed because of non-closed loans."; + throw new InvalidClientStateTransitionException("close", "loan.non-closed", errorMessage); } } List clientSavingAccounts = this.savingsRepository.findSavingAccountByClientId(clientId); @@ -367,6 +370,12 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP if (saving.isActive()) { final String errorMessage = "Client cannot be closed because of non-closed savings account."; throw new InvalidClientStateTransitionException("close", "non-closed.savings.account", errorMessage); + } else if (saving.isSubmittedAndPendingApproval()) { + final String errorMessage = "Client cannot be closed because of non-closed savings account."; + throw new InvalidClientStateTransitionException("close", "non-closed.savings.account", errorMessage); + } else if (saving.isApproved()) { + final String errorMessage = "Client cannot be closed because of non-closed savings account."; + throw new InvalidClientStateTransitionException("close", "non-closed.savings.account", errorMessage); } } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/domain/Group.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/domain/Group.java index 5270fedcf..4f128779b 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/domain/Group.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/domain/Group.java @@ -380,4 +380,8 @@ public final class Group extends AbstractPersistable { public Office getOffice() { return this.office; } + + public boolean isCenter() { + return this.groupLevel.isCenter(); + } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/domain/GroupLevel.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/domain/GroupLevel.java index cb9bae6d0..64b9e54de 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/domain/GroupLevel.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/domain/GroupLevel.java @@ -74,4 +74,8 @@ public class GroupLevel extends AbstractPersistable { public boolean isIdentifiedByParentId(final Long parentLevelId) { return this.parentId.equals(parentLevelId); } + + public boolean isCenter() { + return this.levelName.equalsIgnoreCase("Center"); + } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/exception/CenterNotActiveException.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/exception/CenterNotActiveException.java new file mode 100644 index 000000000..e0a5fe68f --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/exception/CenterNotActiveException.java @@ -0,0 +1,11 @@ +package org.mifosplatform.portfolio.group.exception; + +import org.mifosplatform.infrastructure.core.exception.AbstractPlatformDomainRuleException; + +public class CenterNotActiveException extends AbstractPlatformDomainRuleException { + + public CenterNotActiveException(final Long centerId) { + super("error.msg.center.not.active.exception", "The Center with id `" + centerId + "` is not active", centerId); + } + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/exception/GroupLoanExistsException.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/exception/GroupAccountExistsException.java similarity index 67% rename from mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/exception/GroupLoanExistsException.java rename to mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/exception/GroupAccountExistsException.java index ccf76e171..3657c287d 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/exception/GroupLoanExistsException.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/exception/GroupAccountExistsException.java @@ -7,9 +7,9 @@ package org.mifosplatform.portfolio.group.exception; import org.mifosplatform.infrastructure.core.exception.AbstractPlatformDomainRuleException; -public class GroupLoanExistsException extends AbstractPlatformDomainRuleException { +public class GroupAccountExistsException extends AbstractPlatformDomainRuleException { - public GroupLoanExistsException(final String action, String postFix, String defaultUserMessage, Object... defaultUserMessageArgs) { + public GroupAccountExistsException(final String action, String postFix, String defaultUserMessage, Object... defaultUserMessageArgs) { super("error.msg.group." + action + "." + postFix, defaultUserMessage, defaultUserMessageArgs); } } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/exception/GroupNotActiveException.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/exception/GroupNotActiveException.java new file mode 100644 index 000000000..679ef2ebe --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/exception/GroupNotActiveException.java @@ -0,0 +1,11 @@ +package org.mifosplatform.portfolio.group.exception; + +import org.mifosplatform.infrastructure.core.exception.AbstractPlatformDomainRuleException; + +public class GroupNotActiveException extends AbstractPlatformDomainRuleException { + + public GroupNotActiveException(final Long groupId) { + super("error.msg.group.not.active.exception", "The Group with id `" + groupId + "` is not active", groupId); + } + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/service/GroupingTypesWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/service/GroupingTypesWritePlatformServiceJpaRepositoryImpl.java index 2dd5288d2..b9b8214e2 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/service/GroupingTypesWritePlatformServiceJpaRepositoryImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/service/GroupingTypesWritePlatformServiceJpaRepositoryImpl.java @@ -36,8 +36,8 @@ import org.mifosplatform.portfolio.group.domain.GroupLevel; import org.mifosplatform.portfolio.group.domain.GroupLevelRepository; import org.mifosplatform.portfolio.group.domain.GroupRepositoryWrapper; import org.mifosplatform.portfolio.group.domain.GroupTypes; +import org.mifosplatform.portfolio.group.exception.GroupAccountExistsException; import org.mifosplatform.portfolio.group.exception.GroupHasNoStaffException; -import org.mifosplatform.portfolio.group.exception.GroupLoanExistsException; import org.mifosplatform.portfolio.group.exception.GroupMustBePendingToBeDeletedException; import org.mifosplatform.portfolio.group.exception.InvalidGroupLevelException; import org.mifosplatform.portfolio.group.exception.InvalidGroupStateTransitionException; @@ -46,6 +46,8 @@ import org.mifosplatform.portfolio.loanaccount.domain.Loan; import org.mifosplatform.portfolio.loanaccount.domain.LoanRepository; import org.mifosplatform.portfolio.note.domain.Note; import org.mifosplatform.portfolio.note.domain.NoteRepository; +import org.mifosplatform.portfolio.savings.domain.SavingsAccount; +import org.mifosplatform.portfolio.savings.domain.SavingsAccountRepository; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -69,13 +71,14 @@ public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements Group private final GroupLevelRepository groupLevelRepository; private final GroupingTypesDataValidator fromApiJsonDeserializer; private final LoanRepository loanRepository; + private final SavingsAccountRepository savingsRepository; @Autowired public GroupingTypesWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, final GroupRepositoryWrapper groupRepository, final ClientRepositoryWrapper clientRepository, final OfficeRepository officeRepository, final StaffRepositoryWrapper staffRepository, final NoteRepository noteRepository, final GroupLevelRepository groupLevelRepository, final GroupingTypesDataValidator fromApiJsonDeserializer, - final LoanRepository loanRepository) { + final LoanRepository loanRepository, final SavingsAccountRepository savingsRepository) { this.context = context; this.groupRepository = groupRepository; this.clientRepository = clientRepository; @@ -85,6 +88,7 @@ public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements Group this.groupLevelRepository = groupLevelRepository; this.fromApiJsonDeserializer = fromApiJsonDeserializer; this.loanRepository = loanRepository; + this.savingsRepository = savingsRepository; } private CommandProcessingResult createGroupingType(final JsonCommand command, final GroupTypes groupingType, final Long centerId) { @@ -491,6 +495,7 @@ public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements Group // check if any client has got group loans validateForJLGLoan(groupForUpdate.getId(), clientMembers); + validateForJLGSavings(groupForUpdate.getId(), clientMembers); final Map actualChanges = new HashMap(); final List changes = groupForUpdate.disassociateClients(clientMembers); @@ -516,7 +521,20 @@ public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements Group if (!CollectionUtils.isEmpty(loans)) { final String defaultUserMessage = "Client with identifier " + client.getId() + " cannot be disassociated it has group loans."; - throw new GroupLoanExistsException("disassociate", "client.has.group.loan", defaultUserMessage, client.getId(), groupId); + throw new GroupAccountExistsException("disassociate", "client.has.group.loan", defaultUserMessage, client.getId(), groupId); + } + } + } + + @Transactional + private void validateForJLGSavings(final Long groupId, final Set clientMembers) { + for (final Client client : clientMembers) { + final Collection savings = this.savingsRepository.findByClientIdAndGroupId(client.getId(), groupId); + if (!CollectionUtils.isEmpty(savings)) { + final String defaultUserMessage = "Client with identifier " + client.getId() + + " cannot be disassociated it has group savings."; + throw new GroupAccountExistsException("disassociate", "client.has.group.saving", defaultUserMessage, client.getId(), + groupId); } } } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/Loan.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/Loan.java index fc69b1dd5..d7ccd778d 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/Loan.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/Loan.java @@ -2564,4 +2564,8 @@ public class Loan extends AbstractPersistable { } + public void updateGroup(Group group) { + this.group = group; + } + } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanApplicationWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanApplicationWritePlatformServiceJpaRepositoryImpl.java index b64a0b515..e11152d3b 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanApplicationWritePlatformServiceJpaRepositoryImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanApplicationWritePlatformServiceJpaRepositoryImpl.java @@ -35,9 +35,13 @@ import org.mifosplatform.portfolio.client.domain.AccountNumberGenerator; import org.mifosplatform.portfolio.client.domain.AccountNumberGeneratorFactory; import org.mifosplatform.portfolio.client.domain.Client; import org.mifosplatform.portfolio.client.domain.ClientRepositoryWrapper; +import org.mifosplatform.portfolio.client.exception.ClientNotActiveException; import org.mifosplatform.portfolio.collateral.domain.LoanCollateral; import org.mifosplatform.portfolio.collateral.service.CollateralAssembler; import org.mifosplatform.portfolio.fund.domain.Fund; +import org.mifosplatform.portfolio.group.domain.Group; +import org.mifosplatform.portfolio.group.domain.GroupRepositoryWrapper; +import org.mifosplatform.portfolio.group.exception.GroupNotActiveException; import org.mifosplatform.portfolio.loanaccount.domain.DefaultLoanLifecycleStateMachine; import org.mifosplatform.portfolio.loanaccount.domain.Loan; import org.mifosplatform.portfolio.loanaccount.domain.LoanCharge; @@ -94,6 +98,7 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa private final AprCalculator aprCalculator; private final AccountNumberGeneratorFactory accountIdentifierGeneratorFactory; private final LoanSummaryWrapper loanSummaryWrapper; + private final GroupRepositoryWrapper groupRepository; private final LoanRepaymentScheduleTransactionProcessorFactory loanRepaymentScheduleTransactionProcessorFactory; private final CalendarRepository calendarRepository; private final CalendarInstanceRepository calendarInstanceRepository; @@ -107,7 +112,7 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa final CollateralAssembler loanCollateralAssembler, final LoanRepository loanRepository, final NoteRepository noteRepository, final LoanScheduleCalculationPlatformService calculationPlatformService, final ClientRepositoryWrapper clientRepository, final LoanProductRepository loanProductRepository, final AccountNumberGeneratorFactory accountIdentifierGeneratorFactory, - final LoanSummaryWrapper loanSummaryWrapper, + final LoanSummaryWrapper loanSummaryWrapper, final GroupRepositoryWrapper groupRepository, final LoanRepaymentScheduleTransactionProcessorFactory loanRepaymentScheduleTransactionProcessorFactory, final CalendarRepository calendarRepository, final CalendarInstanceRepository calendarInstanceRepository) { this.context = context; @@ -126,6 +131,7 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa this.loanProductRepository = loanProductRepository; this.accountIdentifierGeneratorFactory = accountIdentifierGeneratorFactory; this.loanSummaryWrapper = loanSummaryWrapper; + this.groupRepository = groupRepository; this.loanRepaymentScheduleTransactionProcessorFactory = loanRepaymentScheduleTransactionProcessorFactory; this.calendarRepository = calendarRepository; this.calendarInstanceRepository = calendarInstanceRepository; @@ -213,6 +219,7 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa this.fromApiJsonDeserializer.validateForModify(command.json()); final Loan existingLoanApplication = retrieveLoanBy(loanId); + checkClientOrGroupActive(existingLoanApplication); if (!existingLoanApplication.isSubmittedAndPendingApproval()) { throw new LoanApplicationNotInSubmittedAndPendingApprovalStateCannotBeModified( loanId); } @@ -232,10 +239,20 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa if (changes.containsKey(clientIdParamName)) { final Long clientId = command.longValueOfParameterNamed(clientIdParamName); final Client client = this.clientRepository.findOneWithNotFoundDetection(clientId); + if (client.isNotActive()) { throw new ClientNotActiveException(clientId); } existingLoanApplication.updateClient(client); } + final String groupIdParamName = "groupId"; + if (changes.containsKey(groupIdParamName)) { + final Long groupId = command.longValueOfParameterNamed(groupIdParamName); + final Group group = this.groupRepository.findOneWithNotFoundDetection(groupId); + if (group.isNotActive()) { throw new GroupNotActiveException(groupId); } + + existingLoanApplication.updateGroup(group); + } + final String productIdParamName = "productId"; if (changes.containsKey(productIdParamName)) { final Long productId = command.longValueOfParameterNamed(productIdParamName); @@ -392,6 +409,7 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa context.authenticatedUser(); final Loan loan = retrieveLoanBy(loanId); + checkClientOrGroupActive(loan); if (loan.isNotSubmittedAndPendingApproval()) { throw new LoanApplicationNotInSubmittedAndPendingApprovalStateCannotBeDeleted(loanId); } @@ -418,6 +436,7 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa this.loanApplicationTransitionApiJsonValidator.validateApproval(command.json()); final Loan loan = retrieveLoanBy(loanId); + checkClientOrGroupActive(loan); final Map changes = loan.loanApplicationApproval(currentUser, command, defaultLoanLifecycleStateMachine()); if (!changes.isEmpty()) { @@ -451,6 +470,7 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa this.fromApiJsonDeserializer.validateForUndo(command.json()); final Loan loan = retrieveLoanBy(loanId); + checkClientOrGroupActive(loan); final Map changes = loan.undoApproval(defaultLoanLifecycleStateMachine()); if (!changes.isEmpty()) { @@ -483,6 +503,7 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa this.loanApplicationTransitionApiJsonValidator.validateRejection(command.json()); final Loan loan = retrieveLoanBy(loanId); + checkClientOrGroupActive(loan); final Map changes = loan.loanApplicationRejection(currentUser, command, defaultLoanLifecycleStateMachine()); if (!changes.isEmpty()) { @@ -515,6 +536,7 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa this.loanApplicationTransitionApiJsonValidator.validateApplicantWithdrawal(command.json()); final Loan loan = retrieveLoanBy(loanId); + checkClientOrGroupActive(loan); final Map changes = loan.loanApplicationWithdrawnByApplicant(currentUser, command, defaultLoanLifecycleStateMachine()); @@ -565,4 +587,15 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa } } + private void checkClientOrGroupActive(final Loan loan) { + final Client client = loan.client(); + if (client != null) { + if (client.isNotActive()) { throw new ClientNotActiveException(client.getId()); } + } + final Group group = loan.group(); + if (group != null) { + if (group.isNotActive()) { throw new GroupNotActiveException(group.getId()); } + } + } + } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanAssembler.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanAssembler.java index 553dae611..e3e3d0aed 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanAssembler.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanAssembler.java @@ -26,6 +26,7 @@ import org.mifosplatform.organisation.workingdays.domain.WorkingDays; import org.mifosplatform.organisation.workingdays.domain.WorkingDaysRepositoryWrapper; import org.mifosplatform.portfolio.client.domain.Client; import org.mifosplatform.portfolio.client.domain.ClientRepositoryWrapper; +import org.mifosplatform.portfolio.client.exception.ClientNotActiveException; import org.mifosplatform.portfolio.collateral.domain.LoanCollateral; import org.mifosplatform.portfolio.collateral.service.CollateralAssembler; import org.mifosplatform.portfolio.fund.domain.Fund; @@ -34,6 +35,7 @@ import org.mifosplatform.portfolio.fund.exception.FundNotFoundException; import org.mifosplatform.portfolio.group.domain.Group; import org.mifosplatform.portfolio.group.domain.GroupRepository; import org.mifosplatform.portfolio.group.exception.ClientNotInGroupException; +import org.mifosplatform.portfolio.group.exception.GroupNotActiveException; import org.mifosplatform.portfolio.group.exception.GroupNotFoundException; import org.mifosplatform.portfolio.loanaccount.domain.DefaultLoanLifecycleStateMachine; import org.mifosplatform.portfolio.loanaccount.domain.Loan; @@ -158,6 +160,9 @@ public class LoanAssembler { if (clientId != null) { client = this.clientRepository.findOneWithNotFoundDetection(clientId); + if (client.isNotActive()) { + throw new ClientNotActiveException(clientId); + } loanApplication = Loan.newIndividualLoanApplication(accountNo, client, loanType.getId().intValue(), loanProduct, fund, loanOfficer, loanPurpose, loanTransactionProcessingStrategy, loanProductRelatedDetail, loanCharges, collateral); @@ -166,6 +171,9 @@ public class LoanAssembler { if (groupId != null) { group = this.groupRepository.findOne(groupId); if (group == null) { throw new GroupNotFoundException(groupId); } + if (group.isNotActive()) { + throw new GroupNotActiveException(groupId); + } loanApplication = Loan.newGroupLoanApplication(accountNo, group, loanType.getId().intValue(), loanProduct, fund, loanOfficer, loanTransactionProcessingStrategy, loanProductRelatedDetail, loanCharges, syncDisbursementWithMeeting); diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java index d94b4f9bf..193cde4c2 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java @@ -48,10 +48,14 @@ import org.mifosplatform.portfolio.charge.exception.LoanChargeCannotBeUpdatedExc import org.mifosplatform.portfolio.charge.exception.LoanChargeCannotBeWaivedException; import org.mifosplatform.portfolio.charge.exception.LoanChargeCannotBeWaivedException.LOAN_CHARGE_CANNOT_BE_WAIVED_REASON; import org.mifosplatform.portfolio.charge.exception.LoanChargeNotFoundException; +import org.mifosplatform.portfolio.client.domain.Client; +import org.mifosplatform.portfolio.client.exception.ClientNotActiveException; import org.mifosplatform.portfolio.collectionsheet.command.CollectionSheetBulkDisbursalCommand; import org.mifosplatform.portfolio.collectionsheet.command.CollectionSheetBulkRepaymentCommand; import org.mifosplatform.portfolio.collectionsheet.command.SingleDisbursalCommand; import org.mifosplatform.portfolio.collectionsheet.command.SingleRepaymentCommand; +import org.mifosplatform.portfolio.group.domain.Group; +import org.mifosplatform.portfolio.group.exception.GroupNotActiveException; import org.mifosplatform.portfolio.loanaccount.command.LoanUpdateCommand; import org.mifosplatform.portfolio.loanaccount.domain.ChangedTransactionDetail; import org.mifosplatform.portfolio.loanaccount.domain.DefaultLoanLifecycleStateMachine; @@ -162,6 +166,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf this.loanEventApiJsonValidator.validateDisbursement(command.json()); final Loan loan = retrieveLoanBy(loanId); + checkClientOrGroupActive(loan); //check for product mix validations checkForProductMixRestrictions(loan); @@ -265,6 +270,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf SingleDisbursalCommand singleLoanDisbursalCommand = disbursalCommand[i]; final Loan loan = retrieveLoanBy(singleLoanDisbursalCommand.getLoanId()); + checkClientOrGroupActive(loan); final MonetaryCurrency currency = loan.getCurrency(); final ApplicationCurrency applicationCurrency = this.applicationCurrencyRepository.findOneWithNotFoundDetection(currency); @@ -314,6 +320,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf context.authenticatedUser(); final Loan loan = retrieveLoanBy(loanId); + checkClientOrGroupActive(loan); removeLoanCycle(loan); final List existingTransactionIds = new ArrayList(); final List existingReversedTransactionIds = new ArrayList(); @@ -382,6 +389,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf private CommandProcessingResultBuilder saveLoanRepayment(final Long loanId, final PaymentDetail paymentDetail, final BigDecimal transactionAmount, final LocalDate transactionDate, final String noteText) { final Loan loan = retrieveLoanBy(loanId); + checkClientOrGroupActive(loan); // TODO: Is it required to validate transaction date with meeting dates // if repayments is synced with meeting? @@ -472,6 +480,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf this.loanEventApiJsonValidator.validateTransaction(command.json()); final Loan loan = retrieveLoanBy(loanId); + checkClientOrGroupActive(loan); final LoanTransaction transactionToAdjust = this.loanTransactionRepository.findOne(transactionId); if (transactionToAdjust == null) { throw new LoanTransactionNotFoundException(transactionId); } @@ -572,6 +581,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf final BigDecimal transactionAmount = command.bigDecimalValueOfParameterNamed("transactionAmount"); final Loan loan = retrieveLoanBy(loanId); + checkClientOrGroupActive(loan); final List existingTransactionIds = new ArrayList(); final List existingReversedTransactionIds = new ArrayList(); @@ -632,6 +642,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf changes.put("dateFormat", command.dateFormat()); final Loan loan = retrieveLoanBy(loanId); + checkClientOrGroupActive(loan); removeLoanCycle(loan); final List existingTransactionIds = new ArrayList(); @@ -671,6 +682,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf this.loanEventApiJsonValidator.validateTransactionWithNoAmount(command.json()); final Loan loan = retrieveLoanBy(loanId); + checkClientOrGroupActive(loan); final Map changes = new LinkedHashMap(); changes.put("transactionDate", command.stringValueOfParameterNamed("transactionDate")); @@ -733,6 +745,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf this.loanEventApiJsonValidator.validateTransactionWithNoAmount(command.json()); final Loan loan = retrieveLoanBy(loanId); + checkClientOrGroupActive(loan); removeLoanCycle(loan); final Map changes = new LinkedHashMap(); @@ -771,6 +784,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf this.loanEventApiJsonValidator.validateAddLoanCharge(command.json()); final Loan loan = retrieveLoanBy(loanId); + checkClientOrGroupActive(loan); final Long chargeDefinitionId = command.longValueOfParameterNamed("chargeId"); final Charge chargeDefinition = this.chargeRepository.findOneWithNotFoundDetection(chargeDefinitionId); @@ -831,6 +845,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf this.loanEventApiJsonValidator.validateUpdateOfLoanCharge(command.json()); final Loan loan = retrieveLoanBy(loanId); + checkClientOrGroupActive(loan); final LoanCharge loanCharge = retrieveLoanChargeBy(loanId, loanChargeId); // Charges may be edited only when the loan associated with them are @@ -860,6 +875,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf this.context.authenticatedUser(); final Loan loan = retrieveLoanBy(loanId); + checkClientOrGroupActive(loan); final LoanCharge loanCharge = retrieveLoanChargeBy(loanId, loanChargeId); // Charges may be waived only when the loan associated with them are @@ -904,6 +920,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf this.context.authenticatedUser(); final Loan loan = retrieveLoanBy(loanId); + checkClientOrGroupActive(loan); final LoanCharge loanCharge = retrieveLoanChargeBy(loanId, loanChargeId); // Charges may be deleted only when the loan associated with them are @@ -955,6 +972,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf final LocalDate dateOfLoanOfficerAssignment = command.localDateValueOfParameterNamed("assignmentDate"); final Loan loan = retrieveLoanBy(loanId); + checkClientOrGroupActive(loan); if (!loan.hasLoanOfficer(fromLoanOfficer)) { throw new LoanOfficerAssignmentException(loanId, fromLoanOfficerId); } @@ -990,6 +1008,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf for (final String loanIdString : loanIds) { final Long loanId = Long.valueOf(loanIdString); final Loan loan = retrieveLoanBy(loanId); + checkClientOrGroupActive(loan); if (!loan.hasLoanOfficer(fromLoanOfficer)) { throw new LoanOfficerAssignmentException(loanId, fromLoanOfficerId); } @@ -1017,6 +1036,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf final LocalDate dateOfLoanOfficerunAssigned = command.localDateValueOfParameterNamed("unassignedDate"); final Loan loan = retrieveLoanBy(loanId); + checkClientOrGroupActive(loan); if (loan.getLoanOfficer() == null) { throw new LoanOfficerUnassignmentException(loanId); } @@ -1286,4 +1306,15 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf } } } + + private void checkClientOrGroupActive(final Loan loan) { + final Client client = loan.client(); + if (client != null) { + if (client.isNotActive()) { throw new ClientNotActiveException(client.getId()); } + } + final Group group = loan.group(); + if (group != null) { + if (group.isNotActive()) { throw new GroupNotActiveException(group.getId()); } + } + } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/SavingsAccount.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/SavingsAccount.java index 2691d21fc..3f187457d 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/SavingsAccount.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/SavingsAccount.java @@ -342,6 +342,10 @@ public class SavingsAccount extends AbstractPersistable { return SavingsAccountStatusType.fromInt(this.status).isSubmittedAndPendingApproval(); } + public boolean isApproved() { + return SavingsAccountStatusType.fromInt(this.status).isApproved(); + } + public void postInterest(final MathContext mc, final LocalDate interestPostingUpToDate, final List existingTransactionIds, final List existingReversedTransactionIds) { @@ -1677,4 +1681,8 @@ public class SavingsAccount extends AbstractPersistable { return lockedInUntilLocalDate; } + + public Group group() { + return this.group; + } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/SavingsAccountAssembler.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/SavingsAccountAssembler.java index 0b0826f29..9468df5be 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/SavingsAccountAssembler.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/SavingsAccountAssembler.java @@ -36,8 +36,11 @@ import org.mifosplatform.organisation.staff.domain.Staff; import org.mifosplatform.organisation.staff.domain.StaffRepositoryWrapper; import org.mifosplatform.portfolio.client.domain.Client; import org.mifosplatform.portfolio.client.domain.ClientRepositoryWrapper; +import org.mifosplatform.portfolio.client.exception.ClientNotActiveException; import org.mifosplatform.portfolio.group.domain.Group; import org.mifosplatform.portfolio.group.domain.GroupRepositoryWrapper; +import org.mifosplatform.portfolio.group.exception.CenterNotActiveException; +import org.mifosplatform.portfolio.group.exception.GroupNotActiveException; import org.mifosplatform.portfolio.savings.SavingsCompoundingInterestPeriodType; import org.mifosplatform.portfolio.savings.SavingsInterestCalculationDaysInYearType; import org.mifosplatform.portfolio.savings.SavingsInterestCalculationType; @@ -100,11 +103,17 @@ public class SavingsAccountAssembler { final Long clientId = fromApiJsonHelper.extractLongNamed(clientIdParamName, element); if (clientId != null) { client = this.clientRepository.findOneWithNotFoundDetection(clientId); + if (client.isNotActive()) { throw new ClientNotActiveException(clientId); } } final Long groupId = fromApiJsonHelper.extractLongNamed(groupIdParamName, element); if (groupId != null) { group = this.groupRepository.findOneWithNotFoundDetection(groupId); + if (group.isNotActive()) { + if (group.isCenter()) { throw new CenterNotActiveException(groupId); } + throw new GroupNotActiveException(groupId); + } + } final Long fieldOfficerId = fromApiJsonHelper.extractLongNamed(fieldOfficerIdParamName, element); diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/SavingsAccountRepository.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/SavingsAccountRepository.java index 67539b0cb..c5f3940b8 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/SavingsAccountRepository.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/SavingsAccountRepository.java @@ -16,4 +16,7 @@ public interface SavingsAccountRepository extends JpaRepository findSavingAccountByClientId(@Param("clientId") Long clientId); + + @Query("from SavingsAccount sa where sa.client.id = :clientId and sa.group.id = :groupId") + List findByClientIdAndGroupId(@Param("clientId") Long clientId, @Param("groupId") Long groupId); } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/service/SavingsAccountWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/service/SavingsAccountWritePlatformServiceJpaRepositoryImpl.java index 27cc1959b..b66ace3af 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/service/SavingsAccountWritePlatformServiceJpaRepositoryImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/service/SavingsAccountWritePlatformServiceJpaRepositoryImpl.java @@ -26,6 +26,10 @@ import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext import org.mifosplatform.organisation.monetary.domain.ApplicationCurrency; import org.mifosplatform.organisation.monetary.domain.ApplicationCurrencyRepositoryWrapper; import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency; +import org.mifosplatform.portfolio.client.domain.Client; +import org.mifosplatform.portfolio.client.exception.ClientNotActiveException; +import org.mifosplatform.portfolio.group.domain.Group; +import org.mifosplatform.portfolio.group.exception.GroupNotActiveException; import org.mifosplatform.portfolio.paymentdetail.domain.PaymentDetail; import org.mifosplatform.portfolio.paymentdetail.service.PaymentDetailWritePlatformService; import org.mifosplatform.portfolio.savings.data.SavingsAccountTransactionDataValidator; @@ -79,6 +83,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi this.savingsAccountTransactionDataValidator.validateActivation(command); final SavingsAccount account = this.savingAccountAssembler.assembleFrom(savingsId); + checkClientOrGroupActive(account); final List existingTransactionIds = new ArrayList(); final List existingReversedTransactionIds = new ArrayList(); @@ -110,6 +115,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi this.savingsAccountTransactionDataValidator.validate(command); final SavingsAccount account = this.savingAccountAssembler.assembleFrom(savingsId); + checkClientOrGroupActive(account); final Locale locale = command.extractLocale(); final DateTimeFormatter fmt = DateTimeFormat.forPattern(command.dateFormat()).withLocale(locale); @@ -164,6 +170,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi this.savingsAccountTransactionDataValidator.validate(command); final SavingsAccount account = this.savingAccountAssembler.assembleFrom(savingsId); + checkClientOrGroupActive(account); final LocalDate transactionDate = command.localDateValueOfParameterNamed("transactionDate"); final BigDecimal transactionAmount = command.bigDecimalValueOfParameterNamed("transactionAmount"); @@ -208,6 +215,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi public CommandProcessingResult applyAnnualFee(final Long savingsId, final LocalDate annualFeeTransactionDate) { final SavingsAccount account = this.savingAccountAssembler.assembleFrom(savingsId); + checkClientOrGroupActive(account); final DateTimeFormatter fmt = DateTimeFormat.forPattern("dd MM yyyy"); @@ -238,6 +246,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi public CommandProcessingResult calculateInterest(final Long savingsId) { final SavingsAccount account = this.savingAccountAssembler.assembleFrom(savingsId); + checkClientOrGroupActive(account); final LocalDate today = DateUtils.getLocalDateOfTenant(); final MathContext mc = new MathContext(15, RoundingMode.HALF_EVEN); @@ -263,6 +272,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi final List existingReversedTransactionIds = new ArrayList(); final SavingsAccount account = this.savingAccountAssembler.assembleFrom(savingsId); + checkClientOrGroupActive(account); final LocalDate today = DateUtils.getLocalDateOfTenant(); final MathContext mc = new MathContext(10, RoundingMode.HALF_EVEN); @@ -298,6 +308,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi final SavingsAccount account = this.savingAccountAssembler.assembleFrom(savingsId); account.undoTransaction(transactionId, reversedTransactionIds, mc, today); + checkClientOrGroupActive(account); postJournalEntries(account, newTransactionIds, reversedTransactionIds); @@ -320,4 +331,15 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi existingTransactionIds, existingReversedTransactionIds); journalEntryWritePlatformService.createJournalEntriesForSavings(accountingBridgeData); } + + private void checkClientOrGroupActive(final SavingsAccount account) { + final Client client = account.getClient(); + if (client != null) { + if (client.isNotActive()) { throw new ClientNotActiveException(client.getId()); } + } + final Group group = account.group(); + if (group != null) { + if (group.isNotActive()) { throw new GroupNotActiveException(group.getId()); } + } + } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/service/SavingsApplicationProcessWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/service/SavingsApplicationProcessWritePlatformServiceJpaRepositoryImpl.java index 540aaac19..9f439c3c5 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/service/SavingsApplicationProcessWritePlatformServiceJpaRepositoryImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/service/SavingsApplicationProcessWritePlatformServiceJpaRepositoryImpl.java @@ -32,8 +32,11 @@ import org.mifosplatform.portfolio.client.domain.AccountNumberGenerator; import org.mifosplatform.portfolio.client.domain.AccountNumberGeneratorFactory; import org.mifosplatform.portfolio.client.domain.Client; import org.mifosplatform.portfolio.client.domain.ClientRepositoryWrapper; +import org.mifosplatform.portfolio.client.exception.ClientNotActiveException; import org.mifosplatform.portfolio.group.domain.Group; import org.mifosplatform.portfolio.group.domain.GroupRepository; +import org.mifosplatform.portfolio.group.exception.CenterNotActiveException; +import org.mifosplatform.portfolio.group.exception.GroupNotActiveException; import org.mifosplatform.portfolio.group.exception.GroupNotFoundException; import org.mifosplatform.portfolio.note.domain.Note; import org.mifosplatform.portfolio.note.domain.NoteRepository; @@ -170,7 +173,7 @@ public class SavingsApplicationProcessWritePlatformServiceJpaRepositoryImpl impl final Map changes = new LinkedHashMap(20); final SavingsAccount account = this.savingAccountAssembler.assembleFrom(savingsId); - + checkClientOrGroupActive(account); account.modifyApplication(command, changes); account.validateNewApplicationState(DateUtils.getLocalDateOfTenant()); @@ -180,6 +183,7 @@ public class SavingsApplicationProcessWritePlatformServiceJpaRepositoryImpl impl final Long clientId = command.longValueOfParameterNamed(SavingsApiConstants.clientIdParamName); if (clientId != null) { final Client client = this.clientRepository.findOneWithNotFoundDetection(clientId); + if (client.isNotActive()) { throw new ClientNotActiveException(clientId); } account.update(client); } else { final Client client = null; @@ -192,6 +196,10 @@ public class SavingsApplicationProcessWritePlatformServiceJpaRepositoryImpl impl if (groupId != null) { final Group group = this.groupRepository.findOne(groupId); if (group == null) { throw new GroupNotFoundException(groupId); } + if (group.isNotActive()) { + if (group.isCenter()) { throw new CenterNotActiveException(groupId); } + throw new GroupNotActiveException(groupId); + } account.update(group); } else { final Group group = null; @@ -241,6 +249,7 @@ public class SavingsApplicationProcessWritePlatformServiceJpaRepositoryImpl impl public CommandProcessingResult deleteApplication(final Long savingsId) { final SavingsAccount account = this.savingAccountAssembler.assembleFrom(savingsId); + checkClientOrGroupActive(account); if (account.isNotSubmittedAndPendingApproval()) { final List dataValidationErrors = new ArrayList(); @@ -276,6 +285,7 @@ public class SavingsApplicationProcessWritePlatformServiceJpaRepositoryImpl impl this.savingsAccountApplicationTransitionApiJsonValidator.validateApproval(command.json()); final SavingsAccount savingsAccount = this.savingAccountAssembler.assembleFrom(savingsId); + checkClientOrGroupActive(savingsAccount); final Map changes = savingsAccount.approveApplication(currentUser, command, DateUtils.getLocalDateOfTenant()); if (!changes.isEmpty()) { @@ -309,6 +319,7 @@ public class SavingsApplicationProcessWritePlatformServiceJpaRepositoryImpl impl this.savingsAccountApplicationTransitionApiJsonValidator.validateForUndo(command.json()); final SavingsAccount savingsAccount = this.savingAccountAssembler.assembleFrom(savingsId); + checkClientOrGroupActive(savingsAccount); final Map changes = savingsAccount.undoApplicationApproval(); if (!changes.isEmpty()) { @@ -342,6 +353,7 @@ public class SavingsApplicationProcessWritePlatformServiceJpaRepositoryImpl impl this.savingsAccountApplicationTransitionApiJsonValidator.validateRejection(command.json()); final SavingsAccount savingsAccount = this.savingAccountAssembler.assembleFrom(savingsId); + checkClientOrGroupActive(savingsAccount); final Map changes = savingsAccount.rejectApplication(currentUser, command, DateUtils.getLocalDateOfTenant()); if (!changes.isEmpty()) { @@ -374,6 +386,7 @@ public class SavingsApplicationProcessWritePlatformServiceJpaRepositoryImpl impl this.savingsAccountApplicationTransitionApiJsonValidator.validateApplicantWithdrawal(command.json()); final SavingsAccount savingsAccount = this.savingAccountAssembler.assembleFrom(savingsId); + checkClientOrGroupActive(savingsAccount); final Map changes = savingsAccount.applicantWithdrawsFromApplication(currentUser, command, DateUtils.getLocalDateOfTenant()); @@ -409,4 +422,18 @@ public class SavingsApplicationProcessWritePlatformServiceJpaRepositoryImpl impl existingTransactionIds, existingReversedTransactionIds); journalEntryWritePlatformService.createJournalEntriesForSavings(accountingBridgeData); } + + private void checkClientOrGroupActive(final SavingsAccount account) { + final Client client = account.getClient(); + if (client != null) { + if (client.isNotActive()) { throw new ClientNotActiveException(client.getId()); } + } + final Group group = account.group(); + if (group != null) { + if (group.isNotActive()) { + if (group.isCenter()) { throw new CenterNotActiveException(group.getId()); } + throw new GroupNotActiveException(group.getId()); + } + } + } } \ No newline at end of file From 32ba28031e58effb333f469d31dce2da993180b3 Mon Sep 17 00:00:00 2001 From: Vishwas Babu A J Date: Mon, 12 Aug 2013 21:24:25 +0530 Subject: [PATCH 10/11] flyway enable out of order migrations --- .../core/service/TenantDatabaseUpgradeService.java | 1 + 1 file changed, 1 insertion(+) diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/service/TenantDatabaseUpgradeService.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/service/TenantDatabaseUpgradeService.java index 6730b8f1e..8873b84f2 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/service/TenantDatabaseUpgradeService.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/service/TenantDatabaseUpgradeService.java @@ -38,6 +38,7 @@ public class TenantDatabaseUpgradeService { Flyway flyway = new Flyway(); flyway.setDataSource(tenant.databaseURL(), tenant.getSchemaUsername(), tenant.getSchemaPassword()); flyway.setLocations("sql"); + flyway.setOutOfOrder(true); flyway.migrate(); } } From b2e2fdf8f1457eb05ac207c826c40ab449a7483d Mon Sep 17 00:00:00 2001 From: Vishwas Babu A J Date: Mon, 12 Aug 2013 21:51:39 +0530 Subject: [PATCH 11/11] updating to 1.7.1 Release --- mifosng-provider/gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mifosng-provider/gradle.properties b/mifosng-provider/gradle.properties index 414b7ebda..e20c1e6b8 100644 --- a/mifosng-provider/gradle.properties +++ b/mifosng-provider/gradle.properties @@ -1 +1 @@ -releaseVersion=1.7.0.RELEASE +releaseVersion=1.7.1.RELEASE