merging 1.7.1 release into develop branch

This commit is contained in:
Vishwas Babu A J
2013-08-12 22:25:24 +05:30
26 changed files with 300 additions and 111 deletions
@@ -1,2 +0,0 @@
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);
@@ -1 +0,0 @@
INSERT INTO `job` (`name`, `display_name`, `cron_expression`, `create_time`, `task_priority`, `group_name`, `previous_run_start_time`, `next_run_time`, `job_key`, `initializing_errorlog`, `is_active`, `currently_running`, `updates_allowed`, `scheduler_group`) VALUES ('Post Interest For Savings', 'Post Interest For Savings', '0 0 0 1/1 * ? *', now(), 5, NULL, NULL, NULL, NULL, NULL, 1, 0, 1, 0);
@@ -1,56 +0,0 @@
INSERT INTO `m_permission`
(`grouping`,`code`,`entity_name`,`action_name`,`can_maker_checker`)
VALUES
('transaction_savings', 'READ_ACCOUNTTRANSFER', 'ACCOUNTTRANSFER', 'READ', 0),
('transaction_savings', 'CREATE_ACCOUNTTRANSFER', 'ACCOUNTTRANSFER', 'CREATE', 1),
('transaction_savings', 'CREATE_ACCOUNTTRANSFER_CHECKER', 'ACCOUNTTRANSFER', 'CREATE', 0);
DROP TABLE IF EXISTS `m_savings_account_transfer`;
CREATE TABLE `m_savings_account_transfer` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`from_office_id` bigint(20) NOT NULL,
`to_office_id` bigint(20) NOT NULL,
`from_client_id` bigint(20) NOT NULL,
`to_client_id` bigint(20) NOT NULL,
`from_savings_account_id` bigint(20) DEFAULT NULL,
`to_savings_account_id` bigint(20) DEFAULT NULL,
`from_loan_account_id` bigint(20) DEFAULT NULL,
`to_loan_account_id` bigint(20) DEFAULT NULL,
`from_savings_transaction_id` bigint(20) DEFAULT NULL,
`from_loan_transaction_id` bigint(20) DEFAULT NULL,
`to_savings_transaction_id` bigint(20) DEFAULT NULL,
`to_loan_transaction_id` bigint(20) DEFAULT NULL,
`is_reversed` tinyint(1) NOT NULL,
`transaction_date` date NOT NULL,
`currency_code` varchar(3) NOT NULL,
`currency_digits` smallint(5) NOT NULL,
`amount` decimal(19,6) NOT NULL,
`description` varchar(200) NOT NULL,
PRIMARY KEY (`id`),
KEY `FKTRAN000000001` (`from_office_id`),
KEY `FKTRAN000000002` (`from_client_id`),
KEY `FKTRAN000000003` (`from_savings_account_id`),
KEY `FKTRAN000000004` (`to_office_id`),
KEY `FKTRAN000000005` (`to_client_id`),
KEY `FKTRAN000000006` (`to_savings_account_id`),
KEY `FKTRAN000000007` (`to_loan_account_id`),
KEY `FKTRAN000000008` (`from_savings_transaction_id`),
KEY `FKTRAN000000009` (`to_savings_transaction_id`),
KEY `FKTRAN000000010` (`to_loan_transaction_id`),
KEY `FKTRAN000000011` (`from_loan_account_id`),
KEY `FKTRAN000000012` (`from_loan_transaction_id`),
CONSTRAINT `FKTRAN000000001` FOREIGN KEY (`from_office_id`) REFERENCES `m_office` (`id`),
CONSTRAINT `FKTRAN000000002` FOREIGN KEY (`from_client_id`) REFERENCES `m_client` (`id`),
CONSTRAINT `FKTRAN000000003` FOREIGN KEY (`from_savings_account_id`) REFERENCES `m_savings_account` (`id`),
CONSTRAINT `FKTRAN000000004` FOREIGN KEY (`to_office_id`) REFERENCES `m_office` (`id`),
CONSTRAINT `FKTRAN000000005` FOREIGN KEY (`to_client_id`) REFERENCES `m_client` (`id`),
CONSTRAINT `FKTRAN000000006` FOREIGN KEY (`to_savings_account_id`) REFERENCES `m_savings_account` (`id`),
CONSTRAINT `FKTRAN000000007` FOREIGN KEY (`to_loan_account_id`) REFERENCES `m_loan` (`id`),
CONSTRAINT `FKTRAN000000008` FOREIGN KEY (`from_savings_transaction_id`) REFERENCES `m_savings_account_transaction` (`id`),
CONSTRAINT `FKTRAN000000009` FOREIGN KEY (`to_savings_transaction_id`) REFERENCES `m_savings_account_transaction` (`id`),
CONSTRAINT `FKTRAN000000010` FOREIGN KEY (`to_loan_transaction_id`) REFERENCES `m_loan_transaction` (`id`),
CONSTRAINT `FKTRAN000000011` FOREIGN KEY (`from_loan_account_id`) REFERENCES `m_loan` (`id`),
CONSTRAINT `FKTRAN000000012` FOREIGN KEY (`from_loan_transaction_id`) REFERENCES `m_loan_transaction` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
@@ -1 +0,0 @@
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ('transaction_savings', 'ADJUSTTRANSACTION_SAVINGSACCOUNT', 'SAVINGSACCOUNT', 'ADJUSTTRANSACTION', 0);
@@ -1,12 +0,0 @@
ALTER TABLE `m_savings_account`
ADD COLUMN `currency_multiplesof` SMALLINT(5) NULL AFTER `currency_digits`;
ALTER TABLE `m_savings_product`
ADD COLUMN `currency_multiplesof` SMALLINT(5) NULL AFTER `currency_digits`;
ALTER TABLE `m_loan`
ADD COLUMN `currency_multiplesof` SMALLINT(5) NULL AFTER `currency_digits`;
ALTER TABLE `m_product_loan`
ADD COLUMN `currency_multiplesof` SMALLINT(5) NULL AFTER `currency_digits`;
ALTER TABLE `m_currency`
ADD COLUMN `currency_multiplesof` SMALLINT(5) NULL AFTER `decimal_places`;
ALTER TABLE `m_organisation_currency`
ADD COLUMN `currency_multiplesof` SMALLINT(5) NULL AFTER `decimal_places`;
+5 -1
View File
@@ -1 +1,5 @@
releaseVersion=1.8.0.DEVELOP <<<<<<< HEAD
releaseVersion=1.8.0.DEVELOP
=======
releaseVersion=1.7.1.RELEASE
>>>>>>> master
@@ -38,6 +38,7 @@ public class TenantDatabaseUpgradeService {
Flyway flyway = new Flyway(); Flyway flyway = new Flyway();
flyway.setDataSource(tenant.databaseURL(), tenant.getSchemaUsername(), tenant.getSchemaPassword()); flyway.setDataSource(tenant.databaseURL(), tenant.getSchemaUsername(), tenant.getSchemaPassword());
flyway.setLocations("sql"); flyway.setLocations("sql");
flyway.setOutOfOrder(true);
flyway.migrate(); flyway.migrate();
} }
} }
@@ -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){ 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); final Recur recur = CalendarHelper.getICalRecur(recurringRule);
if (recur == null) { return null; } if (recur == null) { return null; }
if(isValidRecurringDate(recur, seedDate, oldRepaymentDate)){ if(isValidRecurringDate(recur, seedDate, oldRepaymentDate)){
return oldRepaymentDate; return oldRepaymentDate;
} }
/* Recurring dates should follow loanRepaymentInterval. return getNextRepaymentMeetingDate(recurringRule, seedDate, oldRepaymentDate, loanRepaymentInterval, frequency, workingDays);
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.
*/ public static LocalDate getNextRepaymentMeetingDate(final String recurringRule, final LocalDate seedDate, final LocalDate repaymentDate, final Integer loanRepaymentInterval, final String frequency, final WorkingDays workingDays){
recur.setInterval(loanRepaymentInterval);
final Recur recur = CalendarHelper.getICalRecur(recurringRule);
/*Recurring dates should follow loanRepayment frequency. if (recur == null) { return null; }
//e.g. daily meeting frequency should support all loan products with any type of frequency. LocalDate tmpDate = repaymentDate;
to generate right set of meeting dates reset frequency same as loan repayment frequency. if(isValidRecurringDate(recur, seedDate, repaymentDate)){
*/ tmpDate = repaymentDate.plusDays(1);
if(recur.getFrequency().equals(Recur.DAILY)){ }
recur.setFrequency(frequency); /* 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,
LocalDate newRepaymentDate = getNextRecurringDate(recur, seedDate, oldRepaymentDate); to generate right set of meeting dates reset interval same as loan repayment interval.
LocalDate nextRepaymentDate = getNextRecurringDate(recur, seedDate, newRepaymentDate); */
recur.setInterval(loanRepaymentInterval);
newRepaymentDate = WorkingDaysUtil.getOffSetDateIfNonWorkingDay(newRepaymentDate, nextRepaymentDate, workingDays);
/*Recurring dates should follow loanRepayment frequency.
return newRepaymentDate; //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) { public static boolean isFrequencySame(final String oldRRule, final String newRRule) {
@@ -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);
}
}
@@ -253,7 +253,7 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
public ClientMembersOfGroupMapper() { public ClientMembersOfGroupMapper() {
final StringBuilder sqlBuilder = new StringBuilder(200); 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.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.firstname as firstname, c.middlename as middlename, c.lastname as lastname, ");
sqlBuilder.append("c.fullname as fullname, c.display_name as displayName, "); sqlBuilder.append("c.fullname as fullname, c.display_name as displayName, ");
@@ -276,7 +276,8 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
final String accountNo = rs.getString("accountNo"); 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 officeId = JdbcSupport.getLong(rs, "officeId");
final Long id = JdbcSupport.getLong(rs, "id"); final Long id = JdbcSupport.getLong(rs, "id");
@@ -359,6 +359,9 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
} else if (loanStatus.isPendingApproval()) { } else if (loanStatus.isPendingApproval()) {
final String errorMessage = "Client cannot be closed because of non-closed loans."; final String errorMessage = "Client cannot be closed because of non-closed loans.";
throw new InvalidClientStateTransitionException("close", "loan.non-closed", errorMessage); 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<SavingsAccount> clientSavingAccounts = this.savingsRepository.findSavingAccountByClientId(clientId); List<SavingsAccount> clientSavingAccounts = this.savingsRepository.findSavingAccountByClientId(clientId);
@@ -367,6 +370,12 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
if (saving.isActive()) { if (saving.isActive()) {
final String errorMessage = "Client cannot be closed because of non-closed savings account."; final String errorMessage = "Client cannot be closed because of non-closed savings account.";
throw new InvalidClientStateTransitionException("close", "non-closed.savings.account", errorMessage); 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);
} }
} }
@@ -381,4 +381,7 @@ public final class Group extends AbstractPersistable<Long> {
return this.office; return this.office;
} }
public boolean isCenter() {
return this.groupLevel.isCenter();
}
} }
@@ -74,4 +74,8 @@ public class GroupLevel extends AbstractPersistable<Long> {
public boolean isIdentifiedByParentId(final Long parentLevelId) { public boolean isIdentifiedByParentId(final Long parentLevelId) {
return this.parentId.equals(parentLevelId); return this.parentId.equals(parentLevelId);
} }
public boolean isCenter() {
return this.levelName.equalsIgnoreCase("Center");
}
} }
@@ -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);
}
}
@@ -7,9 +7,9 @@ package org.mifosplatform.portfolio.group.exception;
import org.mifosplatform.infrastructure.core.exception.AbstractPlatformDomainRuleException; 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); super("error.msg.group." + action + "." + postFix, defaultUserMessage, defaultUserMessageArgs);
} }
} }
@@ -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);
}
}
@@ -36,8 +36,8 @@ import org.mifosplatform.portfolio.group.domain.GroupLevel;
import org.mifosplatform.portfolio.group.domain.GroupLevelRepository; import org.mifosplatform.portfolio.group.domain.GroupLevelRepository;
import org.mifosplatform.portfolio.group.domain.GroupRepositoryWrapper; import org.mifosplatform.portfolio.group.domain.GroupRepositoryWrapper;
import org.mifosplatform.portfolio.group.domain.GroupTypes; 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.GroupHasNoStaffException;
import org.mifosplatform.portfolio.group.exception.GroupLoanExistsException;
import org.mifosplatform.portfolio.group.exception.GroupMustBePendingToBeDeletedException; import org.mifosplatform.portfolio.group.exception.GroupMustBePendingToBeDeletedException;
import org.mifosplatform.portfolio.group.exception.InvalidGroupLevelException; import org.mifosplatform.portfolio.group.exception.InvalidGroupLevelException;
import org.mifosplatform.portfolio.group.exception.InvalidGroupStateTransitionException; 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.loanaccount.domain.LoanRepository;
import org.mifosplatform.portfolio.note.domain.Note; import org.mifosplatform.portfolio.note.domain.Note;
import org.mifosplatform.portfolio.note.domain.NoteRepository; 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.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@@ -69,13 +71,14 @@ public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements Group
private final GroupLevelRepository groupLevelRepository; private final GroupLevelRepository groupLevelRepository;
private final GroupingTypesDataValidator fromApiJsonDeserializer; private final GroupingTypesDataValidator fromApiJsonDeserializer;
private final LoanRepository loanRepository; private final LoanRepository loanRepository;
private final SavingsAccountRepository savingsRepository;
@Autowired @Autowired
public GroupingTypesWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, public GroupingTypesWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context,
final GroupRepositoryWrapper groupRepository, final ClientRepositoryWrapper clientRepository, final GroupRepositoryWrapper groupRepository, final ClientRepositoryWrapper clientRepository,
final OfficeRepository officeRepository, final StaffRepositoryWrapper staffRepository, final NoteRepository noteRepository, final OfficeRepository officeRepository, final StaffRepositoryWrapper staffRepository, final NoteRepository noteRepository,
final GroupLevelRepository groupLevelRepository, final GroupingTypesDataValidator fromApiJsonDeserializer, final GroupLevelRepository groupLevelRepository, final GroupingTypesDataValidator fromApiJsonDeserializer,
final LoanRepository loanRepository) { final LoanRepository loanRepository, final SavingsAccountRepository savingsRepository) {
this.context = context; this.context = context;
this.groupRepository = groupRepository; this.groupRepository = groupRepository;
this.clientRepository = clientRepository; this.clientRepository = clientRepository;
@@ -85,6 +88,7 @@ public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements Group
this.groupLevelRepository = groupLevelRepository; this.groupLevelRepository = groupLevelRepository;
this.fromApiJsonDeserializer = fromApiJsonDeserializer; this.fromApiJsonDeserializer = fromApiJsonDeserializer;
this.loanRepository = loanRepository; this.loanRepository = loanRepository;
this.savingsRepository = savingsRepository;
} }
private CommandProcessingResult createGroupingType(final JsonCommand command, final GroupTypes groupingType, final Long centerId) { private CommandProcessingResult createGroupingType(final JsonCommand command, final GroupTypes groupingType, final Long centerId) {
@@ -519,6 +523,7 @@ public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements Group
// check if any client has got group loans // check if any client has got group loans
validateForJLGLoan(groupForUpdate.getId(), clientMembers); validateForJLGLoan(groupForUpdate.getId(), clientMembers);
validateForJLGSavings(groupForUpdate.getId(), clientMembers);
final Map<String, Object> actualChanges = new HashMap<String, Object>(); final Map<String, Object> actualChanges = new HashMap<String, Object>();
final List<String> changes = groupForUpdate.disassociateClients(clientMembers); final List<String> changes = groupForUpdate.disassociateClients(clientMembers);
@@ -544,7 +549,20 @@ public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements Group
if (!CollectionUtils.isEmpty(loans)) { if (!CollectionUtils.isEmpty(loans)) {
final String defaultUserMessage = "Client with identifier " + client.getId() final String defaultUserMessage = "Client with identifier " + client.getId()
+ " cannot be disassociated it has group loans."; + " 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<Client> clientMembers) {
for (final Client client : clientMembers) {
final Collection<SavingsAccount> 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);
} }
} }
} }
@@ -2388,22 +2388,32 @@ public class Loan extends AbstractPersistable<Long> {
public void updateLoanRepaymentScheduleDates(final LocalDate meetingStartDate, final String recuringRule, public void updateLoanRepaymentScheduleDates(final LocalDate meetingStartDate, final String recuringRule,
final boolean isHolidayEnabled, final List<Holiday> holidays, final WorkingDays workingDays) { final boolean isHolidayEnabled, final List<Holiday> holidays, final WorkingDays workingDays) {
//update repayment dates of repayment schedule installaments //update repayment dates of repayment schedule installaments
LocalDate tmpFromDate = getDisbursementDate();//first repayment's from date is same as disbursement date. LocalDate tmpFromDate = this.getDisbursementDate();//first repayment's from date is same as disbursement date.
final PeriodFrequencyType repaymentPeriodFrequencyType = this.loanRepaymentScheduleDetail.getRepaymentPeriodFrequencyType();
final Integer loanRepaymentInterval = this.loanRepaymentScheduleDetail.getRepayEvery();
final String frequency = CalendarHelper.getMeetingFrequencyFromPeriodFrequencyType(repaymentPeriodFrequencyType);
LocalDate newRepaymentDate = null; LocalDate newRepaymentDate = null;
for (final LoanRepaymentScheduleInstallment loanRepaymentScheduleInstallment : this.repaymentScheduleInstallments) { for (final LoanRepaymentScheduleInstallment loanRepaymentScheduleInstallment : this.repaymentScheduleInstallments) {
final LocalDate oldDueDate = loanRepaymentScheduleInstallment.getDueDate(); final LocalDate oldDueDate = loanRepaymentScheduleInstallment.getDueDate();
// FIXME: AA this won't update repayment dates before current date. // FIXME: AA this won't update repayment dates before current date.
if (oldDueDate.isAfter(meetingStartDate) && oldDueDate.isAfter(DateUtils.getLocalDateOfTenant())) { 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,
newRepaymentDate = CalendarHelper.getNewRepaymentMeetingDate(recuringRule, meetingStartDate, oldDueDate, loanRepaymentInterval, frequency, workingDays); loanRepaymentInterval, frequency, workingDays);
if(isHolidayEnabled){
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); newRepaymentDate = HolidayUtil.getRepaymentRescheduleDateToIfHoliday(newRepaymentDate, holidays);
} }
loanRepaymentScheduleInstallment.updateDueDate(newRepaymentDate); loanRepaymentScheduleInstallment.updateDueDate(newRepaymentDate);
// reset from date to get actual daysInPeriod // reset from date to get actual daysInPeriod
loanRepaymentScheduleInstallment.updateFromDate(tmpFromDate); loanRepaymentScheduleInstallment.updateFromDate(tmpFromDate);
@@ -2415,6 +2425,29 @@ public class Loan extends AbstractPersistable<Long> {
} }
} }
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) { public void applyHolidayToRepaymentScheduleDates(final Holiday holiday) {
// first repayment's from date is same as disbursement date. // first repayment's from date is same as disbursement date.
LocalDate tmpFromDate = getDisbursementDate(); LocalDate tmpFromDate = getDisbursementDate();
@@ -2525,4 +2558,8 @@ public class Loan extends AbstractPersistable<Long> {
} }
public void updateGroup(Group group) {
this.group = group;
}
} }
@@ -35,9 +35,13 @@ import org.mifosplatform.portfolio.client.domain.AccountNumberGenerator;
import org.mifosplatform.portfolio.client.domain.AccountNumberGeneratorFactory; import org.mifosplatform.portfolio.client.domain.AccountNumberGeneratorFactory;
import org.mifosplatform.portfolio.client.domain.Client; import org.mifosplatform.portfolio.client.domain.Client;
import org.mifosplatform.portfolio.client.domain.ClientRepositoryWrapper; 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.domain.LoanCollateral;
import org.mifosplatform.portfolio.collateral.service.CollateralAssembler; import org.mifosplatform.portfolio.collateral.service.CollateralAssembler;
import org.mifosplatform.portfolio.fund.domain.Fund; 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.DefaultLoanLifecycleStateMachine;
import org.mifosplatform.portfolio.loanaccount.domain.Loan; import org.mifosplatform.portfolio.loanaccount.domain.Loan;
import org.mifosplatform.portfolio.loanaccount.domain.LoanCharge; import org.mifosplatform.portfolio.loanaccount.domain.LoanCharge;
@@ -94,6 +98,7 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
private final AprCalculator aprCalculator; private final AprCalculator aprCalculator;
private final AccountNumberGeneratorFactory accountIdentifierGeneratorFactory; private final AccountNumberGeneratorFactory accountIdentifierGeneratorFactory;
private final LoanSummaryWrapper loanSummaryWrapper; private final LoanSummaryWrapper loanSummaryWrapper;
private final GroupRepositoryWrapper groupRepository;
private final LoanRepaymentScheduleTransactionProcessorFactory loanRepaymentScheduleTransactionProcessorFactory; private final LoanRepaymentScheduleTransactionProcessorFactory loanRepaymentScheduleTransactionProcessorFactory;
private final CalendarRepository calendarRepository; private final CalendarRepository calendarRepository;
private final CalendarInstanceRepository calendarInstanceRepository; private final CalendarInstanceRepository calendarInstanceRepository;
@@ -107,7 +112,7 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
final CollateralAssembler loanCollateralAssembler, final LoanRepository loanRepository, final NoteRepository noteRepository, final CollateralAssembler loanCollateralAssembler, final LoanRepository loanRepository, final NoteRepository noteRepository,
final LoanScheduleCalculationPlatformService calculationPlatformService, final ClientRepositoryWrapper clientRepository, final LoanScheduleCalculationPlatformService calculationPlatformService, final ClientRepositoryWrapper clientRepository,
final LoanProductRepository loanProductRepository, final AccountNumberGeneratorFactory accountIdentifierGeneratorFactory, final LoanProductRepository loanProductRepository, final AccountNumberGeneratorFactory accountIdentifierGeneratorFactory,
final LoanSummaryWrapper loanSummaryWrapper, final LoanSummaryWrapper loanSummaryWrapper, final GroupRepositoryWrapper groupRepository,
final LoanRepaymentScheduleTransactionProcessorFactory loanRepaymentScheduleTransactionProcessorFactory, final LoanRepaymentScheduleTransactionProcessorFactory loanRepaymentScheduleTransactionProcessorFactory,
final CalendarRepository calendarRepository, final CalendarInstanceRepository calendarInstanceRepository) { final CalendarRepository calendarRepository, final CalendarInstanceRepository calendarInstanceRepository) {
this.context = context; this.context = context;
@@ -126,6 +131,7 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
this.loanProductRepository = loanProductRepository; this.loanProductRepository = loanProductRepository;
this.accountIdentifierGeneratorFactory = accountIdentifierGeneratorFactory; this.accountIdentifierGeneratorFactory = accountIdentifierGeneratorFactory;
this.loanSummaryWrapper = loanSummaryWrapper; this.loanSummaryWrapper = loanSummaryWrapper;
this.groupRepository = groupRepository;
this.loanRepaymentScheduleTransactionProcessorFactory = loanRepaymentScheduleTransactionProcessorFactory; this.loanRepaymentScheduleTransactionProcessorFactory = loanRepaymentScheduleTransactionProcessorFactory;
this.calendarRepository = calendarRepository; this.calendarRepository = calendarRepository;
this.calendarInstanceRepository = calendarInstanceRepository; this.calendarInstanceRepository = calendarInstanceRepository;
@@ -218,6 +224,7 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
this.fromApiJsonDeserializer.validateForModify(command.json()); this.fromApiJsonDeserializer.validateForModify(command.json());
final Loan existingLoanApplication = retrieveLoanBy(loanId); final Loan existingLoanApplication = retrieveLoanBy(loanId);
checkClientOrGroupActive(existingLoanApplication);
if (!existingLoanApplication.isSubmittedAndPendingApproval()) { throw new LoanApplicationNotInSubmittedAndPendingApprovalStateCannotBeModified( if (!existingLoanApplication.isSubmittedAndPendingApproval()) { throw new LoanApplicationNotInSubmittedAndPendingApprovalStateCannotBeModified(
loanId); } loanId); }
@@ -237,10 +244,20 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
if (changes.containsKey(clientIdParamName)) { if (changes.containsKey(clientIdParamName)) {
final Long clientId = command.longValueOfParameterNamed(clientIdParamName); final Long clientId = command.longValueOfParameterNamed(clientIdParamName);
final Client client = this.clientRepository.findOneWithNotFoundDetection(clientId); final Client client = this.clientRepository.findOneWithNotFoundDetection(clientId);
if (client.isNotActive()) { throw new ClientNotActiveException(clientId); }
existingLoanApplication.updateClient(client); 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"; final String productIdParamName = "productId";
if (changes.containsKey(productIdParamName)) { if (changes.containsKey(productIdParamName)) {
final Long productId = command.longValueOfParameterNamed(productIdParamName); final Long productId = command.longValueOfParameterNamed(productIdParamName);
@@ -397,6 +414,7 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
context.authenticatedUser(); context.authenticatedUser();
final Loan loan = retrieveLoanBy(loanId); final Loan loan = retrieveLoanBy(loanId);
checkClientOrGroupActive(loan);
if (loan.isNotSubmittedAndPendingApproval()) { throw new LoanApplicationNotInSubmittedAndPendingApprovalStateCannotBeDeleted(loanId); } if (loan.isNotSubmittedAndPendingApproval()) { throw new LoanApplicationNotInSubmittedAndPendingApprovalStateCannotBeDeleted(loanId); }
@@ -423,6 +441,7 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
this.loanApplicationTransitionApiJsonValidator.validateApproval(command.json()); this.loanApplicationTransitionApiJsonValidator.validateApproval(command.json());
final Loan loan = retrieveLoanBy(loanId); final Loan loan = retrieveLoanBy(loanId);
checkClientOrGroupActive(loan);
final Map<String, Object> changes = loan.loanApplicationApproval(currentUser, command, defaultLoanLifecycleStateMachine()); final Map<String, Object> changes = loan.loanApplicationApproval(currentUser, command, defaultLoanLifecycleStateMachine());
if (!changes.isEmpty()) { if (!changes.isEmpty()) {
@@ -456,6 +475,7 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
this.fromApiJsonDeserializer.validateForUndo(command.json()); this.fromApiJsonDeserializer.validateForUndo(command.json());
final Loan loan = retrieveLoanBy(loanId); final Loan loan = retrieveLoanBy(loanId);
checkClientOrGroupActive(loan);
final Map<String, Object> changes = loan.undoApproval(defaultLoanLifecycleStateMachine()); final Map<String, Object> changes = loan.undoApproval(defaultLoanLifecycleStateMachine());
if (!changes.isEmpty()) { if (!changes.isEmpty()) {
@@ -488,6 +508,7 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
this.loanApplicationTransitionApiJsonValidator.validateRejection(command.json()); this.loanApplicationTransitionApiJsonValidator.validateRejection(command.json());
final Loan loan = retrieveLoanBy(loanId); final Loan loan = retrieveLoanBy(loanId);
checkClientOrGroupActive(loan);
final Map<String, Object> changes = loan.loanApplicationRejection(currentUser, command, defaultLoanLifecycleStateMachine()); final Map<String, Object> changes = loan.loanApplicationRejection(currentUser, command, defaultLoanLifecycleStateMachine());
if (!changes.isEmpty()) { if (!changes.isEmpty()) {
@@ -520,6 +541,7 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
this.loanApplicationTransitionApiJsonValidator.validateApplicantWithdrawal(command.json()); this.loanApplicationTransitionApiJsonValidator.validateApplicantWithdrawal(command.json());
final Loan loan = retrieveLoanBy(loanId); final Loan loan = retrieveLoanBy(loanId);
checkClientOrGroupActive(loan);
final Map<String, Object> changes = loan.loanApplicationWithdrawnByApplicant(currentUser, command, final Map<String, Object> changes = loan.loanApplicationWithdrawnByApplicant(currentUser, command,
defaultLoanLifecycleStateMachine()); defaultLoanLifecycleStateMachine());
@@ -570,4 +592,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()); }
}
}
} }
@@ -27,6 +27,7 @@ import org.mifosplatform.organisation.workingdays.domain.WorkingDaysRepositoryWr
import org.mifosplatform.portfolio.accountdetails.service.AccountEnumerations; import org.mifosplatform.portfolio.accountdetails.service.AccountEnumerations;
import org.mifosplatform.portfolio.client.domain.Client; import org.mifosplatform.portfolio.client.domain.Client;
import org.mifosplatform.portfolio.client.domain.ClientRepositoryWrapper; 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.domain.LoanCollateral;
import org.mifosplatform.portfolio.collateral.service.CollateralAssembler; import org.mifosplatform.portfolio.collateral.service.CollateralAssembler;
import org.mifosplatform.portfolio.fund.domain.Fund; import org.mifosplatform.portfolio.fund.domain.Fund;
@@ -35,6 +36,7 @@ import org.mifosplatform.portfolio.fund.exception.FundNotFoundException;
import org.mifosplatform.portfolio.group.domain.Group; import org.mifosplatform.portfolio.group.domain.Group;
import org.mifosplatform.portfolio.group.domain.GroupRepository; import org.mifosplatform.portfolio.group.domain.GroupRepository;
import org.mifosplatform.portfolio.group.exception.ClientNotInGroupException; 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.group.exception.GroupNotFoundException;
import org.mifosplatform.portfolio.loanaccount.domain.DefaultLoanLifecycleStateMachine; import org.mifosplatform.portfolio.loanaccount.domain.DefaultLoanLifecycleStateMachine;
import org.mifosplatform.portfolio.loanaccount.domain.Loan; import org.mifosplatform.portfolio.loanaccount.domain.Loan;
@@ -158,6 +160,9 @@ public class LoanAssembler {
if (clientId != null) { if (clientId != null) {
client = this.clientRepository.findOneWithNotFoundDetection(clientId); client = this.clientRepository.findOneWithNotFoundDetection(clientId);
if (client.isNotActive()) {
throw new ClientNotActiveException(clientId);
}
loanApplication = Loan.newIndividualLoanApplication(accountNo, client, loanType.getId().intValue(), loanProduct, fund, loanApplication = Loan.newIndividualLoanApplication(accountNo, client, loanType.getId().intValue(), loanProduct, fund,
loanOfficer, loanPurpose, loanTransactionProcessingStrategy, loanProductRelatedDetail, loanCharges, collateral); loanOfficer, loanPurpose, loanTransactionProcessingStrategy, loanProductRelatedDetail, loanCharges, collateral);
@@ -166,6 +171,9 @@ public class LoanAssembler {
if (groupId != null) { if (groupId != null) {
group = this.groupRepository.findOne(groupId); group = this.groupRepository.findOne(groupId);
if (group == null) { throw new GroupNotFoundException(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, loanApplication = Loan.newGroupLoanApplication(accountNo, group, loanType.getId().intValue(), loanProduct, fund, loanOfficer,
loanTransactionProcessingStrategy, loanProductRelatedDetail, loanCharges, syncDisbursementWithMeeting); loanTransactionProcessingStrategy, loanProductRelatedDetail, loanCharges, syncDisbursementWithMeeting);
@@ -49,10 +49,14 @@ import org.mifosplatform.portfolio.charge.exception.LoanChargeCannotBeUpdatedExc
import org.mifosplatform.portfolio.charge.exception.LoanChargeCannotBeWaivedException; 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.LoanChargeCannotBeWaivedException.LOAN_CHARGE_CANNOT_BE_WAIVED_REASON;
import org.mifosplatform.portfolio.charge.exception.LoanChargeNotFoundException; 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.CollectionSheetBulkDisbursalCommand;
import org.mifosplatform.portfolio.collectionsheet.command.CollectionSheetBulkRepaymentCommand; import org.mifosplatform.portfolio.collectionsheet.command.CollectionSheetBulkRepaymentCommand;
import org.mifosplatform.portfolio.collectionsheet.command.SingleDisbursalCommand; import org.mifosplatform.portfolio.collectionsheet.command.SingleDisbursalCommand;
import org.mifosplatform.portfolio.collectionsheet.command.SingleRepaymentCommand; 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.command.LoanUpdateCommand;
import org.mifosplatform.portfolio.loanaccount.domain.ChangedTransactionDetail; import org.mifosplatform.portfolio.loanaccount.domain.ChangedTransactionDetail;
import org.mifosplatform.portfolio.loanaccount.domain.DefaultLoanLifecycleStateMachine; import org.mifosplatform.portfolio.loanaccount.domain.DefaultLoanLifecycleStateMachine;
@@ -162,6 +166,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
this.loanEventApiJsonValidator.validateDisbursement(command.json()); this.loanEventApiJsonValidator.validateDisbursement(command.json());
final Loan loan = retrieveLoanBy(loanId); final Loan loan = retrieveLoanBy(loanId);
checkClientOrGroupActive(loan);
//check for product mix validations //check for product mix validations
checkForProductMixRestrictions(loan); checkForProductMixRestrictions(loan);
@@ -265,6 +270,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
SingleDisbursalCommand singleLoanDisbursalCommand = disbursalCommand[i]; SingleDisbursalCommand singleLoanDisbursalCommand = disbursalCommand[i];
final Loan loan = retrieveLoanBy(singleLoanDisbursalCommand.getLoanId()); final Loan loan = retrieveLoanBy(singleLoanDisbursalCommand.getLoanId());
checkClientOrGroupActive(loan);
final MonetaryCurrency currency = loan.getCurrency(); final MonetaryCurrency currency = loan.getCurrency();
final ApplicationCurrency applicationCurrency = this.applicationCurrencyRepository.findOneWithNotFoundDetection(currency); final ApplicationCurrency applicationCurrency = this.applicationCurrencyRepository.findOneWithNotFoundDetection(currency);
@@ -314,6 +320,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
context.authenticatedUser(); context.authenticatedUser();
final Loan loan = retrieveLoanBy(loanId); final Loan loan = retrieveLoanBy(loanId);
checkClientOrGroupActive(loan);
removeLoanCycle(loan); removeLoanCycle(loan);
final List<Long> existingTransactionIds = new ArrayList<Long>(); final List<Long> existingTransactionIds = new ArrayList<Long>();
final List<Long> existingReversedTransactionIds = new ArrayList<Long>(); final List<Long> existingReversedTransactionIds = new ArrayList<Long>();
@@ -383,6 +390,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
private CommandProcessingResultBuilder saveLoanRepayment(final Long loanId, final PaymentDetail paymentDetail, private CommandProcessingResultBuilder saveLoanRepayment(final Long loanId, final PaymentDetail paymentDetail,
final BigDecimal transactionAmount, final LocalDate transactionDate, final String noteText, final String txnExternalId) { final BigDecimal transactionAmount, final LocalDate transactionDate, final String noteText, final String txnExternalId) {
final Loan loan = retrieveLoanBy(loanId); final Loan loan = retrieveLoanBy(loanId);
checkClientOrGroupActive(loan);
// TODO: Is it required to validate transaction date with meeting dates // TODO: Is it required to validate transaction date with meeting dates
// if repayments is synced with meeting? // if repayments is synced with meeting?
@@ -473,6 +481,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
this.loanEventApiJsonValidator.validateTransaction(command.json()); this.loanEventApiJsonValidator.validateTransaction(command.json());
final Loan loan = retrieveLoanBy(loanId); final Loan loan = retrieveLoanBy(loanId);
checkClientOrGroupActive(loan);
final LoanTransaction transactionToAdjust = this.loanTransactionRepository.findOne(transactionId); final LoanTransaction transactionToAdjust = this.loanTransactionRepository.findOne(transactionId);
if (transactionToAdjust == null) { throw new LoanTransactionNotFoundException(transactionId); } if (transactionToAdjust == null) { throw new LoanTransactionNotFoundException(transactionId); }
@@ -574,6 +583,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
final BigDecimal transactionAmount = command.bigDecimalValueOfParameterNamed("transactionAmount"); final BigDecimal transactionAmount = command.bigDecimalValueOfParameterNamed("transactionAmount");
final Loan loan = retrieveLoanBy(loanId); final Loan loan = retrieveLoanBy(loanId);
checkClientOrGroupActive(loan);
final List<Long> existingTransactionIds = new ArrayList<Long>(); final List<Long> existingTransactionIds = new ArrayList<Long>();
final List<Long> existingReversedTransactionIds = new ArrayList<Long>(); final List<Long> existingReversedTransactionIds = new ArrayList<Long>();
@@ -634,6 +644,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
changes.put("dateFormat", command.dateFormat()); changes.put("dateFormat", command.dateFormat());
final Loan loan = retrieveLoanBy(loanId); final Loan loan = retrieveLoanBy(loanId);
checkClientOrGroupActive(loan);
removeLoanCycle(loan); removeLoanCycle(loan);
final List<Long> existingTransactionIds = new ArrayList<Long>(); final List<Long> existingTransactionIds = new ArrayList<Long>();
@@ -673,6 +684,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
this.loanEventApiJsonValidator.validateTransactionWithNoAmount(command.json()); this.loanEventApiJsonValidator.validateTransactionWithNoAmount(command.json());
final Loan loan = retrieveLoanBy(loanId); final Loan loan = retrieveLoanBy(loanId);
checkClientOrGroupActive(loan);
final Map<String, Object> changes = new LinkedHashMap<String, Object>(); final Map<String, Object> changes = new LinkedHashMap<String, Object>();
changes.put("transactionDate", command.stringValueOfParameterNamed("transactionDate")); changes.put("transactionDate", command.stringValueOfParameterNamed("transactionDate"));
@@ -735,6 +747,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
this.loanEventApiJsonValidator.validateTransactionWithNoAmount(command.json()); this.loanEventApiJsonValidator.validateTransactionWithNoAmount(command.json());
final Loan loan = retrieveLoanBy(loanId); final Loan loan = retrieveLoanBy(loanId);
checkClientOrGroupActive(loan);
removeLoanCycle(loan); removeLoanCycle(loan);
final Map<String, Object> changes = new LinkedHashMap<String, Object>(); final Map<String, Object> changes = new LinkedHashMap<String, Object>();
@@ -773,6 +786,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
this.loanEventApiJsonValidator.validateAddLoanCharge(command.json()); this.loanEventApiJsonValidator.validateAddLoanCharge(command.json());
final Loan loan = retrieveLoanBy(loanId); final Loan loan = retrieveLoanBy(loanId);
checkClientOrGroupActive(loan);
final Long chargeDefinitionId = command.longValueOfParameterNamed("chargeId"); final Long chargeDefinitionId = command.longValueOfParameterNamed("chargeId");
final Charge chargeDefinition = this.chargeRepository.findOneWithNotFoundDetection(chargeDefinitionId); final Charge chargeDefinition = this.chargeRepository.findOneWithNotFoundDetection(chargeDefinitionId);
@@ -833,6 +847,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
this.loanEventApiJsonValidator.validateUpdateOfLoanCharge(command.json()); this.loanEventApiJsonValidator.validateUpdateOfLoanCharge(command.json());
final Loan loan = retrieveLoanBy(loanId); final Loan loan = retrieveLoanBy(loanId);
checkClientOrGroupActive(loan);
final LoanCharge loanCharge = retrieveLoanChargeBy(loanId, loanChargeId); final LoanCharge loanCharge = retrieveLoanChargeBy(loanId, loanChargeId);
// Charges may be edited only when the loan associated with them are // Charges may be edited only when the loan associated with them are
@@ -862,6 +877,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
this.context.authenticatedUser(); this.context.authenticatedUser();
final Loan loan = retrieveLoanBy(loanId); final Loan loan = retrieveLoanBy(loanId);
checkClientOrGroupActive(loan);
final LoanCharge loanCharge = retrieveLoanChargeBy(loanId, loanChargeId); final LoanCharge loanCharge = retrieveLoanChargeBy(loanId, loanChargeId);
// Charges may be waived only when the loan associated with them are // Charges may be waived only when the loan associated with them are
@@ -906,6 +922,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
this.context.authenticatedUser(); this.context.authenticatedUser();
final Loan loan = retrieveLoanBy(loanId); final Loan loan = retrieveLoanBy(loanId);
checkClientOrGroupActive(loan);
final LoanCharge loanCharge = retrieveLoanChargeBy(loanId, loanChargeId); final LoanCharge loanCharge = retrieveLoanChargeBy(loanId, loanChargeId);
// Charges may be deleted only when the loan associated with them are // Charges may be deleted only when the loan associated with them are
@@ -957,6 +974,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
final LocalDate dateOfLoanOfficerAssignment = command.localDateValueOfParameterNamed("assignmentDate"); final LocalDate dateOfLoanOfficerAssignment = command.localDateValueOfParameterNamed("assignmentDate");
final Loan loan = retrieveLoanBy(loanId); final Loan loan = retrieveLoanBy(loanId);
checkClientOrGroupActive(loan);
if (!loan.hasLoanOfficer(fromLoanOfficer)) { throw new LoanOfficerAssignmentException(loanId, fromLoanOfficerId); } if (!loan.hasLoanOfficer(fromLoanOfficer)) { throw new LoanOfficerAssignmentException(loanId, fromLoanOfficerId); }
@@ -992,6 +1010,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
for (final String loanIdString : loanIds) { for (final String loanIdString : loanIds) {
final Long loanId = Long.valueOf(loanIdString); final Long loanId = Long.valueOf(loanIdString);
final Loan loan = retrieveLoanBy(loanId); final Loan loan = retrieveLoanBy(loanId);
checkClientOrGroupActive(loan);
if (!loan.hasLoanOfficer(fromLoanOfficer)) { throw new LoanOfficerAssignmentException(loanId, fromLoanOfficerId); } if (!loan.hasLoanOfficer(fromLoanOfficer)) { throw new LoanOfficerAssignmentException(loanId, fromLoanOfficerId); }
@@ -1019,6 +1038,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
final LocalDate dateOfLoanOfficerunAssigned = command.localDateValueOfParameterNamed("unassignedDate"); final LocalDate dateOfLoanOfficerunAssigned = command.localDateValueOfParameterNamed("unassignedDate");
final Loan loan = retrieveLoanBy(loanId); final Loan loan = retrieveLoanBy(loanId);
checkClientOrGroupActive(loan);
if (loan.getLoanOfficer() == null) { throw new LoanOfficerUnassignmentException(loanId); } if (loan.getLoanOfficer() == null) { throw new LoanOfficerUnassignmentException(loanId); }
@@ -1288,4 +1308,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()); }
}
}
} }
@@ -340,6 +340,10 @@ public class SavingsAccount extends AbstractPersistable<Long> {
return SavingsAccountStatusType.fromInt(this.status).isSubmittedAndPendingApproval(); 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<Long> existingTransactionIds, public void postInterest(final MathContext mc, final LocalDate interestPostingUpToDate, final List<Long> existingTransactionIds,
final List<Long> existingReversedTransactionIds) { final List<Long> existingReversedTransactionIds) {
@@ -1677,4 +1681,8 @@ public class SavingsAccount extends AbstractPersistable<Long> {
return lockedInUntilLocalDate; return lockedInUntilLocalDate;
} }
public Group group() {
return this.group;
}
} }
@@ -37,9 +37,12 @@ import org.mifosplatform.organisation.staff.domain.StaffRepositoryWrapper;
import org.mifosplatform.portfolio.accountdetails.domain.AccountType; import org.mifosplatform.portfolio.accountdetails.domain.AccountType;
import org.mifosplatform.portfolio.client.domain.Client; import org.mifosplatform.portfolio.client.domain.Client;
import org.mifosplatform.portfolio.client.domain.ClientRepositoryWrapper; 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.Group;
import org.mifosplatform.portfolio.group.domain.GroupRepositoryWrapper; import org.mifosplatform.portfolio.group.domain.GroupRepositoryWrapper;
import org.mifosplatform.portfolio.group.exception.ClientNotInGroupException; import org.mifosplatform.portfolio.group.exception.ClientNotInGroupException;
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.SavingsCompoundingInterestPeriodType;
import org.mifosplatform.portfolio.savings.SavingsInterestCalculationDaysInYearType; import org.mifosplatform.portfolio.savings.SavingsInterestCalculationDaysInYearType;
import org.mifosplatform.portfolio.savings.SavingsInterestCalculationType; import org.mifosplatform.portfolio.savings.SavingsInterestCalculationType;
@@ -102,6 +105,7 @@ public class SavingsAccountAssembler {
if (clientId != null) { if (clientId != null) {
client = this.clientRepository.findOneWithNotFoundDetection(clientId); client = this.clientRepository.findOneWithNotFoundDetection(clientId);
accountType = AccountType.INDIVIDUAL; accountType = AccountType.INDIVIDUAL;
if (client.isNotActive()) { throw new ClientNotActiveException(clientId); }
} }
final Long groupId = fromApiJsonHelper.extractLongNamed(groupIdParamName, element); final Long groupId = fromApiJsonHelper.extractLongNamed(groupIdParamName, element);
@@ -113,6 +117,10 @@ public class SavingsAccountAssembler {
if (group != null && client != null) { if (group != null && client != null) {
if (!group.hasClientAsMember(client)) { throw new ClientNotInGroupException(clientId, groupId); } if (!group.hasClientAsMember(client)) { throw new ClientNotInGroupException(clientId, groupId); }
accountType = AccountType.JLG; accountType = AccountType.JLG;
if (group.isNotActive()) {
if (group.isCenter()) { throw new CenterNotActiveException(groupId); }
throw new GroupNotActiveException(groupId);
}
} }
final Long fieldOfficerId = fromApiJsonHelper.extractLongNamed(fieldOfficerIdParamName, element); final Long fieldOfficerId = fromApiJsonHelper.extractLongNamed(fieldOfficerIdParamName, element);
@@ -20,4 +20,7 @@ public interface SavingsAccountRepository extends JpaRepository<SavingsAccount,
@Query("from SavingsAccount s_acc where s_acc.status = :status") @Query("from SavingsAccount s_acc where s_acc.status = :status")
List<SavingsAccount> findSavingAccountByStatus(@Param("status") Integer status); List<SavingsAccount> findSavingAccountByStatus(@Param("status") Integer status);
@Query("from SavingsAccount sa where sa.client.id = :clientId and sa.group.id = :groupId")
List<SavingsAccount> findByClientIdAndGroupId(@Param("clientId") Long clientId, @Param("groupId") Long groupId);
} }
@@ -28,6 +28,10 @@ import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext
import org.mifosplatform.organisation.monetary.domain.ApplicationCurrency; import org.mifosplatform.organisation.monetary.domain.ApplicationCurrency;
import org.mifosplatform.organisation.monetary.domain.ApplicationCurrencyRepositoryWrapper; import org.mifosplatform.organisation.monetary.domain.ApplicationCurrencyRepositoryWrapper;
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency; 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.domain.PaymentDetail;
import org.mifosplatform.portfolio.paymentdetail.service.PaymentDetailWritePlatformService; import org.mifosplatform.portfolio.paymentdetail.service.PaymentDetailWritePlatformService;
import org.mifosplatform.portfolio.savings.SavingsApiConstants; import org.mifosplatform.portfolio.savings.SavingsApiConstants;
@@ -89,6 +93,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
this.savingsAccountTransactionDataValidator.validateActivation(command); this.savingsAccountTransactionDataValidator.validateActivation(command);
final SavingsAccount account = this.savingAccountAssembler.assembleFrom(savingsId); final SavingsAccount account = this.savingAccountAssembler.assembleFrom(savingsId);
checkClientOrGroupActive(account);
final List<Long> existingTransactionIds = new ArrayList<Long>(); final List<Long> existingTransactionIds = new ArrayList<Long>();
final List<Long> existingReversedTransactionIds = new ArrayList<Long>(); final List<Long> existingReversedTransactionIds = new ArrayList<Long>();
@@ -120,6 +125,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
this.savingsAccountTransactionDataValidator.validate(command); this.savingsAccountTransactionDataValidator.validate(command);
final SavingsAccount account = this.savingAccountAssembler.assembleFrom(savingsId); final SavingsAccount account = this.savingAccountAssembler.assembleFrom(savingsId);
checkClientOrGroupActive(account);
final Locale locale = command.extractLocale(); final Locale locale = command.extractLocale();
final DateTimeFormatter fmt = DateTimeFormat.forPattern(command.dateFormat()).withLocale(locale); final DateTimeFormatter fmt = DateTimeFormat.forPattern(command.dateFormat()).withLocale(locale);
@@ -164,6 +170,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
PaymentDetail paymentDetail = paymentDetailWritePlatformService.createAndPersistPaymentDetail(command, changes); PaymentDetail paymentDetail = paymentDetailWritePlatformService.createAndPersistPaymentDetail(command, changes);
final SavingsAccount account = this.savingAccountAssembler.assembleFrom(savingsId); final SavingsAccount account = this.savingAccountAssembler.assembleFrom(savingsId);
checkClientOrGroupActive(account);
SavingsAccountTransaction withdrawal = this.savingsAccountDomainService.handleWithdrawal(account, fmt, transactionDate, SavingsAccountTransaction withdrawal = this.savingsAccountDomainService.handleWithdrawal(account, fmt, transactionDate,
transactionAmount, paymentDetail); transactionAmount, paymentDetail);
@@ -183,6 +190,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
public CommandProcessingResult applyAnnualFee(final Long savingsId, final LocalDate annualFeeTransactionDate) { public CommandProcessingResult applyAnnualFee(final Long savingsId, final LocalDate annualFeeTransactionDate) {
final SavingsAccount account = this.savingAccountAssembler.assembleFrom(savingsId); final SavingsAccount account = this.savingAccountAssembler.assembleFrom(savingsId);
checkClientOrGroupActive(account);
final DateTimeFormatter fmt = DateTimeFormat.forPattern("dd MM yyyy"); final DateTimeFormatter fmt = DateTimeFormat.forPattern("dd MM yyyy");
@@ -213,6 +221,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
public CommandProcessingResult calculateInterest(final Long savingsId) { public CommandProcessingResult calculateInterest(final Long savingsId) {
final SavingsAccount account = this.savingAccountAssembler.assembleFrom(savingsId); final SavingsAccount account = this.savingAccountAssembler.assembleFrom(savingsId);
checkClientOrGroupActive(account);
final LocalDate today = DateUtils.getLocalDateOfTenant(); final LocalDate today = DateUtils.getLocalDateOfTenant();
final MathContext mc = new MathContext(15, RoundingMode.HALF_EVEN); final MathContext mc = new MathContext(15, RoundingMode.HALF_EVEN);
@@ -235,6 +244,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
public CommandProcessingResult postInterest(final Long savingsId) { public CommandProcessingResult postInterest(final Long savingsId) {
final SavingsAccount account = this.savingAccountAssembler.assembleFrom(savingsId); final SavingsAccount account = this.savingAccountAssembler.assembleFrom(savingsId);
checkClientOrGroupActive(account);
postInterest(account); postInterest(account);
return new CommandProcessingResultBuilder() // return new CommandProcessingResultBuilder() //
.withEntityId(savingsId) // .withEntityId(savingsId) //
@@ -284,6 +294,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
final SavingsAccount account = this.savingAccountAssembler.assembleFrom(savingsId); final SavingsAccount account = this.savingAccountAssembler.assembleFrom(savingsId);
account.undoTransaction(transactionId, reversedTransactionIds); account.undoTransaction(transactionId, reversedTransactionIds);
checkClientOrGroupActive(account);
if ((savingsAccountTransaction.isDeposit() || savingsAccountTransaction.isWithdrawal()) if ((savingsAccountTransaction.isDeposit() || savingsAccountTransaction.isWithdrawal())
&& account.isBeforeLastPostingPeriod(savingsAccountTransaction.transactionLocalDate())) { && account.isBeforeLastPostingPeriod(savingsAccountTransaction.transactionLocalDate())) {
account.postInterest(mc, today, newTransactionIds, reversedTransactionIds); account.postInterest(mc, today, newTransactionIds, reversedTransactionIds);
@@ -367,4 +378,15 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
existingTransactionIds, existingReversedTransactionIds); existingTransactionIds, existingReversedTransactionIds);
journalEntryWritePlatformService.createJournalEntriesForSavings(accountingBridgeData); 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()); }
}
}
} }
@@ -32,8 +32,11 @@ import org.mifosplatform.portfolio.client.domain.AccountNumberGenerator;
import org.mifosplatform.portfolio.client.domain.AccountNumberGeneratorFactory; import org.mifosplatform.portfolio.client.domain.AccountNumberGeneratorFactory;
import org.mifosplatform.portfolio.client.domain.Client; import org.mifosplatform.portfolio.client.domain.Client;
import org.mifosplatform.portfolio.client.domain.ClientRepositoryWrapper; 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.Group;
import org.mifosplatform.portfolio.group.domain.GroupRepository; 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.group.exception.GroupNotFoundException;
import org.mifosplatform.portfolio.note.domain.Note; import org.mifosplatform.portfolio.note.domain.Note;
import org.mifosplatform.portfolio.note.domain.NoteRepository; import org.mifosplatform.portfolio.note.domain.NoteRepository;
@@ -170,7 +173,7 @@ public class SavingsApplicationProcessWritePlatformServiceJpaRepositoryImpl impl
final Map<String, Object> changes = new LinkedHashMap<String, Object>(20); final Map<String, Object> changes = new LinkedHashMap<String, Object>(20);
final SavingsAccount account = this.savingAccountAssembler.assembleFrom(savingsId); final SavingsAccount account = this.savingAccountAssembler.assembleFrom(savingsId);
checkClientOrGroupActive(account);
account.modifyApplication(command, changes); account.modifyApplication(command, changes);
account.validateNewApplicationState(DateUtils.getLocalDateOfTenant()); account.validateNewApplicationState(DateUtils.getLocalDateOfTenant());
@@ -180,6 +183,7 @@ public class SavingsApplicationProcessWritePlatformServiceJpaRepositoryImpl impl
final Long clientId = command.longValueOfParameterNamed(SavingsApiConstants.clientIdParamName); final Long clientId = command.longValueOfParameterNamed(SavingsApiConstants.clientIdParamName);
if (clientId != null) { if (clientId != null) {
final Client client = this.clientRepository.findOneWithNotFoundDetection(clientId); final Client client = this.clientRepository.findOneWithNotFoundDetection(clientId);
if (client.isNotActive()) { throw new ClientNotActiveException(clientId); }
account.update(client); account.update(client);
} else { } else {
final Client client = null; final Client client = null;
@@ -192,6 +196,10 @@ public class SavingsApplicationProcessWritePlatformServiceJpaRepositoryImpl impl
if (groupId != null) { if (groupId != null) {
final Group group = this.groupRepository.findOne(groupId); final Group group = this.groupRepository.findOne(groupId);
if (group == null) { throw new GroupNotFoundException(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); account.update(group);
} else { } else {
final Group group = null; final Group group = null;
@@ -241,6 +249,7 @@ public class SavingsApplicationProcessWritePlatformServiceJpaRepositoryImpl impl
public CommandProcessingResult deleteApplication(final Long savingsId) { public CommandProcessingResult deleteApplication(final Long savingsId) {
final SavingsAccount account = this.savingAccountAssembler.assembleFrom(savingsId); final SavingsAccount account = this.savingAccountAssembler.assembleFrom(savingsId);
checkClientOrGroupActive(account);
if (account.isNotSubmittedAndPendingApproval()) { if (account.isNotSubmittedAndPendingApproval()) {
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>(); final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
@@ -276,6 +285,7 @@ public class SavingsApplicationProcessWritePlatformServiceJpaRepositoryImpl impl
this.savingsAccountApplicationTransitionApiJsonValidator.validateApproval(command.json()); this.savingsAccountApplicationTransitionApiJsonValidator.validateApproval(command.json());
final SavingsAccount savingsAccount = this.savingAccountAssembler.assembleFrom(savingsId); final SavingsAccount savingsAccount = this.savingAccountAssembler.assembleFrom(savingsId);
checkClientOrGroupActive(savingsAccount);
final Map<String, Object> changes = savingsAccount.approveApplication(currentUser, command, DateUtils.getLocalDateOfTenant()); final Map<String, Object> changes = savingsAccount.approveApplication(currentUser, command, DateUtils.getLocalDateOfTenant());
if (!changes.isEmpty()) { if (!changes.isEmpty()) {
@@ -309,6 +319,7 @@ public class SavingsApplicationProcessWritePlatformServiceJpaRepositoryImpl impl
this.savingsAccountApplicationTransitionApiJsonValidator.validateForUndo(command.json()); this.savingsAccountApplicationTransitionApiJsonValidator.validateForUndo(command.json());
final SavingsAccount savingsAccount = this.savingAccountAssembler.assembleFrom(savingsId); final SavingsAccount savingsAccount = this.savingAccountAssembler.assembleFrom(savingsId);
checkClientOrGroupActive(savingsAccount);
final Map<String, Object> changes = savingsAccount.undoApplicationApproval(); final Map<String, Object> changes = savingsAccount.undoApplicationApproval();
if (!changes.isEmpty()) { if (!changes.isEmpty()) {
@@ -342,6 +353,7 @@ public class SavingsApplicationProcessWritePlatformServiceJpaRepositoryImpl impl
this.savingsAccountApplicationTransitionApiJsonValidator.validateRejection(command.json()); this.savingsAccountApplicationTransitionApiJsonValidator.validateRejection(command.json());
final SavingsAccount savingsAccount = this.savingAccountAssembler.assembleFrom(savingsId); final SavingsAccount savingsAccount = this.savingAccountAssembler.assembleFrom(savingsId);
checkClientOrGroupActive(savingsAccount);
final Map<String, Object> changes = savingsAccount.rejectApplication(currentUser, command, DateUtils.getLocalDateOfTenant()); final Map<String, Object> changes = savingsAccount.rejectApplication(currentUser, command, DateUtils.getLocalDateOfTenant());
if (!changes.isEmpty()) { if (!changes.isEmpty()) {
@@ -374,6 +386,7 @@ public class SavingsApplicationProcessWritePlatformServiceJpaRepositoryImpl impl
this.savingsAccountApplicationTransitionApiJsonValidator.validateApplicantWithdrawal(command.json()); this.savingsAccountApplicationTransitionApiJsonValidator.validateApplicantWithdrawal(command.json());
final SavingsAccount savingsAccount = this.savingAccountAssembler.assembleFrom(savingsId); final SavingsAccount savingsAccount = this.savingAccountAssembler.assembleFrom(savingsId);
checkClientOrGroupActive(savingsAccount);
final Map<String, Object> changes = savingsAccount.applicantWithdrawsFromApplication(currentUser, command, final Map<String, Object> changes = savingsAccount.applicantWithdrawsFromApplication(currentUser, command,
DateUtils.getLocalDateOfTenant()); DateUtils.getLocalDateOfTenant());
@@ -409,4 +422,18 @@ public class SavingsApplicationProcessWritePlatformServiceJpaRepositoryImpl impl
existingTransactionIds, existingReversedTransactionIds); existingTransactionIds, existingReversedTransactionIds);
journalEntryWritePlatformService.createJournalEntriesForSavings(accountingBridgeData); 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());
}
}
}
} }