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.setDataSource(tenant.databaseURL(), tenant.getSchemaUsername(), tenant.getSchemaPassword());
flyway.setLocations("sql");
flyway.setOutOfOrder(true);
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){
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) {
@@ -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() {
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, ");
@@ -276,7 +276,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");
@@ -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<SavingsAccount> 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);
}
}
@@ -381,4 +381,7 @@ public final class Group extends AbstractPersistable<Long> {
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) {
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;
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);
}
}
@@ -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.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) {
@@ -519,6 +523,7 @@ public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements Group
// check if any client has got group loans
validateForJLGLoan(groupForUpdate.getId(), clientMembers);
validateForJLGSavings(groupForUpdate.getId(), clientMembers);
final Map<String, Object> actualChanges = new HashMap<String, Object>();
final List<String> changes = groupForUpdate.disassociateClients(clientMembers);
@@ -544,7 +549,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<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,
final boolean isHolidayEnabled, final List<Holiday> holidays, final WorkingDays workingDays) {
//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;
for (final 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);
@@ -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) {
// first repayment's from date is same as disbursement date.
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.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;
@@ -218,6 +224,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); }
@@ -237,10 +244,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);
@@ -397,6 +414,7 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
context.authenticatedUser();
final Loan loan = retrieveLoanBy(loanId);
checkClientOrGroupActive(loan);
if (loan.isNotSubmittedAndPendingApproval()) { throw new LoanApplicationNotInSubmittedAndPendingApprovalStateCannotBeDeleted(loanId); }
@@ -423,6 +441,7 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
this.loanApplicationTransitionApiJsonValidator.validateApproval(command.json());
final Loan loan = retrieveLoanBy(loanId);
checkClientOrGroupActive(loan);
final Map<String, Object> changes = loan.loanApplicationApproval(currentUser, command, defaultLoanLifecycleStateMachine());
if (!changes.isEmpty()) {
@@ -456,6 +475,7 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
this.fromApiJsonDeserializer.validateForUndo(command.json());
final Loan loan = retrieveLoanBy(loanId);
checkClientOrGroupActive(loan);
final Map<String, Object> changes = loan.undoApproval(defaultLoanLifecycleStateMachine());
if (!changes.isEmpty()) {
@@ -488,6 +508,7 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
this.loanApplicationTransitionApiJsonValidator.validateRejection(command.json());
final Loan loan = retrieveLoanBy(loanId);
checkClientOrGroupActive(loan);
final Map<String, Object> changes = loan.loanApplicationRejection(currentUser, command, defaultLoanLifecycleStateMachine());
if (!changes.isEmpty()) {
@@ -520,6 +541,7 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
this.loanApplicationTransitionApiJsonValidator.validateApplicantWithdrawal(command.json());
final Loan loan = retrieveLoanBy(loanId);
checkClientOrGroupActive(loan);
final Map<String, Object> changes = loan.loanApplicationWithdrawnByApplicant(currentUser, command,
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.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;
@@ -35,6 +36,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);
@@ -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.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<Long> existingTransactionIds = 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,
final BigDecimal transactionAmount, final LocalDate transactionDate, final String noteText, final String txnExternalId) {
final Loan loan = retrieveLoanBy(loanId);
checkClientOrGroupActive(loan);
// TODO: Is it required to validate transaction date with meeting dates
// if repayments is synced with meeting?
@@ -473,6 +481,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); }
@@ -574,6 +583,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
final BigDecimal transactionAmount = command.bigDecimalValueOfParameterNamed("transactionAmount");
final Loan loan = retrieveLoanBy(loanId);
checkClientOrGroupActive(loan);
final List<Long> existingTransactionIds = new ArrayList<Long>();
final List<Long> existingReversedTransactionIds = new ArrayList<Long>();
@@ -634,6 +644,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
changes.put("dateFormat", command.dateFormat());
final Loan loan = retrieveLoanBy(loanId);
checkClientOrGroupActive(loan);
removeLoanCycle(loan);
final List<Long> existingTransactionIds = new ArrayList<Long>();
@@ -673,6 +684,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
this.loanEventApiJsonValidator.validateTransactionWithNoAmount(command.json());
final Loan loan = retrieveLoanBy(loanId);
checkClientOrGroupActive(loan);
final Map<String, Object> changes = new LinkedHashMap<String, Object>();
changes.put("transactionDate", command.stringValueOfParameterNamed("transactionDate"));
@@ -735,6 +747,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
this.loanEventApiJsonValidator.validateTransactionWithNoAmount(command.json());
final Loan loan = retrieveLoanBy(loanId);
checkClientOrGroupActive(loan);
removeLoanCycle(loan);
final Map<String, Object> changes = new LinkedHashMap<String, Object>();
@@ -773,6 +786,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);
@@ -833,6 +847,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
@@ -862,6 +877,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
@@ -906,6 +922,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
@@ -957,6 +974,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); }
@@ -992,6 +1010,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); }
@@ -1019,6 +1038,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); }
@@ -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();
}
public boolean isApproved() {
return SavingsAccountStatusType.fromInt(this.status).isApproved();
}
public void postInterest(final MathContext mc, final LocalDate interestPostingUpToDate, final List<Long> existingTransactionIds,
final List<Long> existingReversedTransactionIds) {
@@ -1677,4 +1681,8 @@ public class SavingsAccount extends AbstractPersistable<Long> {
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.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.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.SavingsInterestCalculationDaysInYearType;
import org.mifosplatform.portfolio.savings.SavingsInterestCalculationType;
@@ -102,6 +105,7 @@ public class SavingsAccountAssembler {
if (clientId != null) {
client = this.clientRepository.findOneWithNotFoundDetection(clientId);
accountType = AccountType.INDIVIDUAL;
if (client.isNotActive()) { throw new ClientNotActiveException(clientId); }
}
final Long groupId = fromApiJsonHelper.extractLongNamed(groupIdParamName, element);
@@ -113,6 +117,10 @@ public class SavingsAccountAssembler {
if (group != null && client != null) {
if (!group.hasClientAsMember(client)) { throw new ClientNotInGroupException(clientId, groupId); }
accountType = AccountType.JLG;
if (group.isNotActive()) {
if (group.isCenter()) { throw new CenterNotActiveException(groupId); }
throw new GroupNotActiveException(groupId);
}
}
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")
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.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.SavingsApiConstants;
@@ -89,6 +93,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
this.savingsAccountTransactionDataValidator.validateActivation(command);
final SavingsAccount account = this.savingAccountAssembler.assembleFrom(savingsId);
checkClientOrGroupActive(account);
final List<Long> existingTransactionIds = new ArrayList<Long>();
final List<Long> existingReversedTransactionIds = new ArrayList<Long>();
@@ -120,6 +125,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
PaymentDetail paymentDetail = paymentDetailWritePlatformService.createAndPersistPaymentDetail(command, changes);
final SavingsAccount account = this.savingAccountAssembler.assembleFrom(savingsId);
checkClientOrGroupActive(account);
SavingsAccountTransaction withdrawal = this.savingsAccountDomainService.handleWithdrawal(account, fmt, transactionDate,
transactionAmount, paymentDetail);
@@ -183,6 +190,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");
@@ -213,6 +221,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);
@@ -235,6 +244,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
public CommandProcessingResult postInterest(final Long savingsId) {
final SavingsAccount account = this.savingAccountAssembler.assembleFrom(savingsId);
checkClientOrGroupActive(account);
postInterest(account);
return new CommandProcessingResultBuilder() //
.withEntityId(savingsId) //
@@ -284,6 +294,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
final SavingsAccount account = this.savingAccountAssembler.assembleFrom(savingsId);
account.undoTransaction(transactionId, reversedTransactionIds);
checkClientOrGroupActive(account);
if ((savingsAccountTransaction.isDeposit() || savingsAccountTransaction.isWithdrawal())
&& account.isBeforeLastPostingPeriod(savingsAccountTransaction.transactionLocalDate())) {
account.postInterest(mc, today, newTransactionIds, reversedTransactionIds);
@@ -367,4 +378,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()); }
}
}
}
@@ -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<String, Object> changes = new LinkedHashMap<String, Object>(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<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
@@ -276,6 +285,7 @@ public class SavingsApplicationProcessWritePlatformServiceJpaRepositoryImpl impl
this.savingsAccountApplicationTransitionApiJsonValidator.validateApproval(command.json());
final SavingsAccount savingsAccount = this.savingAccountAssembler.assembleFrom(savingsId);
checkClientOrGroupActive(savingsAccount);
final Map<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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());
}
}
}
}