From ab1254ab680bb2e88ed876f098f385999778d425 Mon Sep 17 00:00:00 2001 From: Keith Woodlock Date: Tue, 3 Dec 2013 01:07:13 +0000 Subject: [PATCH 01/15] update properties for release --- api-docs/apiLive.htm | 2 +- mifosng-provider/gradle.properties | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/api-docs/apiLive.htm b/api-docs/apiLive.htm index b15b59f0c..c81ed9a1f 100644 --- a/api-docs/apiLive.htm +++ b/api-docs/apiLive.htm @@ -90,7 +90,7 @@
- +

Overview

diff --git a/mifosng-provider/gradle.properties b/mifosng-provider/gradle.properties index 7602f39de..68ebc7cbe 100644 --- a/mifosng-provider/gradle.properties +++ b/mifosng-provider/gradle.properties @@ -1,3 +1,3 @@ -releaseVersion=1.15.0.RELEASE +releaseVersion=1.15.1.RELEASE From 96cefdddc55c7430a74ff4e959644b1ba0591b8e Mon Sep 17 00:00:00 2001 From: Pramod Nuthakki Date: Mon, 2 Dec 2013 22:08:15 +0530 Subject: [PATCH 02/15] added running balance as optional to GLAccount --- api-docs/apiLive.htm | 5 ++ .../glaccount/api/GLAccountsApiResource.java | 14 ++-- .../service/GLAccountReadPlatformService.java | 5 +- .../GLAccountReadPlatformServiceImpl.java | 68 +++++++++++++------ 4 files changed, 65 insertions(+), 27 deletions(-) diff --git a/api-docs/apiLive.htm b/api-docs/apiLive.htm index c81ed9a1f..d35024065 100644 --- a/api-docs/apiLive.htm +++ b/api-docs/apiLive.htm @@ -19232,6 +19232,8 @@ Request Body:

glaccounts?type=1&manualEntriesAllowed=true&usage=1&disabled=false
+
+
glaccounts?fetchRunningBalance=true
@@ -19544,6 +19546,9 @@ GET https://DomainName/api/v1/glaccounts/template?type=1

