Merge branch 'develop'

This commit is contained in:
Adi Narayana Raju
2015-12-02 16:24:53 +05:30
50 changed files with 2947 additions and 353 deletions
+31
View File
@@ -6,6 +6,7 @@ See VERSIONING (https://github.com/openMF/mifosx/blob/master/VERSIONING.md) for
Releases
===============
1. 02 Dec 2015 - 15.12.1.RELEASE
1. 18 Nov 2015 - 15.11.2.RELEASE
1. 04 Nov 2015 - 15.11.1.RELEASE
1. 21 Oct 2015 - 15.10.2.RELEASE
@@ -80,6 +81,36 @@ Releases
1. 05 April 2013 - 0.11.1.beta
1. 05 April 2013 - 0.11.0.beta
15.12.1.RELEASE
=============
This release includes first part of Social Performance Management Framework.
This release also includes few bug fixes as mentioned below.
Platform & API
New Features & Improvements
Following stories of Social Performance Management Framework Epic
- [MIFOSX-1961] - Create new survey
- [MIFOSX-1962] - Add general information
- [MIFOSX-1963] - Add questions to a survey
- [MIFOSX-1964] - Add look-up tables
- [MIFOSX-1965] - Assign default look-up table
Bugs
- [MIFOSX-2184] - As a user I want my penalties only to apply to new loans that go overdue
- [MIFOSX-2313] - Loan provisioning entries not getting created for multi tranche loans if first tranche disbursement date is back dated
- [MIFOSX-2322] - Template-User defined report is not working as expected
- [MIFOSX-2348] - incorrect error Insufficient account balance due to guarantors funds onhold
- [MIFOSX-2363] - Repayment schedule generated after early repayment with interest recalculation is not proper
- [MIFOSX-2368] - For the Multi tranche Loans with Equal Principal payments, last installment is not calculating properly
Community-App
Bugs
- [MIFOSX-2058] - Opening Screen for Non-Admin Users
- [MIFOSX-2327] - Does not come back to group, when cancel transfer clients
- [MIFOSX-2362] - Not able to save modify loan aplication after undo disburse and undo approval
15.11.2.RELEASE
=============
This release introduces floating rates feature.
+643 -170
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -1,3 +1,3 @@
releaseVersion=15.11.2.RELEASE
releaseVersion=15.12.1.RELEASE
@@ -68,8 +68,8 @@ public class ProvisioningEntriesReadPlatformServiceImpl implements ProvisioningE
.append("GREATEST(datediff(").append(formattedDate).append(",sch.duedate),0) <= pcd.max_age) and ")
.append("pcd.criteria_id is not null ").append("LEFT JOIN m_client mclient ON mclient.id = loan.client_id ")
.append("LEFT JOIN m_group mgroup ON mgroup.id = loan.group_id ")
.append("where loan.loan_status_id=300 and sch.completed_derived=false ")
.append("GROUP BY loan.id order by loan.product_id");
.append("where loan.loan_status_id=300 and sch.duedate = ")
.append("(select MIN(sch1.duedate) from m_loan_repayment_schedule sch1 where sch1.loan_id=loan.id and sch1.completed_derived=false)");
}
@Override
@@ -49,4 +49,5 @@ public interface ConfigurationDomainService {
int getRoundingMode();
boolean isBackdatePenaltiesEnabled();
}
@@ -187,10 +187,18 @@ public class ConfigurationDomainServiceJpa implements ConfigurationDomainService
final GlobalConfigurationProperty property = this.globalConfigurationRepository.findOneByNameWithNotFoundDetection(propertyName);
if (property.isEnabled()) {
int value = property.getValue().intValue();
if (value < 0 || value > 6) { return defaultValue; }
if (value < 0 || value > 6) {
return defaultValue;
}
return value;
}
return defaultValue;
}
public boolean isBackdatePenaltiesEnabled() {
final String propertyName = "backdate-penalties-enabled";
final GlobalConfigurationProperty property = this.globalConfigurationRepository.findOneByNameWithNotFoundDetection(propertyName);
return property.isEnabled();
}
}
@@ -45,6 +45,7 @@ import org.mifosplatform.portfolio.loanaccount.loanschedule.exception.MultiDisbu
import org.mifosplatform.portfolio.loanaccount.rescheduleloan.domain.LoanRescheduleModel;
import org.mifosplatform.portfolio.loanaccount.rescheduleloan.domain.LoanRescheduleModelRepaymentPeriod;
import org.mifosplatform.portfolio.loanaccount.rescheduleloan.domain.LoanRescheduleRequest;
import org.mifosplatform.portfolio.loanproduct.domain.AmortizationMethod;
import org.mifosplatform.portfolio.loanproduct.domain.LoanProductMinimumRepaymentScheduleRelatedDetail;
/**
@@ -124,6 +125,11 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
// actual outstanding balance for interest calculation
Money outstandingBalance = principalToBeScheduled;
//Set Fixed Principal Amount
if(loanApplicationTerms.getAmortizationMethod().equals(AmortizationMethod.EQUAL_PRINCIPAL)) {
loanApplicationTerms.updateFixedPrincipalAmount(mc, periodNumber, outstandingBalance) ;
}
// Set fixed EMI Amount
if (loanApplicationTerms.getFixedEmiAmount() == null) {
updateFixedInstallmentAmount(mc, loanApplicationTerms, actualRepaymentDate, periodNumber, outstandingBalance, holidayDetailDTO);
@@ -221,6 +227,7 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
loanApplicationTerms.updateAnnualNominalInterestRate(variation.getTermValue());
}
}
isFirstRepayment = false;
}
while (!outstandingBalance.isZero() || !disburseDetailMap.isEmpty()) {
@@ -76,7 +76,7 @@ public interface LoanReadPlatformService {
* result overdue installments with this charge already applied are not
* returned.
*/
Collection<OverdueLoanScheduleData> retrieveAllLoansWithOverdueInstallments(final Long penaltyWaitPeriod);
Collection<OverdueLoanScheduleData> retrieveAllLoansWithOverdueInstallments(final Long penaltyWaitPeriod, final Boolean backdatePenalties);
Integer retriveLoanCounter(Long groupId, Integer loanType, Long productId);
@@ -17,8 +17,11 @@ import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.joda.time.Days;
import org.joda.time.LocalDate;
import org.joda.time.format.DateTimeFormat;
@@ -1465,12 +1468,31 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
}
@Override
public Collection<OverdueLoanScheduleData> retrieveAllLoansWithOverdueInstallments(final Long penaltyWaitPeriod) {
public Collection<OverdueLoanScheduleData> retrieveAllLoansWithOverdueInstallments(final Long penaltyWaitPeriod, final Boolean backdatePenalties) {
final MusoniOverdueLoanScheduleMapper rm = new MusoniOverdueLoanScheduleMapper();
final String sql = "select " + rm.schema() + " where DATE_SUB(CURDATE(),INTERVAL ? DAY) > ls.duedate "
+ " and ls.completed_derived <> 1 and mc.charge_applies_to_enum =1 "
+ " and mc.charge_time_enum = 9 and ml.loan_status_id = 300 ";
return this.jdbcTemplate.query(sql, rm, new Object[] { penaltyWaitPeriod });
final StringBuilder sqlBuilder = new StringBuilder(400);
sqlBuilder
.append("select ")
.append(rm.schema())
.append(" where DATE_SUB(CURDATE(),INTERVAL ? DAY) > ls.duedate ")
.append( " and ls.completed_derived <> 1 and mc.charge_applies_to_enum =1 ")
.append(" and mc.charge_time_enum = 9 and ml.loan_status_id = 300 ");
if(backdatePenalties)
{
return this.jdbcTemplate.query(sqlBuilder.toString(), rm, new Object[] { penaltyWaitPeriod });
}
else
{
// Only apply for duedate = yesterday (so that we don't apply penalties on the duedate itself)
sqlBuilder.append(" and ls.duedate >= DATE_SUB(CURDATE(),INTERVAL (? + 1) DAY)");
return this.jdbcTemplate.query(sqlBuilder.toString(), rm, new Object[] { penaltyWaitPeriod, penaltyWaitPeriod });
}
}
@SuppressWarnings("deprecation")
@@ -49,8 +49,9 @@ public class LoanSchedularServiceImpl implements LoanSchedularService {
public void applyChargeForOverdueLoans() throws JobExecutionException {
final Long penaltyWaitPeriodValue = this.configurationDomainService.retrievePenaltyWaitPeriod();
final Boolean backdatePenalties = this.configurationDomainService.isBackdatePenaltiesEnabled();
final Collection<OverdueLoanScheduleData> overdueLoanScheduledInstallments = this.loanReadPlatformService
.retrieveAllLoansWithOverdueInstallments(penaltyWaitPeriodValue);
.retrieveAllLoansWithOverdueInstallments(penaltyWaitPeriodValue,backdatePenalties);
if (!overdueLoanScheduledInstallments.isEmpty()) {
final StringBuilder sb = new StringBuilder();
@@ -2441,7 +2441,6 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
}
}
@Override
@Transactional
public void applyOverdueChargesForLoan(final Long loanId, Collection<OverdueLoanScheduleData> overdueLoanScheduleDatas) {
@@ -5,8 +5,12 @@
*/
package org.mifosplatform.portfolio.savings.domain;
import java.math.BigDecimal;
import java.util.Date;
import org.joda.time.LocalDate;
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
import org.mifosplatform.organisation.monetary.domain.Money;
import org.mifosplatform.portfolio.loanaccount.guarantor.domain.GuarantorFundingTransaction;
import org.mifosplatform.portfolio.savings.DepositAccountOnHoldTransactionType;
import org.springframework.data.jpa.domain.AbstractPersistable;
import javax.persistence.CascadeType;
import javax.persistence.Column;
@@ -17,11 +21,8 @@ import javax.persistence.OneToOne;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import org.joda.time.LocalDate;
import org.mifosplatform.portfolio.loanaccount.guarantor.domain.GuarantorFundingTransaction;
import org.mifosplatform.portfolio.savings.DepositAccountOnHoldTransactionType;
import org.springframework.data.jpa.domain.AbstractPersistable;
import java.math.BigDecimal;
import java.util.Date;
@Entity
@Table(name = "m_deposit_account_on_hold_transaction")
@@ -81,6 +82,10 @@ public class DepositAccountOnHoldTransaction extends AbstractPersistable<Long> {
return this.amount;
}
public Money getAmountMoney(final MonetaryCurrency currency) {
return Money.of(currency, this.amount);
}
public void reverseTransaction() {
this.reversed = true;
if (this.getTransactionType().isHold()) {
@@ -92,7 +97,14 @@ public class DepositAccountOnHoldTransaction extends AbstractPersistable<Long> {
public DepositAccountOnHoldTransactionType getTransactionType() {
return DepositAccountOnHoldTransactionType.fromInt(this.transactionType);
}
public LocalDate getTransactionDate() {
LocalDate transactionDate = null;
if(this.transactionDate !=null){
transactionDate = LocalDate.fromDateFields(this.transactionDate);
}
return transactionDate;
}
}
@@ -8,7 +8,10 @@ package org.mifosplatform.portfolio.savings.domain;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import java.util.List;
public interface DepositAccountOnHoldTransactionRepository extends JpaRepository<DepositAccountOnHoldTransaction, Long>,
JpaSpecificationExecutor<DepositAccountOnHoldTransaction> {
List<DepositAccountOnHoldTransaction> findBySavingsAccountAndReversedFalseOrderByCreatedDateAsc(SavingsAccount account);
}
@@ -5,52 +5,7 @@
*/
package org.mifosplatform.portfolio.savings.domain;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.SAVINGS_ACCOUNT_RESOURCE_NAME;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.allowOverdraftParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.dueAsOfDateParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.enforceMinRequiredBalanceParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.localeParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.lockinPeriodFrequencyParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.lockinPeriodFrequencyTypeParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.minRequiredBalanceParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.overdraftLimitParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.withdrawalFeeForTransfersParamName;
import java.math.BigDecimal;
import java.math.MathContext;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorType;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OrderBy;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;
import javax.persistence.UniqueConstraint;
import javax.persistence.Version;
import com.google.gson.JsonArray;
import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang.StringUtils;
import org.hibernate.annotations.LazyCollection;
@@ -96,7 +51,50 @@ import org.mifosplatform.useradministration.domain.AppUser;
import org.springframework.data.jpa.domain.AbstractPersistable;
import org.springframework.util.CollectionUtils;
import com.google.gson.JsonArray;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorType;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OrderBy;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;
import javax.persistence.UniqueConstraint;
import javax.persistence.Version;
import java.math.BigDecimal;
import java.math.MathContext;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.SAVINGS_ACCOUNT_RESOURCE_NAME;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.allowOverdraftParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.dueAsOfDateParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.enforceMinRequiredBalanceParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.localeParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.lockinPeriodFrequencyParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.lockinPeriodFrequencyTypeParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.minRequiredBalanceParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.overdraftLimitParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.withdrawalFeeForTransfersParamName;
@Entity
@Table(name = "m_savings_account", uniqueConstraints = { @UniqueConstraint(columnNames = { "account_no" }, name = "sa_account_no_UNIQUE"),
@@ -859,10 +857,11 @@ public class SavingsAccount extends AbstractPersistable<Long> {
return transactionBeforeLastInterestPosting;
}
public void validateAccountBalanceDoesNotBecomeNegative(final BigDecimal transactionAmount, final boolean isException) {
public void validateAccountBalanceDoesNotBecomeNegative(final BigDecimal transactionAmount, final boolean isException,final List<DepositAccountOnHoldTransaction> depositAccountOnHoldTransactions) {
final List<SavingsAccountTransaction> transactionsSortedByDate = retreiveListOfTransactions();
Money runningBalance = Money.zero(this.currency);
Money minRequiredBalance = minRequiredBalanceDerived(getCurrency());
LocalDate lastSavingsDate = null;
for (final SavingsAccountTransaction transaction : transactionsSortedByDate) {
if (transaction.isNotReversed() && transaction.isCredit()) {
runningBalance = runningBalance.plus(transaction.getAmount(this.currency));
@@ -872,22 +871,44 @@ public class SavingsAccount extends AbstractPersistable<Long> {
continue;
}
final BigDecimal withdrawalFee = null;
/* Loop through the onHold funds and see if we need to deduct or add to minimum required balance
and the point in time the transaction was made: */
if(depositAccountOnHoldTransactions !=null){
for(final DepositAccountOnHoldTransaction onHoldTransaction: depositAccountOnHoldTransactions) {
// Compare the balance of the on hold:
if((onHoldTransaction.getTransactionDate().isBefore(transaction.transactionLocalDate()) || onHoldTransaction.getTransactionDate().isEqual(transaction.transactionLocalDate()))
&& (lastSavingsDate == null || onHoldTransaction.getTransactionDate().isAfter(lastSavingsDate))) {
if(onHoldTransaction.getTransactionType().isHold()) {
minRequiredBalance = minRequiredBalance.plus(onHoldTransaction.getAmountMoney(this.currency));
}else{
minRequiredBalance = minRequiredBalance.minus(onHoldTransaction.getAmountMoney(this.currency));
}
}
}
}
// deal with potential minRequiredBalance and
// enforceMinRequiredBalance
if (!isException && transaction.canProcessBalanceCheck()) {
if (runningBalance.minus(minRequiredBalance).isLessThanZero()) { throw new InsufficientAccountBalanceException(
"transactionAmount", getAccountBalance(), withdrawalFee, transactionAmount); }
}
lastSavingsDate = transaction.transactionLocalDate();
}
}
public void validateAccountBalanceDoesNotBecomeNegative(final String transactionAction) {
public void validateAccountBalanceDoesNotBecomeNegative(final String transactionAction,final List<DepositAccountOnHoldTransaction> depositAccountOnHoldTransactions) {
final List<SavingsAccountTransaction> transactionsSortedByDate = retreiveListOfTransactions();
Money runningBalance = Money.zero(this.currency);
Money minRequiredBalance = minRequiredBalanceDerived(getCurrency());
LocalDate lastSavingsDate = null;
for (final SavingsAccountTransaction transaction : transactionsSortedByDate) {
if (transaction.isNotReversed() && transaction.isCredit()) {
runningBalance = runningBalance.plus(transaction.getAmount(this.currency));
@@ -895,6 +916,22 @@ public class SavingsAccount extends AbstractPersistable<Long> {
runningBalance = runningBalance.minus(transaction.getAmount(this.currency));
}
/* Loop through the onHold funds and see if we need to deduct or add to minimum required balance
and the point in time the transaction was made: */
if(depositAccountOnHoldTransactions !=null){
for(final DepositAccountOnHoldTransaction onHoldTransaction: depositAccountOnHoldTransactions) {
// Compare the balance of the on hold:
if((onHoldTransaction.getTransactionDate().isBefore(transaction.transactionLocalDate()) || onHoldTransaction.getTransactionDate().isEqual(transaction.transactionLocalDate()))
&& (lastSavingsDate == null || onHoldTransaction.getTransactionDate().isAfter(lastSavingsDate))) {
if(onHoldTransaction.getTransactionType().isHold()) {
minRequiredBalance = minRequiredBalance.plus(onHoldTransaction.getAmountMoney(this.currency));
}else{
minRequiredBalance = minRequiredBalance.minus(onHoldTransaction.getAmountMoney(this.currency));
}
}
}
}
// enforceMinRequiredBalance
if (transaction.canProcessBalanceCheck()) {
if (runningBalance.minus(minRequiredBalance).isLessThanZero()) {
@@ -910,6 +947,8 @@ public class SavingsAccount extends AbstractPersistable<Long> {
}
}
lastSavingsDate = transaction.transactionLocalDate();
}
}
@@ -2454,7 +2493,7 @@ public class SavingsAccount extends AbstractPersistable<Long> {
}
private Money minRequiredBalanceDerived(final MonetaryCurrency currency) {
Money minReqBalance = Money.of(currency, this.onHoldFunds);
Money minReqBalance = Money.zero(currency);
if (this.enforceMinRequiredBalance) {
minReqBalance = minReqBalance.plus(this.minRequiredBalance);
}
@@ -2477,6 +2516,6 @@ public class SavingsAccount extends AbstractPersistable<Long> {
}
public BigDecimal getWithdrawableBalance() {
return getAccountBalance().subtract(minRequiredBalanceDerived(getCurrency()).getAmount());
return getAccountBalance().subtract(minRequiredBalanceDerived(getCurrency()).getAmount()).subtract(this.getOnHoldFunds());
}
}
@@ -5,13 +5,6 @@
*/
package org.mifosplatform.portfolio.savings.domain;
import java.math.BigDecimal;
import java.math.MathContext;
import java.util.Date;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.joda.time.LocalDate;
import org.joda.time.format.DateTimeFormatter;
import org.mifosplatform.accounting.journalentry.service.JournalEntryWritePlatformService;
@@ -30,6 +23,14 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.math.MathContext;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
@Service
public class SavingsAccountDomainServiceJpa implements SavingsAccountDomainService {
@@ -39,19 +40,22 @@ public class SavingsAccountDomainServiceJpa implements SavingsAccountDomainServi
private final ApplicationCurrencyRepositoryWrapper applicationCurrencyRepositoryWrapper;
private final JournalEntryWritePlatformService journalEntryWritePlatformService;
private final ConfigurationDomainService configurationDomainService;
private final DepositAccountOnHoldTransactionRepository depositAccountOnHoldTransactionRepository;
@Autowired
public SavingsAccountDomainServiceJpa(final SavingsAccountRepositoryWrapper savingsAccountRepository,
final SavingsAccountTransactionRepository savingsAccountTransactionRepository,
final ApplicationCurrencyRepositoryWrapper applicationCurrencyRepositoryWrapper,
final JournalEntryWritePlatformService journalEntryWritePlatformService,
final ConfigurationDomainService configurationDomainService, final PlatformSecurityContext context) {
final ConfigurationDomainService configurationDomainService, final PlatformSecurityContext context,
final DepositAccountOnHoldTransactionRepository depositAccountOnHoldTransactionRepository) {
this.savingsAccountRepository = savingsAccountRepository;
this.savingsAccountTransactionRepository = savingsAccountTransactionRepository;
this.applicationCurrencyRepositoryWrapper = applicationCurrencyRepositoryWrapper;
this.journalEntryWritePlatformService = journalEntryWritePlatformService;
this.configurationDomainService = configurationDomainService;
this.context = context;
this.depositAccountOnHoldTransactionRepository = depositAccountOnHoldTransactionRepository;
}
@Transactional
@@ -84,7 +88,11 @@ public class SavingsAccountDomainServiceJpa implements SavingsAccountDomainServi
account.calculateInterestUsing(mc, today, transactionBooleanValues.isInterestTransfer(),
isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth);
}
account.validateAccountBalanceDoesNotBecomeNegative(transactionAmount, transactionBooleanValues.isExceptionForBalanceCheck());
List<DepositAccountOnHoldTransaction> depositAccountOnHoldTransactions = null;
if(account.getOnHoldFunds().compareTo(BigDecimal.ZERO) == 1){
depositAccountOnHoldTransactions = this.depositAccountOnHoldTransactionRepository.findBySavingsAccountAndReversedFalseOrderByCreatedDateAsc(account);
}
account.validateAccountBalanceDoesNotBecomeNegative(transactionAmount, transactionBooleanValues.isExceptionForBalanceCheck(), depositAccountOnHoldTransactions);
saveTransactionToGenerateTransactionId(withdrawal);
this.savingsAccountRepository.save(account);
@@ -5,24 +5,6 @@
*/
package org.mifosplatform.portfolio.savings.service;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.RECURRING_DEPOSIT_ACCOUNT_RESOURCE_NAME;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.SAVINGS_ACCOUNT_RESOURCE_NAME;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.amountParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.chargeIdParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.dueAsOfDateParamName;
import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import org.apache.commons.lang.StringUtils;
import org.joda.time.LocalDate;
import org.joda.time.format.DateTimeFormat;
@@ -42,7 +24,6 @@ import org.mifosplatform.infrastructure.jobs.exception.JobExecutionException;
import org.mifosplatform.infrastructure.jobs.service.JobName;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.organisation.holiday.domain.HolidayRepositoryWrapper;
import org.mifosplatform.organisation.holiday.service.HolidayWritePlatformService;
import org.mifosplatform.organisation.monetary.domain.ApplicationCurrency;
import org.mifosplatform.organisation.monetary.domain.ApplicationCurrencyRepositoryWrapper;
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
@@ -51,7 +32,6 @@ import org.mifosplatform.organisation.monetary.domain.MoneyHelper;
import org.mifosplatform.organisation.office.domain.Office;
import org.mifosplatform.organisation.staff.domain.Staff;
import org.mifosplatform.organisation.workingdays.domain.WorkingDaysRepositoryWrapper;
import org.mifosplatform.organisation.workingdays.service.WorkingDaysWritePlatformService;
import org.mifosplatform.portfolio.account.PortfolioAccountType;
import org.mifosplatform.portfolio.account.data.AccountTransferDTO;
import org.mifosplatform.portfolio.account.data.PortfolioAccountData;
@@ -86,6 +66,8 @@ import org.mifosplatform.portfolio.savings.data.SavingsAccountChargeDataValidato
import org.mifosplatform.portfolio.savings.data.SavingsAccountTransactionDTO;
import org.mifosplatform.portfolio.savings.domain.DepositAccountAssembler;
import org.mifosplatform.portfolio.savings.domain.DepositAccountDomainService;
import org.mifosplatform.portfolio.savings.domain.DepositAccountOnHoldTransaction;
import org.mifosplatform.portfolio.savings.domain.DepositAccountOnHoldTransactionRepository;
import org.mifosplatform.portfolio.savings.domain.DepositAccountRecurringDetail;
import org.mifosplatform.portfolio.savings.domain.FixedDepositAccount;
import org.mifosplatform.portfolio.savings.domain.RecurringDepositAccount;
@@ -105,6 +87,23 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.math.MathContext;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.RECURRING_DEPOSIT_ACCOUNT_RESOURCE_NAME;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.SAVINGS_ACCOUNT_RESOURCE_NAME;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.amountParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.chargeIdParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.dueAsOfDateParamName;
@Service
public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements DepositAccountWritePlatformService {
@@ -129,6 +128,8 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
private final ConfigurationDomainService configurationDomainService;
private final HolidayRepositoryWrapper holidayRepository;
private final WorkingDaysRepositoryWrapper workingDaysRepository;
private final DepositAccountOnHoldTransactionRepository depositAccountOnHoldTransactionRepository;
@Autowired
public DepositAccountWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context,
@@ -147,7 +148,8 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
final AccountAssociationsReadPlatformService accountAssociationsReadPlatformService,
final AccountTransfersWritePlatformService accountTransfersWritePlatformService,
final DepositAccountReadPlatformService depositAccountReadPlatformService,
final CalendarInstanceRepository calendarInstanceRepository, final ConfigurationDomainService configurationDomainService) {
final CalendarInstanceRepository calendarInstanceRepository, final ConfigurationDomainService configurationDomainService,
final DepositAccountOnHoldTransactionRepository depositAccountOnHoldTransactionRepository) {
this.context = context;
this.savingAccountRepository = savingAccountRepository;
@@ -170,6 +172,7 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
this.depositAccountReadPlatformService = depositAccountReadPlatformService;
this.calendarInstanceRepository = calendarInstanceRepository;
this.configurationDomainService = configurationDomainService;
this.depositAccountOnHoldTransactionRepository =depositAccountOnHoldTransactionRepository;
}
@Transactional
@@ -235,7 +238,11 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
final boolean isPreMatureClosure = false;
account.updateMaturityDateAndAmount(mc, isPreMatureClosure, isSavingsInterestPostingAtCurrentPeriodEnd,
financialYearBeginningMonth);
account.validateAccountBalanceDoesNotBecomeNegative(SavingsAccountTransactionType.PAY_CHARGE.name());
List<DepositAccountOnHoldTransaction> depositAccountOnHoldTransactions = null;
if(account.getOnHoldFunds().compareTo(BigDecimal.ZERO) == 1){
depositAccountOnHoldTransactions = this.depositAccountOnHoldTransactionRepository.findBySavingsAccountAndReversedFalseOrderByCreatedDateAsc(account);
}
account.validateAccountBalanceDoesNotBecomeNegative(SavingsAccountTransactionType.PAY_CHARGE.name(),depositAccountOnHoldTransactions);
this.savingAccountRepository.save(account);
}
@@ -327,8 +334,12 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
financialYearBeginningMonth);
}
List<DepositAccountOnHoldTransaction> depositAccountOnHoldTransactions = null;
if(account.getOnHoldFunds().compareTo(BigDecimal.ZERO) == 1){
depositAccountOnHoldTransactions = this.depositAccountOnHoldTransactionRepository.findBySavingsAccountAndReversedFalseOrderByCreatedDateAsc(account);
}
account.validateAccountBalanceDoesNotBecomeNegative(SavingsAccountTransactionType.PAY_CHARGE.name());
account.validateAccountBalanceDoesNotBecomeNegative(SavingsAccountTransactionType.PAY_CHARGE.name(),depositAccountOnHoldTransactions);
this.savingAccountRepository.save(account);
}
@@ -586,7 +597,12 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
financialYearBeginningMonth);
}
account.validateAccountBalanceDoesNotBecomeNegative(SavingsApiConstants.undoTransactionAction);
List<DepositAccountOnHoldTransaction> depositAccountOnHoldTransactions = null;
if(account.getOnHoldFunds().compareTo(BigDecimal.ZERO) == 1){
depositAccountOnHoldTransactions = this.depositAccountOnHoldTransactionRepository.findBySavingsAccountAndReversedFalseOrderByCreatedDateAsc(account);
}
account.validateAccountBalanceDoesNotBecomeNegative(SavingsApiConstants.undoTransactionAction,depositAccountOnHoldTransactions);
// account.activateAccountBasedOnBalance();
final boolean isPreMatureClosure = false;
account.updateMaturityDateAndAmount(mc, isPreMatureClosure, isSavingsInterestPostingAtCurrentPeriodEnd,
@@ -682,8 +698,12 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
financialYearBeginningMonth);
}
List<DepositAccountOnHoldTransaction> depositAccountOnHoldTransactions = null;
if(account.getOnHoldFunds().compareTo(BigDecimal.ZERO) == 1){
depositAccountOnHoldTransactions = this.depositAccountOnHoldTransactionRepository.findBySavingsAccountAndReversedFalseOrderByCreatedDateAsc(account);
}
account.validateAccountBalanceDoesNotBecomeNegative(SavingsApiConstants.adjustTransactionAction);
account.validateAccountBalanceDoesNotBecomeNegative(SavingsApiConstants.adjustTransactionAction,depositAccountOnHoldTransactions);
account.activateAccountBasedOnBalance();
if (savingsAccountTransaction.isDeposit()) {
@@ -1118,8 +1138,12 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
financialYearBeginningMonth);
}
List<DepositAccountOnHoldTransaction> depositAccountOnHoldTransactions = null;
if(account.getOnHoldFunds().compareTo(BigDecimal.ZERO) == 1){
depositAccountOnHoldTransactions = this.depositAccountOnHoldTransactionRepository.findBySavingsAccountAndReversedFalseOrderByCreatedDateAsc(account);
}
account.validateAccountBalanceDoesNotBecomeNegative(SavingsApiConstants.waiveChargeTransactionAction);
account.validateAccountBalanceDoesNotBecomeNegative(SavingsApiConstants.waiveChargeTransactionAction,depositAccountOnHoldTransactions);
this.savingAccountRepository.saveAndFlush(account);
@@ -1245,8 +1269,12 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
financialYearBeginningMonth);
}
List<DepositAccountOnHoldTransaction> depositAccountOnHoldTransactions = null;
if(account.getOnHoldFunds().compareTo(BigDecimal.ZERO) == 1){
depositAccountOnHoldTransactions = this.depositAccountOnHoldTransactionRepository.findBySavingsAccountAndReversedFalseOrderByCreatedDateAsc(account);
}
account.validateAccountBalanceDoesNotBecomeNegative("." + SavingsAccountTransactionType.PAY_CHARGE.getCode());
account.validateAccountBalanceDoesNotBecomeNegative("." + SavingsAccountTransactionType.PAY_CHARGE.getCode(),depositAccountOnHoldTransactions);
this.savingAccountRepository.save(account);
@@ -5,24 +5,6 @@
*/
package org.mifosplatform.portfolio.savings.service;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.SAVINGS_ACCOUNT_CHARGE_RESOURCE_NAME;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.SAVINGS_ACCOUNT_RESOURCE_NAME;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.amountParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.chargeIdParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.dueAsOfDateParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.withdrawBalanceParamName;
import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import org.apache.commons.lang.StringUtils;
import org.joda.time.LocalDate;
import org.joda.time.format.DateTimeFormat;
@@ -68,6 +50,8 @@ import org.mifosplatform.portfolio.savings.data.SavingsAccountChargeDataValidato
import org.mifosplatform.portfolio.savings.data.SavingsAccountDataValidator;
import org.mifosplatform.portfolio.savings.data.SavingsAccountTransactionDTO;
import org.mifosplatform.portfolio.savings.data.SavingsAccountTransactionDataValidator;
import org.mifosplatform.portfolio.savings.domain.DepositAccountOnHoldTransaction;
import org.mifosplatform.portfolio.savings.domain.DepositAccountOnHoldTransactionRepository;
import org.mifosplatform.portfolio.savings.domain.SavingsAccount;
import org.mifosplatform.portfolio.savings.domain.SavingsAccountAssembler;
import org.mifosplatform.portfolio.savings.domain.SavingsAccountCharge;
@@ -89,6 +73,23 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import java.math.BigDecimal;
import java.math.MathContext;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.SAVINGS_ACCOUNT_CHARGE_RESOURCE_NAME;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.SAVINGS_ACCOUNT_RESOURCE_NAME;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.amountParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.chargeIdParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.dueAsOfDateParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.withdrawBalanceParamName;
@Service
public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements SavingsAccountWritePlatformService {
@@ -113,6 +114,8 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
private final HolidayRepositoryWrapper holidayRepository;
private final WorkingDaysRepositoryWrapper workingDaysRepository;
private final ConfigurationDomainService configurationDomainService;
private final DepositAccountOnHoldTransactionRepository depositAccountOnHoldTransactionRepository;
@Autowired
public SavingsAccountWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context,
@@ -130,7 +133,8 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
final AccountAssociationsReadPlatformService accountAssociationsReadPlatformService,
final ChargeRepositoryWrapper chargeRepository, final SavingsAccountChargeRepositoryWrapper savingsAccountChargeRepository,
final SavingsAccountDataValidator fromApiJsonDeserializer, final SavingsAccountRepositoryWrapper savingsRepository,
final StaffRepositoryWrapper staffRepository, final ConfigurationDomainService configurationDomainService) {
final StaffRepositoryWrapper staffRepository, final ConfigurationDomainService configurationDomainService,
final DepositAccountOnHoldTransactionRepository depositAccountOnHoldTransactionRepository) {
this.context = context;
this.savingAccountRepository = savingAccountRepository;
this.savingsAccountTransactionRepository = savingsAccountTransactionRepository;
@@ -152,6 +156,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
this.savingsRepository = savingsRepository;
this.staffRepository = staffRepository;
this.configurationDomainService = configurationDomainService;
this.depositAccountOnHoldTransactionRepository= depositAccountOnHoldTransactionRepository;
}
@Transactional
@@ -208,7 +213,11 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
updateExistingTransactionsDetails(account, existingTransactionIds, existingReversedTransactionIds);
}
account.processAccountUponActivation(isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth, user);
account.validateAccountBalanceDoesNotBecomeNegative(SavingsAccountTransactionType.PAY_CHARGE.name());
List<DepositAccountOnHoldTransaction> depositAccountOnHoldTransactions = null;
if(account.getOnHoldFunds().compareTo(BigDecimal.ZERO) == 1){
depositAccountOnHoldTransactions = this.depositAccountOnHoldTransactionRepository.findBySavingsAccountAndReversedFalseOrderByCreatedDateAsc(account);
}
account.validateAccountBalanceDoesNotBecomeNegative(SavingsAccountTransactionType.PAY_CHARGE.name(),depositAccountOnHoldTransactions);
}
@Transactional
@@ -440,7 +449,11 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
financialYearBeginningMonth);
}
account.validateAccountBalanceDoesNotBecomeNegative(SavingsApiConstants.undoTransactionAction);
List<DepositAccountOnHoldTransaction> depositAccountOnHoldTransactions = null;
if(account.getOnHoldFunds().compareTo(BigDecimal.ZERO) == 1){
depositAccountOnHoldTransactions = this.depositAccountOnHoldTransactionRepository.findBySavingsAccountAndReversedFalseOrderByCreatedDateAsc(account);
}
account.validateAccountBalanceDoesNotBecomeNegative(SavingsApiConstants.undoTransactionAction,depositAccountOnHoldTransactions);
account.activateAccountBasedOnBalance();
postJournalEntries(account, existingTransactionIds, existingReversedTransactionIds);
@@ -525,7 +538,11 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
financialYearBeginningMonth);
}
account.validateAccountBalanceDoesNotBecomeNegative(SavingsApiConstants.adjustTransactionAction);
List<DepositAccountOnHoldTransaction> depositAccountOnHoldTransactions = null;
if(account.getOnHoldFunds().compareTo(BigDecimal.ZERO) == 1){
depositAccountOnHoldTransactions = this.depositAccountOnHoldTransactionRepository.findBySavingsAccountAndReversedFalseOrderByCreatedDateAsc(account);
}
account.validateAccountBalanceDoesNotBecomeNegative(SavingsApiConstants.adjustTransactionAction,depositAccountOnHoldTransactions);
account.activateAccountBasedOnBalance();
postJournalEntries(account, existingTransactionIds, existingReversedTransactionIds);
return new CommandProcessingResultBuilder() //
@@ -869,8 +886,12 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
financialYearBeginningMonth);
}
List<DepositAccountOnHoldTransaction> depositAccountOnHoldTransactions = null;
if(account.getOnHoldFunds().compareTo(BigDecimal.ZERO) == 1){
depositAccountOnHoldTransactions = this.depositAccountOnHoldTransactionRepository.findBySavingsAccountAndReversedFalseOrderByCreatedDateAsc(account);
}
account.validateAccountBalanceDoesNotBecomeNegative(SavingsApiConstants.waiveChargeTransactionAction);
account.validateAccountBalanceDoesNotBecomeNegative(SavingsApiConstants.waiveChargeTransactionAction,depositAccountOnHoldTransactions);
this.savingAccountRepository.saveAndFlush(account);
@@ -995,8 +1016,12 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
financialYearBeginningMonth);
}
List<DepositAccountOnHoldTransaction> depositAccountOnHoldTransactions = null;
if(account.getOnHoldFunds().compareTo(BigDecimal.ZERO) == 1){
depositAccountOnHoldTransactions = this.depositAccountOnHoldTransactionRepository.findBySavingsAccountAndReversedFalseOrderByCreatedDateAsc(account);
}
account.validateAccountBalanceDoesNotBecomeNegative("." + SavingsAccountTransactionType.PAY_CHARGE.getCode());
account.validateAccountBalanceDoesNotBecomeNegative("." + SavingsAccountTransactionType.PAY_CHARGE.getCode(),depositAccountOnHoldTransactions);
this.savingAccountRepository.save(account);
@@ -0,0 +1,104 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.spm.api;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.spm.data.LookupTableData;
import org.mifosplatform.spm.domain.LookupTable;
import org.mifosplatform.spm.domain.Survey;
import org.mifosplatform.spm.exception.LookupTableNotFoundException;
import org.mifosplatform.spm.exception.SurveyNotFoundException;
import org.mifosplatform.spm.service.LookupTableService;
import org.mifosplatform.spm.service.SpmService;
import org.mifosplatform.spm.util.LookupTableMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import java.util.ArrayList;
import java.util.List;
@Path("/surveys/{surveyId}/lookuptables")
@Component
@Scope("singleton")
public class LookupTableApiResource {
private final PlatformSecurityContext securityContext;
private final SpmService spmService;
private final LookupTableService lookupTableService;
@Autowired
public LookupTableApiResource(final PlatformSecurityContext securityContext,
final SpmService spmService,
final LookupTableService lookupTableService) {
super();
this.securityContext = securityContext;
this.spmService = spmService;
this.lookupTableService = lookupTableService;
}
@GET
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public List<LookupTableData> fetchLookupTables(@PathParam("surveyId") final Long surveyId) {
this.securityContext.authenticatedUser();
final Survey survey = findSurvey(surveyId);
final List<LookupTableData> result = new ArrayList<>();
final List<LookupTable> lookupTables = this.lookupTableService.findBySurvey(survey);
if (lookupTables != null) {
for (final LookupTable lookupTable : lookupTables) {
result.add(LookupTableMapper.map(lookupTable));
}
}
return result;
}
@GET
@Path("/{id}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public LookupTableData findLookupTable(@PathParam("surveyId") final Long surveyId,
@PathParam("id") final Long id) {
this.securityContext.authenticatedUser();
findSurvey(surveyId);
final LookupTable lookupTable = this.lookupTableService.findById(id);
if (lookupTable == null) {
throw new LookupTableNotFoundException(id);
}
return LookupTableMapper.map(lookupTable);
}
@POST
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public void createLookupTable(@PathParam("surveyId") final Long surveyId,
final LookupTableData lookupTableData) {
this.securityContext.authenticatedUser();
final Survey survey = findSurvey(surveyId);
this.lookupTableService.createLookupTable(LookupTableMapper.map(lookupTableData, survey));
}
private Survey findSurvey(final Long surveyId) {
final Survey survey = this.spmService.findById(surveyId);
if (survey == null) {
throw new SurveyNotFoundException(surveyId);
}
return survey;
}
}
@@ -0,0 +1,105 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.spm.api;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.organisation.staff.domain.Staff;
import org.mifosplatform.organisation.staff.domain.StaffRepository;
import org.mifosplatform.organisation.staff.exception.StaffNotFoundException;
import org.mifosplatform.portfolio.client.domain.Client;
import org.mifosplatform.portfolio.client.domain.ClientRepository;
import org.mifosplatform.portfolio.client.exception.ClientNotFoundException;
import org.mifosplatform.spm.data.ScorecardData;
import org.mifosplatform.spm.domain.Scorecard;
import org.mifosplatform.spm.domain.Survey;
import org.mifosplatform.spm.exception.SurveyNotFoundException;
import org.mifosplatform.spm.service.ScorecardService;
import org.mifosplatform.spm.service.SpmService;
import org.mifosplatform.spm.util.ScorecardMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import java.util.ArrayList;
import java.util.List;
@Path("/surveys/{surveyId}/scorecards")
@Component
@Scope("singleton")
public class ScorecardApiResource {
private final PlatformSecurityContext securityContext;
private final SpmService spmService;
private final ScorecardService scorecardService;
private final StaffRepository staffRepository;
private final ClientRepository clientRepository;
@Autowired
public ScorecardApiResource(final PlatformSecurityContext securityContext, final SpmService spmService,
final ScorecardService scorecardService, final StaffRepository staffRepository,
final ClientRepository clientRepository) {
super();
this.securityContext = securityContext;
this.spmService = spmService;
this.scorecardService = scorecardService;
this.staffRepository = staffRepository;
this.clientRepository = clientRepository;
}
@GET
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public List<ScorecardData> findBySurvey(@PathParam("surveyId") final Long surveyId) {
this.securityContext.authenticatedUser();
final Survey survey = findSurvey(surveyId);
final List<ScorecardData> result = new ArrayList<>();
final List<Scorecard> scorecards = this.scorecardService.findBySurvey(survey);
if (scorecards == null) {
for (final Scorecard scorecard : scorecards) {
result.add(ScorecardMapper.map(scorecard));
}
}
return result;
}
@POST
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public void createScorecard(@PathParam("surveyId") final Long surveyId, final ScorecardData scorecardData) {
this.securityContext.authenticatedUser();
final Survey survey = findSurvey(surveyId);
final Staff staff = this.staffRepository.findOne(scorecardData.getStaffId());
if (staff == null) {
throw new StaffNotFoundException(scorecardData.getStaffId());
}
final Client client = this.clientRepository.findOne(scorecardData.getClientId());
if (client == null) {
throw new ClientNotFoundException(scorecardData.getClientId());
}
this.scorecardService.createScorecard(ScorecardMapper.map(scorecardData, survey, staff, client));
}
private Survey findSurvey(final Long surveyId) {
final Survey survey = this.spmService.findById(surveyId);
if (survey == null) {
throw new SurveyNotFoundException(surveyId);
}
return survey;
}
}
@@ -0,0 +1,93 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.spm.api;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.spm.data.SurveyData;
import org.mifosplatform.spm.domain.Survey;
import org.mifosplatform.spm.exception.SurveyNotFoundException;
import org.mifosplatform.spm.service.SpmService;
import org.mifosplatform.spm.util.SurveyMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import java.util.ArrayList;
import java.util.List;
@Path("/surveys")
@Component
@Scope("singleton")
public class SpmApiResource {
private final PlatformSecurityContext securityContext;
private final SpmService spmService;
@Autowired
public SpmApiResource(final PlatformSecurityContext securityContext,
final SpmService spmService) {
this.securityContext = securityContext;
this.spmService = spmService;
}
@GET
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public List<SurveyData> fetchActiveSurveys() {
this.securityContext.authenticatedUser();
final List<SurveyData> result = new ArrayList<>();
final List<Survey> surveys = this.spmService.fetchValidSurveys();
if (surveys != null) {
for (final Survey survey : surveys) {
result.add(SurveyMapper.map(survey));
}
}
return result;
}
@GET
@Path("/{id}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public SurveyData findSurvey(@PathParam("id") final Long id) {
this.securityContext.authenticatedUser();
final Survey survey = this.spmService.findById(id);
if (survey == null) {
throw new SurveyNotFoundException(id);
}
return SurveyMapper.map(survey);
}
@POST
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public void createSurvey(final SurveyData surveyData) {
this.securityContext.authenticatedUser();
final Survey survey = SurveyMapper.map(surveyData);
this.spmService.createSurvey(survey);
}
@DELETE
@Path("/{id}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public void deactivateSurvey(@PathParam("id") final Long id) {
this.securityContext.authenticatedUser();
this.spmService.deactivateSurvey(id);
}
}
@@ -0,0 +1,59 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.spm.data;
public class ComponentData {
private String key;
private String text;
private String description;
private Integer sequenceNo;
public ComponentData() {
super();
}
public ComponentData(final String key, final String text,
final String description, final Integer sequenceNo) {
super();
this.key = key;
this.text = text;
this.description = description;
this.sequenceNo = sequenceNo;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public String getText() {
return text;
}
public void setText(String title) {
this.text = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Integer getSequenceNo() {
return sequenceNo;
}
public void setSequenceNo(Integer sequenceNo) {
this.sequenceNo = sequenceNo;
}
}
@@ -0,0 +1,79 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.spm.data;
public class LookupTableData {
private Long id;
private String key;
private String description;
private Integer valueFrom;
private Integer valueTo;
private Double score;
public LookupTableData() {
super();
}
public LookupTableData(final Long id, final String key, final String description, final Integer valueFrom,
final Integer valueTo, final Double score) {
super();
this.id = id;
this.key = key;
this.description = description;
this.valueFrom = valueFrom;
this.valueTo = valueTo;
this.score = score;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Integer getValueFrom() {
return valueFrom;
}
public void setValueFrom(Integer valueFrom) {
this.valueFrom = valueFrom;
}
public Integer getValueTo() {
return valueTo;
}
public void setValueTo(Integer valueTo) {
this.valueTo = valueTo;
}
public Double getScore() {
return score;
}
public void setScore(Double score) {
this.score = score;
}
}
@@ -0,0 +1,81 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.spm.data;
import java.util.List;
public class QuestionData {
private List<ResponseData> responseDatas;
private String componentKey;
private String key;
private String text;
private String description;
private Integer sequenceNo;
public QuestionData() {
super();
}
public QuestionData(final List<ResponseData> responseDatas, final String componentKey, final String key,
final String text, final String description, final Integer sequenceNo) {
super();
this.responseDatas = responseDatas;
this.componentKey = componentKey;
this.key = key;
this.text = text;
this.description = description;
this.sequenceNo = sequenceNo;
}
public List<ResponseData> getResponseDatas() {
return responseDatas;
}
public void setResponseDatas(List<ResponseData> responseDatas) {
this.responseDatas = responseDatas;
}
public String getComponentKey() {
return componentKey;
}
public void setComponentKey(String componentKey) {
this.componentKey = componentKey;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Integer getSequenceNo() {
return sequenceNo;
}
public void setSequenceNo(Integer sequenceNo) {
this.sequenceNo = sequenceNo;
}
}
@@ -0,0 +1,49 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.spm.data;
public class ResponseData {
private String text;
private Integer value;
private Integer sequenceNo;
public ResponseData() {
super();
}
public ResponseData(final String text, final Integer value,
final Integer sequenceNo) {
super();
this.text = text;
this.value = value;
this.sequenceNo = sequenceNo;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public Integer getValue() {
return value;
}
public void setValue(Integer value) {
this.value = value;
}
public Integer getSequenceNo() {
return sequenceNo;
}
public void setSequenceNo(Integer sequenceNo) {
this.sequenceNo = sequenceNo;
}
}
@@ -0,0 +1,81 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.spm.data;
import java.util.Date;
public class ScorecardData {
private Long questionId;
private Long responseId;
private Long staffId;
private Long clientId;
private Date createdOn;
private Integer value;
public ScorecardData() {
super();
}
public ScorecardData(final Long questionId, final Long responseId, final Long staffId, final Long clientId,
final Date createdOn, final Integer value) {
super();
this.questionId = questionId;
this.responseId = responseId;
this.staffId = staffId;
this.clientId = clientId;
this.createdOn = createdOn;
this.value = value;
}
public Long getQuestionId() {
return questionId;
}
public void setQuestionId(Long questionId) {
this.questionId = questionId;
}
public Long getResponseId() {
return responseId;
}
public void setResponseId(Long responseId) {
this.responseId = responseId;
}
public Long getStaffId() {
return staffId;
}
public void setStaffId(Long staffId) {
this.staffId = staffId;
}
public Long getClientId() {
return clientId;
}
public void setClientId(Long clientId) {
this.clientId = clientId;
}
public Date getCreatedOn() {
return createdOn;
}
public void setCreatedOn(Date createdOn) {
this.createdOn = createdOn;
}
public Integer getValue() {
return value;
}
public void setValue(Integer value) {
this.value = value;
}
}
@@ -0,0 +1,113 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.spm.data;
import java.util.Date;
import java.util.List;
public class SurveyData {
private Long id;
private List<ComponentData> componentDatas;
private List<QuestionData> questionDatas;
private String key;
private String name;
private String description;
private String countryCode;
private Date validFrom;
private Date validTo;
public SurveyData() {
super();
}
public SurveyData(final Long id, final List<ComponentData> componentDatas, final List<QuestionData> questionDatas,
final String key, final String name, final String description, final String countryCode,
final Date validFrom, final Date validTo) {
super();
this.id = id;
this.componentDatas = componentDatas;
this.questionDatas = questionDatas;
this.key = key;
this.name = name;
this.description = description;
this.countryCode = countryCode;
this.validFrom = validFrom;
this.validTo = validTo;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public List<ComponentData> getComponentDatas() {
return componentDatas;
}
public void setComponentDatas(List<ComponentData> componentDatas) {
this.componentDatas = componentDatas;
}
public List<QuestionData> getQuestionDatas() {
return questionDatas;
}
public void setQuestionDatas(List<QuestionData> questionDatas) {
this.questionDatas = questionDatas;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getCountryCode() {
return countryCode;
}
public void setCountryCode(String countryCode) {
this.countryCode = countryCode;
}
public Date getValidFrom() {
return validFrom;
}
public void setValidFrom(Date validFrom) {
this.validFrom = validFrom;
}
public Date getValidTo() {
return validTo;
}
public void setValidTo(Date validTo) {
this.validTo = validTo;
}
}
@@ -0,0 +1,75 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.spm.domain;
import org.springframework.data.jpa.domain.AbstractPersistable;
import javax.persistence.*;
@Entity
@Table(name = "m_survey_components")
public class Component extends AbstractPersistable<Long> {
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "survey_id")
private Survey survey;
@Column(name = "a_key", length = 32)
private String key;
@Column(name = "a_text", length = 255)
private String text;
@Column(name = "description", length = 4096)
private String description;
@Column(name = "sequence_no", precision = 4)
private Integer sequenceNo;
public Component() {
super();
}
public Survey getSurvey() {
return survey;
}
public void setSurvey(Survey survey) {
this.survey = survey;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public String getText() {
return text;
}
public void setText(String title) {
this.text = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Integer getSequenceNo() {
return sequenceNo;
}
public void setSequenceNo(Integer sequenceNo) {
this.sequenceNo = sequenceNo;
}
}
@@ -0,0 +1,86 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.spm.domain;
import org.springframework.data.jpa.domain.AbstractPersistable;
import javax.persistence.*;
@Entity
@Table(name = "m_survey_lookup_tables")
public class LookupTable extends AbstractPersistable<Long> {
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "survey_id")
private Survey survey;
@Column(name = "a_key", length = 32)
private String key;
@Column(name = "description", length = 4096)
private String description;
@Column(name = "value_from", precision = 4)
private Integer valueFrom;
@Column(name = "value_to", precision = 4)
private Integer valueTo;
@Column(name = "score", precision = 5, scale = 2)
private Double score;
public LookupTable() {
super();
}
public Survey getSurvey() {
return survey;
}
public void setSurvey(Survey survey) {
this.survey = survey;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Integer getValueFrom() {
return valueFrom;
}
public void setValueFrom(Integer valueFrom) {
this.valueFrom = valueFrom;
}
public Integer getValueTo() {
return valueTo;
}
public void setValueTo(Integer valueTo) {
this.valueTo = valueTo;
}
public Double getScore() {
return score;
}
public void setScore(Double score) {
this.score = score;
}
}
@@ -0,0 +1,99 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.spm.domain;
import org.springframework.data.jpa.domain.AbstractPersistable;
import javax.persistence.*;
import java.util.List;
@Entity
@Table(name = "m_survey_questions")
public class Question extends AbstractPersistable<Long> {
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "survey_id")
private Survey survey;
@OneToMany(mappedBy = "question", fetch = FetchType.EAGER)
@OrderBy("sequenceNo")
private List<Response> responses;
@Column(name = "component_key", length = 32)
private String componentKey;
@Column(name = "a_key", length = 32)
private String key;
@Column(name = "a_text", length = 255)
private String text;
@Column(name = "description", length = 4096)
private String description;
@Column(name = "sequence_no", precision = 4)
private Integer sequenceNo;
public Question() {
super();
}
public Survey getSurvey() {
return survey;
}
public void setSurvey(Survey survey) {
this.survey = survey;
}
public List<Response> getResponses() {
return responses;
}
public void setResponses(List<Response> responses) {
this.responses = responses;
}
public String getComponentKey() {
return componentKey;
}
public void setComponentKey(String componentKey) {
this.componentKey = componentKey;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Integer getSequenceNo() {
return sequenceNo;
}
public void setSequenceNo(Integer sequenceNo) {
this.sequenceNo = sequenceNo;
}
}
@@ -0,0 +1,64 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.spm.domain;
import org.springframework.data.jpa.domain.AbstractPersistable;
import javax.persistence.*;
@Entity
@Table(name = "m_survey_responses")
public class Response extends AbstractPersistable<Long> {
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "question_id")
private Question question;
@Column(name = "a_text", length = 255)
private String text;
@Column(name = "a_value", precision = 4)
private Integer value;
@Column(name = "sequence_no", precision = 4)
private Integer sequenceNo;
public Response() {
super();
}
public Question getQuestion() {
return question;
}
public void setQuestion(Question question) {
this.question = question;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public Integer getValue() {
return value;
}
public void setValue(Integer value) {
this.value = value;
}
public Integer getSequenceNo() {
return sequenceNo;
}
public void setSequenceNo(Integer sequenceNo) {
this.sequenceNo = sequenceNo;
}
}
@@ -0,0 +1,106 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.spm.domain;
import org.mifosplatform.organisation.staff.domain.Staff;
import org.mifosplatform.portfolio.client.domain.Client;
import org.springframework.data.jpa.domain.AbstractPersistable;
import javax.persistence.*;
import java.util.Date;
@Entity
@Table(name = "m_survey_scorecards")
public class Scorecard extends AbstractPersistable<Long> {
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "survey_id")
private Survey survey;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "question_id")
private Question question;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "response_id")
private Response response;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "staff_id")
private Staff staff;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "client_id")
private Client client;
@Column(name = "created_on")
@Temporal(value = TemporalType.TIMESTAMP)
@OrderBy("createdOn DESC")
private Date createdOn;
@Column(name = "a_value", precision = 4)
private Integer value;
public Scorecard() {
super();
}
public Survey getSurvey() {
return survey;
}
public void setSurvey(Survey survey) {
this.survey = survey;
}
public Question getQuestion() {
return question;
}
public void setQuestion(Question question) {
this.question = question;
}
public Response getResponse() {
return response;
}
public void setResponse(Response response) {
this.response = response;
}
public Staff getStaff() {
return staff;
}
public void setStaff(Staff staff) {
this.staff = staff;
}
public Client getClient() {
return client;
}
public void setClient(Client client) {
this.client = client;
}
public Date getCreatedOn() {
return createdOn;
}
public void setCreatedOn(Date createdOn) {
this.createdOn = createdOn;
}
public Integer getValue() {
return value;
}
public void setValue(Integer value) {
this.value = value;
}
}
@@ -0,0 +1,113 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.spm.domain;
import org.springframework.data.jpa.domain.AbstractPersistable;
import javax.persistence.*;
import java.util.Date;
import java.util.List;
@Entity
@Table(name = "m_surveys")
public class Survey extends AbstractPersistable<Long> {
@OneToMany(mappedBy = "survey", fetch = FetchType.EAGER)
@OrderBy("sequenceNo")
private List<Component> components;
@OneToMany(mappedBy = "survey", fetch = FetchType.EAGER)
@OrderBy("sequenceNo")
private List<Question> questions;
@Column(name = "a_key", length = 32)
private String key;
@Column(name = "a_name", length = 255)
private String name;
@Column(name = "description", length = 4096)
private String description;
@Column(name = "country_code", length = 2)
private String countryCode;
@Column(name = "valid_from")
@Temporal(value = TemporalType.TIMESTAMP)
private Date validFrom;
@Column(name = "valid_to")
@Temporal(value = TemporalType.TIMESTAMP)
private Date validTo;
public Survey() {
super();
}
public List<Component> getComponents() {
return components;
}
public void setComponents(List<Component> components) {
this.components = components;
}
public List<Question> getQuestions() {
return questions;
}
public void setQuestions(List<Question> questions) {
this.questions = questions;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getCountryCode() {
return countryCode;
}
public void setCountryCode(String countryCode) {
this.countryCode = countryCode;
}
public Date getValidFrom() {
return validFrom;
}
public void setValidFrom(Date validFrom) {
this.validFrom = validFrom;
}
public Date getValidTo() {
return validTo;
}
public void setValidTo(Date validTo) {
this.validTo = validTo;
}
}
@@ -0,0 +1,15 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.spm.exception;
import org.mifosplatform.infrastructure.core.exception.AbstractPlatformResourceNotFoundException;
public class LookupTableNotFoundException extends AbstractPlatformResourceNotFoundException {
public LookupTableNotFoundException(final Long id) {
super("error.msg.survey.lookuptable.id.notfound", "Lookup table with id " + id + " not found!", id);
}
}
@@ -0,0 +1,15 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.spm.exception;
import org.mifosplatform.infrastructure.core.exception.AbstractPlatformResourceNotFoundException;
public class SurveyNotFoundException extends AbstractPlatformResourceNotFoundException {
public SurveyNotFoundException(final Long id) {
super("error.msg.survey.id.notfound", "Survey with id " + id + " not found!", id);
}
}
@@ -0,0 +1,17 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.spm.repository;
import org.mifosplatform.spm.domain.LookupTable;
import org.mifosplatform.spm.domain.Survey;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
public interface LookupTableRepository extends JpaRepository<LookupTable, Long> {
List<LookupTable> findBySurvey(final Survey survey);
}
@@ -0,0 +1,19 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.spm.repository;
import org.mifosplatform.portfolio.client.domain.Client;
import org.mifosplatform.spm.domain.Scorecard;
import org.mifosplatform.spm.domain.Survey;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
public interface ScorecardRepository extends JpaRepository<Scorecard, Long> {
List<Scorecard> findBySurvey(final Survey survey);
List<Scorecard> findBySurveyAndClient(final Survey survey, final Client client);
}
@@ -0,0 +1,22 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.spm.repository;
import org.mifosplatform.spm.domain.Survey;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import java.util.Date;
import java.util.List;
public interface SurveyRepository extends JpaRepository<Survey, Long> {
@Query("select s from Survey s where :pointInTime between s.validFrom and s.validTo")
List<Survey> fetchActiveSurveys(@Param("pointInTime") final Date pointInTime);
Survey findByKey(final String key);
}
@@ -0,0 +1,48 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.spm.service;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.spm.domain.LookupTable;
import org.mifosplatform.spm.domain.Survey;
import org.mifosplatform.spm.repository.LookupTableRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class LookupTableService {
private final PlatformSecurityContext securityContext;
private final LookupTableRepository lookupTableRepository;
@Autowired
public LookupTableService(final PlatformSecurityContext securityContext,
final LookupTableRepository lookupTableRepository) {
super();
this.securityContext = securityContext;
this.lookupTableRepository = lookupTableRepository;
}
public LookupTable findById(final Long id) {
this.securityContext.authenticatedUser();
return this.lookupTableRepository.findOne(id);
}
public List<LookupTable> findBySurvey(final Survey survey) {
this.securityContext.authenticatedUser();
return this.lookupTableRepository.findBySurvey(survey);
}
public LookupTable createLookupTable(final LookupTable lookupTable) {
this.securityContext.authenticatedUser();
return this.lookupTableRepository.save(lookupTable);
}
}
@@ -0,0 +1,51 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.spm.service;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.portfolio.client.domain.Client;
import org.mifosplatform.spm.domain.Scorecard;
import org.mifosplatform.spm.domain.Survey;
import org.mifosplatform.spm.repository.ScorecardRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Service
public class ScorecardService {
private final PlatformSecurityContext securityContext;
private final ScorecardRepository scorecardRepository;
@Autowired
public ScorecardService(final PlatformSecurityContext securityContext,
final ScorecardRepository scorecardRepository) {
super();
this.securityContext = securityContext;
this.scorecardRepository = scorecardRepository;
}
@Transactional
public Scorecard createScorecard(final Scorecard scorecard) {
this.securityContext.authenticatedUser();
return this.scorecardRepository.save(scorecard);
}
public List<Scorecard> findBySurvey(final Survey survey) {
this.securityContext.authenticatedUser();
return this.scorecardRepository.findBySurvey(survey);
}
public List<Scorecard> findBySurveyAndClient(final Survey survey, final Client client) {
this.securityContext.authenticatedUser();
return this.scorecardRepository.findBySurveyAndClient(survey, client);
}
}
@@ -0,0 +1,100 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.spm.service;
import org.joda.time.DateTime;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.spm.domain.Survey;
import org.mifosplatform.spm.repository.SurveyRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date;
import java.util.List;
@Service
public class SpmService {
private final PlatformSecurityContext securityContext;
private final SurveyRepository surveyRepository;
@Autowired
public SpmService(final PlatformSecurityContext securityContext,
final SurveyRepository surveyRepository) {
super();
this.securityContext = securityContext;
this.surveyRepository = surveyRepository;
}
public List<Survey> fetchValidSurveys() {
this.securityContext.authenticatedUser();
return this.surveyRepository.fetchActiveSurveys(new Date());
}
public Survey findById(final Long id) {
this.securityContext.authenticatedUser();
return this.surveyRepository.findOne(id);
}
@Transactional
public Survey createSurvey(final Survey survey) {
this.securityContext.authenticatedUser();
final Survey previousSurvey = this.surveyRepository.findByKey(survey.getKey());
if (previousSurvey != null) {
this.deactivateSurvey(previousSurvey.getId());
}
// set valid from to start of today
final DateTime dateTime = DateTime
.now()
.withHourOfDay(0)
.withMinuteOfHour(0)
.withSecondOfMinute(0)
.withMillisOfSecond(0);
survey.setValidFrom(dateTime.toDate());
// set valid from to end in 100 years
dateTime
.withDayOfMonth(31)
.withMonthOfYear(12)
.withHourOfDay(23)
.withMinuteOfHour(59)
.withSecondOfMinute(59)
.withMillisOfSecond(999)
.plusYears(100);
survey.setValidTo(dateTime.toDate());
return this.surveyRepository.save(survey);
}
@Transactional
public void deactivateSurvey(final Long id) {
this.securityContext.authenticatedUser();
final Survey survey = this.surveyRepository.findOne(id);
if (survey != null) {
// set valid to to yesterday night
final DateTime dateTime = DateTime
.now()
.withHourOfDay(23)
.withMinuteOfHour(59)
.withSecondOfMinute(59)
.withMillisOfSecond(999)
.minusDays(1);
survey.setValidTo(dateTime.toDate());
this.surveyRepository.save(survey);
}
}
}
@@ -0,0 +1,36 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.spm.util;
import org.mifosplatform.spm.data.LookupTableData;
import org.mifosplatform.spm.domain.LookupTable;
import org.mifosplatform.spm.domain.Survey;
public class LookupTableMapper {
private LookupTableMapper() {
super();
}
public static LookupTableData map(final LookupTable lookupTable) {
final LookupTableData lookupTableData = new LookupTableData(
lookupTable.getId(), lookupTable.getKey(), lookupTable.getDescription(), lookupTable.getValueFrom(),
lookupTable.getValueFrom(), lookupTable.getScore()
);
return lookupTableData;
}
public static LookupTable map(final LookupTableData lookupTableData, final Survey survey) {
final LookupTable lookupTable = new LookupTable();
lookupTable.setSurvey(survey);
lookupTable.setKey(lookupTableData.getKey());
lookupTable.setDescription(lookupTableData.getDescription());
lookupTable.setValueFrom(lookupTableData.getValueFrom());
lookupTable.setValueTo(lookupTableData.getValueTo());
lookupTable.setScore(lookupTableData.getScore());
return lookupTable;
}
}
@@ -0,0 +1,59 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.spm.util;
import org.mifosplatform.organisation.staff.domain.Staff;
import org.mifosplatform.portfolio.client.domain.Client;
import org.mifosplatform.spm.data.ScorecardData;
import org.mifosplatform.spm.domain.Question;
import org.mifosplatform.spm.domain.Response;
import org.mifosplatform.spm.domain.Scorecard;
import org.mifosplatform.spm.domain.Survey;
import java.util.List;
public class ScorecardMapper {
private ScorecardMapper() {
super();
}
public static ScorecardData map(final Scorecard scorecard) {
final ScorecardData scorecardData = new ScorecardData(
scorecard.getQuestion().getId(), scorecard.getResponse().getId(), scorecard.getStaff().getId(),
scorecard.getClient().getId(), scorecard.getCreatedOn(), scorecard.getValue()
);
return scorecardData;
}
public static Scorecard map(final ScorecardData scorecardData, final Survey survey,
final Staff staff, final Client client) {
final Scorecard scorecard = new Scorecard();
ScorecardMapper.setQuestionAndResponse(scorecardData, scorecard, survey);
scorecard.setStaff(staff);
scorecard.setClient(client);
scorecard.setCreatedOn(scorecardData.getCreatedOn());
scorecard.setValue(scorecardData.getValue());
return scorecard;
}
private static void setQuestionAndResponse(final ScorecardData scorecardData, final Scorecard scorecard,
final Survey survey) {
final List<Question> questions = survey.getQuestions();
for (final Question question : questions) {
if (question.getId().equals(scorecardData.getQuestionId())) {
scorecard.setQuestion(question);
for (final Response response : question.getResponses()) {
if (response.getId().equals(scorecardData.getResponseId())) {
scorecard.setResponse(response);
break;
}
}
break;
}
}
}
}
@@ -0,0 +1,130 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.spm.util;
import org.mifosplatform.spm.data.ComponentData;
import org.mifosplatform.spm.data.QuestionData;
import org.mifosplatform.spm.data.ResponseData;
import org.mifosplatform.spm.data.SurveyData;
import org.mifosplatform.spm.domain.Component;
import org.mifosplatform.spm.domain.Question;
import org.mifosplatform.spm.domain.Response;
import org.mifosplatform.spm.domain.Survey;
import java.util.ArrayList;
import java.util.List;
public class SurveyMapper {
private SurveyMapper() {
super();
}
public static SurveyData map(final Survey survey) {
final SurveyData surveyData = new SurveyData(
survey.getId(), SurveyMapper.mapComponents(survey.getComponents()),
SurveyMapper.mapQuestions(survey.getQuestions()), survey.getKey(), survey.getName(),
survey.getDescription(), survey.getCountryCode(), survey.getValidFrom(), survey.getValidTo()
);
return surveyData;
}
public static Survey map(final SurveyData surveyData) {
final Survey survey = new Survey();
survey.setComponents(SurveyMapper.mapComponentDatas(surveyData.getComponentDatas()));
survey.setQuestions(SurveyMapper.mapQuestionDatas(surveyData.getQuestionDatas(), survey));
survey.setKey(surveyData.getKey());
survey.setName(surveyData.getName());
survey.setDescription(surveyData.getDescription());
survey.setCountryCode(surveyData.getCountryCode());
return survey;
}
private static List<ComponentData> mapComponents(final List<Component> components) {
final List<ComponentData> componentDatas = new ArrayList<>();
if (components != null) {
for (final Component component : components) {
componentDatas.add(new ComponentData(
component.getKey(), component.getText(), component.getDescription(), component.getSequenceNo()
));
}
}
return componentDatas;
}
private static List<Component> mapComponentDatas(final List<ComponentData> componentDatas) {
final List<Component> components = new ArrayList<>();
if (componentDatas != null) {
for (final ComponentData componentData : componentDatas) {
final Component component = new Component();
component.setKey(componentData.getKey());
component.setText(componentData.getText());
component.setDescription(componentData.getDescription());
component.setSequenceNo(componentData.getSequenceNo());
components.add(component);
}
}
return components;
}
private static List<QuestionData> mapQuestions(final List<Question> questions) {
final List<QuestionData> questionDatas = new ArrayList<>();
if (questions != null) {
for (final Question question : questions) {
questionDatas.add(new QuestionData(
SurveyMapper.mapResponses(question.getResponses()), question.getComponentKey(), question.getKey(),
question.getText(), question.getDescription(), question.getSequenceNo()
));
}
}
return questionDatas;
}
private static List<Question> mapQuestionDatas(final List<QuestionData> questionDatas, final Survey survey) {
final List<Question> questions = new ArrayList<>();
if (questionDatas != null) {
for (final QuestionData questionData : questionDatas) {
final Question question = new Question();
question.setSurvey(survey);
question.setComponentKey(questionData.getComponentKey());
question.setResponses(SurveyMapper.mapResponseDatas(questionData.getResponseDatas(), question));
question.setKey(questionData.getKey());
question.setText(questionData.getText());
question.setDescription(question.getDescription());
question.setSequenceNo(questionData.getSequenceNo());
questions.add(question);
}
}
return questions;
}
private static List<ResponseData> mapResponses(final List<Response> responses) {
final List<ResponseData> responseDatas = new ArrayList<>();
if (responses != null) {
for (final Response response : responses) {
responseDatas.add(new ResponseData(
response.getText(), response.getValue(), response.getSequenceNo()
));
}
}
return responseDatas;
}
private static List<Response> mapResponseDatas(final List<ResponseData> responseDatas, final Question question) {
final List<Response> responses = new ArrayList<>();
if (responseDatas != null) {
for (final ResponseData responseData : responseDatas) {
final Response response = new Response();
response.setQuestion(question);
response.setText(responseData.getText());
response.setValue(responseData.getValue());
response.setSequenceNo(responseData.getSequenceNo());
responses.add(response);
}
}
return responses;
}
}
@@ -24,6 +24,7 @@ import java.util.Map;
import java.util.Map.Entry;
import org.codehaus.jackson.map.ObjectMapper;
import org.mifosplatform.infrastructure.core.service.ThreadLocalContextUtil;
import org.mifosplatform.template.domain.Template;
import org.mifosplatform.template.domain.TemplateFunctions;
import org.slf4j.Logger;
@@ -38,6 +39,7 @@ import com.github.mustachejava.MustacheFactory;
@Service
public class TemplateMergeService {
private final static Logger logger = LoggerFactory.getLogger(TemplateMergeService.class);
// private final FromJsonHelper fromApiJsonHelper;
private Map<String, Object> scopes;
@@ -46,16 +48,18 @@ public class TemplateMergeService {
// @Autowired
// public TemplateMergeService(final FromJsonHelper fromApiJsonHelper) {
// this.fromApiJsonHelper = fromApiJsonHelper;
// }
//
public void setAuthToken(final String authToken) {
this.authToken = authToken;
//final String auth = ThreadLocalContextUtil.getAuthToken();
this.authToken = authToken;
}
public String compile(final Template template, final Map<String, Object> scopes) throws MalformedURLException, IOException {
this.scopes = scopes;
this.scopes.put("static", new TemplateFunctions());
final MustacheFactory mf = new DefaultMustacheFactory();
final Mustache mustache = mf.compile(new StringReader(template.getText()), template.getName());
@@ -169,6 +173,8 @@ public class TemplateMergeService {
private void expandMapArrays(Object value) {
if (value instanceof Map) {
Map<String, Object> valueAsMap = (Map<String, Object>) value;
//Map<String, Object> newValue = null;
Map<String,Object> valueAsMap_second = new HashMap<>();
for (Entry<String, Object> valueAsMapEntry : valueAsMap.entrySet()) {
Object valueAsMapEntryValue = valueAsMapEntry.getValue();
if (valueAsMapEntryValue instanceof Map) { // JSON Object
@@ -178,12 +184,16 @@ public class TemplateMergeService {
String valueAsMapEntryKey = valueAsMapEntry.getKey();
int i = 0;
for (Object object : valueAsMapEntryValueIterable) {
valueAsMap.put(valueAsMapEntryKey + "#" + i, object);
valueAsMap_second.put(valueAsMapEntryKey + "#" + i, object);
++i;
expandMapArrays(object);
}
}
}
valueAsMap.putAll(valueAsMap_second);
}
}
@@ -85,4 +85,5 @@
</property>
</bean>
<import resource="spmContext.xml"/>
</beans>
@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this file,
You can obtain one at http://mozilla.org/MPL/2.0/.
-->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<tx:annotation-driven />
<context:component-scan base-package="org.mifosplatform.spm"/>
<jpa:repositories base-package="org.mifosplatform.spm.repository"/>
</beans>
@@ -0,0 +1,72 @@
CREATE TABLE `m_surveys` (
`id` BIGINT(20) NOT NULL AUTO_INCREMENT,
`a_key` VARCHAR(32) NOT NULL,
`a_name` VARCHAR(255) NOT NULL,
`description` VARCHAR(4000) NULL,
`country_code` VARCHAR(2) NOT NULL,
`valid_from` DATETIME NULL DEFAULT NULL,
`valid_to` DATETIME NULL DEFAULT NULL,
PRIMARY KEY (`id`)
);
CREATE TABLE `m_survey_components` (
`id` BIGINT(20) NOT NULL AUTO_INCREMENT,
`survey_id` BIGINT(20) NOT NULL,
`a_key` VARCHAR(32) NOT NULL,
`a_text` VARCHAR(255) NOT NULL,
`description` VARCHAR(4000) NULL,
`sequence_no` INT(4) NOT NULL,
PRIMARY KEY (`id`),
FOREIGN KEY (`survey_id`) REFERENCES `m_surveys` (`id`)
);
CREATE TABLE `m_survey_questions` (
`id` BIGINT(20) NOT NULL AUTO_INCREMENT,
`survey_id` BIGINT(20) NOT NULL,
`component_key` VARCHAR(32) NULL,
`a_key` VARCHAR(32) NOT NULL,
`a_text` VARCHAR(255) NOT NULL,
`description` VARCHAR(4000) NULL,
`sequence_no` INT(4) NOT NULL,
PRIMARY KEY (`id`),
FOREIGN KEY (`survey_id`) REFERENCES `m_surveys` (`id`)
);
CREATE TABLE `m_survey_responses` (
`id` BIGINT(20) NOT NULL AUTO_INCREMENT,
`question_id` BIGINT(20) NOT NULL,
`a_text` VARCHAR(255) NOT NULL,
`a_value` INT(4) NOT NULL,
`sequence_no` INT(4) NOT NULL,
PRIMARY KEY (`id`),
FOREIGN KEY (`question_id`) REFERENCES `m_survey_questions` (`id`)
);
CREATE TABLE `m_survey_lookup_tables` (
`id` BIGINT(20) NOT NULL AUTO_INCREMENT,
`survey_id` BIGINT(20) NOT NULL,
`a_key` VARCHAR(255) NOT NULL,
`description` INT(4) NULL,
`value_from` INT(4) NOT NULL,
`value_to` INT(4) NOT NULL,
`score` DECIMAL(5, 2) NOT NULL,
PRIMARY KEY (`id`),
FOREIGN KEY (`survey_id`) REFERENCES `m_surveys` (`id`)
);
CREATE TABLE `m_survey_scorecards` (
`id` BIGINT(20) NOT NULL AUTO_INCREMENT,
`survey_id` BIGINT(20) NOT NULL,
`question_id` BIGINT(20) NOT NULL,
`response_id` BIGINT(20) NOT NULL,
`staff_id` BIGINT(20) NOT NULL,
`client_id` BIGINT(20) NOT NULL,
`created_on` DATETIME NULL DEFAULT NULL,
`a_value` INT(4) NOT NULL,
PRIMARY KEY (`id`),
FOREIGN KEY (`survey_id`) REFERENCES `m_surveys` (`id`),
FOREIGN KEY (`question_id`) REFERENCES `m_survey_questions` (`id`),
FOREIGN KEY (`response_id`) REFERENCES `m_survey_responses` (`id`),
FOREIGN KEY (`staff_id`) REFERENCES `m_staff` (`id`),
FOREIGN KEY (`client_id`) REFERENCES `m_client` (`id`)
);
@@ -0,0 +1,4 @@
INSERT INTO `c_configuration` ( `name`, `value`, `enabled`, `description`)
VALUES
( 'backdate-penalties-enabled', 0, 1, 'If this parameter is disabled penalties will only be added to instalments due moving forward, any old overdue instalments will not be affected.');
@@ -246,7 +246,7 @@ CREATE TABLE IF NOT EXISTS `c_configuration` (
`description` varchar(300) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `name_UNIQUE` (`name`)
) ENGINE=InnoDB AUTO_INCREMENT=24 DEFAULT CHARSET=utf8;
) ENGINE=InnoDB AUTO_INCREMENT=25 DEFAULT CHARSET=utf8;
-- Dumping data for table mifostenant-default.c_configuration: ~19 rows (approximately)
/*!40000 ALTER TABLE `c_configuration` DISABLE KEYS */;
@@ -269,7 +269,8 @@ INSERT INTO `c_configuration` (`id`, `name`, `value`, `enabled`, `is_trap_door`,
(20, 'office-specific-products-enabled', 0, 0, 0, 'Whether products and fees should be office specific or not? This property should NOT be changed once Mifos is Live.'),
(21, 'restrict-products-to-user-office', 0, 0, 0, 'This should be enabled only if, products & fees are office specific (i.e. office-specific-products-enabled is enabled). This property specifies if the products should be auto-restricted to office of the user who created the proudct? Note: This property should NOT be changed once Mifos is Live.'),
(22, 'office-opening-balances-contra-account', 0, 1, 0, NULL),
(23, 'rounding-mode', 6, 1, 1, '0 - UP, 1 - DOWN, 2- CEILING, 3- FLOOR, 4- HALF_UP, 5- HALF_DOWN, 6 - HALF_EVEN');
(23, 'rounding-mode', 6, 1, 1, '0 - UP, 1 - DOWN, 2- CEILING, 3- FLOOR, 4- HALF_UP, 5- HALF_DOWN, 6 - HALF_EVEN'),
(24, 'backdate-penalties-enabled', 0, 1, 0, 'If this parameter is disabled penalties will only be added to instalments due moving forward, any old overdue instalments will not be affected.');
/*!40000 ALTER TABLE `c_configuration` ENABLE KEYS */;
@@ -339,25 +340,25 @@ CREATE TABLE IF NOT EXISTS `job` (
-- Dumping data for table mifostenant-default.job: ~19 rows (approximately)
/*!40000 ALTER TABLE `job` DISABLE KEYS */;
INSERT INTO `job` (`id`, `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`, `is_misfired`) VALUES
(1, 'Update loan Summary', 'Update loan Summary', '0 0 22 1/1 * ? *', '2015-06-03 02:56:57', 5, NULL, NULL, '2015-11-18 22:00:00', 'Update loan SummaryJobDetail1 _ DEFAULT', NULL, 1, 0, 1, 0, 0),
(2, 'Update Loan Arrears Ageing', 'Update Loan Arrears Ageing', '0 1 0 1/1 * ? *', '2015-06-03 02:56:57', 5, NULL, NULL, '2015-11-19 00:01:00', 'Update Loan Arrears AgeingJobDetail1 _ DEFAULT', NULL, 1, 0, 1, 0, 0),
(3, 'Update Loan Paid In Advance', 'Update Loan Paid In Advance', '0 5 0 1/1 * ? *', '2015-06-03 02:56:57', 5, NULL, NULL, '2015-11-19 00:05:00', 'Update Loan Paid In AdvanceJobDetail1 _ DEFAULT', NULL, 1, 0, 1, 0, 0),
(4, 'Apply Annual Fee For Savings', 'Apply Annual Fee For Savings', '0 20 22 1/1 * ? *', '2015-06-03 02:56:57', 5, NULL, NULL, '2015-11-18 22:20:00', 'Apply Annual Fee For SavingsJobDetail1 _ DEFAULT', NULL, 1, 0, 1, 0, 0),
(5, 'Apply Holidays To Loans', 'Apply Holidays To Loans', '0 0 12 * * ?', '2015-06-03 02:56:57', 5, NULL, NULL, '2015-11-19 12:00:00', 'Apply Holidays To LoansJobDetail1 _ DEFAULT', NULL, 1, 0, 1, 0, 0),
(6, 'Post Interest For Savings', 'Post Interest For Savings', '0 0 0 1/1 * ? *', '2015-06-03 02:56:58', 5, NULL, NULL, '2015-11-19 00:00:00', 'Post Interest For SavingsJobDetail1 _ DEFAULT', NULL, 1, 0, 1, 1, 0),
(7, 'Transfer Fee For Loans From Savings', 'Transfer Fee For Loans From Savings', '0 1 0 1/1 * ? *', '2015-06-03 02:57:00', 5, NULL, NULL, '2015-11-19 00:01:00', 'Transfer Fee For Loans From SavingsJobDetail1 _ DEFAULT', NULL, 1, 0, 1, 0, 0),
(8, 'Pay Due Savings Charges', 'Pay Due Savings Charges', '0 0 12 * * ?', '2013-09-23 00:00:00', 5, NULL, NULL, '2015-11-19 12:00:00', 'Pay Due Savings ChargesJobDetail1 _ DEFAULT', NULL, 1, 0, 1, 0, 0),
(9, 'Update Accounting Running Balances', 'Update Accounting Running Balances', '0 1 0 1/1 * ? *', '2015-06-03 02:57:00', 5, NULL, NULL, '2015-11-19 00:01:00', 'Update Accounting Running BalancesJobDetail1 _ DEFAULT', NULL, 1, 0, 1, 0, 0),
(10, 'Execute Standing Instruction', 'Execute Standing Instruction', '0 0 0 1/1 * ? *', '2015-06-03 02:57:04', 5, NULL, NULL, '2015-11-19 00:00:00', 'Execute Standing InstructionJobDetail1 _ DEFAULT', NULL, 1, 0, 1, 0, 0),
(11, 'Add Accrual Transactions', 'Add Accrual Transactions', '0 1 0 1/1 * ? *', '2015-06-03 02:57:04', 3, NULL, NULL, '2015-11-19 00:01:00', 'Add Accrual TransactionsJobDetail1 _ DEFAULT', NULL, 1, 0, 1, 3, 0),
(12, 'Apply penalty to overdue loans', 'Apply penalty to overdue loans', '0 0 0 1/1 * ? *', '2015-06-03 02:57:04', 5, NULL, NULL, '2015-11-19 00:00:00', 'Apply penalty to overdue loansJobDetail1 _ DEFAULT', NULL, 1, 0, 1, 0, 0),
(13, 'Update Non Performing Assets', 'Update Non Performing Assets', '0 0 0 1/1 * ? *', '2015-06-03 02:57:04', 5, NULL, NULL, '2015-11-19 00:00:00', 'Update Non Performing AssetsJobDetail1 _ DEFAULT', NULL, 1, 0, 1, 3, 0),
(14, 'Transfer Interest To Savings', 'Transfer Interest To Savings', '0 2 0 1/1 * ? *', '2015-06-03 02:57:05', 4, NULL, NULL, '2015-11-19 00:02:00', 'Transfer Interest To SavingsJobDetail1 _ DEFAULT', NULL, 1, 0, 1, 1, 0),
(15, 'Update Deposit Accounts Maturity details', 'Update Deposit Accounts Maturity details', '0 0 0 1/1 * ? *', '2015-06-03 02:57:05', 5, NULL, NULL, '2015-11-19 00:00:00', 'Update Deposit Accounts Maturity detailsJobDetail1 _ DEFAULT', NULL, 1, 0, 1, 0, 0),
(16, 'Add Periodic Accrual Transactions', 'Add Periodic Accrual Transactions', '0 2 0 1/1 * ? *', '2015-06-03 02:57:06', 2, NULL, NULL, '2015-11-19 00:02:00', 'Add Periodic Accrual TransactionsJobDetail1 _ DEFAULT', NULL, 1, 0, 1, 3, 0),
(17, 'Recalculate Interest For Loans', 'Recalculate Interest For Loans', '0 1 0 1/1 * ? *', '2015-06-03 02:57:07', 4, NULL, NULL, '2015-11-19 00:01:00', 'Recalculate Interest For LoansJobDetail1 _ DEFAULT', NULL, 1, 0, 1, 3, 0),
(18, 'Generate Mandatory Savings Schedule', 'Generate Mandatory Savings Schedule', '0 5 0 1/1 * ? *', '2015-06-03 02:57:12', 5, NULL, NULL, '2015-11-19 00:05:00', 'Generate Mandatory Savings ScheduleJobDetail1 _ DEFAULT', NULL, 1, 0, 1, 0, 0),
(19, 'Generate Loan Loss Provisioning', 'Generate Loan Loss Provisioning', '0 0 0 1/1 * ? *', '2015-10-20 19:57:53', 5, NULL, NULL, '2015-11-19 00:00:00', 'Generate Loan Loss ProvisioningJobDetail1 _ DEFAULT', NULL, 1, 0, 1, 0, 0);
(1, 'Update loan Summary', 'Update loan Summary', '0 0 22 1/1 * ? *', '2015-06-03 02:56:57', 5, NULL, NULL, '2015-12-02 22:00:00', 'Update loan SummaryJobDetail1 _ DEFAULT', NULL, 1, 0, 1, 0, 0),
(2, 'Update Loan Arrears Ageing', 'Update Loan Arrears Ageing', '0 1 0 1/1 * ? *', '2015-06-03 02:56:57', 5, NULL, NULL, '2015-12-03 00:01:00', 'Update Loan Arrears AgeingJobDetail1 _ DEFAULT', NULL, 1, 0, 1, 0, 0),
(3, 'Update Loan Paid In Advance', 'Update Loan Paid In Advance', '0 5 0 1/1 * ? *', '2015-06-03 02:56:57', 5, NULL, NULL, '2015-12-03 00:05:00', 'Update Loan Paid In AdvanceJobDetail1 _ DEFAULT', NULL, 1, 0, 1, 0, 0),
(4, 'Apply Annual Fee For Savings', 'Apply Annual Fee For Savings', '0 20 22 1/1 * ? *', '2015-06-03 02:56:57', 5, NULL, NULL, '2015-12-02 22:20:00', 'Apply Annual Fee For SavingsJobDetail1 _ DEFAULT', NULL, 1, 0, 1, 0, 0),
(5, 'Apply Holidays To Loans', 'Apply Holidays To Loans', '0 0 12 * * ?', '2015-06-03 02:56:57', 5, NULL, NULL, '2015-12-03 12:00:00', 'Apply Holidays To LoansJobDetail1 _ DEFAULT', NULL, 1, 0, 1, 0, 0),
(6, 'Post Interest For Savings', 'Post Interest For Savings', '0 0 0 1/1 * ? *', '2015-06-03 02:56:58', 5, NULL, NULL, '2015-12-03 00:00:00', 'Post Interest For SavingsJobDetail1 _ DEFAULT', NULL, 1, 0, 1, 1, 0),
(7, 'Transfer Fee For Loans From Savings', 'Transfer Fee For Loans From Savings', '0 1 0 1/1 * ? *', '2015-06-03 02:57:00', 5, NULL, NULL, '2015-12-03 00:01:00', 'Transfer Fee For Loans From SavingsJobDetail1 _ DEFAULT', NULL, 1, 0, 1, 0, 0),
(8, 'Pay Due Savings Charges', 'Pay Due Savings Charges', '0 0 12 * * ?', '2013-09-23 00:00:00', 5, NULL, NULL, '2015-12-03 12:00:00', 'Pay Due Savings ChargesJobDetail1 _ DEFAULT', NULL, 1, 0, 1, 0, 0),
(9, 'Update Accounting Running Balances', 'Update Accounting Running Balances', '0 1 0 1/1 * ? *', '2015-06-03 02:57:00', 5, NULL, NULL, '2015-12-03 00:01:00', 'Update Accounting Running BalancesJobDetail1 _ DEFAULT', NULL, 1, 0, 1, 0, 0),
(10, 'Execute Standing Instruction', 'Execute Standing Instruction', '0 0 0 1/1 * ? *', '2015-06-03 02:57:04', 5, NULL, NULL, '2015-12-03 00:00:00', 'Execute Standing InstructionJobDetail1 _ DEFAULT', NULL, 1, 0, 1, 0, 0),
(11, 'Add Accrual Transactions', 'Add Accrual Transactions', '0 1 0 1/1 * ? *', '2015-06-03 02:57:04', 3, NULL, NULL, '2015-12-03 00:01:00', 'Add Accrual TransactionsJobDetail1 _ DEFAULT', NULL, 1, 0, 1, 3, 0),
(12, 'Apply penalty to overdue loans', 'Apply penalty to overdue loans', '0 0 0 1/1 * ? *', '2015-06-03 02:57:04', 5, NULL, NULL, '2015-12-03 00:00:00', 'Apply penalty to overdue loansJobDetail1 _ DEFAULT', NULL, 1, 0, 1, 0, 0),
(13, 'Update Non Performing Assets', 'Update Non Performing Assets', '0 0 0 1/1 * ? *', '2015-06-03 02:57:04', 5, NULL, NULL, '2015-12-03 00:00:00', 'Update Non Performing AssetsJobDetail1 _ DEFAULT', NULL, 1, 0, 1, 3, 0),
(14, 'Transfer Interest To Savings', 'Transfer Interest To Savings', '0 2 0 1/1 * ? *', '2015-06-03 02:57:05', 4, NULL, NULL, '2015-12-03 00:02:00', 'Transfer Interest To SavingsJobDetail1 _ DEFAULT', NULL, 1, 0, 1, 1, 0),
(15, 'Update Deposit Accounts Maturity details', 'Update Deposit Accounts Maturity details', '0 0 0 1/1 * ? *', '2015-06-03 02:57:05', 5, NULL, NULL, '2015-12-03 00:00:00', 'Update Deposit Accounts Maturity detailsJobDetail1 _ DEFAULT', NULL, 1, 0, 1, 0, 0),
(16, 'Add Periodic Accrual Transactions', 'Add Periodic Accrual Transactions', '0 2 0 1/1 * ? *', '2015-06-03 02:57:06', 2, NULL, NULL, '2015-12-03 00:02:00', 'Add Periodic Accrual TransactionsJobDetail1 _ DEFAULT', NULL, 1, 0, 1, 3, 0),
(17, 'Recalculate Interest For Loans', 'Recalculate Interest For Loans', '0 1 0 1/1 * ? *', '2015-06-03 02:57:07', 4, NULL, NULL, '2015-12-03 00:01:00', 'Recalculate Interest For LoansJobDetail1 _ DEFAULT', NULL, 1, 0, 1, 3, 0),
(18, 'Generate Mandatory Savings Schedule', 'Generate Mandatory Savings Schedule', '0 5 0 1/1 * ? *', '2015-06-03 02:57:12', 5, NULL, NULL, '2015-12-03 00:05:00', 'Generate Mandatory Savings ScheduleJobDetail1 _ DEFAULT', NULL, 1, 0, 1, 0, 0),
(19, 'Generate Loan Loss Provisioning', 'Generate Loan Loss Provisioning', '0 0 0 1/1 * ? *', '2015-10-20 19:57:53', 5, NULL, NULL, '2015-12-03 00:00:00', 'Generate Loan Loss ProvisioningJobDetail1 _ DEFAULT', NULL, 1, 0, 1, 0, 0);
/*!40000 ALTER TABLE `job` ENABLE KEYS */;
@@ -2825,7 +2826,7 @@ CREATE TABLE IF NOT EXISTS `m_permission` (
UNIQUE KEY `code` (`code`)
) ENGINE=InnoDB AUTO_INCREMENT=695 DEFAULT CHARSET=utf8;
-- Dumping data for table mifostenant-default.m_permission: ~775 rows (approximately)
-- Dumping data for table mifostenant-default.m_permission: ~570 rows (approximately)
/*!40000 ALTER TABLE `m_permission` DISABLE KEYS */;
INSERT INTO `m_permission` (`id`, `grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES
(1, 'special', 'ALL_FUNCTIONS', NULL, NULL, 0),
@@ -4630,7 +4631,7 @@ CREATE TABLE IF NOT EXISTS `schema_version` (
KEY `schema_version_s_idx` (`success`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- Dumping data for table mifostenant-default.schema_version: ~371 rows (approximately)
-- Dumping data for table mifostenant-default.schema_version: ~197 rows (approximately)
/*!40000 ALTER TABLE `schema_version` DISABLE KEYS */;
INSERT INTO `schema_version` (`version_rank`, `installed_rank`, `version`, `description`, `type`, `script`, `checksum`, `installed_by`, `installed_on`, `execution_time`, `success`) VALUES
(1, 1, '1', 'mifosplatform-core-ddl-latest', 'SQL', 'V1__mifosplatform-core-ddl-latest.sql', 1800446512, 'root', '2015-06-03 15:26:50', 919, 1),
@@ -4847,6 +4848,8 @@ INSERT INTO `schema_version` (`version_rank`, `installed_rank`, `version`, `desc
(291, 291, '278', 'LoanTransactionProcessingStrategy', 'SQL', 'V278__LoanTransactionProcessingStrategy.sql', -1388446419, 'root', '2015-11-04 17:03:00', 878, 1),
(292, 292, '279', 'floating rates', 'SQL', 'V279__floating_rates.sql', 830029264, 'root', '2015-11-18 16:13:08', 620, 1),
(28, 28, '28', 'accounting-abstractions-and-autoposting', 'SQL', 'V28__accounting-abstractions-and-autoposting.sql', -626584837, 'root', '2015-06-03 15:26:53', 63, 1),
(293, 293, '280', 'spm framework initial tables', 'SQL', 'V280__spm_framework_initial_tables.sql', -1638980235, 'root', '2015-12-02 16:07:43', 509, 1),
(294, 294, '281', 'add configuration param backdate-penalties', 'SQL', 'V281__add_configuration_param_backdate-penalties.sql', -45520299, 'root', '2015-12-02 16:07:44', 39, 1),
(29, 29, '29', 'add-support-for-annual-fees-on-savings', 'SQL', 'V29__add-support-for-annual-fees-on-savings.sql', -1595233842, 'root', '2015-06-03 15:26:53', 157, 1),
(3, 3, '3', 'mifosx-permissions-and-authorisation-utf8', 'SQL', 'V3__mifosx-permissions-and-authorisation-utf8.sql', 914436650, 'root', '2015-06-03 15:26:50', 14, 1),
(30, 30, '30', 'add-referenceNumber-to-acc gl journal entry', 'SQL', 'V30__add-referenceNumber-to-acc_gl_journal_entry.sql', 255130282, 'root', '2015-06-03 15:26:53', 59, 1),
@@ -5014,7 +5017,7 @@ CREATE TABLE IF NOT EXISTS `stretchy_report` (
UNIQUE KEY `report_name_UNIQUE` (`report_name`)
) ENGINE=InnoDB AUTO_INCREMENT=165 DEFAULT CHARSET=utf8;
-- Dumping data for table mifostenant-default.stretchy_report: ~125 rows (approximately)
-- Dumping data for table mifostenant-default.stretchy_report: ~61 rows (approximately)
/*!40000 ALTER TABLE `stretchy_report` DISABLE KEYS */;
INSERT INTO `stretchy_report` (`id`, `report_name`, `report_type`, `report_subtype`, `report_category`, `report_sql`, `description`, `core_report`, `use_report`) VALUES
(1, 'Client Listing', 'Table', NULL, 'Client', 'select\nconcat(repeat("..",\n ((LENGTH(ounder.`hierarchy`) - LENGTH(REPLACE(ounder.`hierarchy`, \'.\', \'\')) - 1))), ounder.`name`) as "Office/Branch",\n c.account_no as "Client Account No.",\nc.display_name as "Name",\nr.enum_message_property as "Status",\nc.activation_date as "Activation", c.external_id as "External Id"\nfrom m_office o\njoin m_office ounder on ounder.hierarchy like concat(o.hierarchy, \'%\')\nand ounder.hierarchy like concat(\'${currentUserHierarchy}\', \'%\')\njoin m_client c on c.office_id = ounder.id\nleft join r_enum_value r on r.enum_name = \'status_enum\' and r.enum_id = c.status_enum\nwhere o.id = ${officeId}\norder by ounder.hierarchy, c.account_no', 'Individual Client Report\r\n\r\nLists the small number of defined fields on the client table. Would expect to copy this \n\nreport and add any \'one to one\' additional data for specific tenant needs.\r\n\r\nCan be run for any size MFI but you\'d expect it only to be run within a branch for \n\nlarger ones. Depending on how many columns are displayed, there is probably is a limit of about 20/50k clients returned for html display (export to excel doesn\'t \n\nhave that client browser/memory impact).', 1, 1),
@@ -323,7 +323,7 @@ CREATE TABLE IF NOT EXISTS `c_configuration` (
`description` varchar(300) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `name_UNIQUE` (`name`)
) ENGINE=InnoDB AUTO_INCREMENT=24 DEFAULT CHARSET=utf8;
) ENGINE=InnoDB AUTO_INCREMENT=25 DEFAULT CHARSET=utf8;
-- Dumping data for table mifostenant-reference.c_configuration: ~19 rows (approximately)
/*!40000 ALTER TABLE `c_configuration` DISABLE KEYS */;
@@ -346,7 +346,8 @@ INSERT INTO `c_configuration` (`id`, `name`, `value`, `enabled`, `is_trap_door`,
(20, 'office-specific-products-enabled', 0, 0, 0, 'Whether products and fees should be office specific or not? This property should NOT be changed once Mifos is Live.'),
(21, 'restrict-products-to-user-office', 0, 0, 0, 'This should be enabled only if, products & fees are office specific (i.e. office-specific-products-enabled is enabled). This property specifies if the products should be auto-restricted to office of the user who created the proudct? Note: This property should NOT be changed once Mifos is Live.'),
(22, 'office-opening-balances-contra-account', 0, 1, 0, NULL),
(23, 'rounding-mode', 6, 1, 1, '0 - UP, 1 - DOWN, 2- CEILING, 3- FLOOR, 4- HALF_UP, 5- HALF_DOWN, 6 - HALF_EVEN');
(23, 'rounding-mode', 6, 1, 1, '0 - UP, 1 - DOWN, 2- CEILING, 3- FLOOR, 4- HALF_UP, 5- HALF_DOWN, 6 - HALF_EVEN'),
(24, 'backdate-penalties-enabled', 0, 1, 0, 'If this parameter is disabled penalties will only be added to instalments due moving forward, any old overdue instalments will not be affected.');
/*!40000 ALTER TABLE `c_configuration` ENABLE KEYS */;
@@ -416,25 +417,25 @@ CREATE TABLE IF NOT EXISTS `job` (
-- Dumping data for table mifostenant-reference.job: ~19 rows (approximately)
/*!40000 ALTER TABLE `job` DISABLE KEYS */;
INSERT INTO `job` (`id`, `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`, `is_misfired`) VALUES
(1, 'Update loan Summary', 'Update loan Summary', '0 0 22 1/1 * ? *', '2014-03-07 18:29:14', 5, NULL, '2014-06-11 09:30:00', '2015-11-18 22:00:00', 'Update loan SummaryJobDetail2 _ DEFAULT', NULL, 1, 0, 1, 0, 0),
(2, 'Update Loan Arrears Ageing', 'Update Loan Arrears Ageing', '0 1 0 1/1 * ? *', '2014-03-07 18:29:14', 5, NULL, NULL, '2015-11-19 00:01:00', 'Update Loan Arrears AgeingJobDetail2 _ DEFAULT', NULL, 1, 0, 1, 0, 0),
(3, 'Update Loan Paid In Advance', 'Update Loan Paid In Advance', '0 5 0 1/1 * ? *', '2014-03-07 18:29:14', 5, NULL, NULL, '2015-11-19 00:05:00', 'Update Loan Paid In AdvanceJobDetail2 _ DEFAULT', NULL, 1, 0, 1, 0, 0),
(4, 'Apply Annual Fee For Savings', 'Apply Annual Fee For Savings', '0 20 22 1/1 * ? *', '2014-03-07 18:29:14', 5, NULL, '2014-06-11 09:50:00', '2015-11-18 22:20:00', 'Apply Annual Fee For SavingsJobDetail2 _ DEFAULT', NULL, 1, 0, 1, 0, 0),
(5, 'Apply Holidays To Loans', 'Apply Holidays To Loans', '0 0 12 * * ?', '2014-03-07 18:29:14', 5, NULL, '2014-03-24 12:00:04', '2015-11-19 12:00:00', 'Apply Holidays To LoansJobDetail2 _ DEFAULT', NULL, 1, 0, 1, 0, 0),
(6, 'Post Interest For Savings', 'Post Interest For Savings', '0 0 0 1/1 * ? *', '2014-03-07 18:29:21', 5, NULL, NULL, '2015-11-19 00:00:00', 'Post Interest For SavingsJobDetail2 _ DEFAULT', NULL, 1, 0, 1, 1, 0),
(7, 'Transfer Fee For Loans From Savings', 'Transfer Fee For Loans From Savings', '0 1 0 1/1 * ? *', '2014-03-07 18:29:32', 5, NULL, NULL, '2015-11-19 00:01:00', 'Transfer Fee For Loans From SavingsJobDetail2 _ DEFAULT', NULL, 1, 0, 1, 0, 0),
(8, 'Pay Due Savings Charges', 'Pay Due Savings Charges', '0 0 12 * * ?', '2013-09-23 00:00:00', 5, NULL, '2014-03-24 12:00:04', '2015-11-19 12:00:00', 'Pay Due Savings ChargesJobDetail2 _ DEFAULT', NULL, 1, 0, 1, 0, 0),
(9, 'Update Accounting Running Balances', 'Update Accounting Running Balances', '0 1 0 1/1 * ? *', '2014-03-07 18:29:37', 5, NULL, NULL, '2015-11-19 00:01:00', 'Update Accounting Running BalancesJobDetail2 _ DEFAULT', NULL, 1, 0, 1, 0, 0),
(10, 'Execute Standing Instruction', 'Execute Standing Instruction', '0 0 0 1/1 * ? *', '2014-05-01 16:10:35', 5, NULL, NULL, '2015-11-19 00:00:00', 'Execute Standing InstructionJobDetail2 _ DEFAULT', NULL, 1, 0, 1, 0, 0),
(11, 'Add Accrual Transactions', 'Add Accrual Transactions', '0 1 0 1/1 * ? *', '2014-05-01 16:10:36', 3, NULL, NULL, '2015-11-19 00:01:00', 'Add Accrual TransactionsJobDetail2 _ DEFAULT', NULL, 1, 0, 1, 3, 0),
(12, 'Apply penalty to overdue loans', 'Apply penalty to overdue loans', '0 0 0 1/1 * ? *', '2014-05-01 16:10:36', 5, NULL, NULL, '2015-11-19 00:00:00', 'Apply penalty to overdue loansJobDetail2 _ DEFAULT', NULL, 1, 0, 1, 0, 0),
(13, 'Update Non Performing Assets', 'Update Non Performing Assets', '0 0 0 1/1 * ? *', '2014-05-01 16:10:41', 5, NULL, NULL, '2015-11-19 00:00:00', 'Update Non Performing AssetsJobDetail2 _ DEFAULT', NULL, 1, 0, 1, 3, 0),
(14, 'Transfer Interest To Savings', 'Transfer Interest To Savings', '0 2 0 1/1 * ? *', '2014-06-11 09:09:15', 4, NULL, NULL, '2015-11-19 00:02:00', 'Transfer Interest To SavingsJobDetail2 _ DEFAULT', NULL, 1, 0, 1, 1, 0),
(15, 'Update Deposit Accounts Maturity details', 'Update Deposit Accounts Maturity details', '0 0 0 1/1 * ? *', '2014-06-11 09:09:15', 5, NULL, NULL, '2015-11-19 00:00:00', 'Update Deposit Accounts Maturity detailsJobDetail2 _ DEFAULT', NULL, 1, 0, 1, 0, 0),
(16, 'Add Periodic Accrual Transactions', 'Add Periodic Accrual Transactions', '0 2 0 1/1 * ? *', '2014-10-14 16:19:45', 2, NULL, NULL, '2015-11-19 00:02:00', 'Add Periodic Accrual TransactionsJobDetail2 _ DEFAULT', NULL, 1, 0, 1, 3, 0),
(17, 'Recalculate Interest For Loans', 'Recalculate Interest For Loans', '0 1 0 1/1 * ? *', '2014-10-14 16:19:55', 4, NULL, NULL, '2015-11-19 00:01:00', 'Recalculate Interest For LoansJobDetail2 _ DEFAULT', NULL, 1, 0, 1, 3, 0),
(18, 'Generate Mandatory Savings Schedule', 'Generate Mandatory Savings Schedule', '0 5 0 1/1 * ? *', '2015-04-16 02:28:43', 5, NULL, NULL, '2015-11-19 00:05:00', 'Generate Mandatory Savings ScheduleJobDetail2 _ DEFAULT', NULL, 1, 0, 1, 0, 0),
(19, 'Generate Loan Loss Provisioning', 'Generate Loan Loss Provisioning', '0 0 0 1/1 * ? *', '2015-10-20 19:57:58', 5, NULL, NULL, '2015-11-19 00:00:00', 'Generate Loan Loss ProvisioningJobDetail2 _ DEFAULT', NULL, 1, 0, 1, 0, 0);
(1, 'Update loan Summary', 'Update loan Summary', '0 0 22 1/1 * ? *', '2014-03-07 18:29:14', 5, NULL, '2014-06-11 09:30:00', '2015-12-02 22:00:00', 'Update loan SummaryJobDetail2 _ DEFAULT', NULL, 1, 0, 1, 0, 0),
(2, 'Update Loan Arrears Ageing', 'Update Loan Arrears Ageing', '0 1 0 1/1 * ? *', '2014-03-07 18:29:14', 5, NULL, NULL, '2015-12-03 00:01:00', 'Update Loan Arrears AgeingJobDetail2 _ DEFAULT', NULL, 1, 0, 1, 0, 0),
(3, 'Update Loan Paid In Advance', 'Update Loan Paid In Advance', '0 5 0 1/1 * ? *', '2014-03-07 18:29:14', 5, NULL, NULL, '2015-12-03 00:05:00', 'Update Loan Paid In AdvanceJobDetail2 _ DEFAULT', NULL, 1, 0, 1, 0, 0),
(4, 'Apply Annual Fee For Savings', 'Apply Annual Fee For Savings', '0 20 22 1/1 * ? *', '2014-03-07 18:29:14', 5, NULL, '2014-06-11 09:50:00', '2015-12-02 22:20:00', 'Apply Annual Fee For SavingsJobDetail2 _ DEFAULT', NULL, 1, 0, 1, 0, 0),
(5, 'Apply Holidays To Loans', 'Apply Holidays To Loans', '0 0 12 * * ?', '2014-03-07 18:29:14', 5, NULL, '2014-03-24 12:00:04', '2015-12-03 12:00:00', 'Apply Holidays To LoansJobDetail2 _ DEFAULT', NULL, 1, 0, 1, 0, 0),
(6, 'Post Interest For Savings', 'Post Interest For Savings', '0 0 0 1/1 * ? *', '2014-03-07 18:29:21', 5, NULL, NULL, '2015-12-03 00:00:00', 'Post Interest For SavingsJobDetail2 _ DEFAULT', NULL, 1, 0, 1, 1, 0),
(7, 'Transfer Fee For Loans From Savings', 'Transfer Fee For Loans From Savings', '0 1 0 1/1 * ? *', '2014-03-07 18:29:32', 5, NULL, NULL, '2015-12-03 00:01:00', 'Transfer Fee For Loans From SavingsJobDetail2 _ DEFAULT', NULL, 1, 0, 1, 0, 0),
(8, 'Pay Due Savings Charges', 'Pay Due Savings Charges', '0 0 12 * * ?', '2013-09-23 00:00:00', 5, NULL, '2014-03-24 12:00:04', '2015-12-03 12:00:00', 'Pay Due Savings ChargesJobDetail2 _ DEFAULT', NULL, 1, 0, 1, 0, 0),
(9, 'Update Accounting Running Balances', 'Update Accounting Running Balances', '0 1 0 1/1 * ? *', '2014-03-07 18:29:37', 5, NULL, NULL, '2015-12-03 00:01:00', 'Update Accounting Running BalancesJobDetail2 _ DEFAULT', NULL, 1, 0, 1, 0, 0),
(10, 'Execute Standing Instruction', 'Execute Standing Instruction', '0 0 0 1/1 * ? *', '2014-05-01 16:10:35', 5, NULL, NULL, '2015-12-03 00:00:00', 'Execute Standing InstructionJobDetail2 _ DEFAULT', NULL, 1, 0, 1, 0, 0),
(11, 'Add Accrual Transactions', 'Add Accrual Transactions', '0 1 0 1/1 * ? *', '2014-05-01 16:10:36', 3, NULL, NULL, '2015-12-03 00:01:00', 'Add Accrual TransactionsJobDetail2 _ DEFAULT', NULL, 1, 0, 1, 3, 0),
(12, 'Apply penalty to overdue loans', 'Apply penalty to overdue loans', '0 0 0 1/1 * ? *', '2014-05-01 16:10:36', 5, NULL, NULL, '2015-12-03 00:00:00', 'Apply penalty to overdue loansJobDetail2 _ DEFAULT', NULL, 1, 0, 1, 0, 0),
(13, 'Update Non Performing Assets', 'Update Non Performing Assets', '0 0 0 1/1 * ? *', '2014-05-01 16:10:41', 5, NULL, NULL, '2015-12-03 00:00:00', 'Update Non Performing AssetsJobDetail2 _ DEFAULT', NULL, 1, 0, 1, 3, 0),
(14, 'Transfer Interest To Savings', 'Transfer Interest To Savings', '0 2 0 1/1 * ? *', '2014-06-11 09:09:15', 4, NULL, NULL, '2015-12-03 00:02:00', 'Transfer Interest To SavingsJobDetail2 _ DEFAULT', NULL, 1, 0, 1, 1, 0),
(15, 'Update Deposit Accounts Maturity details', 'Update Deposit Accounts Maturity details', '0 0 0 1/1 * ? *', '2014-06-11 09:09:15', 5, NULL, NULL, '2015-12-03 00:00:00', 'Update Deposit Accounts Maturity detailsJobDetail2 _ DEFAULT', NULL, 1, 0, 1, 0, 0),
(16, 'Add Periodic Accrual Transactions', 'Add Periodic Accrual Transactions', '0 2 0 1/1 * ? *', '2014-10-14 16:19:45', 2, NULL, NULL, '2015-12-03 00:02:00', 'Add Periodic Accrual TransactionsJobDetail2 _ DEFAULT', NULL, 1, 0, 1, 3, 0),
(17, 'Recalculate Interest For Loans', 'Recalculate Interest For Loans', '0 1 0 1/1 * ? *', '2014-10-14 16:19:55', 4, NULL, NULL, '2015-12-03 00:01:00', 'Recalculate Interest For LoansJobDetail2 _ DEFAULT', NULL, 1, 0, 1, 3, 0),
(18, 'Generate Mandatory Savings Schedule', 'Generate Mandatory Savings Schedule', '0 5 0 1/1 * ? *', '2015-04-16 02:28:43', 5, NULL, NULL, '2015-12-03 00:05:00', 'Generate Mandatory Savings ScheduleJobDetail2 _ DEFAULT', NULL, 1, 0, 1, 0, 0),
(19, 'Generate Loan Loss Provisioning', 'Generate Loan Loss Provisioning', '0 0 0 1/1 * ? *', '2015-10-20 19:57:58', 5, NULL, NULL, '2015-12-03 00:00:00', 'Generate Loan Loss ProvisioningJobDetail2 _ DEFAULT', NULL, 1, 0, 1, 0, 0);
/*!40000 ALTER TABLE `job` ENABLE KEYS */;
@@ -2997,7 +2998,7 @@ CREATE TABLE IF NOT EXISTS `m_permission` (
UNIQUE KEY `code` (`code`)
) ENGINE=InnoDB AUTO_INCREMENT=695 DEFAULT CHARSET=utf8;
-- Dumping data for table mifostenant-reference.m_permission: ~706 rows (approximately)
-- Dumping data for table mifostenant-reference.m_permission: ~741 rows (approximately)
/*!40000 ALTER TABLE `m_permission` DISABLE KEYS */;
INSERT INTO `m_permission` (`id`, `grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES
(1, 'special', 'ALL_FUNCTIONS', NULL, NULL, 0),
@@ -3739,7 +3740,7 @@ CREATE TABLE IF NOT EXISTS `m_portfolio_command_source` (
CONSTRAINT `FK_m_maker_m_appuser` FOREIGN KEY (`maker_id`) REFERENCES `m_appuser` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=73 DEFAULT CHARSET=utf8;
-- Dumping data for table mifostenant-reference.m_portfolio_command_source: ~75 rows (approximately)
-- Dumping data for table mifostenant-reference.m_portfolio_command_source: ~71 rows (approximately)
/*!40000 ALTER TABLE `m_portfolio_command_source` DISABLE KEYS */;
INSERT INTO `m_portfolio_command_source` (`id`, `action_name`, `entity_name`, `office_id`, `group_id`, `client_id`, `loan_id`, `savings_account_id`, `api_get_url`, `resource_id`, `subresource_id`, `command_as_json`, `maker_id`, `made_on_date`, `checker_id`, `checked_on_date`, `processing_result_enum`, `product_id`, `transaction_id`) VALUES
(1, 'CREATE', 'STAFF', 1, NULL, NULL, NULL, NULL, '/staff/template', 1, NULL, '{"isLoanOfficer":true,"officeId":1,"firstname":"Aliya","lastname":"A"}', 1, '2014-03-07 19:10:05', NULL, NULL, 1, NULL, NULL),
@@ -4887,7 +4888,7 @@ CREATE TABLE IF NOT EXISTS `schema_version` (
KEY `schema_version_s_idx` (`success`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
-- Dumping data for table mifostenant-reference.schema_version: ~280 rows (approximately)
-- Dumping data for table mifostenant-reference.schema_version: ~322 rows (approximately)
/*!40000 ALTER TABLE `schema_version` DISABLE KEYS */;
INSERT INTO `schema_version` (`version_rank`, `installed_rank`, `version`, `description`, `type`, `script`, `checksum`, `installed_by`, `installed_on`, `execution_time`, `success`) VALUES
(1, 1, '1', 'mifosplatform-core-ddl-latest', 'SQL', 'V1__mifosplatform-core-ddl-latest.sql', -1957145051, 'root', '2014-03-08 02:28:38', 10710, 1),
@@ -5104,6 +5105,8 @@ INSERT INTO `schema_version` (`version_rank`, `installed_rank`, `version`, `desc
(291, 291, '278', 'LoanTransactionProcessingStrategy', 'SQL', 'V278__LoanTransactionProcessingStrategy.sql', -1388446419, 'root', '2015-11-04 17:03:01', 877, 1),
(292, 292, '279', 'floating rates', 'SQL', 'V279__floating_rates.sql', 830029264, 'root', '2015-11-18 16:13:09', 645, 1),
(28, 28, '28', 'accounting-abstractions-and-autoposting', 'SQL', 'V28__accounting-abstractions-and-autoposting.sql', -966431980, 'root', '2014-03-08 02:28:53', 556, 1),
(293, 293, '280', 'spm framework initial tables', 'SQL', 'V280__spm_framework_initial_tables.sql', -1638980235, 'root', '2015-12-02 16:07:45', 630, 1),
(294, 294, '281', 'add configuration param backdate-penalties', 'SQL', 'V281__add_configuration_param_backdate-penalties.sql', -45520299, 'root', '2015-12-02 16:07:45', 45, 1),
(29, 29, '29', 'add-support-for-annual-fees-on-savings', 'SQL', 'V29__add-support-for-annual-fees-on-savings.sql', 992227725, 'root', '2014-03-08 02:28:55', 1556, 1),
(3, 3, '3', 'mifosx-permissions-and-authorisation-utf8', 'SQL', 'V3__mifosx-permissions-and-authorisation-utf8.sql', 1922951887, 'root', '2014-03-08 02:28:38', 110, 1),
(30, 30, '30', 'add-referenceNumber-to-acc gl journal entry', 'SQL', 'V30__add-referenceNumber-to-acc_gl_journal_entry.sql', 2079970797, 'root', '2014-03-08 02:28:55', 327, 1),
@@ -5271,7 +5274,7 @@ CREATE TABLE IF NOT EXISTS `stretchy_report` (
UNIQUE KEY `report_name_UNIQUE` (`report_name`)
) ENGINE=InnoDB AUTO_INCREMENT=165 DEFAULT CHARSET=utf8;
-- Dumping data for table mifostenant-reference.stretchy_report: ~61 rows (approximately)
-- Dumping data for table mifostenant-reference.stretchy_report: ~125 rows (approximately)
/*!40000 ALTER TABLE `stretchy_report` DISABLE KEYS */;
INSERT INTO `stretchy_report` (`id`, `report_name`, `report_type`, `report_subtype`, `report_category`, `report_sql`, `description`, `core_report`, `use_report`) VALUES
(1, 'Client Listing', 'Table', NULL, 'Client', 'select \nconcat(repeat("..", \n ((LENGTH(ounder.`hierarchy`) - LENGTH(REPLACE(ounder.`hierarchy`, \'.\', \'\')) - 1))), ounder.`name`) as "Office/Branch",\n c.account_no as "Client Account No.", \nc.display_name as "Name", \nr.enum_message_property as "Status",\nc.activation_date as "Activation", c.external_id as "External Id"\nfrom m_office o \njoin m_office ounder on ounder.hierarchy like concat(o.hierarchy, \'%\')\nand ounder.hierarchy like concat(\'${currentUserHierarchy}\', \'%\')\njoin m_client c on c.office_id = ounder.id\nleft join r_enum_value r on r.enum_name = \'status_enum\' and r.enum_id = c.status_enum\nwhere o.id = ${officeId}\norder by ounder.hierarchy, c.account_no', 'Individual Client Report\r\n\r\nLists the small number of defined fields on the client table. Would expect to copy this \n\nreport and add any \'one to one\' additional data for specific tenant needs.\r\n\r\nCan be run for any size MFI but you\'d expect it only to be run within a branch for \n\nlarger ones. Depending on how many columns are displayed, there is probably is a limit of about 20/50k clients returned for html display (export to excel doesn\'t \n\nhave that client browser/memory impact).', 1, 1),