glaccounts/1?fields=name,glCode
+
+
+
glaccounts/1?fetchRunningBalance=true
diff --git a/mifosng-provider/src/main/java/org/mifosplatform/accounting/glaccount/api/GLAccountsApiResource.java b/mifosng-provider/src/main/java/org/mifosplatform/accounting/glaccount/api/GLAccountsApiResource.java index 02a150463..07233f6f8 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/accounting/glaccount/api/GLAccountsApiResource.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/accounting/glaccount/api/GLAccountsApiResource.java @@ -29,6 +29,7 @@ import org.mifosplatform.accounting.common.AccountingDropdownReadPlatformService import org.mifosplatform.accounting.glaccount.data.GLAccountData; import org.mifosplatform.accounting.glaccount.domain.GLAccountType; import org.mifosplatform.accounting.glaccount.service.GLAccountReadPlatformService; +import org.mifosplatform.accounting.journalentry.data.JournalEntryAssociationParametersData; import org.mifosplatform.commands.domain.CommandWrapper; import org.mifosplatform.commands.service.CommandWrapperBuilder; import org.mifosplatform.commands.service.PortfolioCommandSourceWritePlatformService; @@ -100,11 +101,13 @@ public class GLAccountsApiResource { @Produces({ MediaType.APPLICATION_JSON }) public String retrieveAllAccounts(@Context final UriInfo uriInfo, @QueryParam("type") final Integer type, @QueryParam("searchParam") final String searchParam, @QueryParam("usage") final Integer usage, - @QueryParam("manualEntriesAllowed") final Boolean manualEntriesAllowed, @QueryParam("disabled") final Boolean disabled) { + @QueryParam("manualEntriesAllowed") final Boolean manualEntriesAllowed, @QueryParam("disabled") final Boolean disabled, + @QueryParam("fetchRunningBalance") final boolean runningBalance) { this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermission); + JournalEntryAssociationParametersData associationParametersData = new JournalEntryAssociationParametersData(false, runningBalance); final List glAccountDatas = this.glAccountReadPlatformService.retrieveAllGLAccounts(type, searchParam, usage, - manualEntriesAllowed, disabled); + manualEntriesAllowed, disabled, associationParametersData); final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters()); return this.apiJsonSerializerService.serialize(settings, glAccountDatas, RESPONSE_DATA_PARAMETERS); @@ -114,13 +117,14 @@ public class GLAccountsApiResource { @Path("{glAccountId}") @Consumes({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON }) - public String retreiveAccount(@PathParam("glAccountId") final Long glAccountId, @Context final UriInfo uriInfo) { + public String retreiveAccount(@PathParam("glAccountId") final Long glAccountId, @Context final UriInfo uriInfo, + @QueryParam("fetchRunningBalance") final boolean runningBalance) { this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermission); final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters()); - - GLAccountData glAccountData = this.glAccountReadPlatformService.retrieveGLAccountById(glAccountId); + JournalEntryAssociationParametersData associationParametersData = new JournalEntryAssociationParametersData(false, runningBalance); + GLAccountData glAccountData = this.glAccountReadPlatformService.retrieveGLAccountById(glAccountId,associationParametersData); if (settings.isTemplate()) { glAccountData = handleTemplate(glAccountData); } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/accounting/glaccount/service/GLAccountReadPlatformService.java b/mifosng-provider/src/main/java/org/mifosplatform/accounting/glaccount/service/GLAccountReadPlatformService.java index c03ba7423..95f891c1d 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/accounting/glaccount/service/GLAccountReadPlatformService.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/accounting/glaccount/service/GLAccountReadPlatformService.java @@ -10,13 +10,14 @@ import java.util.List; import org.mifosplatform.accounting.glaccount.data.GLAccountData; import org.mifosplatform.accounting.glaccount.data.GLAccountDataForLookup; import org.mifosplatform.accounting.glaccount.domain.GLAccountType; +import org.mifosplatform.accounting.journalentry.data.JournalEntryAssociationParametersData; public interface GLAccountReadPlatformService { List retrieveAllGLAccounts(Integer accountClassification, String searchParam, Integer usage, - Boolean manualTransactionsAllowed, Boolean disabled); + Boolean manualTransactionsAllowed, Boolean disabled, JournalEntryAssociationParametersData associationParametersData); - GLAccountData retrieveGLAccountById(long glAccountId); + GLAccountData retrieveGLAccountById(long glAccountId,JournalEntryAssociationParametersData associationParametersData); List retrieveAllEnabledDetailGLAccounts(); diff --git a/mifosng-provider/src/main/java/org/mifosplatform/accounting/glaccount/service/GLAccountReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/accounting/glaccount/service/GLAccountReadPlatformServiceImpl.java index 2f629f12a..2d6558914 100755 --- a/mifosng-provider/src/main/java/org/mifosplatform/accounting/glaccount/service/GLAccountReadPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/accounting/glaccount/service/GLAccountReadPlatformServiceImpl.java @@ -18,6 +18,7 @@ import org.mifosplatform.accounting.glaccount.domain.GLAccountType; import org.mifosplatform.accounting.glaccount.domain.GLAccountUsage; import org.mifosplatform.accounting.glaccount.exception.GLAccountInvalidClassificationException; import org.mifosplatform.accounting.glaccount.exception.GLAccountNotFoundException; +import org.mifosplatform.accounting.journalentry.data.JournalEntryAssociationParametersData; import org.mifosplatform.infrastructure.codes.data.CodeValueData; import org.mifosplatform.infrastructure.core.data.EnumOptionData; import org.mifosplatform.infrastructure.core.domain.JdbcSupport; @@ -41,15 +42,31 @@ public class GLAccountReadPlatformServiceImpl implements GLAccountReadPlatformSe private static final class GLAccountMapper implements RowMapper { + private final JournalEntryAssociationParametersData associationParametersData; + + + public GLAccountMapper(final JournalEntryAssociationParametersData associationParametersData) { + if(associationParametersData == null){ + this.associationParametersData = new JournalEntryAssociationParametersData(); + }else{ + this.associationParametersData = associationParametersData; + } + } + public String schema() { - return " gl.id as id, name as name, parent_id as parentId, gl_code as glCode, disabled as disabled, manual_journal_entries_allowed as manualEntriesAllowed, " - + "classification_enum as classification, account_usage as accountUsage, gl.description as description, " - + nameDecoratedBaseOnHierarchy - + "as nameDecorated, " - + "cv.id as codeId, cv.code_value as codeValue,gl_j.organization_running_balance as organizationRunningBalance " - + "from acc_gl_account gl left join m_code_value cv on tag_id=cv.id " - + "left outer Join acc_gl_journal_entry gl_j on gl_j.account_id = gl.id"; - + StringBuilder sb = new StringBuilder(); + sb.append(" gl.id as id, name as name, parent_id as parentId, gl_code as glCode, disabled as disabled, manual_journal_entries_allowed as manualEntriesAllowed, ") + .append("classification_enum as classification, account_usage as accountUsage, gl.description as description, ") + .append(nameDecoratedBaseOnHierarchy).append(" as nameDecorated, ") + .append("cv.id as codeId, cv.code_value as codeValue "); + if(this.associationParametersData.isRunningBalanceRequired()){ + sb.append(",gl_j.organization_running_balance as organizationRunningBalance "); + } + sb.append("from acc_gl_account gl left join m_code_value cv on tag_id=cv.id "); + if(this.associationParametersData.isRunningBalanceRequired()){ + sb.append("left outer Join acc_gl_journal_entry gl_j on gl_j.account_id = gl.id"); + } + return sb.toString(); } @Override @@ -70,7 +87,10 @@ public class GLAccountReadPlatformServiceImpl implements GLAccountReadPlatformSe final Long codeId = rs.wasNull() ? null : rs.getLong("codeId"); final String codeValue = rs.getString("codeValue"); final CodeValueData tagId = CodeValueData.instance(codeId, codeValue); - final Long organizationRunningBalance = rs.getLong("organizationRunningBalance"); + Long organizationRunningBalance = null; + if(associationParametersData.isRunningBalanceRequired()){ + organizationRunningBalance = rs.getLong("organizationRunningBalance"); + } return new GLAccountData(id, name, parentId, glCode, disabled, manualEntriesAllowed, accountType, usage, description, nameDecorated, tagId, organizationRunningBalance); } @@ -78,7 +98,7 @@ public class GLAccountReadPlatformServiceImpl implements GLAccountReadPlatformSe @Override public List retrieveAllGLAccounts(final Integer accountClassification, final String searchParam, final Integer usage, - final Boolean manualTransactionsAllowed, final Boolean disabled) { + final Boolean manualTransactionsAllowed, final Boolean disabled, JournalEntryAssociationParametersData associationParametersData) { if (accountClassification != null) { if (!checkValidGLAccountType(accountClassification)) { throw new GLAccountInvalidClassificationException(accountClassification); } } @@ -87,11 +107,13 @@ public class GLAccountReadPlatformServiceImpl implements GLAccountReadPlatformSe if (!checkValidGLAccountUsage(usage)) { throw new GLAccountInvalidClassificationException(accountClassification); } } - final GLAccountMapper rm = new GLAccountMapper(); + final GLAccountMapper rm = new GLAccountMapper(associationParametersData); String sql = "select " + rm.schema(); // append SQL statement for fetching account totals + if(associationParametersData.isRunningBalanceRequired()){ sql = sql + " and gl_j.id in (select t1.id from (SELECT t2.id , max(concat(t2.entry_date,t2.id)) " + "FROM acc_gl_journal_entry t2 WHERE is_running_balance_caculated = 1 GROUP BY t2.account_id DESC) t1)"; + } final Object[] paramaterArray = new Object[3]; int arrayPos = 0; boolean filtersPresent = false; @@ -162,14 +184,20 @@ public class GLAccountReadPlatformServiceImpl implements GLAccountReadPlatformSe } @Override - public GLAccountData retrieveGLAccountById(final long glAccountId) { + public GLAccountData retrieveGLAccountById(final long glAccountId,JournalEntryAssociationParametersData associationParametersData) { try { - final GLAccountMapper rm = new GLAccountMapper(); - final String sql = "select " + rm.schema() - + " and gl_j.is_running_balance_caculated = 1 where gl.id = ? ORDER BY gl_j.entry_date DESC,gl_j.id DESC LIMIT 1"; - - final GLAccountData glAccountData = this.jdbcTemplate.queryForObject(sql, rm, new Object[] { glAccountId }); + final GLAccountMapper rm = new GLAccountMapper(associationParametersData); + final StringBuilder sql = new StringBuilder(); + sql.append("select ").append(rm.schema()); + if(associationParametersData.isRunningBalanceRequired()){ + sql.append(" and gl_j.is_running_balance_caculated = 1 "); + } + sql.append("where gl.id = ?"); + if(associationParametersData.isRunningBalanceRequired()){ + sql.append(" ORDER BY gl_j.entry_date DESC,gl_j.id DESC LIMIT 1"); + } + final GLAccountData glAccountData = this.jdbcTemplate.queryForObject(sql.toString(), rm, new Object[] { glAccountId }); return glAccountData; } catch (final EmptyResultDataAccessException e) { @@ -179,12 +207,12 @@ public class GLAccountReadPlatformServiceImpl implements GLAccountReadPlatformSe @Override public List retrieveAllEnabledDetailGLAccounts(final GLAccountType accountType) { - return retrieveAllGLAccounts(accountType.getValue(), null, GLAccountUsage.DETAIL.getValue(), null, false); + return retrieveAllGLAccounts(accountType.getValue(), null, GLAccountUsage.DETAIL.getValue(), null, false, new JournalEntryAssociationParametersData()); } @Override public List retrieveAllEnabledDetailGLAccounts() { - return retrieveAllGLAccounts(null, null, GLAccountUsage.DETAIL.getValue(), null, false); + return retrieveAllGLAccounts(null, null, GLAccountUsage.DETAIL.getValue(), null, false, new JournalEntryAssociationParametersData()); } private static boolean checkValidGLAccountType(final int type) { @@ -208,7 +236,7 @@ public class GLAccountReadPlatformServiceImpl implements GLAccountReadPlatformSe @Override public List retrieveAllEnabledHeaderGLAccounts(final GLAccountType accountType) { - return retrieveAllGLAccounts(accountType.getValue(), null, GLAccountUsage.HEADER.getValue(), null, false); + return retrieveAllGLAccounts(accountType.getValue(), null, GLAccountUsage.HEADER.getValue(), null, false, new JournalEntryAssociationParametersData()); } @Override From d86dfe4e667259926f4c335dc5e87cf2043eddb0 Mon Sep 17 00:00:00 2001 From: Pramod Nuthakki Date: Tue, 3 Dec 2013 15:04:32 +0530 Subject: [PATCH 03/15] MIFOS-805:Corrected update of loan product for term variation for loan cycle --- ...cheduleCalculationPlatformServiceImpl.java | 23 +++++++++++++++++-- .../loanproduct/domain/LoanProduct.java | 7 +++--- 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/loanschedule/service/LoanScheduleCalculationPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/loanschedule/service/LoanScheduleCalculationPlatformServiceImpl.java index db7215389..442e7c60a 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/loanschedule/service/LoanScheduleCalculationPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/loanschedule/service/LoanScheduleCalculationPlatformServiceImpl.java @@ -13,8 +13,10 @@ import org.mifosplatform.infrastructure.core.data.ApiParameterError; import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder; import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException; import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper; +import org.mifosplatform.portfolio.accountdetails.domain.AccountType; import org.mifosplatform.portfolio.loanaccount.loanschedule.domain.LoanScheduleModel; import org.mifosplatform.portfolio.loanaccount.serialization.CalculateLoanScheduleQueryFromApiJsonHelper; +import org.mifosplatform.portfolio.loanaccount.service.LoanReadPlatformService; import org.mifosplatform.portfolio.loanproduct.domain.LoanProduct; import org.mifosplatform.portfolio.loanproduct.domain.LoanProductRepository; import org.mifosplatform.portfolio.loanproduct.exception.LoanProductNotFoundException; @@ -30,16 +32,19 @@ public class LoanScheduleCalculationPlatformServiceImpl implements LoanScheduleC private final FromJsonHelper fromJsonHelper; private final LoanProductRepository loanProductRepository; private final LoanProductDataValidator loanProductCommandFromApiJsonDeserializer; + private final LoanReadPlatformService loanReadPlatformService; @Autowired public LoanScheduleCalculationPlatformServiceImpl(final CalculateLoanScheduleQueryFromApiJsonHelper fromApiJsonDeserializer, final LoanScheduleAssembler loanScheduleAssembler, final FromJsonHelper fromJsonHelper, - final LoanProductRepository loanProductRepository, final LoanProductDataValidator loanProductCommandFromApiJsonDeserializer) { + final LoanProductRepository loanProductRepository, final LoanProductDataValidator loanProductCommandFromApiJsonDeserializer, + final LoanReadPlatformService loanReadPlatformService) { this.fromApiJsonDeserializer = fromApiJsonDeserializer; this.loanScheduleAssembler = loanScheduleAssembler; this.fromJsonHelper = fromJsonHelper; this.loanProductRepository = loanProductRepository; this.loanProductCommandFromApiJsonDeserializer = loanProductCommandFromApiJsonDeserializer; + this.loanReadPlatformService = loanReadPlatformService; } @Override @@ -54,7 +59,21 @@ public class LoanScheduleCalculationPlatformServiceImpl implements LoanScheduleC final LoanProduct loanProduct = this.loanProductRepository.findOne(productId); if (loanProduct == null) { throw new LoanProductNotFoundException(productId); } - this.loanProductCommandFromApiJsonDeserializer.validateMinMaxConstraints(query.parsedJson(), baseDataValidator, loanProduct); + if (loanProduct.useBorrowerCycle()) { + final Long clientId = this.fromJsonHelper.extractLongNamed("clientId", query.parsedJson()); + final Long groupId = this.fromJsonHelper.extractLongNamed("groupId", query.parsedJson()); + Integer cycleNumber = 0; + if (clientId != null) { + cycleNumber = this.loanReadPlatformService.retriveLoanCounter(clientId); + } else if (groupId != null) { + cycleNumber = this.loanReadPlatformService.retriveLoanCounter(groupId, AccountType.GROUP.getValue()); + } + this.loanProductCommandFromApiJsonDeserializer.validateMinMaxConstraints(query.parsedJson(), baseDataValidator, + loanProduct, cycleNumber); + } else { + this.loanProductCommandFromApiJsonDeserializer.validateMinMaxConstraints(query.parsedJson(), baseDataValidator, + loanProduct); + } if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); } return this.loanScheduleAssembler.assembleLoanScheduleFrom(query.parsedJson()); diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanproduct/domain/LoanProduct.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanproduct/domain/LoanProduct.java index fd4a1163d..f13bafb30 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanproduct/domain/LoanProduct.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanproduct/domain/LoanProduct.java @@ -520,10 +520,9 @@ public class LoanProduct extends AbstractPersistable { this.includeInBorrowerCycle = newValue; } - final String useBorrowerCycleParamName = "useBorrowerCycle"; - if (command.isChangeInBooleanParameterNamed(useBorrowerCycleParamName, this.includeInBorrowerCycle)) { - final boolean newValue = command.booleanPrimitiveValueOfParameterNamed(useBorrowerCycleParamName); - actualChanges.put(useBorrowerCycleParamName, newValue); + if (command.isChangeInBooleanParameterNamed(LoanProductConstants.useBorrowerCycleParameterName, this.useBorrowerCycle)) { + final boolean newValue = command.booleanPrimitiveValueOfParameterNamed(LoanProductConstants.useBorrowerCycleParameterName); + actualChanges.put(LoanProductConstants.useBorrowerCycleParameterName, newValue); this.useBorrowerCycle = newValue; } From 8ffba8a732b4bcac7b2ce1b7845603e92c6a822f Mon Sep 17 00:00:00 2001 From: Keith Woodlock Date: Tue, 3 Dec 2013 13:25:13 +0000 Subject: [PATCH 04/15] MIFSOX-810: exception message returned rather than clean error message when attempt to add user that already exists. --- .../useradministration/domain/JpaUserDomainService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mifosng-provider/src/main/java/org/mifosplatform/useradministration/domain/JpaUserDomainService.java b/mifosng-provider/src/main/java/org/mifosplatform/useradministration/domain/JpaUserDomainService.java index 0c5fcc40c..c4353c3ac 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/useradministration/domain/JpaUserDomainService.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/useradministration/domain/JpaUserDomainService.java @@ -38,7 +38,7 @@ public class JpaUserDomainService implements UserDomainService { final String encodePassword = this.applicationPasswordEncoder.encode(appUser); appUser.updatePassword(encodePassword); - this.userRepository.save(appUser); + this.userRepository.saveAndFlush(appUser); if (sendPasswordToEmail.booleanValue()) { final EmailDetail emailDetail = new EmailDetail(appUser.getOffice().getName(), appUser.getFirstname(), appUser.getEmail(), From c11e8d562737c25c76435e42e2edde34d33df38b Mon Sep 17 00:00:00 2001 From: Pramod Nuthakki Date: Tue, 3 Dec 2013 19:01:26 +0530 Subject: [PATCH 05/15] mifosx-801:submitted date updation for clients --- .../core_db/V134_1__submitted_date_updation_for_clients.sql | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100755 mifosng-db/migrations/core_db/V134_1__submitted_date_updation_for_clients.sql diff --git a/mifosng-db/migrations/core_db/V134_1__submitted_date_updation_for_clients.sql b/mifosng-db/migrations/core_db/V134_1__submitted_date_updation_for_clients.sql new file mode 100755 index 000000000..da828085b --- /dev/null +++ b/mifosng-db/migrations/core_db/V134_1__submitted_date_updation_for_clients.sql @@ -0,0 +1,6 @@ +UPDATE m_client mc SET mc.submittedon_date=mc.activation_date where mc.submittedon_date is NULL; +UPDATE m_client mc SET mc.submittedon_date=now() where mc.submittedon_date is NULL; + +UPDATE m_group mg SET mg.submittedon_date=mg.activation_date where mg.submittedon_date is NULL; +UPDATE m_group mg SET mg.submittedon_date=now() where mg.submittedon_date is NULL; + From 046b9aaf2dc83e8fd297ede8098cd4e3b888abbb Mon Sep 17 00:00:00 2001 From: Keith Woodlock Date: Tue, 3 Dec 2013 15:07:56 +0000 Subject: [PATCH 06/15] MIFOSX-811: ensure undo disbursement regenerated schedule when expected and actual disbursement dates are different. --- .../portfolio/loanaccount/domain/Loan.java | 77 +++++++++++-------- ...WritePlatformServiceJpaRepositoryImpl.java | 27 +++++-- 2 files changed, 68 insertions(+), 36 deletions(-) diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/Loan.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/Loan.java index 6d08b5129..387003f89 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/Loan.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/Loan.java @@ -449,7 +449,8 @@ public class Loan extends AbstractPersistable { loanCharge.update(chargeAmt, loanCharge.getDueLocalDate(), amount, repaymentScheduleDetail().getNumberOfRepayments(), totalChargeAmt); - // NOTE: must add new loan charge to set of loan charges before reporcessing the repayment schedule. + // NOTE: must add new loan charge to set of loan charges before + // reporcessing the repayment schedule. setOfLoanCharges().add(loanCharge); final LoanRepaymentScheduleTransactionProcessor loanRepaymentScheduleTransactionProcessor = this.transactionProcessorFactory @@ -480,11 +481,11 @@ public class Loan extends AbstractPersistable { * Creates a loanTransaction for "Apply Charge Event" with transaction date * set to "suppliedTransactionDate". The newly created transaction is also * added to the Loan on which this method is called. - * + * * If "suppliedTransactionDate" is not passed Id, the transaction date is * set to the loans due date if the due date is lesser than todays date. If * not, the transaction date is set to todays date - * + * * @param loanCharge * @param suppliedTransactionDate * @return @@ -520,7 +521,7 @@ public class Loan extends AbstractPersistable { } private void handleChargePaidTransaction(final LoanCharge charge, final LoanTransaction chargesPayment, - final LoanLifecycleStateMachine loanLifecycleStateMachine, Integer installmentNumber) { + final LoanLifecycleStateMachine loanLifecycleStateMachine, final Integer installmentNumber) { chargesPayment.updateLoan(this); final LoanChargePaidBy loanChargePaidBy = new LoanChargePaidBy(chargesPayment, charge, chargesPayment.getAmount(getCurrency()) .getAmount()); @@ -538,7 +539,7 @@ public class Loan extends AbstractPersistable { if (installmentNumber == null && charge.isDueForCollectionFromAndUpToAndIncluding(startDate, installment.getDueDate())) { chargePaymentInstallments.add(installment); break; - }else if(installmentNumber != null && installment.getInstallmentNumber().equals(installmentNumber)){ + } else if (installmentNumber != null && installment.getInstallmentNumber().equals(installmentNumber)) { chargePaymentInstallments.add(installment); break; } @@ -604,7 +605,7 @@ public class Loan extends AbstractPersistable { * TODO Vishwas Currently we do not allow removing a loan charge * after a loan is approved (hence there is no need to adjust any * loan transactions). - * + * * Consider removing this block of code or logically completing it * for the future by getting the list of affected Transactions ***/ @@ -662,7 +663,7 @@ public class Loan extends AbstractPersistable { * TODO Vishwas Currently we do not allow waiving updating loan * charge after a loan is approved (hence there is no need to adjust * any loan transactions). - * + * * Consider removing this block of code or logically completing it * for the future by getting the list of affected Transactions ***/ @@ -707,8 +708,7 @@ public class Loan extends AbstractPersistable { * @return */ public BigDecimal getTotalInterest() { - return this.loanSummaryWrapper.calculateTotalInterestCharged( - this.repaymentScheduleInstallments, getCurrency()).getAmount(); + return this.loanSummaryWrapper.calculateTotalInterestCharged(this.repaymentScheduleInstallments, getCurrency()).getAmount(); } private BigDecimal calculatePerInstallmentChargeAmount(final LoanCharge loanCharge) { @@ -729,7 +729,7 @@ public class Loan extends AbstractPersistable { * @param installment * @return */ - private Money calculateInstallmentChargeAmount(final ChargeCalculationType calculationType, final BigDecimal percentage, + private Money calculateInstallmentChargeAmount(final ChargeCalculationType calculationType, final BigDecimal percentage, final LoanRepaymentScheduleInstallment installment) { Money amount = Money.zero(getCurrency()); Money percentOf = Money.zero(getCurrency()); @@ -751,8 +751,8 @@ public class Loan extends AbstractPersistable { } public LoanTransaction waiveLoanCharge(final LoanCharge loanCharge, final LoanLifecycleStateMachine loanLifecycleStateMachine, - final Map changes, final List existingTransactionIds, final List existingReversedTransactionIds, - Integer loanInstallmentNumber) { + final Map changes, final List existingTransactionIds, final List existingReversedTransactionIds, + final Integer loanInstallmentNumber) { validateLoanIsNotClosed(loanCharge); @@ -790,7 +790,7 @@ public class Loan extends AbstractPersistable { * TODO Vishwas Currently we do not allow waiving fully paid loan * charge and waiving partially paid loan charges only waives the * remaining amount. - * + * * Consider removing this block of code or logically completing it * for the future by getting the list of affected Transactions ***/ @@ -894,7 +894,7 @@ public class Loan extends AbstractPersistable { public void updateLoanSchedule(final LoanScheduleModel modifiedLoanSchedule) { clearInstallmentLoanCharge(); this.repaymentScheduleInstallments.clear(); - + for (final LoanScheduleModelPeriod scheduledLoanInstallment : modifiedLoanSchedule.getPeriods()) { if (scheduledLoanInstallment.isRepaymentPeriod()) { @@ -909,12 +909,12 @@ public class Loan extends AbstractPersistable { updateLoanScheduleDependentDerivedFields(); updateLoanSummaryDerivedFields(); - + } - - private void clearInstallmentLoanCharge(){ - for(LoanCharge loanCharge:setOfLoanCharges()){ - if(loanCharge.isInstalmentFee()){ + + private void clearInstallmentLoanCharge() { + for (final LoanCharge loanCharge : setOfLoanCharges()) { + if (loanCharge.isInstalmentFee()) { loanCharge.clearLoanInstallmentCharges(); } } @@ -1669,7 +1669,10 @@ public class Loan extends AbstractPersistable { return chargesPayment; } - public Map undoDisbursal(final List existingTransactionIds, final List existingReversedTransactionIds) { + public Map undoDisbursal(final LoanScheduleGeneratorFactory loanScheduleFactory, + final ApplicationCurrency applicationCurrency, final List existingTransactionIds, + final List existingReversedTransactionIds, final LocalDate calculatedRepaymentsStartingFromDate, + final boolean isHolidayEnabled, final List holidays, final WorkingDays workingDays) { final Map actualChanges = new LinkedHashMap(); @@ -1680,6 +1683,17 @@ public class Loan extends AbstractPersistable { this.loanStatus = statusEnum.getValue(); actualChanges.put("status", LoanEnumerations.status(this.loanStatus)); + final LocalDate actualDisbursementDate = getDisbursementDate(); + if (isRepaymentScheduleRegenerationRequiredForDisbursement(actualDisbursementDate)) { + // clear off actual disbusrement date so schedule regeneration + // uses expected date. + this.actualDisbursementDate = null; + this.disbursedBy = null; + + regenerateRepaymentSchedule(loanScheduleFactory, applicationCurrency, calculatedRepaymentsStartingFromDate, + isHolidayEnabled, holidays, workingDays); + } + this.actualDisbursementDate = null; this.disbursedBy = null; actualChanges.put("actualDisbursementDate", ""); @@ -1757,7 +1771,7 @@ public class Loan extends AbstractPersistable { public void makeChargePayment(final Long chargeId, final LoanLifecycleStateMachine loanLifecycleStateMachine, final List existingTransactionIds, final List existingReversedTransactionIds, final boolean allowTransactionsOnHoliday, final List holidays, final WorkingDays workingDays, - final boolean allowTransactionsOnNonWorkingDay, final LoanTransaction paymentTransaction, Integer installmentNumber) { + final boolean allowTransactionsOnNonWorkingDay, final LoanTransaction paymentTransaction, final Integer installmentNumber) { validateActivityNotBeforeClientOrGroupTransferDate(LoanEvent.LOAN_CHARGE_PAYMENT, paymentTransaction.getTransactionDate()); validateRepaymentDateIsOnHoliday(paymentTransaction.getTransactionDate(), allowTransactionsOnHoliday, holidays); @@ -2995,22 +3009,23 @@ public class Loan extends AbstractPersistable { public Set charges() { return this.charges; } - - public Set generateInstallmentLoanCharges(final LoanCharge loanCharge){ - Set loanChargePerInstallments = new HashSet(); - if(loanCharge.isInstalmentFee()){ + + public Set generateInstallmentLoanCharges(final LoanCharge loanCharge) { + final Set loanChargePerInstallments = new HashSet(); + if (loanCharge.isInstalmentFee()) { for (final LoanRepaymentScheduleInstallment installment : this.repaymentScheduleInstallments) { BigDecimal amount = BigDecimal.ZERO; - if(loanCharge.getChargeCalculation().isFlat()){ - amount = loanCharge.amount().divide(BigDecimal.valueOf(repaymentScheduleDetail().getNumberOfRepayments())); - }else{ - amount = calculateInstallmentChargeAmount(loanCharge.getChargeCalculation(), loanCharge.getPercentage(), installment).getAmount(); + if (loanCharge.getChargeCalculation().isFlat()) { + amount = loanCharge.amount().divide(BigDecimal.valueOf(repaymentScheduleDetail().getNumberOfRepayments())); + } else { + amount = calculateInstallmentChargeAmount(loanCharge.getChargeCalculation(), loanCharge.getPercentage(), installment) + .getAmount(); } - LoanInstallmentCharge loanInstallmentCharge = new LoanInstallmentCharge(amount, loanCharge, installment); + final LoanInstallmentCharge loanInstallmentCharge = new LoanInstallmentCharge(amount, loanCharge, installment); loanChargePerInstallments.add(loanInstallmentCharge); } } return loanChargePerInstallments; } - + } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java index 240551ff7..412841109 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java @@ -434,9 +434,28 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf final Loan loan = this.loanAssembler.assembleFrom(loanId); checkClientOrGroupActive(loan); removeLoanCycle(loan); + + // + final MonetaryCurrency currency = loan.getCurrency(); + final ApplicationCurrency applicationCurrency = this.applicationCurrencyRepository.findOneWithNotFoundDetection(currency); + + final CalendarInstance calendarInstance = this.calendarInstanceRepository.findCalendarInstaneByLoanId(loan.getId(), + CalendarEntityType.LOANS.getValue()); + final LocalDate actualDisbursementDate = loan.getDisbursementDate(); + final LocalDate calculatedRepaymentsStartingFromDate = getCalculatedRepaymentsStartingFromDate(actualDisbursementDate, loan, + calendarInstance); + + final boolean isHolidayEnabled = this.configurationDomainService.isRescheduleRepaymentsOnHolidaysEnabled(); + final List holidays = this.holidayRepository.findByOfficeIdAndGreaterThanDate(loan.getOfficeId(), + actualDisbursementDate.toDate()); + final WorkingDays workingDays = this.workingDaysRepository.findOne(); + final List existingTransactionIds = new ArrayList(); final List existingReversedTransactionIds = new ArrayList(); - final Map changes = loan.undoDisbursal(existingTransactionIds, existingReversedTransactionIds); + + final Map changes = loan.undoDisbursal(this.loanScheduleFactory, applicationCurrency, existingTransactionIds, + existingReversedTransactionIds, calculatedRepaymentsStartingFromDate, isHolidayEnabled, holidays, workingDays); + if (!changes.isEmpty()) { this.loanRepository.saveAndFlush(loan); this.accountTransfersWritePlatformService.reverseAllTransactions(loanId, PortfolioAccountType.LOAN); @@ -449,9 +468,6 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf } } - final MonetaryCurrency currency = loan.getCurrency(); - final ApplicationCurrency applicationCurrency = this.applicationCurrencyRepository.findOneWithNotFoundDetection(currency); - final Map accountingBridgeData = loan.deriveAccountingBridgeData(applicationCurrency.toData(), existingTransactionIds, existingReversedTransactionIds); this.journalEntryWritePlatformService.createJournalEntriesForLoan(accountingBridgeData); @@ -1621,7 +1637,8 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf public void applyChargeForOverdueLoans() throws JobExecutionException { final Long penaltyWaitPeriodValue = this.configurationDomainService.retrievePenaltyWaitPeriod(); - final Collection overdueLoanScheduledInstallments = this.loanReadPlatformService.retrieveAllLoansWithOverdueInstallmentsNotAlreadyPenalized(penaltyWaitPeriodValue); + final Collection overdueLoanScheduledInstallments = this.loanReadPlatformService + .retrieveAllLoansWithOverdueInstallmentsNotAlreadyPenalized(penaltyWaitPeriodValue); if (!overdueLoanScheduledInstallments.isEmpty()) { for (final OverdueLoanScheduleData overdueInstallment : overdueLoanScheduledInstallments) { From 865ce43de08955f804bc3f95bff693ac0f7aea7f Mon Sep 17 00:00:00 2001 From: Keith Woodlock Date: Wed, 4 Dec 2013 18:02:33 +0000 Subject: [PATCH 07/15] update changelog for 1.15.1 release --- CHANGELOG.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6325838dd..d75591329 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ See VERSIONING (https://github.com/openMF/mifosx/blob/master/VERSIONING.md) for Releases =============== +1. 04 Dec 2013 - 1.15.1.RELEASE 1. 01 Dec 2013 - 1.15.0.RELEASE 1. 21 Nov 2013 - 1.14.0.RELEASE 1. 03 Nov 2013 - 1.13.4.RELEASE @@ -50,6 +51,17 @@ Releases 1. 05 April 2013 - 0.11.1.beta 1. 05 April 2013 - 0.11.0.beta +1.15.1.RELEASE +============= +Bug Release + +Bugs + - [MIFOSX-801] - Clean up implementation of [MIFOSX-765] + - MIFOSX-805] - Terms vary based on loan cycle is not getting updated in Edit Loan Product page. + - [MIFOSX-810] - Unhandled API error while creating multiple users with same name + - [MIFOSX-811] - Repayment schedule dates for Loan disbursement after undo disbursal is not proper + - [MIFOSX-744] - Implementation of mifosx-735 should be optional + 1.15.0.RELEASE ============= Feature Release From f991075cb7db556c33d5e1f23210bca83c66d8e5 Mon Sep 17 00:00:00 2001 From: Pramod Nuthakki Date: Wed, 4 Dec 2013 23:39:25 +0530 Subject: [PATCH 08/15] mifosx-816 : corrected loan variations to pick based on loan product count --- ...cheduleCalculationPlatformServiceImpl.java | 4 +-- ...WritePlatformServiceJpaRepositoryImpl.java | 8 ++--- .../service/LoanReadPlatformService.java | 4 +-- .../service/LoanReadPlatformServiceImpl.java | 16 ++++----- .../loanproduct/domain/LoanProduct.java | 35 ++++++++++++------- 5 files changed, 39 insertions(+), 28 deletions(-) diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/loanschedule/service/LoanScheduleCalculationPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/loanschedule/service/LoanScheduleCalculationPlatformServiceImpl.java index 442e7c60a..8d7728244 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/loanschedule/service/LoanScheduleCalculationPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/loanschedule/service/LoanScheduleCalculationPlatformServiceImpl.java @@ -64,9 +64,9 @@ public class LoanScheduleCalculationPlatformServiceImpl implements LoanScheduleC final Long groupId = this.fromJsonHelper.extractLongNamed("groupId", query.parsedJson()); Integer cycleNumber = 0; if (clientId != null) { - cycleNumber = this.loanReadPlatformService.retriveLoanCounter(clientId); + cycleNumber = this.loanReadPlatformService.retriveLoanCounter(clientId, loanProduct.getId()); } else if (groupId != null) { - cycleNumber = this.loanReadPlatformService.retriveLoanCounter(groupId, AccountType.GROUP.getValue()); + cycleNumber = this.loanReadPlatformService.retriveLoanCounter(groupId, AccountType.GROUP.getValue(), loanProduct.getId()); } this.loanProductCommandFromApiJsonDeserializer.validateMinMaxConstraints(query.parsedJson(), baseDataValidator, loanProduct, cycleNumber); diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanApplicationWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanApplicationWritePlatformServiceJpaRepositoryImpl.java index 6356d6155..d78039c7d 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanApplicationWritePlatformServiceJpaRepositoryImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanApplicationWritePlatformServiceJpaRepositoryImpl.java @@ -180,9 +180,9 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa final Long groupId = this.fromJsonHelper.extractLongNamed("groupId", command.parsedJson()); Integer cycleNumber = 0; if (clientId != null) { - cycleNumber = this.loanReadPlatformService.retriveLoanCounter(clientId); + cycleNumber = this.loanReadPlatformService.retriveLoanCounter(clientId, loanProduct.getId()); } else if (groupId != null) { - cycleNumber = this.loanReadPlatformService.retriveLoanCounter(groupId, AccountType.GROUP.getValue()); + cycleNumber = this.loanReadPlatformService.retriveLoanCounter(groupId, AccountType.GROUP.getValue(), loanProduct.getId()); } this.loanProductCommandFromApiJsonDeserializer.validateMinMaxConstraints(command.parsedJson(), baseDataValidator, loanProduct, cycleNumber); @@ -314,9 +314,9 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa final Long groupId = this.fromJsonHelper.extractLongNamed("groupId", command.parsedJson()); Integer cycleNumber = 0; if (clientId != null) { - cycleNumber = this.loanReadPlatformService.retriveLoanCounter(clientId); + cycleNumber = this.loanReadPlatformService.retriveLoanCounter(clientId, loanProduct.getId()); } else if (groupId != null) { - cycleNumber = this.loanReadPlatformService.retriveLoanCounter(groupId, AccountType.GROUP.getValue()); + cycleNumber = this.loanReadPlatformService.retriveLoanCounter(groupId, AccountType.GROUP.getValue(), loanProduct.getId()); } this.loanProductCommandFromApiJsonDeserializer.validateMinMaxConstraints(command.parsedJson(), baseDataValidator, loanProduct, cycleNumber); diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanReadPlatformService.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanReadPlatformService.java index a14b047c5..f4321cb57 100755 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanReadPlatformService.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanReadPlatformService.java @@ -62,7 +62,7 @@ public interface LoanReadPlatformService { */ Collection retrieveAllLoansWithOverdueInstallmentsNotAlreadyPenalized(final Long penaltyWaitPeriod); - Integer retriveLoanCounter(Long groupId, Integer loanType); + Integer retriveLoanCounter(Long groupId, Integer loanType, Long productId); - Integer retriveLoanCounter(Long clientId); + Integer retriveLoanCounter(Long clientId, Long productId); } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java index b7161e181..e1af7f225 100755 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java @@ -1067,9 +1067,9 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService { Integer loanCycleCounter = null; if (loanProduct.useBorrowerCycle()) { if (clientId == null) { - loanCycleCounter = retriveLoanCounter(groupId, AccountType.GROUP.getValue()); + loanCycleCounter = retriveLoanCounter(groupId, AccountType.GROUP.getValue(), loanProduct.getId()); } else { - loanCycleCounter = retriveLoanCounter(clientId); + loanCycleCounter = retriveLoanCounter(clientId, loanProduct.getId()); } } return LoanAccountData.loanProductWithTemplateDefaults(loanProduct, loanTermFrequencyTypeOptions, repaymentFrequencyTypeOptions, @@ -1161,14 +1161,14 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService { } @Override - public Integer retriveLoanCounter(final Long groupId, final Integer loanType) { - final String sql = "Select MAX(l.loan_counter) from m_loan l where l.group_id = ? " + " and l.loan_type_enum = ?"; - return this.jdbcTemplate.queryForInt(sql, groupId, loanType); + public Integer retriveLoanCounter(final Long groupId, final Integer loanType, Long productId) { + final String sql = "Select MAX(l.loan_product_counter) from m_loan l where l.group_id = ? and l.loan_type_enum = ? and l.product_id=?"; + return this.jdbcTemplate.queryForInt(sql, groupId, loanType,productId); } @Override - public Integer retriveLoanCounter(final Long clientId) { - final String sql = "Select MAX(l.loan_counter) from m_loan l where l.client_id = ?"; - return this.jdbcTemplate.queryForInt(sql, clientId); + public Integer retriveLoanCounter(final Long clientId, Long productId) { + final String sql = "Select MAX(l.loan_product_counter) from m_loan l where l.client_id = ? and l.product_id=?"; + return this.jdbcTemplate.queryForInt(sql, clientId,productId); } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanproduct/domain/LoanProduct.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanproduct/domain/LoanProduct.java index f13bafb30..660da76aa 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanproduct/domain/LoanProduct.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanproduct/domain/LoanProduct.java @@ -680,20 +680,31 @@ public class LoanProduct extends AbstractPersistable { public Map fetchBorrowerCycleVariationsForCycleNumber(final Integer cycleNumber) { Map borrowerCycleVariations = new HashMap(); borrowerCycleVariations.put(LoanProductConstants.principal, this.loanProductRelatedDetail.getPrincipal().getAmount()); - borrowerCycleVariations.put(LoanProductConstants.minPrincipal, this.loanProductMinMaxConstraints.getMinPrincipal()); - borrowerCycleVariations.put(LoanProductConstants.maxPrincipal, this.loanProductMinMaxConstraints.getMaxPrincipal()); borrowerCycleVariations.put(LoanProductConstants.interestRatePerPeriod, this.loanProductRelatedDetail.getNominalInterestRatePerPeriod()); - borrowerCycleVariations.put(LoanProductConstants.minInterestRatePerPeriod, - this.loanProductMinMaxConstraints.getMinNominalInterestRatePerPeriod()); - borrowerCycleVariations.put(LoanProductConstants.maxInterestRatePerPeriod, - this.loanProductMinMaxConstraints.getMaxNominalInterestRatePerPeriod()); - borrowerCycleVariations.put(LoanProductConstants.numberOfRepayments, - BigDecimal.valueOf(this.loanProductRelatedDetail.getNumberOfRepayments())); - borrowerCycleVariations.put(LoanProductConstants.minNumberOfRepayments, - BigDecimal.valueOf(this.loanProductMinMaxConstraints.getMinNumberOfRepayments())); - borrowerCycleVariations.put(LoanProductConstants.maxNumberOfRepayments, - BigDecimal.valueOf(this.loanProductMinMaxConstraints.getMaxNumberOfRepayments())); + if(this.loanProductRelatedDetail.getNumberOfRepayments() != null){ + borrowerCycleVariations.put(LoanProductConstants.numberOfRepayments, + BigDecimal.valueOf(this.loanProductRelatedDetail.getNumberOfRepayments())); + } + + if(this.loanProductMinMaxConstraints !=null){ + borrowerCycleVariations.put(LoanProductConstants.minPrincipal, this.loanProductMinMaxConstraints.getMinPrincipal()); + borrowerCycleVariations.put(LoanProductConstants.maxPrincipal, this.loanProductMinMaxConstraints.getMaxPrincipal()); + borrowerCycleVariations.put(LoanProductConstants.minInterestRatePerPeriod, + this.loanProductMinMaxConstraints.getMinNominalInterestRatePerPeriod()); + borrowerCycleVariations.put(LoanProductConstants.maxInterestRatePerPeriod, + this.loanProductMinMaxConstraints.getMaxNominalInterestRatePerPeriod()); + + if(this.loanProductMinMaxConstraints.getMinNumberOfRepayments() != null){ + borrowerCycleVariations.put(LoanProductConstants.minNumberOfRepayments, + BigDecimal.valueOf(this.loanProductMinMaxConstraints.getMinNumberOfRepayments())); + } + + if(this.loanProductMinMaxConstraints.getMaxNumberOfRepayments() != null){ + borrowerCycleVariations.put(LoanProductConstants.maxNumberOfRepayments, + BigDecimal.valueOf(this.loanProductMinMaxConstraints.getMaxNumberOfRepayments())); + } + } if (cycleNumber > 0) { Integer principalCycleUsed = 0; Integer interestCycleUsed = 0; From 3fa2c26897e2e2b21ab6f1d28bbc99c8adee219c Mon Sep 17 00:00:00 2001 From: Vishwas Babu A J Date: Thu, 5 Dec 2013 21:04:23 +0530 Subject: [PATCH 09/15] fix for MIFOSX-820 --- .../core_db/V134_2__permissions_spelling_correction.sql | 1 + 1 file changed, 1 insertion(+) create mode 100644 mifosng-db/migrations/core_db/V134_2__permissions_spelling_correction.sql diff --git a/mifosng-db/migrations/core_db/V134_2__permissions_spelling_correction.sql b/mifosng-db/migrations/core_db/V134_2__permissions_spelling_correction.sql new file mode 100644 index 000000000..afcd37c08 --- /dev/null +++ b/mifosng-db/migrations/core_db/V134_2__permissions_spelling_correction.sql @@ -0,0 +1 @@ +update m_permission set grouping="organisation" where grouping = "organistion"; From 5aa6fecd5cacbcb42b22985ca356d5655dc6540d Mon Sep 17 00:00:00 2001 From: Vishwas Babu A J Date: Fri, 6 Dec 2013 18:03:55 +0530 Subject: [PATCH 10/15] fix for MIFOSX-818 --- .../service/ConfigurationReadPlatformServiceImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/service/ConfigurationReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/service/ConfigurationReadPlatformServiceImpl.java index db1e42f84..26f4444d4 100755 --- a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/service/ConfigurationReadPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/service/ConfigurationReadPlatformServiceImpl.java @@ -38,7 +38,7 @@ public class ConfigurationReadPlatformServiceImpl implements ConfigurationReadPl this.context.authenticatedUser(); - final String sql = "SELECT c.name, c.enabled FROM c_configuration c order by c.id"; + final String sql = "SELECT c.name, c.enabled, c.value FROM c_configuration c order by c.id"; final List globalConfiguration = this.jdbcTemplate.query(sql, this.rm, new Object[] {}); return new GlobalConfigurationData(globalConfiguration); From cebdc5cfc1463b1f65cf014842e3595c75458bfe Mon Sep 17 00:00:00 2001 From: Vishwas Babu A J Date: Fri, 6 Dec 2013 18:41:59 +0530 Subject: [PATCH 11/15] fix for MIFOSX-821 --- .../service/LoanWritePlatformServiceJpaRepositoryImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java index 412841109..75b5cf0e8 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java @@ -1481,7 +1481,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf for (final Loan loanToUpdate : loansToUpdateForLoanCounter) { // Update client loan counter if loan product includeInBorrowerCycle // is true - if (includeInBorrowerCycle) { + if (loanToUpdate.loanProduct().isIncludeInBorrowerCycle()) { Integer currentLoanCounter = loanToUpdate.getCurrentLoanCounter(); if (newLoanCounter > currentLoanCounter) { newLoanCounter = currentLoanCounter; From 5c30edc7105698e16008f51edbdf57141419f505 Mon Sep 17 00:00:00 2001 From: Vishwas Babu A J Date: Wed, 11 Dec 2013 06:42:46 +0530 Subject: [PATCH 12/15] fix for MIFOSX-822 --- .../loanaccount/domain/LoanAccountDomainServiceJpa.java | 2 ++ .../service/LoanWritePlatformServiceJpaRepositoryImpl.java | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/LoanAccountDomainServiceJpa.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/LoanAccountDomainServiceJpa.java index e9212ba3e..339146a23 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/LoanAccountDomainServiceJpa.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/LoanAccountDomainServiceJpa.java @@ -141,6 +141,8 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService { if (changedTransactionDetail != null) { for (Map.Entry mapEntry : changedTransactionDetail.getNewTransactionMappings().entrySet()) { this.loanTransactionRepository.save(mapEntry.getValue()); + //update loan with references to the newly created transactions + loan.getLoanTransactions().add(mapEntry.getValue()); updateLoanTransaction(mapEntry.getKey(), mapEntry.getValue()); } } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java index 75b5cf0e8..a7356ff89 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java @@ -612,6 +612,8 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf if (changedTransactionDetail != null) { for (final Map.Entry mapEntry : changedTransactionDetail.getNewTransactionMappings().entrySet()) { this.loanTransactionRepository.save(mapEntry.getValue()); + //update loan with references to the newly created transactions + loan.getLoanTransactions().add(mapEntry.getValue()); this.accountTransfersWritePlatformService.updateLoanTransaction(mapEntry.getKey(), mapEntry.getValue()); } } @@ -688,6 +690,8 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf if (changedTransactionDetail != null) { for (final Map.Entry mapEntry : changedTransactionDetail.getNewTransactionMappings().entrySet()) { this.loanTransactionRepository.save(mapEntry.getValue()); + //update loan with references to the newly created transactions + loan.getLoanTransactions().add(mapEntry.getValue()); this.accountTransfersWritePlatformService.updateLoanTransaction(mapEntry.getKey(), mapEntry.getValue()); } } @@ -909,6 +913,8 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf if (changedTransactionDetail != null) { for (final Map.Entry mapEntry : changedTransactionDetail.getNewTransactionMappings().entrySet()) { this.loanTransactionRepository.save(mapEntry.getValue()); + //update loan with references to the newly created transactions + loan.getLoanTransactions().add(mapEntry.getValue()); this.accountTransfersWritePlatformService.updateLoanTransaction(mapEntry.getKey(), mapEntry.getValue()); } } From 3789ac1f0722159c922b8a65518c4115c63bc913 Mon Sep 17 00:00:00 2001 From: Vishwas Babu A J Date: Thu, 12 Dec 2013 15:11:47 +0530 Subject: [PATCH 13/15] Update CHANGELOG.md --- CHANGELOG.md | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d75591329..bf147dd91 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ See VERSIONING (https://github.com/openMF/mifosx/blob/master/VERSIONING.md) for Releases =============== +1. 12 Dec 2013 - 1.15.2.RELEASE 1. 04 Dec 2013 - 1.15.1.RELEASE 1. 01 Dec 2013 - 1.15.0.RELEASE 1. 21 Nov 2013 - 1.14.0.RELEASE @@ -51,13 +52,25 @@ Releases 1. 05 April 2013 - 0.11.1.beta 1. 05 April 2013 - 0.11.0.beta + +1.15.2.RELEASE +============= +Bug Release + +Bugs + - [MIFOSX-816] - Future loan amounts should be with respect to Loan cycle (not to be confused with borrower cycle) + - [MIFOSX-818] - Not able to retrieve Global Configurations through API + - [MIFOSX-820] - Fix spelling mistakes in permissions for better Display on community app + - [MIFOSX-821] - Null pointer exception while disbursing the loan + - [MIFOSX-822] - Backdated transaction that results in transaction reversals does not create journal entries for new transactions + 1.15.1.RELEASE ============= Bug Release Bugs - [MIFOSX-801] - Clean up implementation of [MIFOSX-765] - - MIFOSX-805] - Terms vary based on loan cycle is not getting updated in Edit Loan Product page. + - [MIFOSX-805] - Terms vary based on loan cycle is not getting updated in Edit Loan Product page. - [MIFOSX-810] - Unhandled API error while creating multiple users with same name - [MIFOSX-811] - Repayment schedule dates for Loan disbursement after undo disbursal is not proper - [MIFOSX-744] - Implementation of mifosx-735 should be optional From 66f974720f4df32acc221378d2a3d23336986e5b Mon Sep 17 00:00:00 2001 From: Vishwas Babu A J Date: Thu, 12 Dec 2013 15:31:12 +0530 Subject: [PATCH 14/15] adding instructions for deploying the community app --- INSTALL.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/INSTALL.md b/INSTALL.md index 637d07230..dcf08612c 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -12,7 +12,7 @@ The release artifact (.zip file) has the following structure: + api-docs ... folder contains html based documentation on the platform API for this release + database ... folder contains database setup and upgrade scripts required for installation + pentahoReports ... folder contains any out-of-the-box reports provided through pentaho - + apps ... folder contains apps like reference app that speak to the platform + + apps ... folder contains apps like reference app and community app that speak to the platform | -- CHANGELOG.MD ... file documents changelog of project up to this release -- CONTRIBUTORS.MD ... file provides details on contributors to project @@ -221,10 +221,12 @@ The two ways to get up and running with mifos platform is: Drop the following from the release artifact into [TOMCAT_HOME]/webapps/ROOT folder: - The entire ```apps/IndividualLendingGeneralJavaScript``` folder + - The entire ```apps/community-app``` folder. This contains a preview version of the community-app which will soon deprecate the older Reference app (IndividualLendingGeneralJavaScript) - The entire api-docs folder #### 2.3.7 Startup tomcat Startup tomcat: - Platform application should be available @ https://[server ip address]:8443/mifosng-provider/api/v1/offices?tenantIdentifier=default&pretty=true - Reference application should be available @ https://[server ip address]:8443/IndividualLendingGeneralJavaScript/IndivLendHome.html?baseApiUrl=https://[server ip address]:8443/mifosng-provider/api/v1/ + - Preview version of the Community application should be available @ https://[server ip address]:8443/community-app?baseApiUrl=https://[server ip address]:8443/mifosng-provider/api/v1/ - API docs should be available @ https://[server ip address]:8443/api-docs/apiLive.htm From 7e9e3f48575976af96e8820214582479b30445ed Mon Sep 17 00:00:00 2001 From: Vishwas Babu A J Date: Mon, 16 Dec 2013 02:18:47 +0530 Subject: [PATCH 15/15] updates for 1.15.2 release --- INSTALL.md | 2 +- mifosng-provider/gradle.properties | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/INSTALL.md b/INSTALL.md index dcf08612c..4e35fa4e5 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -228,5 +228,5 @@ The two ways to get up and running with mifos platform is: Startup tomcat: - Platform application should be available @ https://[server ip address]:8443/mifosng-provider/api/v1/offices?tenantIdentifier=default&pretty=true - Reference application should be available @ https://[server ip address]:8443/IndividualLendingGeneralJavaScript/IndivLendHome.html?baseApiUrl=https://[server ip address]:8443/mifosng-provider/api/v1/ - - Preview version of the Community application should be available @ https://[server ip address]:8443/community-app?baseApiUrl=https://[server ip address]:8443/mifosng-provider/api/v1/ + - Preview version of the Community application should be available @ https://[server ip address]:8443/community-app?baseApiUrl=https://[server ip address]:8443/mifosng-provider/api/v1/ (Refresh the Browser if you see untranslated labels while loading the application for the first time) - API docs should be available @ https://[server ip address]:8443/api-docs/apiLive.htm diff --git a/mifosng-provider/gradle.properties b/mifosng-provider/gradle.properties index 68ebc7cbe..2170fc550 100644 --- a/mifosng-provider/gradle.properties +++ b/mifosng-provider/gradle.properties @@ -1,3 +1,3 @@ -releaseVersion=1.15.1.RELEASE +releaseVersion=1.15.2.RELEASE