MIFOSX-245: add basic shell for savings products and accounts.
This commit is contained in:
+724
-2062
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,66 @@
|
||||
ALTER TABLE `mifostenant-default`.`m_note`
|
||||
DROP FOREIGN KEY `FK_m_note_m_saving_account`,
|
||||
DROP FOREIGN KEY `FK_m_note_m_deposit_account`;
|
||||
|
||||
ALTER TABLE `mifostenant-default`.`m_note`
|
||||
DROP COLUMN `saving_account_id`,
|
||||
DROP COLUMN `deposit_account_id`,
|
||||
DROP INDEX `FK_m_note_m_saving_account`,
|
||||
DROP INDEX `FK_m_note_m_deposit_account`;
|
||||
|
||||
|
||||
drop table `mifostenant-default`.`m_saving_account_transaction`;
|
||||
drop table `mifostenant-default`.`m_saving_schedule`;
|
||||
drop table `mifostenant-default`.`m_saving_account`;
|
||||
|
||||
drop table `mifostenant-default`.`m_deposit_account_transaction`;
|
||||
drop table `mifostenant-default`.`m_deposit_account`;
|
||||
|
||||
drop table `mifostenant-default`.`m_product_savings`;
|
||||
drop table `mifostenant-default`.`m_product_deposit`;
|
||||
|
||||
|
||||
|
||||
DROP TABLE IF EXISTS `m_savings_account`;
|
||||
DROP TABLE IF EXISTS `m_savings_product`;
|
||||
|
||||
CREATE TABLE `m_savings_product` (
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT,
|
||||
`name` varchar(100) NOT NULL,
|
||||
`description` varchar(500) NOT NULL,
|
||||
`currency_code` varchar(3) NOT NULL,
|
||||
`currency_digits` smallint(5) NOT NULL,
|
||||
`nominal_interest_rate_per_period` decimal(19,6) NOT NULL,
|
||||
`nominal_interest_rate_period_frequency_enum` smallint(5) NOT NULL,
|
||||
`min_required_opening_balance` decimal(19,6) DEFAULT NULL,
|
||||
`lockin_period_frequency` decimal(19,6) DEFAULT NULL,
|
||||
`lockin_period_frequency_enum` smallint(5) DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `sp_unq_name` (`name`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
CREATE TABLE `m_savings_account` (
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT,
|
||||
`account_no` varchar(20) NOT NULL,
|
||||
`external_id` varchar(100) DEFAULT NULL,
|
||||
`client_id` bigint(20) DEFAULT NULL,
|
||||
`group_id` bigint(20) DEFAULT NULL,
|
||||
`product_id` bigint(20) DEFAULT NULL,
|
||||
`currency_code` varchar(3) NOT NULL,
|
||||
`currency_digits` smallint(5) NOT NULL,
|
||||
`nominal_interest_rate_per_period` decimal(19,6) NOT NULL,
|
||||
`nominal_interest_rate_period_frequency_enum` smallint(5) NOT NULL,
|
||||
`annual_nominal_interest_rate` decimal(19,6) NOT NULL,
|
||||
`min_required_opening_balance` decimal(19,6) DEFAULT NULL,
|
||||
`lockin_period_frequency` decimal(19,6) DEFAULT NULL,
|
||||
`lockin_period_frequency_enum` smallint(5) DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `sa_account_no_UNIQUE` (`account_no`),
|
||||
UNIQUE KEY `sa_externalid_UNIQUE` (`external_id`),
|
||||
KEY `FKSA00000000000001` (`client_id`),
|
||||
KEY `FKSA00000000000002` (`group_id`),
|
||||
KEY `FKSA00000000000003` (`product_id`),
|
||||
CONSTRAINT `FKSA00000000000001` FOREIGN KEY (`client_id`) REFERENCES `m_client` (`id`),
|
||||
CONSTRAINT `FKSA00000000000002` FOREIGN KEY (`group_id`) REFERENCES `m_group` (`id`),
|
||||
CONSTRAINT `FKSA00000000000003` FOREIGN KEY (`product_id`) REFERENCES `m_savings_product` (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
+100
-128
@@ -27,7 +27,8 @@ public class CommandWrapperBuilder {
|
||||
|
||||
public CommandWrapper build() {
|
||||
return new CommandWrapper(this.officeId, this.groupId, this.clientId, this.loanId, this.actionName, this.entityName, this.entityId,
|
||||
this.apptableId, this.datatableId, this.codeId, this.supportedEntityType, this.supportedEntityId, this.href, this.json, this.transactionId);
|
||||
this.apptableId, this.datatableId, this.codeId, this.supportedEntityType, this.supportedEntityId, this.href, this.json,
|
||||
this.transactionId);
|
||||
}
|
||||
|
||||
// public CommandWrapperBuilder withEntityId(final Long withId) {
|
||||
@@ -372,7 +373,7 @@ public class CommandWrapperBuilder {
|
||||
return this;
|
||||
}
|
||||
|
||||
public CommandWrapperBuilder updateLoanCharge(final Long loanId, Long loanChargeId) {
|
||||
public CommandWrapperBuilder updateLoanCharge(final Long loanId, final Long loanChargeId) {
|
||||
this.actionName = "UPDATE";
|
||||
this.entityName = "LOANCHARGE";
|
||||
this.entityId = loanChargeId;
|
||||
@@ -568,7 +569,7 @@ public class CommandWrapperBuilder {
|
||||
return this;
|
||||
}
|
||||
|
||||
public CommandWrapperBuilder updateCodeValue(Long codeId, final Long codeValueId) {
|
||||
public CommandWrapperBuilder updateCodeValue(final Long codeId, final Long codeValueId) {
|
||||
this.actionName = "UPDATE";
|
||||
this.entityName = "CODEVALUE";
|
||||
this.entityId = codeValueId;
|
||||
@@ -633,7 +634,7 @@ public class CommandWrapperBuilder {
|
||||
this.href = "/glaccounts/" + glAccountId;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public CommandWrapperBuilder createJournalEntry() {
|
||||
this.actionName = "CREATE";
|
||||
this.entityName = "JOURNALENTRY";
|
||||
@@ -641,16 +642,16 @@ public class CommandWrapperBuilder {
|
||||
this.href = "/journalentries/template";
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public CommandWrapperBuilder reverseJournalEntry(final String transactionId) {
|
||||
this.actionName = "REVERSE";
|
||||
this.entityName = "JOURNALENTRY";
|
||||
this.entityId = null;
|
||||
this.transactionId = transactionId;
|
||||
this.href = "/journalentries/"+transactionId;
|
||||
this.href = "/journalentries/" + transactionId;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public CommandWrapperBuilder createDepositProduct() {
|
||||
this.actionName = "CREATE";
|
||||
this.entityName = "DEPOSITPRODUCT";
|
||||
@@ -659,198 +660,166 @@ public class CommandWrapperBuilder {
|
||||
return this;
|
||||
}
|
||||
|
||||
public CommandWrapperBuilder updateDepositProduct(final Long productId) {
|
||||
this.actionName = "UPDATE";
|
||||
public CommandWrapperBuilder updateDepositProduct(final Long productId) {
|
||||
this.actionName = "UPDATE";
|
||||
this.entityName = "DEPOSITPRODUCT";
|
||||
this.entityId = productId;
|
||||
this.href = "/depositproducts/"+productId;
|
||||
this.href = "/depositproducts/" + productId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CommandWrapperBuilder deleteDepositProduct(final Long productId) {
|
||||
this.actionName = "DELETE";
|
||||
this.entityName = "DEPOSITPRODUCT";
|
||||
this.entityId = productId;
|
||||
this.href = "/depositproducts/"+productId;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
public CommandWrapperBuilder createDepositAccount() {
|
||||
this.actionName = "CREATE";
|
||||
public CommandWrapperBuilder deleteDepositProduct(final Long productId) {
|
||||
this.actionName = "DELETE";
|
||||
this.entityName = "DEPOSITPRODUCT";
|
||||
this.entityId = productId;
|
||||
this.href = "/depositproducts/" + productId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CommandWrapperBuilder createDepositAccount() {
|
||||
this.actionName = "CREATE";
|
||||
this.entityName = "DEPOSITACCOUNT";
|
||||
this.entityId = null;
|
||||
this.href = "/depositaccounts/template";
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
public CommandWrapperBuilder updateDepositAccount(Long accountId) {
|
||||
this.actionName = "UPDATE";
|
||||
public CommandWrapperBuilder updateDepositAccount(final Long accountId) {
|
||||
this.actionName = "UPDATE";
|
||||
this.entityName = "DEPOSITACCOUNT";
|
||||
this.entityId = accountId;
|
||||
this.href = "/depositaccounts/"+accountId;
|
||||
this.href = "/depositaccounts/" + accountId;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
public CommandWrapperBuilder deleteDepositAccount(Long accountId) {
|
||||
this.actionName = "DELETE";
|
||||
public CommandWrapperBuilder deleteDepositAccount(final Long accountId) {
|
||||
this.actionName = "DELETE";
|
||||
this.entityName = "DEPOSITACCOUNT";
|
||||
this.entityId = accountId;
|
||||
this.href = "/depositaccounts/"+accountId;
|
||||
this.href = "/depositaccounts/" + accountId;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
public CommandWrapperBuilder approveDepositApplication(Long accountId) {
|
||||
this.actionName = "APPROVE";
|
||||
public CommandWrapperBuilder approveDepositApplication(final Long accountId) {
|
||||
this.actionName = "APPROVE";
|
||||
this.entityName = "DEPOSITACCOUNT";
|
||||
this.entityId = accountId;
|
||||
this.href = "/depositaccounts/"+accountId;
|
||||
this.href = "/depositaccounts/" + accountId;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
public CommandWrapperBuilder withdrawDepositAmount(Long accountId) {
|
||||
this.actionName = "WITHDRAWAL";
|
||||
public CommandWrapperBuilder withdrawDepositAmount(final Long accountId) {
|
||||
this.actionName = "WITHDRAWAL";
|
||||
this.entityName = "DEPOSITACCOUNT";
|
||||
this.entityId = accountId;
|
||||
this.href = "/depositaccounts/"+accountId;
|
||||
this.href = "/depositaccounts/" + accountId;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
public CommandWrapperBuilder withdrawInterestDepositAmount(Long accountId) {
|
||||
this.actionName = "INTEREST";
|
||||
public CommandWrapperBuilder withdrawInterestDepositAmount(final Long accountId) {
|
||||
this.actionName = "INTEREST";
|
||||
this.entityName = "DEPOSITACCOUNT";
|
||||
this.entityId = accountId;
|
||||
this.href = "/depositaccounts/"+accountId;
|
||||
this.href = "/depositaccounts/" + accountId;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
public CommandWrapperBuilder renewDepositAccount(Long accountId) {
|
||||
this.actionName = "RENEW";
|
||||
public CommandWrapperBuilder renewDepositAccount(final Long accountId) {
|
||||
this.actionName = "RENEW";
|
||||
this.entityName = "DEPOSITACCOUNT";
|
||||
this.entityId = accountId;
|
||||
this.href = "/depositaccounts/"+accountId;
|
||||
this.href = "/depositaccounts/" + accountId;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
public CommandWrapperBuilder rejectDepositAccount(Long accountId) {
|
||||
this.actionName = "REJECT";
|
||||
public CommandWrapperBuilder rejectDepositAccount(final Long accountId) {
|
||||
this.actionName = "REJECT";
|
||||
this.entityName = "DEPOSITACCOUNT";
|
||||
this.entityId = accountId;
|
||||
this.href = "/depositaccounts/"+accountId;
|
||||
this.href = "/depositaccounts/" + accountId;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
public CommandWrapperBuilder withdrawDepositApplication(Long accountId) {
|
||||
this.actionName = "WITHDRAW";
|
||||
public CommandWrapperBuilder withdrawDepositApplication(final Long accountId) {
|
||||
this.actionName = "WITHDRAW";
|
||||
this.entityName = "DEPOSITACCOUNT";
|
||||
this.entityId = accountId;
|
||||
this.href = "/depositaccounts/"+accountId;
|
||||
this.href = "/depositaccounts/" + accountId;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
public CommandWrapperBuilder undoDepositApplicationApproval(Long accountId) {
|
||||
this.actionName = "APPROVALUNDO";
|
||||
public CommandWrapperBuilder undoDepositApplicationApproval(final Long accountId) {
|
||||
this.actionName = "APPROVALUNDO";
|
||||
this.entityName = "DEPOSITACCOUNT";
|
||||
this.entityId = accountId;
|
||||
this.href = "/depositaccounts/"+accountId;
|
||||
this.href = "/depositaccounts/" + accountId;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
public CommandWrapperBuilder createSavingProduct() {
|
||||
this.actionName = "CREATE";
|
||||
public CommandWrapperBuilder createSavingProduct() {
|
||||
this.actionName = "CREATE";
|
||||
this.entityName = "SAVINGSPRODUCT";
|
||||
this.entityId = null;
|
||||
this.href = "/savingproducts/template";
|
||||
this.href = "/savingsproducts/template";
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
public CommandWrapperBuilder updateSavingProduct(Long productId) {
|
||||
this.actionName = "UPDATE";
|
||||
public CommandWrapperBuilder updateSavingProduct(final Long productId) {
|
||||
this.actionName = "UPDATE";
|
||||
this.entityName = "SAVINGSPRODUCT";
|
||||
this.entityId = productId;
|
||||
this.href = "/savingproducts/"+productId;
|
||||
this.href = "/savingsproducts/" + productId;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
public CommandWrapperBuilder deleteSavingProduct(Long productId) {
|
||||
this.actionName = "DELETE";
|
||||
public CommandWrapperBuilder deleteSavingProduct(final Long productId) {
|
||||
this.actionName = "DELETE";
|
||||
this.entityName = "SAVINGSPRODUCT";
|
||||
this.entityId = productId;
|
||||
this.href = "/savingproducts/"+productId;
|
||||
this.href = "/savingsproducts/" + productId;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
public CommandWrapperBuilder createSavingAccount() {
|
||||
this.actionName = "CREATE";
|
||||
public CommandWrapperBuilder createSavingsAccount() {
|
||||
this.actionName = "CREATE";
|
||||
this.entityName = "SAVINGSACCOUNT";
|
||||
this.entityId = null;
|
||||
this.href = "/savingaccounts/template";
|
||||
this.href = "/savingsaccounts/template";
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
public CommandWrapperBuilder updateSavingAccount(Long accountId) {
|
||||
this.actionName = "UPDATE";
|
||||
public CommandWrapperBuilder updateSavingsAccount(final Long accountId) {
|
||||
this.actionName = "UPDATE";
|
||||
this.entityName = "SAVINGSACCOUNT";
|
||||
this.entityId = accountId;
|
||||
this.href = "/savingproducts/"+accountId;
|
||||
this.href = "/savingsaccounts/" + accountId;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
public CommandWrapperBuilder deleteSavingAccount(Long accountId) {
|
||||
this.actionName = "DELETE";
|
||||
public CommandWrapperBuilder deleteSavingsAccount(final Long accountId) {
|
||||
this.actionName = "DELETE";
|
||||
this.entityName = "SAVINGSACCOUNT";
|
||||
this.entityId = accountId;
|
||||
this.href = "/savingproducts/"+accountId;
|
||||
this.href = "/savingsaccounts/" + accountId;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
public CommandWrapperBuilder approveSavingAccountApplication(Long accountId) {
|
||||
this.actionName = "APPROVE";
|
||||
public CommandWrapperBuilder depositOfSavingAmount(final Long accountId) {
|
||||
this.actionName = "DEPOSIT";
|
||||
this.entityName = "SAVINGSACCOUNT";
|
||||
this.entityId = accountId;
|
||||
this.href = "/depositaccounts/"+accountId;
|
||||
this.href = "/savingsaccounts/" + accountId;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
public CommandWrapperBuilder depositOfSavingAmount(Long accountId) {
|
||||
this.actionName = "DEPOSIT";
|
||||
public CommandWrapperBuilder withdrawSavingAmount(final Long accountId) {
|
||||
this.actionName = "WITHDRAWAL";
|
||||
this.entityName = "SAVINGSACCOUNT";
|
||||
this.entityId = accountId;
|
||||
this.href = "/depositaccounts/"+accountId;
|
||||
this.href = "/savingsaccounts/" + accountId;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
public CommandWrapperBuilder withdrawSavingAmount(Long accountId) {
|
||||
this.actionName = "WITHDRAWAL";
|
||||
this.entityName = "SAVINGSACCOUNT";
|
||||
this.entityId = accountId;
|
||||
this.href = "/depositaccounts/"+accountId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CommandWrapperBuilder rejectSavingApplication(Long accountId) {
|
||||
this.actionName = "REJECT";
|
||||
this.entityName = "SAVINGSACCOUNT";
|
||||
this.entityId = accountId;
|
||||
this.href = "/depositaccounts/"+accountId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CommandWrapperBuilder withdrawSavingApplication(Long accountId) {
|
||||
this.actionName = "WITHDRAW";
|
||||
this.entityName = "SAVINGSACCOUNT";
|
||||
this.entityId = accountId;
|
||||
this.href = "/depositaccounts/"+accountId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CommandWrapperBuilder undoApprovalOfSavingApplication(Long accountId) {
|
||||
this.actionName = "APPROVALUNDO";
|
||||
this.entityName = "SAVINGSACCOUNT";
|
||||
this.entityId = accountId;
|
||||
this.href = "/depositaccounts/"+accountId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CommandWrapperBuilder createCalendar(final String supportedEntityType, final Long supportedEntityId) {
|
||||
this.actionName = "CREATE";
|
||||
this.entityName = "CALENDAR";
|
||||
@@ -875,10 +844,11 @@ public class CommandWrapperBuilder {
|
||||
this.href = "/" + supportedEntityType + "/" + supportedEntityId + "/calendars/" + calendarId;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public CommandWrapperBuilder createNote(final String entityName, final String resourceType, final Long resourceId) {
|
||||
this.actionName = "CREATE";
|
||||
this.entityName = entityName;//Note supports multiple resources. Note Permissions are set for each resource.
|
||||
this.entityName = entityName;// Note supports multiple resources. Note
|
||||
// Permissions are set for each resource.
|
||||
this.supportedEntityType = resourceType;
|
||||
this.supportedEntityId = resourceId;
|
||||
this.href = "/" + resourceType + "/" + resourceId + "/notes/template";
|
||||
@@ -887,7 +857,8 @@ public class CommandWrapperBuilder {
|
||||
|
||||
public CommandWrapperBuilder updateNote(final String entityName, final String resourceType, final Long resourceId, final Long noteId) {
|
||||
this.actionName = "UPDATE";
|
||||
this.entityName = entityName;//Note supports multiple resources. Note Permissions are set for each resource.
|
||||
this.entityName = entityName;// Note supports multiple resources. Note
|
||||
// Permissions are set for each resource.
|
||||
this.entityId = noteId;
|
||||
this.supportedEntityType = resourceType;
|
||||
this.supportedEntityId = resourceId;
|
||||
@@ -897,21 +868,22 @@ public class CommandWrapperBuilder {
|
||||
|
||||
public CommandWrapperBuilder deleteNote(final String entityName, final String resourceType, final Long resourceId, final Long noteId) {
|
||||
this.actionName = "DELETE";
|
||||
this.entityName = entityName;//Note supports multiple resources. Note Permissions are set for each resource.
|
||||
this.entityName = entityName;// Note supports multiple resources. Note
|
||||
// Permissions are set for each resource.
|
||||
this.entityId = noteId;
|
||||
this.supportedEntityType = resourceType;
|
||||
this.supportedEntityId = resourceId;
|
||||
this.href = "/" + resourceType + "/" + resourceId + "/calendars/" + noteId;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public CommandWrapperBuilder createGroup() {
|
||||
this.actionName = "CREATE";
|
||||
this.entityName = "GROUP";
|
||||
this.href = "/groups/template";
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public CommandWrapperBuilder updateGroup(final Long groupId) {
|
||||
this.actionName = "UPDATE";
|
||||
this.entityName = "GROUP";
|
||||
|
||||
+6
-18
@@ -375,33 +375,21 @@ public class SynchronousCommandProcessingService implements CommandProcessingSer
|
||||
}
|
||||
} else if (wrapper.isSavingProductResource()) {
|
||||
if (wrapper.isCreate()) {
|
||||
handler = applicationContext.getBean("createSavingProductCommandHandler", NewCommandSourceHandler.class);
|
||||
handler = applicationContext.getBean("createSavingsProductCommandHandler", NewCommandSourceHandler.class);
|
||||
} else if (wrapper.isUpdate()) {
|
||||
handler = applicationContext.getBean("updateSavingProductCommandHandler", NewCommandSourceHandler.class);
|
||||
handler = applicationContext.getBean("updateSavingsProductCommandHandler", NewCommandSourceHandler.class);
|
||||
} else if (wrapper.isDelete()) {
|
||||
handler = applicationContext.getBean("deleteSavingProductCommandHandler", NewCommandSourceHandler.class);
|
||||
handler = applicationContext.getBean("deleteSavingsProductCommandHandler", NewCommandSourceHandler.class);
|
||||
} else {
|
||||
throw new UnsupportedCommandException(wrapper.commandName());
|
||||
}
|
||||
} else if (wrapper.isSavingAccountResource()) {
|
||||
if (wrapper.isCreate()) {
|
||||
handler = applicationContext.getBean("createSavingAccountCommandHandler", NewCommandSourceHandler.class);
|
||||
handler = applicationContext.getBean("createSavingsAccountCommandHandler", NewCommandSourceHandler.class);
|
||||
} else if (wrapper.isUpdate()) {
|
||||
handler = applicationContext.getBean("updateSavingAccountCommandHandler", NewCommandSourceHandler.class);
|
||||
handler = applicationContext.getBean("updateSavingsAccountCommandHandler", NewCommandSourceHandler.class);
|
||||
} else if (wrapper.isDelete()) {
|
||||
handler = applicationContext.getBean("deleteSavingAccountCommandHandler", NewCommandSourceHandler.class);
|
||||
} else if (wrapper.isApprovalOfSaving()) {
|
||||
handler = applicationContext.getBean("approveSavingAccountCommandHandler", NewCommandSourceHandler.class);
|
||||
} else if (wrapper.isSavingAccountDeposit()) {
|
||||
handler = applicationContext.getBean("depositSavingAmountCommandHandler", NewCommandSourceHandler.class);
|
||||
} else if (wrapper.isRejectOfSavingAccount()) {
|
||||
handler = applicationContext.getBean("rejectSavingAccountCommandHandler", NewCommandSourceHandler.class);
|
||||
} else if (wrapper.isWithdrawSavingAmount()) {
|
||||
handler = applicationContext.getBean("withdrawSavingAmountCommandHandler", NewCommandSourceHandler.class);
|
||||
} else if (wrapper.isWithdrawOfSavingApplicatin()) {
|
||||
handler = applicationContext.getBean("withdrawSavingApplicationCommandHandler", NewCommandSourceHandler.class);
|
||||
} else if (wrapper.isUndoApprovalOfSavingAccount()) {
|
||||
handler = applicationContext.getBean("undoApprovalSavingAccountCommandHandler", NewCommandSourceHandler.class);
|
||||
handler = applicationContext.getBean("deleteSavingsAccountCommandHandler", NewCommandSourceHandler.class);
|
||||
} else {
|
||||
throw new UnsupportedCommandException(wrapper.commandName());
|
||||
}
|
||||
|
||||
+8
@@ -42,6 +42,7 @@ import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.support.rowset.SqlRowSet;
|
||||
import org.springframework.jdbc.support.rowset.SqlRowSetMetaData;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
@@ -103,6 +104,7 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
|
||||
logger.error(dve.getMessage(), dve);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public void registerDatatable(final String dataTableName, final String applicationTableName) {
|
||||
|
||||
@@ -176,6 +178,7 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
|
||||
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public void deregisterDatatable(final String datatable) {
|
||||
final String permissionList = "('CREATE_" + datatable + "', 'CREATE_" + datatable + "_CHECKER', 'READ_" + datatable + "', 'UPDATE_"
|
||||
@@ -192,6 +195,7 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
|
||||
this.jdbcTemplate.batchUpdate(sqlArray);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public void createNewDatatableEntry(final String dataTableName, final Long appTableId, final JsonCommand command) {
|
||||
|
||||
@@ -230,6 +234,7 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public Map<String, Object> updateDatatableEntryOneToOne(final String datatable, final Long appTableId, final JsonCommand command) {
|
||||
|
||||
@@ -258,6 +263,7 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
|
||||
return changes;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public Map<String, Object> updateDatatableEntryOneToMany(final String datatable, final Long appTableId, final Long datatableId,
|
||||
final JsonCommand command) {
|
||||
@@ -284,6 +290,7 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
|
||||
return changes;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public void deleteDatatableEntries(final String datatable, final Long appTableId) {
|
||||
|
||||
@@ -295,6 +302,7 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
|
||||
if (rowsDeleted < 1) { throw new DatatableNotFoundException(datatable, appTableId); }
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public void deleteDatatableEntry(final String datatable, final Long appTableId, final Long datatableId) {
|
||||
|
||||
|
||||
+4
@@ -17,4 +17,8 @@ public class AccountNumberGeneratorFactory {
|
||||
public AccountNumberGenerator determineLoanAccountNoGenerator(final Long loanId) {
|
||||
return new ZeroPaddedAccountNumberGenerator(loanId, 9);
|
||||
}
|
||||
|
||||
public AccountNumberGenerator determineSavingsAccountNoGenerator(final Long savingsAccountId) {
|
||||
return new ZeroPaddedAccountNumberGenerator(savingsAccountId, 9);
|
||||
}
|
||||
}
|
||||
+16
-12
@@ -37,7 +37,7 @@ import org.mifosplatform.portfolio.group.domain.Group;
|
||||
import org.springframework.data.jpa.domain.AbstractPersistable;
|
||||
|
||||
@Entity
|
||||
@Table(name = "m_client", uniqueConstraints = { @UniqueConstraint(columnNames = { "account_no" }, name = "account_no_UNIQUE")})
|
||||
@Table(name = "m_client", uniqueConstraints = { @UniqueConstraint(columnNames = { "account_no" }, name = "account_no_UNIQUE") })
|
||||
public class Client extends AbstractPersistable<Long> {
|
||||
|
||||
@Column(name = "account_no", length = 20, unique = true, nullable = false)
|
||||
@@ -79,11 +79,11 @@ public class Client extends AbstractPersistable<Long> {
|
||||
@ManyToMany
|
||||
@JoinTable(name = "m_group_client", joinColumns = @JoinColumn(name = "client_id"), inverseJoinColumns = @JoinColumn(name = "group_id"))
|
||||
private Set<Group> parentGroups;
|
||||
|
||||
|
||||
@Transient
|
||||
private boolean accountNumberRequiresAutoGeneration = false;
|
||||
|
||||
public static Client fromJson(final Office clientOffice, final Group clientParentGroup , final JsonCommand command) {
|
||||
public static Client fromJson(final Office clientOffice, final Group clientParentGroup, final JsonCommand command) {
|
||||
|
||||
final String accountNo = command.stringValueOfParameterNamed("accountNo");
|
||||
final String firstname = command.stringValueOfParameterNamed("firstname");
|
||||
@@ -93,15 +93,15 @@ public class Client extends AbstractPersistable<Long> {
|
||||
final LocalDate joiningDate = command.localDateValueOfParameterNamed("joinedDate");
|
||||
final String externalId = command.stringValueOfParameterNamed("externalId");
|
||||
|
||||
return new Client(clientOffice, clientParentGroup ,accountNo, firstname, middlename, lastname, fullname, joiningDate, externalId);
|
||||
return new Client(clientOffice, clientParentGroup, accountNo, firstname, middlename, lastname, fullname, joiningDate, externalId);
|
||||
}
|
||||
|
||||
protected Client() {
|
||||
|
||||
|
||||
}
|
||||
|
||||
private Client(final Office office, final Group clientParentGroup, final String accountNo, final String firstname, final String middlename, final String lastname,
|
||||
final String fullname, final LocalDate openingDate, final String externalId) {
|
||||
private Client(final Office office, final Group clientParentGroup, final String accountNo, final String firstname,
|
||||
final String middlename, final String lastname, final String fullname, final LocalDate openingDate, final String externalId) {
|
||||
if (StringUtils.isBlank(accountNo)) {
|
||||
this.accountNumber = new RandomPasswordGenerator(19).generate();
|
||||
this.accountNumberRequiresAutoGeneration = true;
|
||||
@@ -139,11 +139,11 @@ public class Client extends AbstractPersistable<Long> {
|
||||
this.fullname = null;
|
||||
}
|
||||
|
||||
if(clientParentGroup != null){
|
||||
if (clientParentGroup != null) {
|
||||
this.parentGroups = new HashSet<Group>();
|
||||
this.parentGroups.add(clientParentGroup);
|
||||
}
|
||||
|
||||
|
||||
deriveDisplayName();
|
||||
validateNameParts();
|
||||
}
|
||||
@@ -152,7 +152,7 @@ public class Client extends AbstractPersistable<Long> {
|
||||
return this.accountNumberRequiresAutoGeneration;
|
||||
}
|
||||
|
||||
public void setAccountNumberRequiresAutoGeneration(boolean accountNumberRequiresAutoGeneration) {
|
||||
public void setAccountNumberRequiresAutoGeneration(final boolean accountNumberRequiresAutoGeneration) {
|
||||
this.accountNumberRequiresAutoGeneration = accountNumberRequiresAutoGeneration;
|
||||
}
|
||||
|
||||
@@ -160,7 +160,7 @@ public class Client extends AbstractPersistable<Long> {
|
||||
return identifier.equalsIgnoreCase(this.externalId);
|
||||
}
|
||||
|
||||
public boolean identifiedBy(Long clientId) {
|
||||
public boolean identifiedBy(final Long clientId) {
|
||||
return getId().equals(clientId);
|
||||
}
|
||||
|
||||
@@ -346,7 +346,11 @@ public class Client extends AbstractPersistable<Long> {
|
||||
return imageKey;
|
||||
}
|
||||
|
||||
public void setImageKey(String imageKey) {
|
||||
public void setImageKey(final String imageKey) {
|
||||
this.imageKey = imageKey;
|
||||
}
|
||||
|
||||
public Long officeId() {
|
||||
return this.office.getId();
|
||||
}
|
||||
}
|
||||
+53
-93
@@ -216,31 +216,35 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
|
||||
List<ClientAccountSummaryData> preclosedDepositAccounts = new ArrayList<ClientAccountSummaryData>();
|
||||
List<ClientAccountSummaryData> maturedDepositAccounts = new ArrayList<ClientAccountSummaryData>();
|
||||
|
||||
ClientDespoitAccountSummaryDataMapper depositAccountMapper = new ClientDespoitAccountSummaryDataMapper();
|
||||
|
||||
String depositAccountsSql = "select " + depositAccountMapper.schema() + " where da.client_id = ? and da.is_deleted=0";
|
||||
List<ClientAccountSummaryData> depositAccountResults = this.jdbcTemplate.query(depositAccountsSql, depositAccountMapper,
|
||||
new Object[] { clientId });
|
||||
if (depositAccountResults != null) {
|
||||
for (ClientAccountSummaryData row : depositAccountResults) {
|
||||
|
||||
if (row.accountStatusId() == 100) {
|
||||
pendingApprovalDepositAccounts.add(row);
|
||||
} else if (row.accountStatusId() == 300) {
|
||||
approvedDepositAccounts.add(row);
|
||||
} else if (row.accountStatusId() == 400) {
|
||||
withdrawnByClientDespositAccounts.add(row);
|
||||
} else if (row.accountStatusId() == 500) {
|
||||
rejectedDepositAccounts.add(row);
|
||||
} else if (row.accountStatusId() == 600) {
|
||||
closedDepositAccounts.add(row);
|
||||
} else if (row.accountStatusId() == 700) {
|
||||
maturedDepositAccounts.add(row);
|
||||
} else if (row.accountStatusId() == 800) {
|
||||
preclosedDepositAccounts.add(row);
|
||||
}
|
||||
}
|
||||
}
|
||||
// ClientDespoitAccountSummaryDataMapper depositAccountMapper = new
|
||||
// ClientDespoitAccountSummaryDataMapper();
|
||||
//
|
||||
// String depositAccountsSql = "select " +
|
||||
// depositAccountMapper.schema() +
|
||||
// " where da.client_id = ? and da.is_deleted=0";
|
||||
// List<ClientAccountSummaryData> depositAccountResults =
|
||||
// this.jdbcTemplate.query(depositAccountsSql, depositAccountMapper,
|
||||
// new Object[] { clientId });
|
||||
// if (depositAccountResults != null) {
|
||||
// for (ClientAccountSummaryData row : depositAccountResults) {
|
||||
//
|
||||
// if (row.accountStatusId() == 100) {
|
||||
// pendingApprovalDepositAccounts.add(row);
|
||||
// } else if (row.accountStatusId() == 300) {
|
||||
// approvedDepositAccounts.add(row);
|
||||
// } else if (row.accountStatusId() == 400) {
|
||||
// withdrawnByClientDespositAccounts.add(row);
|
||||
// } else if (row.accountStatusId() == 500) {
|
||||
// rejectedDepositAccounts.add(row);
|
||||
// } else if (row.accountStatusId() == 600) {
|
||||
// closedDepositAccounts.add(row);
|
||||
// } else if (row.accountStatusId() == 700) {
|
||||
// maturedDepositAccounts.add(row);
|
||||
// } else if (row.accountStatusId() == 800) {
|
||||
// preclosedDepositAccounts.add(row);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
List<ClientAccountSummaryData> pendingApprovalSavingAccounts = new ArrayList<ClientAccountSummaryData>();
|
||||
List<ClientAccountSummaryData> approvedSavingAccounts = new ArrayList<ClientAccountSummaryData>();
|
||||
@@ -248,25 +252,30 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
|
||||
List<ClientAccountSummaryData> rejectedSavingAccounts = new ArrayList<ClientAccountSummaryData>();
|
||||
List<ClientAccountSummaryData> closedSavingAccounts = new ArrayList<ClientAccountSummaryData>();
|
||||
|
||||
ClientSavingAccountSummaryDataMapper clientSavingAccountSummaryDataMapper = new ClientSavingAccountSummaryDataMapper();
|
||||
String savingAccountsSql = "select " + clientSavingAccountSummaryDataMapper.schema()
|
||||
+ " where sa.client_id=? and sa.is_deleted=0";
|
||||
List<ClientAccountSummaryData> savingAccountsResults = this.jdbcTemplate.query(savingAccountsSql,
|
||||
clientSavingAccountSummaryDataMapper, new Object[] { clientId });
|
||||
|
||||
if (savingAccountsResults != null) {
|
||||
for (ClientAccountSummaryData account : savingAccountsResults) {
|
||||
if (account.accountStatusId() == 100)
|
||||
pendingApprovalSavingAccounts.add(account);
|
||||
else if (account.accountStatusId() == 300)
|
||||
approvedSavingAccounts.add(account);
|
||||
else if (account.accountStatusId() == 400)
|
||||
withdrawnByClientSavingAccounts.add(account);
|
||||
else if (account.accountStatusId() == 500)
|
||||
rejectedSavingAccounts.add(account);
|
||||
else if (account.accountStatusId() == 600) closedSavingAccounts.add(account);
|
||||
}
|
||||
}
|
||||
// ClientSavingAccountSummaryDataMapper
|
||||
// clientSavingAccountSummaryDataMapper = new
|
||||
// ClientSavingAccountSummaryDataMapper();
|
||||
// String savingAccountsSql = "select " +
|
||||
// clientSavingAccountSummaryDataMapper.schema()
|
||||
// + " where sa.client_id=? and sa.is_deleted=0";
|
||||
// List<ClientAccountSummaryData> savingAccountsResults =
|
||||
// this.jdbcTemplate.query(savingAccountsSql,
|
||||
// clientSavingAccountSummaryDataMapper, new Object[] { clientId });
|
||||
//
|
||||
// if (savingAccountsResults != null) {
|
||||
// for (ClientAccountSummaryData account : savingAccountsResults) {
|
||||
// if (account.accountStatusId() == 100)
|
||||
// pendingApprovalSavingAccounts.add(account);
|
||||
// else if (account.accountStatusId() == 300)
|
||||
// approvedSavingAccounts.add(account);
|
||||
// else if (account.accountStatusId() == 400)
|
||||
// withdrawnByClientSavingAccounts.add(account);
|
||||
// else if (account.accountStatusId() == 500)
|
||||
// rejectedSavingAccounts.add(account);
|
||||
// else if (account.accountStatusId() == 600)
|
||||
// closedSavingAccounts.add(account);
|
||||
// }
|
||||
// }
|
||||
|
||||
return new ClientAccountSummaryCollectionData(pendingApprovalLoans, awaitingDisbursalLoans, openLoans, closedLoans,
|
||||
pendingApprovalDepositAccounts, approvedDepositAccounts, withdrawnByClientDespositAccounts, rejectedDepositAccounts,
|
||||
@@ -320,30 +329,6 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
|
||||
}
|
||||
}
|
||||
|
||||
private static final class ClientDespoitAccountSummaryDataMapper implements RowMapper<ClientAccountSummaryData> {
|
||||
|
||||
public String schema() {
|
||||
|
||||
StringBuilder accountsSummary = new StringBuilder("da.id as id, da.external_id as externalId,");
|
||||
accountsSummary.append("da.product_id as productId, dp.name as productName,").append("da.status_enum as statusId ")
|
||||
.append("from m_deposit_account da ").append("LEFT JOIN m_product_deposit AS dp ON dp.id = da.product_id ");
|
||||
|
||||
return accountsSummary.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClientAccountSummaryData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {
|
||||
|
||||
Long id = JdbcSupport.getLong(rs, "id");
|
||||
String externalId = rs.getString("externalId");
|
||||
Long productId = JdbcSupport.getLong(rs, "productId");
|
||||
String productName = rs.getString("productName");
|
||||
Integer accountStatusId = JdbcSupport.getInteger(rs, "statusId");
|
||||
|
||||
return new ClientAccountSummaryData(id, externalId, productId, productName, accountStatusId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClientData retrieveClientByIdentifier(final Long identifierTypeId, final String identifierKey) {
|
||||
try {
|
||||
@@ -383,29 +368,4 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
|
||||
return ClientData.clientIdentifier(id, accountNo, firstname, middlename, lastname, fullname, displayName, officeId, officeName);
|
||||
}
|
||||
}
|
||||
|
||||
private static final class ClientSavingAccountSummaryDataMapper implements RowMapper<ClientAccountSummaryData> {
|
||||
|
||||
public String schema() {
|
||||
|
||||
StringBuilder accountsSummary = new StringBuilder("sa.id as id, sa.external_id as externalId,");
|
||||
accountsSummary.append("sa.product_id as productId, sp.name as productName,").append("sa.status_enum as statusId ")
|
||||
.append("from m_saving_account sa ").append("LEFT JOIN m_product_savings AS sp ON sp.id = sa.product_id ");
|
||||
|
||||
return accountsSummary.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClientAccountSummaryData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {
|
||||
|
||||
Long id = JdbcSupport.getLong(rs, "id");
|
||||
String externalId = rs.getString("externalId");
|
||||
Long productId = JdbcSupport.getLong(rs, "productId");
|
||||
String productName = rs.getString("productName");
|
||||
Integer accountStatusId = JdbcSupport.getInteger(rs, "statusId");
|
||||
|
||||
return new ClientAccountSummaryData(id, externalId, productId, productName, accountStatusId);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -215,4 +215,7 @@ public class Group extends AbstractPersistable<Long> {
|
||||
return this.office.identifiedBy(officeId);
|
||||
}
|
||||
|
||||
}
|
||||
public Long officeId() {
|
||||
return this.office.getId();
|
||||
}
|
||||
}
|
||||
-2
@@ -191,8 +191,6 @@ public class LoansApiResource {
|
||||
|
||||
final boolean feeChargesOnly = false;
|
||||
chargeOptions = this.chargeReadPlatformService.retrieveLoanApplicableCharges(feeChargesOnly);
|
||||
// chargeTemplate =
|
||||
// this.loanChargeReadPlatformService.retrieveLoanChargeTemplate();
|
||||
}
|
||||
|
||||
LoanAccountData newLoanAccount = null;
|
||||
|
||||
+3
-3
@@ -441,7 +441,7 @@ public class Loan extends AbstractPersistable<Long> {
|
||||
* @param suppliedTransactionDate
|
||||
* @return
|
||||
*/
|
||||
private LoanTransaction getChargeAppliedTransaction(final LoanCharge loanCharge, LocalDate suppliedTransactionDate) {
|
||||
private LoanTransaction getChargeAppliedTransaction(final LoanCharge loanCharge, final LocalDate suppliedTransactionDate) {
|
||||
final Money chargeAmount = loanCharge.getAmount(getCurrency());
|
||||
Money feeCharges = chargeAmount;
|
||||
Money penaltyCharges = Money.zero(loanCurrency());
|
||||
@@ -2165,9 +2165,9 @@ public class Loan extends AbstractPersistable<Long> {
|
||||
public Long getOfficeId() {
|
||||
Long officeId = null;
|
||||
if (this.client != null) {
|
||||
officeId = this.client.getOffice().getId();
|
||||
officeId = this.client.officeId();
|
||||
} else {
|
||||
// officeId = this.group.getOffice().getId();
|
||||
officeId = this.group.officeId();
|
||||
}
|
||||
return officeId;
|
||||
}
|
||||
|
||||
+3
-3
@@ -13,10 +13,11 @@ import org.springframework.stereotype.Component;
|
||||
@Component
|
||||
public class AprCalculator {
|
||||
|
||||
public BigDecimal calculateFrom(PeriodFrequencyType interestPeriodFrequencyType, BigDecimal interestRatePerPeriod) {
|
||||
public BigDecimal calculateFrom(final PeriodFrequencyType interestPeriodFrequencyType, final BigDecimal interestRatePerPeriod) {
|
||||
BigDecimal defaultAnnualNominalInterestRate = BigDecimal.ZERO;
|
||||
switch (interestPeriodFrequencyType) {
|
||||
case DAYS:
|
||||
defaultAnnualNominalInterestRate = interestRatePerPeriod.multiply(BigDecimal.valueOf(365));
|
||||
break;
|
||||
case WEEKS:
|
||||
defaultAnnualNominalInterestRate = interestRatePerPeriod.multiply(BigDecimal.valueOf(52));
|
||||
@@ -33,5 +34,4 @@ public class AprCalculator {
|
||||
|
||||
return defaultAnnualNominalInterestRate;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
+41
-37
@@ -69,13 +69,14 @@ public class NotesApiResource {
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String retrieveNotesByResource(@PathParam("resourceType") final String resourceType,
|
||||
@PathParam("resourceId") final Long resourceId, @Context final UriInfo uriInfo) {
|
||||
|
||||
|
||||
NoteType noteType = NoteType.fromApiUrl(resourceType);
|
||||
|
||||
if(noteType == null){ throw new NoteResourceNotSupportedException(resourceType); };
|
||||
|
||||
|
||||
if (noteType == null) { throw new NoteResourceNotSupportedException(resourceType); }
|
||||
;
|
||||
|
||||
this.context.authenticatedUser().validateHasReadPermission(getResourceNameForPermissions(noteType));
|
||||
|
||||
|
||||
final Integer noteTypeId = noteType.getValue();
|
||||
|
||||
final Collection<NoteData> notes = this.readPlatformService.retrieveNotesByResource(resourceId, noteTypeId);
|
||||
@@ -92,9 +93,10 @@ public class NotesApiResource {
|
||||
@PathParam("noteId") final Long noteId, @Context final UriInfo uriInfo) {
|
||||
|
||||
NoteType noteType = NoteType.fromApiUrl(resourceType);
|
||||
|
||||
if(noteType == null){ throw new NoteResourceNotSupportedException(resourceType); };
|
||||
|
||||
|
||||
if (noteType == null) { throw new NoteResourceNotSupportedException(resourceType); }
|
||||
;
|
||||
|
||||
this.context.authenticatedUser().validateHasReadPermission(getResourceNameForPermissions(noteType));
|
||||
|
||||
final Integer noteTypeId = noteType.getValue();
|
||||
@@ -112,9 +114,10 @@ public class NotesApiResource {
|
||||
final String apiRequestBodyAsJson) {
|
||||
|
||||
NoteType noteType = NoteType.fromApiUrl(resourceType);
|
||||
|
||||
if(noteType == null){ throw new NoteResourceNotSupportedException(resourceType); };
|
||||
|
||||
|
||||
if (noteType == null) { throw new NoteResourceNotSupportedException(resourceType); }
|
||||
;
|
||||
|
||||
final String resourceNameForPermissions = getResourceNameForPermissions(noteType);
|
||||
final CommandWrapper commandRequest = new CommandWrapperBuilder().createNote(resourceNameForPermissions, resourceType, resourceId)
|
||||
.withJson(apiRequestBodyAsJson).build();
|
||||
@@ -130,20 +133,22 @@ public class NotesApiResource {
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String updateNote(@PathParam("resourceType") final String resourceType, @PathParam("resourceId") final Long resourceId,
|
||||
@PathParam("noteId") final Long noteId, final String apiRequestBodyAsJson) {
|
||||
|
||||
|
||||
NoteType noteType = NoteType.fromApiUrl(resourceType);
|
||||
|
||||
if(noteType == null){ throw new NoteResourceNotSupportedException(resourceType); };
|
||||
|
||||
|
||||
if (noteType == null) { throw new NoteResourceNotSupportedException(resourceType); }
|
||||
;
|
||||
|
||||
final String resourceNameForPermissions = getResourceNameForPermissions(noteType);
|
||||
|
||||
final CommandWrapper commandRequest = new CommandWrapperBuilder().updateNote(resourceNameForPermissions, resourceType, resourceId, noteId).withJson(apiRequestBodyAsJson).build();
|
||||
|
||||
final CommandWrapper commandRequest = new CommandWrapperBuilder()
|
||||
.updateNote(resourceNameForPermissions, resourceType, resourceId, noteId).withJson(apiRequestBodyAsJson).build();
|
||||
|
||||
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
||||
|
||||
return this.toApiJsonSerializer.serialize(result);
|
||||
}
|
||||
|
||||
|
||||
@DELETE
|
||||
@Path("{noteId}")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@@ -152,42 +157,41 @@ public class NotesApiResource {
|
||||
@PathParam("noteId") final Long noteId) {
|
||||
|
||||
NoteType noteType = NoteType.fromApiUrl(resourceType);
|
||||
|
||||
if(noteType == null){ throw new NoteResourceNotSupportedException(resourceType); };
|
||||
|
||||
|
||||
if (noteType == null) { throw new NoteResourceNotSupportedException(resourceType); }
|
||||
;
|
||||
|
||||
final String resourceNameForPermissions = getResourceNameForPermissions(noteType);
|
||||
|
||||
final CommandWrapper commandRequest = new CommandWrapperBuilder().deleteNote(resourceNameForPermissions, resourceType, resourceId, noteId).build();
|
||||
|
||||
final CommandWrapper commandRequest = new CommandWrapperBuilder().deleteNote(resourceNameForPermissions, resourceType, resourceId,
|
||||
noteId).build();
|
||||
|
||||
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
||||
|
||||
return this.toApiJsonSerializer.serialize(result);
|
||||
}
|
||||
|
||||
private String getResourceNameForPermissions(NoteType type){
|
||||
|
||||
private String getResourceNameForPermissions(final NoteType type) {
|
||||
String resourceNameForPermissions = "INVALIDNOTE";
|
||||
switch(type){
|
||||
switch (type) {
|
||||
case CLIENT:
|
||||
resourceNameForPermissions = "CLIENTNOTE";
|
||||
break;
|
||||
break;
|
||||
case LOAN:
|
||||
resourceNameForPermissions = "LOANNOTE";
|
||||
break;
|
||||
break;
|
||||
case LOAN_TRANSACTION:
|
||||
resourceNameForPermissions = "LOANTRANSACTIONNOTE";
|
||||
break;
|
||||
case DEPOSIT:
|
||||
resourceNameForPermissions = "DEPOSITNOTE";
|
||||
break;
|
||||
case SAVING:
|
||||
break;
|
||||
case SAVING_ACCOUNT:
|
||||
resourceNameForPermissions = "SAVINGNOTE";
|
||||
break;
|
||||
break;
|
||||
case GROUP:
|
||||
resourceNameForPermissions = "GROUPNOTE";
|
||||
break;
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
|
||||
return resourceNameForPermissions;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,8 +21,6 @@ import org.mifosplatform.portfolio.client.domain.Client;
|
||||
import org.mifosplatform.portfolio.group.domain.Group;
|
||||
import org.mifosplatform.portfolio.loanaccount.domain.Loan;
|
||||
import org.mifosplatform.portfolio.loanaccount.domain.LoanTransaction;
|
||||
import org.mifosplatform.portfolio.savingsaccount.domain.SavingAccount;
|
||||
import org.mifosplatform.portfolio.savingsdepositaccount.domain.DepositAccount;
|
||||
import org.mifosplatform.useradministration.domain.AppUser;
|
||||
|
||||
@Entity
|
||||
@@ -55,15 +53,10 @@ public class Note extends AbstractAuditableCustom<AppUser, Long> {
|
||||
@Column(name = "note_type_enum")
|
||||
private final Integer noteTypeId;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "deposit_account_id", nullable = true)
|
||||
private DepositAccount depositAccount;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "saving_account_id", nullable = true)
|
||||
private SavingAccount savingAccount;
|
||||
// @SuppressWarnings("unused")
|
||||
// @ManyToOne
|
||||
// @JoinColumn(name = "saving_account_id", nullable = true)
|
||||
// private SavingAccount savingAccount;
|
||||
|
||||
public static Note clientNoteFromJson(final Client client, final JsonCommand command) {
|
||||
final String note = command.stringValueOfParameterNamed("note");
|
||||
@@ -83,13 +76,10 @@ public class Note extends AbstractAuditableCustom<AppUser, Long> {
|
||||
return new Note(loan, loanTransaction, note);
|
||||
}
|
||||
|
||||
public static Note depositNote(final DepositAccount account, final String note) {
|
||||
return new Note(account, note);
|
||||
}
|
||||
|
||||
public static Note savingNote(final SavingAccount account, final String note) {
|
||||
return new Note(account, note);
|
||||
}
|
||||
// public static Note savingNote(final SavingAccount account, final String
|
||||
// note) {
|
||||
// return new Note(account, note);
|
||||
// }
|
||||
|
||||
private Note(final Client client, final String note) {
|
||||
this.client = client;
|
||||
@@ -128,19 +118,12 @@ public class Note extends AbstractAuditableCustom<AppUser, Long> {
|
||||
this.noteTypeId = null;
|
||||
}
|
||||
|
||||
public Note(final DepositAccount account, final String note) {
|
||||
this.depositAccount = account;
|
||||
this.client = account.client();
|
||||
this.note = note;
|
||||
this.noteTypeId = NoteType.DEPOSIT.getValue();
|
||||
}
|
||||
|
||||
public Note(final SavingAccount account, final String note) {
|
||||
this.savingAccount = account;
|
||||
this.client = account.getClient();
|
||||
this.note = note;
|
||||
this.noteTypeId = NoteType.SAVING.getValue();
|
||||
}
|
||||
// public Note(final SavingAccount account, final String note) {
|
||||
// this.savingAccount = account;
|
||||
// this.client = account.getClient();
|
||||
// this.note = note;
|
||||
// this.noteTypeId = NoteType.SAVING_ACCOUNT.getValue();
|
||||
// }
|
||||
|
||||
public Map<String, Object> update(final JsonCommand command) {
|
||||
final Map<String, Object> actualChanges = new LinkedHashMap<String, Object>(7);
|
||||
|
||||
+2
-2
@@ -24,7 +24,7 @@ public interface NoteRepository extends JpaRepository<Note, Long>, JpaSpecificat
|
||||
|
||||
Note findByLoanTransactionIdAndId(Long loanTransactionId, Long id);
|
||||
|
||||
Note findByDepositAccountIdAndId(Long depositAccountId, Long id);
|
||||
// Note findByDepositAccountIdAndId(Long depositAccountId, Long id);
|
||||
|
||||
Note findBySavingAccountIdAndId(Long savingAccountId, Long id);
|
||||
// Note findBySavingAccountIdAndId(Long savingAccountId, Long id);
|
||||
}
|
||||
+5
-3
@@ -5,9 +5,11 @@ import java.util.Map;
|
||||
|
||||
public enum NoteType {
|
||||
|
||||
CLIENT(100, "noteType.client", "clients"), LOAN(200, "noteType.loan", "loans"), LOAN_TRANSACTION(300, "noteType.loan.transaction",
|
||||
"loanTransactions"), DEPOSIT(400, "noteType.deposit", "deposits"), SAVING(500, "noteType.saving", "savings"), GROUP(600,
|
||||
"noteType.group", "groups");
|
||||
CLIENT(100, "noteType.client", "clients"), //
|
||||
LOAN(200, "noteType.loan", "loans"), //
|
||||
LOAN_TRANSACTION(300, "noteType.loan.transaction", "loanTransactions"), //
|
||||
SAVING_ACCOUNT(500, "noteType.saving", "savings"), //
|
||||
GROUP(600, "noteType.group", "groups");
|
||||
|
||||
private Integer value;
|
||||
private String code;
|
||||
|
||||
+3
-6
@@ -26,11 +26,8 @@ public class NoteEnumerations {
|
||||
case LOAN_TRANSACTION:
|
||||
optionData = new EnumOptionData(type.getValue().longValue(), type.getCode(), "Loan transaction note");
|
||||
break;
|
||||
case DEPOSIT:
|
||||
optionData = new EnumOptionData(type.getValue().longValue(), type.getCode(), "Deposit transaction note");
|
||||
break;
|
||||
case SAVING:
|
||||
optionData = new EnumOptionData(type.getValue().longValue(), type.getCode(), "Saving transaction note");
|
||||
case SAVING_ACCOUNT:
|
||||
optionData = new EnumOptionData(type.getValue().longValue(), type.getCode(), "Saving account note");
|
||||
break;
|
||||
case GROUP:
|
||||
optionData = new EnumOptionData(type.getValue().longValue(), type.getCode(), "Group note");
|
||||
@@ -41,5 +38,5 @@ public class NoteEnumerations {
|
||||
}
|
||||
return optionData;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
+9
-10
@@ -31,8 +31,8 @@ public class NoteReadPlatformServiceImpl implements NoteReadPlatformService {
|
||||
private static final class NoteMapper implements RowMapper<NoteData> {
|
||||
|
||||
public String schema() {
|
||||
return " select n.id as id, n.client_id as clientId, n.group_id as groupId, n.loan_id as loanId, n.loan_transaction_id as transactionId, n.deposit_account_id as depositAccountId, "
|
||||
+ " n.saving_account_id as savingAccountId, n.note_type_enum as noteTypeEnum, n.note as note, n.created_date as createdDate, n.createdby_id as createdById, "
|
||||
return " select n.id as id, n.client_id as clientId, n.group_id as groupId, n.loan_id as loanId, n.loan_transaction_id as transactionId, "
|
||||
+ " n.note_type_enum as noteTypeEnum, n.note as note, n.created_date as createdDate, n.createdby_id as createdById, "
|
||||
+ " cb.username as createdBy, n.lastmodified_date as lastModifiedDate, n.lastmodifiedby_id as lastModifiedById, mb.username as modifiedBy "
|
||||
+ " from m_note n left join m_appuser cb on cb.id=n.createdby_id left join m_appuser mb on mb.id=n.lastmodifiedby_id ";
|
||||
}
|
||||
@@ -45,8 +45,10 @@ public class NoteReadPlatformServiceImpl implements NoteReadPlatformService {
|
||||
final Long groupId = JdbcSupport.getLong(rs, "groupId");
|
||||
final Long loanId = JdbcSupport.getLong(rs, "loanId");
|
||||
final Long transactionId = JdbcSupport.getLong(rs, "transactionId");
|
||||
final Long depositAccountId = JdbcSupport.getLong(rs, "depositAccountId");
|
||||
final Long savingAccountId = JdbcSupport.getLong(rs, "savingAccountId");
|
||||
// final Long depositAccountId = JdbcSupport.getLong(rs,
|
||||
// "depositAccountId");
|
||||
// final Long savingAccountId = JdbcSupport.getLong(rs,
|
||||
// "savingAccountId");
|
||||
final Integer noteTypeId = JdbcSupport.getInteger(rs, "noteTypeEnum");
|
||||
final EnumOptionData noteType = NoteEnumerations.noteType(noteTypeId);
|
||||
final String note = rs.getString("note");
|
||||
@@ -56,7 +58,7 @@ public class NoteReadPlatformServiceImpl implements NoteReadPlatformService {
|
||||
final Long lastModifiedById = JdbcSupport.getLong(rs, "lastModifiedById");
|
||||
final String createdByUsername = rs.getString("createdBy");
|
||||
final String updatedByUsername = rs.getString("modifiedBy");
|
||||
return new NoteData(id, clientId, groupId, loanId, transactionId, depositAccountId, savingAccountId, noteType, note,
|
||||
return new NoteData(id, clientId, groupId, loanId, transactionId, null, null, noteType, note,
|
||||
createdDate, createdById, createdByUsername, lastModifiedDate, lastModifiedById, updatedByUsername);
|
||||
}
|
||||
}
|
||||
@@ -84,7 +86,7 @@ public class NoteReadPlatformServiceImpl implements NoteReadPlatformService {
|
||||
final NoteType noteType = NoteType.fromInt(noteTypeId);
|
||||
final NoteMapper rm = new NoteMapper();
|
||||
String conditionSql = getResourceCondition(noteType);
|
||||
|
||||
|
||||
final String sql = rm.schema() + " where " + conditionSql + " order by n.created_date DESC";
|
||||
|
||||
return this.jdbcTemplate.query(sql, rm, new Object[] { resourceId });
|
||||
@@ -102,10 +104,7 @@ public class NoteReadPlatformServiceImpl implements NoteReadPlatformService {
|
||||
case LOAN_TRANSACTION:
|
||||
conditionSql = " n.loan_transaction_id = ? ";
|
||||
break;
|
||||
case DEPOSIT:
|
||||
conditionSql = " n.deposit_account_id = ? ";
|
||||
break;
|
||||
case SAVING:
|
||||
case SAVING_ACCOUNT:
|
||||
conditionSql = " n.saving_account_id = ? ";
|
||||
break;
|
||||
case GROUP:
|
||||
|
||||
+77
-133
@@ -28,12 +28,6 @@ import org.mifosplatform.portfolio.note.domain.NoteType;
|
||||
import org.mifosplatform.portfolio.note.exception.NoteNotFoundException;
|
||||
import org.mifosplatform.portfolio.note.exception.NoteResourceNotSupportedException;
|
||||
import org.mifosplatform.portfolio.note.serialization.NoteCommandFromApiJsonDeserializer;
|
||||
import org.mifosplatform.portfolio.savingsaccount.domain.SavingAccount;
|
||||
import org.mifosplatform.portfolio.savingsaccount.domain.SavingAccountRepository;
|
||||
import org.mifosplatform.portfolio.savingsaccount.exception.SavingAccountNotFoundException;
|
||||
import org.mifosplatform.portfolio.savingsdepositaccount.domain.DepositAccount;
|
||||
import org.mifosplatform.portfolio.savingsdepositaccount.domain.DepositAccountRepository;
|
||||
import org.mifosplatform.portfolio.savingsdepositaccount.exception.DepositAccountNotFoundException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@@ -43,22 +37,21 @@ public class NoteWritePlatformServiceJpaRepositoryImpl implements NoteWritePlatf
|
||||
private final NoteRepository noteRepository;
|
||||
private final ClientRepository clientRepository;
|
||||
private final GroupRepository groupRepository;
|
||||
private final DepositAccountRepository depositAccountRepository;
|
||||
private final SavingAccountRepository savingAccountRepository;
|
||||
// private final SavingAccountRepository savingAccountRepository;
|
||||
private final LoanRepository loanRepository;
|
||||
private final LoanTransactionRepository loanTransactionRepository;
|
||||
private final NoteCommandFromApiJsonDeserializer fromApiJsonDeserializer;
|
||||
|
||||
@Autowired
|
||||
public NoteWritePlatformServiceJpaRepositoryImpl(final NoteRepository noteRepository, final ClientRepository clientRepository,
|
||||
final GroupRepository groupRepository, final DepositAccountRepository depositAccountRepository,
|
||||
final SavingAccountRepository savingAccountRepository, final LoanRepository loanRepository,
|
||||
final LoanTransactionRepository loanTransactionRepository, final NoteCommandFromApiJsonDeserializer fromApiJsonDeserializer) {
|
||||
final GroupRepository groupRepository,
|
||||
// final SavingAccountRepository savingAccountRepository,
|
||||
final LoanRepository loanRepository, final LoanTransactionRepository loanTransactionRepository,
|
||||
final NoteCommandFromApiJsonDeserializer fromApiJsonDeserializer) {
|
||||
this.noteRepository = noteRepository;
|
||||
this.clientRepository = clientRepository;
|
||||
this.groupRepository = groupRepository;
|
||||
this.depositAccountRepository = depositAccountRepository;
|
||||
this.savingAccountRepository = savingAccountRepository;
|
||||
// this.savingAccountRepository = savingAccountRepository;
|
||||
this.loanRepository = loanRepository;
|
||||
this.loanTransactionRepository = loanTransactionRepository;
|
||||
this.fromApiJsonDeserializer = fromApiJsonDeserializer;
|
||||
@@ -145,41 +138,26 @@ public class NoteWritePlatformServiceJpaRepositoryImpl implements NoteWritePlatf
|
||||
.build();
|
||||
}
|
||||
|
||||
private CommandProcessingResult createDepositAccountNote(final JsonCommand command) {
|
||||
|
||||
final Long resourceId = command.getSupportedEntityId();
|
||||
|
||||
final DepositAccount depositAccount = this.depositAccountRepository.findOne(resourceId);
|
||||
if (depositAccount == null) { throw new DepositAccountNotFoundException(resourceId); }
|
||||
|
||||
final String note = command.stringValueOfParameterNamed("note");
|
||||
final Note newNote = Note.depositNote(depositAccount, note);
|
||||
|
||||
this.noteRepository.save(newNote);
|
||||
|
||||
return new CommandProcessingResultBuilder() //
|
||||
.withCommandId(command.commandId()) //
|
||||
.withEntityId(newNote.getId()) //
|
||||
.withClientId(depositAccount.client().getId()).withOfficeId(depositAccount.client().getOffice().getId()).build();
|
||||
}
|
||||
|
||||
private CommandProcessingResult createSavingAccountNote(final JsonCommand command) {
|
||||
|
||||
final Long resourceId = command.getSupportedEntityId();
|
||||
|
||||
final SavingAccount savingAccount = this.savingAccountRepository.findOne(resourceId);
|
||||
if (savingAccount == null) { throw new SavingAccountNotFoundException(resourceId); }
|
||||
|
||||
final String note = command.stringValueOfParameterNamed("note");
|
||||
final Note newNote = Note.savingNote(savingAccount, note);
|
||||
|
||||
this.noteRepository.save(newNote);
|
||||
|
||||
return new CommandProcessingResultBuilder() //
|
||||
.withCommandId(command.commandId()) //
|
||||
.withEntityId(newNote.getId()) //
|
||||
.withClientId(savingAccount.getClient().getId()).withOfficeId(savingAccount.getClient().getOffice().getId()).build();
|
||||
}
|
||||
// private CommandProcessingResult createSavingAccountNote(final JsonCommand
|
||||
// command) {
|
||||
//
|
||||
// final Long resourceId = command.getSupportedEntityId();
|
||||
//
|
||||
// final SavingAccount savingAccount =
|
||||
// this.savingAccountRepository.findOne(resourceId);
|
||||
// if (savingAccount == null) { throw new
|
||||
// SavingAccountNotFoundException(resourceId); }
|
||||
//
|
||||
// final String note = command.stringValueOfParameterNamed("note");
|
||||
// final Note newNote = Note.savingNote(savingAccount, note);
|
||||
//
|
||||
// this.noteRepository.save(newNote);
|
||||
//
|
||||
// return new CommandProcessingResultBuilder() //
|
||||
// .withCommandId(command.commandId()) //
|
||||
// .withEntityId(newNote.getId()) //
|
||||
// .withClientId(savingAccount.getClient().getId()).withOfficeId(savingAccount.getClient().getOffice().getId()).build();
|
||||
// }
|
||||
|
||||
@Override
|
||||
public CommandProcessingResult createNote(final JsonCommand command) {
|
||||
@@ -192,9 +170,6 @@ public class NoteWritePlatformServiceJpaRepositoryImpl implements NoteWritePlatf
|
||||
case CLIENT: {
|
||||
return createClientNote(command);
|
||||
}
|
||||
case DEPOSIT: {
|
||||
return createDepositAccountNote(command);
|
||||
}
|
||||
case GROUP: {
|
||||
return createGroupNote(command);
|
||||
}
|
||||
@@ -204,9 +179,9 @@ public class NoteWritePlatformServiceJpaRepositoryImpl implements NoteWritePlatf
|
||||
case LOAN_TRANSACTION: {
|
||||
return createLoanTransactionNote(command);
|
||||
}
|
||||
case SAVING: {
|
||||
return createSavingAccountNote(command);
|
||||
}
|
||||
// case SAVING_ACCOUNT: {
|
||||
// return createSavingAccountNote(command);
|
||||
// }
|
||||
default:
|
||||
throw new NoteResourceNotSupportedException(resourceUrl);
|
||||
}
|
||||
@@ -236,40 +211,10 @@ public class NoteWritePlatformServiceJpaRepositoryImpl implements NoteWritePlatf
|
||||
return new CommandProcessingResultBuilder() //
|
||||
.withCommandId(command.commandId()) //
|
||||
.withEntityId(noteForUpdate.getId()) //
|
||||
.withClientId(client.getId()).withOfficeId(client.getOffice().getId())
|
||||
.with(changes)
|
||||
.build();
|
||||
.withClientId(client.getId()).withOfficeId(client.getOffice().getId()).with(changes).build();
|
||||
|
||||
}
|
||||
|
||||
private CommandProcessingResult updateDepositAccountNote(final JsonCommand command) {
|
||||
|
||||
final Long resourceId = command.getSupportedEntityId();
|
||||
final Long noteId = command.entityId();
|
||||
final String resourceUrl = command.getSupportedEntityType();
|
||||
|
||||
final NoteType type = NoteType.fromApiUrl(resourceUrl);
|
||||
|
||||
final DepositAccount depositAccount = this.depositAccountRepository.findOne(resourceId);
|
||||
if (depositAccount == null) { throw new DepositAccountNotFoundException(resourceId); }
|
||||
final Note noteForUpdate = this.noteRepository.findByDepositAccountIdAndId(resourceId, noteId);
|
||||
|
||||
if (noteForUpdate == null) { throw new NoteNotFoundException(noteId, resourceId, type.name().toLowerCase()); }
|
||||
|
||||
final Map<String, Object> changes = noteForUpdate.update(command);
|
||||
|
||||
if (!changes.isEmpty()) {
|
||||
this.noteRepository.saveAndFlush(noteForUpdate);
|
||||
}
|
||||
|
||||
return new CommandProcessingResultBuilder() //
|
||||
.withCommandId(command.commandId()) //
|
||||
.withEntityId(noteForUpdate.getId()) //
|
||||
.withClientId(depositAccount.client().getId()).withOfficeId(depositAccount.client().getOffice().getId())
|
||||
.with(changes)
|
||||
.build();
|
||||
}
|
||||
|
||||
private CommandProcessingResult updateGroupNote(final JsonCommand command) {
|
||||
|
||||
final Long resourceId = command.getSupportedEntityId();
|
||||
@@ -293,9 +238,7 @@ public class NoteWritePlatformServiceJpaRepositoryImpl implements NoteWritePlatf
|
||||
return new CommandProcessingResultBuilder() //
|
||||
.withCommandId(command.commandId()) //
|
||||
.withEntityId(noteForUpdate.getId()) //
|
||||
.withGroupId(group.getId()).withOfficeId(group.getOfficeId())
|
||||
.with(changes)
|
||||
.build();
|
||||
.withGroupId(group.getId()).withOfficeId(group.getOfficeId()).with(changes).build();
|
||||
}
|
||||
|
||||
private CommandProcessingResult updateLoanNote(final JsonCommand command) {
|
||||
@@ -320,8 +263,7 @@ public class NoteWritePlatformServiceJpaRepositoryImpl implements NoteWritePlatf
|
||||
|
||||
return new CommandProcessingResultBuilder().withCommandId(command.commandId()).withEntityId(noteForUpdate.getId())
|
||||
.withClientId(loan.getClientId()).withLoanId(loan.getId()).withGroupId(loan.getGroupId()).withOfficeId(loan.getOfficeId())
|
||||
.with(changes)
|
||||
.build();
|
||||
.with(changes).build();
|
||||
}
|
||||
|
||||
private CommandProcessingResult updateLoanTransactionNote(final JsonCommand command) {
|
||||
@@ -348,38 +290,44 @@ public class NoteWritePlatformServiceJpaRepositoryImpl implements NoteWritePlatf
|
||||
|
||||
return new CommandProcessingResultBuilder().withCommandId(command.commandId()).withEntityId(noteForUpdate.getId())
|
||||
.withClientId(loan.getClientId()).withLoanId(loan.getId()).withGroupId(loan.getGroupId()).withOfficeId(loan.getOfficeId())
|
||||
.with(changes)
|
||||
.build();
|
||||
.with(changes).build();
|
||||
}
|
||||
|
||||
private CommandProcessingResult updateSavingAccountNote(final JsonCommand command) {
|
||||
|
||||
final Long resourceId = command.getSupportedEntityId();
|
||||
final Long noteId = command.entityId();
|
||||
final String resourceUrl = command.getSupportedEntityType();
|
||||
|
||||
final NoteType type = NoteType.fromApiUrl(resourceUrl);
|
||||
|
||||
final SavingAccount savingAccount = this.savingAccountRepository.findOne(resourceId);
|
||||
if (savingAccount == null) { throw new SavingAccountNotFoundException(resourceId); }
|
||||
|
||||
final Note noteForUpdate = this.noteRepository.findBySavingAccountIdAndId(resourceId, noteId);
|
||||
|
||||
if (noteForUpdate == null) { throw new NoteNotFoundException(noteId, resourceId, type.name().toLowerCase()); }
|
||||
|
||||
final Map<String, Object> changes = noteForUpdate.update(command);
|
||||
|
||||
if (!changes.isEmpty()) {
|
||||
this.noteRepository.saveAndFlush(noteForUpdate);
|
||||
}
|
||||
|
||||
return new CommandProcessingResultBuilder() //
|
||||
.withCommandId(command.commandId()) //
|
||||
.withEntityId(noteForUpdate.getId()) //
|
||||
.withClientId(savingAccount.getClient().getId()).withOfficeId(savingAccount.getClient().getOffice().getId())
|
||||
.with(changes)
|
||||
.build();
|
||||
}
|
||||
// private CommandProcessingResult updateSavingAccountNote(final JsonCommand
|
||||
// command) {
|
||||
//
|
||||
// final Long resourceId = command.getSupportedEntityId();
|
||||
// final Long noteId = command.entityId();
|
||||
// final String resourceUrl = command.getSupportedEntityType();
|
||||
//
|
||||
// final NoteType type = NoteType.fromApiUrl(resourceUrl);
|
||||
//
|
||||
// final SavingAccount savingAccount =
|
||||
// this.savingAccountRepository.findOne(resourceId);
|
||||
// if (savingAccount == null) { throw new
|
||||
// SavingAccountNotFoundException(resourceId); }
|
||||
//
|
||||
// final Note noteForUpdate =
|
||||
// this.noteRepository.findBySavingAccountIdAndId(resourceId, noteId);
|
||||
//
|
||||
// if (noteForUpdate == null) { throw new NoteNotFoundException(noteId,
|
||||
// resourceId, type.name().toLowerCase()); }
|
||||
//
|
||||
// final Map<String, Object> changes = noteForUpdate.update(command);
|
||||
//
|
||||
// if (!changes.isEmpty()) {
|
||||
// this.noteRepository.saveAndFlush(noteForUpdate);
|
||||
// }
|
||||
//
|
||||
// return new CommandProcessingResultBuilder()
|
||||
// //
|
||||
// .withCommandId(command.commandId())
|
||||
// //
|
||||
// .withEntityId(noteForUpdate.getId())
|
||||
// //
|
||||
// .withClientId(savingAccount.getClient().getId()).withOfficeId(savingAccount.getClient().getOffice().getId()).with(changes)
|
||||
// .build();
|
||||
// }
|
||||
|
||||
@Override
|
||||
public CommandProcessingResult updateNote(final JsonCommand command) {
|
||||
@@ -393,9 +341,6 @@ public class NoteWritePlatformServiceJpaRepositoryImpl implements NoteWritePlatf
|
||||
case CLIENT: {
|
||||
return updateClientNote(command);
|
||||
}
|
||||
case DEPOSIT: {
|
||||
return updateDepositAccountNote(command);
|
||||
}
|
||||
case GROUP: {
|
||||
return updateGroupNote(command);
|
||||
}
|
||||
@@ -405,9 +350,9 @@ public class NoteWritePlatformServiceJpaRepositoryImpl implements NoteWritePlatf
|
||||
case LOAN_TRANSACTION: {
|
||||
return updateLoanTransactionNote(command);
|
||||
}
|
||||
case SAVING: {
|
||||
return updateSavingAccountNote(command);
|
||||
}
|
||||
// case SAVING_ACCOUNT: {
|
||||
// return updateSavingAccountNote(command);
|
||||
// }
|
||||
default:
|
||||
throw new NoteResourceNotSupportedException(resourceUrl);
|
||||
}
|
||||
@@ -436,10 +381,6 @@ public class NoteWritePlatformServiceJpaRepositoryImpl implements NoteWritePlatf
|
||||
noteForUpdate = this.noteRepository.findByClientIdAndId(resourceId, noteId);
|
||||
}
|
||||
break;
|
||||
case DEPOSIT: {
|
||||
noteForUpdate = this.noteRepository.findByDepositAccountIdAndId(resourceId, noteId);
|
||||
}
|
||||
break;
|
||||
case GROUP: {
|
||||
noteForUpdate = this.noteRepository.findByGroupIdAndId(resourceId, noteId);
|
||||
}
|
||||
@@ -452,9 +393,12 @@ public class NoteWritePlatformServiceJpaRepositoryImpl implements NoteWritePlatf
|
||||
noteForUpdate = this.noteRepository.findByLoanTransactionIdAndId(resourceId, noteId);
|
||||
}
|
||||
break;
|
||||
case SAVING: {
|
||||
noteForUpdate = this.noteRepository.findBySavingAccountIdAndId(resourceId, noteId);
|
||||
}
|
||||
// case SAVING_ACCOUNT: {
|
||||
// noteForUpdate =
|
||||
// this.noteRepository.findBySavingAccountIdAndId(resourceId, noteId);
|
||||
// }
|
||||
// break;
|
||||
case SAVING_ACCOUNT:
|
||||
break;
|
||||
}
|
||||
if (noteForUpdate == null) { throw new NoteNotFoundException(noteId, resourceId, type.name().toLowerCase()); }
|
||||
|
||||
+168
@@ -0,0 +1,168 @@
|
||||
/**
|
||||
* 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.portfolio.savings.api;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.DELETE;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.PUT;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.QueryParam;
|
||||
import javax.ws.rs.core.Context;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.UriInfo;
|
||||
|
||||
import org.mifosplatform.commands.domain.CommandWrapper;
|
||||
import org.mifosplatform.commands.service.CommandWrapperBuilder;
|
||||
import org.mifosplatform.commands.service.PortfolioCommandSourceWritePlatformService;
|
||||
import org.mifosplatform.infrastructure.core.api.ApiRequestParameterHelper;
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
|
||||
import org.mifosplatform.infrastructure.core.serialization.ApiRequestJsonSerializationSettings;
|
||||
import org.mifosplatform.infrastructure.core.serialization.DefaultToApiJsonSerializer;
|
||||
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
|
||||
import org.mifosplatform.portfolio.savings.data.SavingsAccountData;
|
||||
import org.mifosplatform.portfolio.savings.data.SavingsProductData;
|
||||
import org.mifosplatform.portfolio.savings.service.SavingsAccountReadPlatformService;
|
||||
import org.mifosplatform.portfolio.savings.service.SavingsDropdownReadPlatformService;
|
||||
import org.mifosplatform.portfolio.savings.service.SavingsProductReadPlatformService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Path("/savingsaccounts")
|
||||
@Component
|
||||
@Scope("singleton")
|
||||
public class SavingsAccountsApiResource {
|
||||
|
||||
private final SavingsAccountReadPlatformService savingsAccountReadPlatformService;
|
||||
private final SavingsProductReadPlatformService savingsProductReadPlatformService;
|
||||
private final SavingsDropdownReadPlatformService dropdownReadPlatformService;
|
||||
private final PlatformSecurityContext context;
|
||||
private final DefaultToApiJsonSerializer<SavingsAccountData> toApiJsonSerializer;
|
||||
private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
|
||||
private final ApiRequestParameterHelper apiRequestParameterHelper;
|
||||
|
||||
@Autowired
|
||||
public SavingsAccountsApiResource(final SavingsAccountReadPlatformService savingsAccountReadPlatformService,
|
||||
final SavingsProductReadPlatformService savingsProductReadPlatformService,
|
||||
final SavingsDropdownReadPlatformService dropdownReadPlatformService, final PlatformSecurityContext context,
|
||||
final DefaultToApiJsonSerializer<SavingsAccountData> toApiJsonSerializer,
|
||||
final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService,
|
||||
final ApiRequestParameterHelper apiRequestParameterHelper) {
|
||||
this.savingsAccountReadPlatformService = savingsAccountReadPlatformService;
|
||||
this.savingsProductReadPlatformService = savingsProductReadPlatformService;
|
||||
this.dropdownReadPlatformService = dropdownReadPlatformService;
|
||||
this.context = context;
|
||||
this.toApiJsonSerializer = toApiJsonSerializer;
|
||||
this.commandsSourceWritePlatformService = commandsSourceWritePlatformService;
|
||||
this.apiRequestParameterHelper = apiRequestParameterHelper;
|
||||
}
|
||||
|
||||
@POST
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String create(final String apiRequestBodyAsJson) {
|
||||
|
||||
final CommandWrapper commandRequest = new CommandWrapperBuilder().createSavingsAccount().withJson(apiRequestBodyAsJson).build();
|
||||
|
||||
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
||||
|
||||
return this.toApiJsonSerializer.serialize(result);
|
||||
}
|
||||
|
||||
@PUT
|
||||
@Path("{accountId}")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String update(@PathParam("accountId") final Long accountId, final String apiRequestBodyAsJson) {
|
||||
|
||||
final CommandWrapper commandRequest = new CommandWrapperBuilder().updateSavingsAccount(accountId).withJson(apiRequestBodyAsJson)
|
||||
.build();
|
||||
|
||||
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
||||
|
||||
return this.toApiJsonSerializer.serialize(result);
|
||||
|
||||
}
|
||||
|
||||
@GET
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String retrieveAll(@Context final UriInfo uriInfo) {
|
||||
|
||||
context.authenticatedUser().validateHasReadPermission(SavingsApiConstants.SAVINGS_ACCOUNT_RESOURCE_NAME);
|
||||
|
||||
final Collection<SavingsAccountData> products = this.savingsAccountReadPlatformService.retrieveAll();
|
||||
|
||||
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
||||
return this.toApiJsonSerializer.serialize(settings, products, SavingsApiConstants.SAVINGS_ACCOUNT_RESPONSE_DATA_PARAMETERS);
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("{accountId}")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String retrieveOne(@PathParam("accountId") final Long accountId, @Context final UriInfo uriInfo) {
|
||||
|
||||
context.authenticatedUser().validateHasReadPermission(SavingsApiConstants.SAVINGS_ACCOUNT_RESOURCE_NAME);
|
||||
|
||||
SavingsAccountData savingsAccount = this.savingsAccountReadPlatformService.retrieveOne(accountId);
|
||||
|
||||
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
||||
|
||||
if (settings.isTemplate()) {
|
||||
savingsAccount = populateTemplateOptions(savingsAccount);
|
||||
}
|
||||
|
||||
return this.toApiJsonSerializer.serialize(settings, savingsAccount, SavingsApiConstants.SAVINGS_ACCOUNT_RESPONSE_DATA_PARAMETERS);
|
||||
}
|
||||
|
||||
private SavingsAccountData populateTemplateOptions(final SavingsAccountData savingsAccount) {
|
||||
|
||||
final Collection<SavingsProductData> productOptions = this.savingsProductReadPlatformService.retrieveAllForLookup();
|
||||
final Collection<EnumOptionData> interestRatePeriodFrequencyTypeOptions = this.dropdownReadPlatformService
|
||||
.retrieveInterestRatePeriodFrequencyTypeOptions();
|
||||
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions = this.dropdownReadPlatformService
|
||||
.retrieveLockinPeriodFrequencyTypeOptions();
|
||||
|
||||
return SavingsAccountData.withTemplateOptions(savingsAccount, productOptions, interestRatePeriodFrequencyTypeOptions,
|
||||
lockinPeriodFrequencyTypeOptions);
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("template")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String retrieveTemplate(@QueryParam("clientId") final Long clientId, @QueryParam("groupId") final Long groupId,
|
||||
@QueryParam("productId") final Long productId, @Context final UriInfo uriInfo) {
|
||||
|
||||
context.authenticatedUser().validateHasReadPermission(SavingsApiConstants.SAVINGS_ACCOUNT_RESOURCE_NAME);
|
||||
|
||||
final SavingsAccountData savingsAccount = this.savingsAccountReadPlatformService.retrieveTemplate(clientId, groupId, productId);
|
||||
|
||||
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
||||
return this.toApiJsonSerializer.serialize(settings, savingsAccount, SavingsApiConstants.SAVINGS_ACCOUNT_RESPONSE_DATA_PARAMETERS);
|
||||
}
|
||||
|
||||
@DELETE
|
||||
@Path("{accountId}")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String delete(@PathParam("accountId") final Long accountId) {
|
||||
|
||||
final CommandWrapper commandRequest = new CommandWrapperBuilder().deleteSavingsAccount(accountId).build();
|
||||
|
||||
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
||||
|
||||
return this.toApiJsonSerializer.serialize(result);
|
||||
}
|
||||
}
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
package org.mifosplatform.portfolio.savings.api;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.mifosplatform.portfolio.savings.data.SavingsAccountData;
|
||||
import org.mifosplatform.portfolio.savings.data.SavingsProductData;
|
||||
|
||||
public class SavingsApiConstants {
|
||||
|
||||
public static final String SAVINGS_PRODUCT_RESOURCE_NAME = "savingsproduct";
|
||||
public static final String SAVINGS_ACCOUNT_RESOURCE_NAME = "savingsaccount";
|
||||
|
||||
public static final String localeParamName = "locale";
|
||||
public static final String idParamName = "id";
|
||||
public static final String accountNoParamName = "accountNo";
|
||||
public static final String externalIdParamName = "externalId";
|
||||
public static final String clientIdParamName = "clientId";
|
||||
public static final String groupIdParamName = "groupId";
|
||||
public static final String productIdParamName = "productId";
|
||||
public static final String nameParamName = "name";
|
||||
public static final String descriptionParamName = "description";
|
||||
public static final String currencyCodeParamName = "currencyCode";
|
||||
public static final String digitsAfterDecimalParamName = "digitsAfterDecimal";
|
||||
public static final String interestRateParamName = "interestRate";
|
||||
public static final String interestRatePeriodFrequencyTypeParamName = "interestRatePeriodFrequencyType";
|
||||
public static final String minRequiredOpeningBalanceParamName = "minRequiredOpeningBalance";
|
||||
public static final String lockinPeriodFrequencyParamName = "lockinPeriodFrequency";
|
||||
public static final String lockinPeriodFrequencyTypeParamName = "lockinPeriodFrequencyType";
|
||||
|
||||
public static final Set<String> SAVINGS_PRODUCT_REQUEST_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(localeParamName,
|
||||
nameParamName, descriptionParamName, currencyCodeParamName, digitsAfterDecimalParamName, interestRateParamName,
|
||||
interestRatePeriodFrequencyTypeParamName, minRequiredOpeningBalanceParamName, lockinPeriodFrequencyParamName,
|
||||
lockinPeriodFrequencyTypeParamName));
|
||||
|
||||
/**
|
||||
* These parameters will match the class level parameters of
|
||||
* {@link SavingsProductData}. Where possible, we try to get response
|
||||
* parameters to match those of request parameters.
|
||||
*/
|
||||
public static final Set<String> SAVINGS_PRODUCT_RESPONSE_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(idParamName,
|
||||
nameParamName, descriptionParamName, "currency", digitsAfterDecimalParamName, interestRateParamName,
|
||||
interestRatePeriodFrequencyTypeParamName, minRequiredOpeningBalanceParamName, lockinPeriodFrequencyParamName,
|
||||
lockinPeriodFrequencyTypeParamName, "currencyOptions", "interestRatePeriodFrequencyTypeOptions",
|
||||
"lockinPeriodFrequencyTypeOptions"));
|
||||
|
||||
public static final Set<String> SAVINGS_ACCOUNT_REQUEST_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(localeParamName,
|
||||
accountNoParamName, externalIdParamName, clientIdParamName, groupIdParamName, productIdParamName, interestRateParamName,
|
||||
interestRatePeriodFrequencyTypeParamName, minRequiredOpeningBalanceParamName, lockinPeriodFrequencyParamName,
|
||||
lockinPeriodFrequencyTypeParamName));
|
||||
|
||||
/**
|
||||
* These parameters will match the class level parameters of
|
||||
* {@link SavingsAccountData}. Where possible, we try to get response
|
||||
* parameters to match those of request parameters.
|
||||
*/
|
||||
public static final Set<String> SAVINGS_ACCOUNT_RESPONSE_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(idParamName,
|
||||
accountNoParamName, externalIdParamName, clientIdParamName, "clientName", groupIdParamName, "groupName", "savingsProductId",
|
||||
"savingsProductName", "currency", interestRateParamName, interestRatePeriodFrequencyTypeParamName, "annualInterestRate",
|
||||
minRequiredOpeningBalanceParamName, lockinPeriodFrequencyParamName, lockinPeriodFrequencyTypeParamName, "productOptions",
|
||||
"interestRatePeriodFrequencyTypeOptions", "lockinPeriodFrequencyTypeOptions"));
|
||||
}
|
||||
+72
-64
@@ -3,13 +3,9 @@
|
||||
* 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.portfolio.savingsdepositproduct.api;
|
||||
package org.mifosplatform.portfolio.savings.api;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.DELETE;
|
||||
@@ -35,44 +31,38 @@ import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext
|
||||
import org.mifosplatform.organisation.monetary.data.CurrencyData;
|
||||
import org.mifosplatform.organisation.monetary.service.CurrencyReadPlatformService;
|
||||
import org.mifosplatform.portfolio.loanproduct.domain.PeriodFrequencyType;
|
||||
import org.mifosplatform.portfolio.savingsaccountproduct.service.SavingsDepositEnumerations;
|
||||
import org.mifosplatform.portfolio.savingsdepositproduct.data.DepositProductData;
|
||||
import org.mifosplatform.portfolio.savingsdepositproduct.service.DepositProductReadPlatformService;
|
||||
import org.mifosplatform.portfolio.savings.data.SavingsProductData;
|
||||
import org.mifosplatform.portfolio.savings.service.SavingsDropdownReadPlatformService;
|
||||
import org.mifosplatform.portfolio.savings.service.SavingsEnumerations;
|
||||
import org.mifosplatform.portfolio.savings.service.SavingsProductReadPlatformService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Path("/depositproducts")
|
||||
@Path("/savingsproducts")
|
||||
@Component
|
||||
@Scope("singleton")
|
||||
public class DepositProductsApiResource {
|
||||
public class SavingsProductsApiResource {
|
||||
|
||||
private final Set<String> DEPOSIT_PRODUCT_DATA_PARAMETERS = new HashSet<String>(Arrays.asList("id", "externalId", "name",
|
||||
"description", "currencyCode", "digitsAfterDecimal", "minDeposit", "defaultDeposit", "maxDeposit", "tenureInMonths",
|
||||
"defaultInterestRate", "minInterestRate", "maxInterestRate", "interestCompoundedEvery",
|
||||
"interestCompoundedEveryPeriodType", "renewalAllowed", "preClosureAllowed", "preClosureInterestRate",
|
||||
"interestCompoundingAllowed", "isLockinPeriodAllowed", "lockinPeriod", "lockinPeriodType", "currency", "currencyOptions",
|
||||
"interestCompoundedEveryPeriodTypeOptions"));
|
||||
|
||||
private final String entityType = "DEPOSITPRODUCT";
|
||||
|
||||
private final PlatformSecurityContext context;
|
||||
private final DepositProductReadPlatformService depositProductReadPlatformService;
|
||||
private final SavingsProductReadPlatformService savingProductReadPlatformService;
|
||||
private final SavingsDropdownReadPlatformService dropdownReadPlatformService;
|
||||
private final CurrencyReadPlatformService currencyReadPlatformService;
|
||||
private final DefaultToApiJsonSerializer<DepositProductData> toApiJsonSerializer;
|
||||
private final PlatformSecurityContext context;
|
||||
private final DefaultToApiJsonSerializer<SavingsProductData> toApiJsonSerializer;
|
||||
private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
|
||||
private final ApiRequestParameterHelper apiRequestParameterHelper;
|
||||
|
||||
@Autowired
|
||||
public DepositProductsApiResource(final PlatformSecurityContext context,
|
||||
final DepositProductReadPlatformService depositProductReadPlatformService,
|
||||
final CurrencyReadPlatformService currencyReadPlatformService,
|
||||
final DefaultToApiJsonSerializer<DepositProductData> toApiJsonSerializer,
|
||||
public SavingsProductsApiResource(final SavingsProductReadPlatformService savingProductReadPlatformService,
|
||||
final SavingsDropdownReadPlatformService dropdownReadPlatformService,
|
||||
final CurrencyReadPlatformService currencyReadPlatformService, final PlatformSecurityContext context,
|
||||
final DefaultToApiJsonSerializer<SavingsProductData> toApiJsonSerializer,
|
||||
final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService,
|
||||
final ApiRequestParameterHelper apiRequestParameterHelper) {
|
||||
this.context = context;
|
||||
this.depositProductReadPlatformService = depositProductReadPlatformService;
|
||||
this.savingProductReadPlatformService = savingProductReadPlatformService;
|
||||
this.dropdownReadPlatformService = dropdownReadPlatformService;
|
||||
this.currencyReadPlatformService = currencyReadPlatformService;
|
||||
this.context = context;
|
||||
this.toApiJsonSerializer = toApiJsonSerializer;
|
||||
this.commandsSourceWritePlatformService = commandsSourceWritePlatformService;
|
||||
this.apiRequestParameterHelper = apiRequestParameterHelper;
|
||||
@@ -81,9 +71,9 @@ public class DepositProductsApiResource {
|
||||
@POST
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String createDepositProduct(final String apiRequestBodyAsJson) {
|
||||
public String create(final String apiRequestBodyAsJson) {
|
||||
|
||||
final CommandWrapper commandRequest = new CommandWrapperBuilder().createDepositProduct().withJson(apiRequestBodyAsJson).build();
|
||||
final CommandWrapper commandRequest = new CommandWrapperBuilder().createSavingProduct().withJson(apiRequestBodyAsJson).build();
|
||||
|
||||
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
||||
|
||||
@@ -94,79 +84,97 @@ public class DepositProductsApiResource {
|
||||
@Path("{productId}")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String updateDepositProduct(@PathParam("productId") final Long productId, final String apiRequestBodyAsJson) {
|
||||
public String update(@PathParam("productId") final Long productId, final String apiRequestBodyAsJson) {
|
||||
|
||||
final CommandWrapper commandRequest = new CommandWrapperBuilder().updateDepositProduct(productId).withJson(apiRequestBodyAsJson)
|
||||
final CommandWrapper commandRequest = new CommandWrapperBuilder().updateSavingProduct(productId).withJson(apiRequestBodyAsJson)
|
||||
.build();
|
||||
|
||||
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
||||
|
||||
return this.toApiJsonSerializer.serialize(result);
|
||||
}
|
||||
|
||||
@DELETE
|
||||
@Path("{productId}")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String deleteDepositProduct(@PathParam("productId") final Long productId) {
|
||||
|
||||
final CommandWrapper commandRequest = new CommandWrapperBuilder().deleteDepositProduct(productId).build();
|
||||
|
||||
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
||||
|
||||
return this.toApiJsonSerializer.serialize(result);
|
||||
}
|
||||
|
||||
@GET
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String retrieveAllDepositProducts(@Context final UriInfo uriInfo) {
|
||||
context.authenticatedUser().validateHasReadPermission(entityType);
|
||||
Collection<DepositProductData> products = this.depositProductReadPlatformService.retrieveAllDepositProducts();
|
||||
public String retrieveAll(@Context final UriInfo uriInfo) {
|
||||
|
||||
context.authenticatedUser().validateHasReadPermission(SavingsApiConstants.SAVINGS_PRODUCT_RESOURCE_NAME);
|
||||
|
||||
final Collection<SavingsProductData> products = this.savingProductReadPlatformService.retrieveAll();
|
||||
|
||||
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
||||
return this.toApiJsonSerializer.serialize(settings, products, DEPOSIT_PRODUCT_DATA_PARAMETERS);
|
||||
return this.toApiJsonSerializer.serialize(settings, products, SavingsApiConstants.SAVINGS_PRODUCT_RESPONSE_DATA_PARAMETERS);
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("{productId}")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String retrieveDepositProductDetails(@PathParam("productId") final Long productId, @Context final UriInfo uriInfo) {
|
||||
public String retrieveOne(@PathParam("productId") final Long productId, @Context final UriInfo uriInfo) {
|
||||
|
||||
context.authenticatedUser().validateHasReadPermission(SavingsApiConstants.SAVINGS_PRODUCT_RESOURCE_NAME);
|
||||
|
||||
SavingsProductData savingProduct = this.savingProductReadPlatformService.retrieveOne(productId);
|
||||
|
||||
context.authenticatedUser().validateHasReadPermission(entityType);
|
||||
DepositProductData productData = this.depositProductReadPlatformService.retrieveDepositProductData(productId);
|
||||
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
||||
|
||||
if (settings.isTemplate()) {
|
||||
productData = handleTemplateRelatedData(productData);
|
||||
savingProduct = handleTemplateRelatedData(savingProduct);
|
||||
}
|
||||
|
||||
return this.toApiJsonSerializer.serialize(settings, productData, DEPOSIT_PRODUCT_DATA_PARAMETERS);
|
||||
return this.toApiJsonSerializer.serialize(settings, savingProduct, SavingsApiConstants.SAVINGS_PRODUCT_RESPONSE_DATA_PARAMETERS);
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("template")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String retrieveNewDepositProductDetails(@Context final UriInfo uriInfo) {
|
||||
public String retrieveTemplate(@Context final UriInfo uriInfo) {
|
||||
|
||||
context.authenticatedUser().validateHasReadPermission(entityType);
|
||||
context.authenticatedUser().validateHasReadPermission(SavingsApiConstants.SAVINGS_PRODUCT_RESOURCE_NAME);
|
||||
|
||||
DepositProductData depositProduct = this.depositProductReadPlatformService.retrieveNewDepositProductDetails();
|
||||
|
||||
depositProduct = handleTemplateRelatedData(depositProduct);
|
||||
SavingsProductData savingProduct = handleTemplateRelatedData(null);
|
||||
|
||||
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
||||
return this.toApiJsonSerializer.serialize(settings, depositProduct, DEPOSIT_PRODUCT_DATA_PARAMETERS);
|
||||
return this.toApiJsonSerializer.serialize(settings, savingProduct, SavingsApiConstants.SAVINGS_PRODUCT_RESPONSE_DATA_PARAMETERS);
|
||||
}
|
||||
|
||||
private DepositProductData handleTemplateRelatedData(final DepositProductData productData) {
|
||||
private SavingsProductData handleTemplateRelatedData(final SavingsProductData savingsProduct) {
|
||||
|
||||
Collection<CurrencyData> allowedCurrencies = this.currencyReadPlatformService.retrieveAllowedCurrencies();
|
||||
final EnumOptionData interestRatePeriodFrequencyType = SavingsEnumerations
|
||||
.interestRatePeriodFrequencyType(PeriodFrequencyType.YEARS);
|
||||
|
||||
EnumOptionData monthly = SavingsDepositEnumerations.interestCompoundingPeriodType(PeriodFrequencyType.MONTHS);
|
||||
List<EnumOptionData> interestCompoundedEveryPeriodTypeOptions = Arrays.asList(monthly);
|
||||
final Collection<CurrencyData> currencyOptions = this.currencyReadPlatformService.retrieveAllowedCurrencies();
|
||||
final Collection<EnumOptionData> interestRatePeriodFrequencyTypeOptions = this.dropdownReadPlatformService
|
||||
.retrieveInterestRatePeriodFrequencyTypeOptions();
|
||||
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions = this.dropdownReadPlatformService
|
||||
.retrieveLockinPeriodFrequencyTypeOptions();
|
||||
|
||||
SavingsProductData savingsProductToReturn = null;
|
||||
if (savingsProduct != null) {
|
||||
savingsProductToReturn = SavingsProductData.withTemplate(savingsProduct, currencyOptions,
|
||||
interestRatePeriodFrequencyTypeOptions, lockinPeriodFrequencyTypeOptions);
|
||||
} else {
|
||||
savingsProductToReturn = SavingsProductData.template(CurrencyData.blank(), interestRatePeriodFrequencyType, currencyOptions,
|
||||
interestRatePeriodFrequencyTypeOptions, lockinPeriodFrequencyTypeOptions);
|
||||
}
|
||||
|
||||
return savingsProductToReturn;
|
||||
}
|
||||
|
||||
@DELETE
|
||||
@Path("{productId}")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String delete(@PathParam("productId") final Long productId) {
|
||||
|
||||
final CommandWrapper commandRequest = new CommandWrapperBuilder().deleteSavingProduct(productId).build();
|
||||
|
||||
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
||||
|
||||
return this.toApiJsonSerializer.serialize(result);
|
||||
|
||||
return new DepositProductData(productData, allowedCurrencies, interestCompoundedEveryPeriodTypeOptions);
|
||||
}
|
||||
}
|
||||
+123
@@ -0,0 +1,123 @@
|
||||
/**
|
||||
* 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.portfolio.savings.data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Collection;
|
||||
|
||||
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
|
||||
import org.mifosplatform.organisation.monetary.data.CurrencyData;
|
||||
|
||||
/**
|
||||
* Immutable data object representing a savings account.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public class SavingsAccountData {
|
||||
|
||||
private final Long id;
|
||||
private final String accountNo;
|
||||
private final String externalId;
|
||||
private final Long groupId;
|
||||
private final String groupName;
|
||||
private final Long clientId;
|
||||
private final String clientName;
|
||||
private final Long savingsProductId;
|
||||
private final String savingsProductName;
|
||||
private final CurrencyData currency;
|
||||
private final BigDecimal interestRate;
|
||||
private final EnumOptionData interestRatePeriodFrequencyType;
|
||||
private final BigDecimal annualInterestRate;
|
||||
private final BigDecimal minRequiredOpeningBalance;
|
||||
private final Integer lockinPeriodFrequency;
|
||||
private final EnumOptionData lockinPeriodFrequencyType;
|
||||
|
||||
// template
|
||||
private final Collection<SavingsProductData> productOptions;
|
||||
private final Collection<EnumOptionData> interestRatePeriodFrequencyTypeOptions;
|
||||
private final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions;
|
||||
|
||||
public static SavingsAccountData instance(final Long id, final String accountNo, final String externalId, final Long groupId,
|
||||
final String groupName, final Long clientId, final String clientName, final Long productId, final String productName,
|
||||
final CurrencyData currency, final BigDecimal interestRate, final EnumOptionData interestRatePeriodFrequencyType,
|
||||
final BigDecimal annualInterestRate, final BigDecimal minRequiredOpeningBalance, final Integer lockinPeriodFrequency,
|
||||
final EnumOptionData lockinPeriodFrequencyType) {
|
||||
|
||||
final Collection<SavingsProductData> productOptions = null;
|
||||
final Collection<EnumOptionData> interestRatePeriodFrequencyTypeOptions = null;
|
||||
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions = null;
|
||||
|
||||
return new SavingsAccountData(id, accountNo, externalId, groupId, groupName, clientId, clientName, productId, productName,
|
||||
currency, interestRate, interestRatePeriodFrequencyType, annualInterestRate, minRequiredOpeningBalance,
|
||||
lockinPeriodFrequency, lockinPeriodFrequencyType, productOptions, interestRatePeriodFrequencyTypeOptions,
|
||||
lockinPeriodFrequencyTypeOptions);
|
||||
}
|
||||
|
||||
public static SavingsAccountData withTemplateOptions(final SavingsAccountData account,
|
||||
final Collection<SavingsProductData> productOptions, final Collection<EnumOptionData> interestRatePeriodFrequencyTypeOptions,
|
||||
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions) {
|
||||
|
||||
return new SavingsAccountData(account.id, account.accountNo, account.externalId, account.groupId, account.groupName,
|
||||
account.clientId, account.clientName, account.savingsProductId, account.savingsProductName, account.currency,
|
||||
account.interestRate, account.interestRatePeriodFrequencyType, account.annualInterestRate,
|
||||
account.minRequiredOpeningBalance, account.lockinPeriodFrequency, account.lockinPeriodFrequencyType, productOptions,
|
||||
interestRatePeriodFrequencyTypeOptions, lockinPeriodFrequencyTypeOptions);
|
||||
}
|
||||
|
||||
public static SavingsAccountData withClientTemplate(final Long clientId, final String clientName, final Long groupId,
|
||||
final String groupName) {
|
||||
|
||||
final Long id = null;
|
||||
final String accountNo = null;
|
||||
final String externalId = null;
|
||||
final Long productId = null;
|
||||
final String productName = null;
|
||||
final CurrencyData currency = null;
|
||||
final BigDecimal interestRate = null;
|
||||
final EnumOptionData interestRatePeriodFrequencyType = null;
|
||||
final BigDecimal annualInterestRate = null;
|
||||
final BigDecimal minRequiredOpeningBalance = null;
|
||||
final Integer lockinPeriodFrequency = null;
|
||||
final EnumOptionData lockinPeriodFrequencyType = null;
|
||||
final Collection<SavingsProductData> productOptions = null;
|
||||
final Collection<CurrencyData> currencyOptions = null;
|
||||
final Collection<EnumOptionData> interestRatePeriodFrequencyTypeOptions = null;
|
||||
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions = null;
|
||||
|
||||
return new SavingsAccountData(id, accountNo, externalId, groupId, groupName, clientId, clientName, productId, productName,
|
||||
currency, interestRate, interestRatePeriodFrequencyType, annualInterestRate, minRequiredOpeningBalance,
|
||||
lockinPeriodFrequency, lockinPeriodFrequencyType, productOptions, interestRatePeriodFrequencyTypeOptions,
|
||||
lockinPeriodFrequencyTypeOptions);
|
||||
}
|
||||
|
||||
private SavingsAccountData(final Long id, final String accountNo, final String externalId, final Long groupId, final String groupName,
|
||||
final Long clientId, final String clientName, final Long productId, final String productName, final CurrencyData currency,
|
||||
final BigDecimal interestRate, final EnumOptionData interestRatePeriodFrequencyType, final BigDecimal annualInterestRate,
|
||||
final BigDecimal minRequiredOpeningBalance, final Integer lockinPeriodFrequency,
|
||||
final EnumOptionData lockinPeriodFrequencyType, final Collection<SavingsProductData> productOptions,
|
||||
final Collection<EnumOptionData> interestRatePeriodFrequencyTypeOptions,
|
||||
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions) {
|
||||
this.id = id;
|
||||
this.accountNo = accountNo;
|
||||
this.externalId = externalId;
|
||||
this.groupId = groupId;
|
||||
this.groupName = groupName;
|
||||
this.clientId = clientId;
|
||||
this.clientName = clientName;
|
||||
this.savingsProductId = productId;
|
||||
this.savingsProductName = productName;
|
||||
this.currency = currency;
|
||||
this.interestRate = interestRate;
|
||||
this.interestRatePeriodFrequencyType = interestRatePeriodFrequencyType;
|
||||
this.annualInterestRate = annualInterestRate;
|
||||
this.minRequiredOpeningBalance = minRequiredOpeningBalance;
|
||||
this.lockinPeriodFrequency = lockinPeriodFrequency;
|
||||
this.lockinPeriodFrequencyType = lockinPeriodFrequencyType;
|
||||
|
||||
this.productOptions = productOptions;
|
||||
this.interestRatePeriodFrequencyTypeOptions = interestRatePeriodFrequencyTypeOptions;
|
||||
this.lockinPeriodFrequencyTypeOptions = lockinPeriodFrequencyTypeOptions;
|
||||
}
|
||||
}
|
||||
+244
@@ -0,0 +1,244 @@
|
||||
package org.mifosplatform.portfolio.savings.data;
|
||||
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.accountNoParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.clientIdParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.externalIdParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.groupIdParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.interestRateParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.interestRatePeriodFrequencyTypeParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.lockinPeriodFrequencyParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.lockinPeriodFrequencyTypeParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.minRequiredOpeningBalanceParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.productIdParamName;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.mifosplatform.infrastructure.core.data.ApiParameterError;
|
||||
import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder;
|
||||
import org.mifosplatform.infrastructure.core.exception.InvalidJsonException;
|
||||
import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException;
|
||||
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
|
||||
import org.mifosplatform.portfolio.savings.api.SavingsApiConstants;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
@Component
|
||||
public class SavingsAccountDataValidator {
|
||||
|
||||
private final FromJsonHelper fromApiJsonHelper;
|
||||
|
||||
@Autowired
|
||||
public SavingsAccountDataValidator(final FromJsonHelper fromApiJsonHelper) {
|
||||
this.fromApiJsonHelper = fromApiJsonHelper;
|
||||
}
|
||||
|
||||
public void validateForCreate(final String json) {
|
||||
|
||||
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
|
||||
|
||||
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
|
||||
fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, SavingsApiConstants.SAVINGS_ACCOUNT_REQUEST_DATA_PARAMETERS);
|
||||
|
||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
|
||||
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
|
||||
.resource(SavingsApiConstants.SAVINGS_ACCOUNT_RESOURCE_NAME);
|
||||
|
||||
final JsonElement element = fromApiJsonHelper.parse(json);
|
||||
final Long clientId = fromApiJsonHelper.extractLongNamed(clientIdParamName, element);
|
||||
if (clientId != null) {
|
||||
baseDataValidator.reset().parameter(clientIdParamName).value(clientId).longGreaterThanZero();
|
||||
}
|
||||
|
||||
final Long groupId = fromApiJsonHelper.extractLongNamed(groupIdParamName, element);
|
||||
if (groupId != null) {
|
||||
baseDataValidator.reset().parameter(groupIdParamName).value(groupId).longGreaterThanZero();
|
||||
}
|
||||
|
||||
if (clientId == null && groupId == null) {
|
||||
baseDataValidator.reset().parameter(clientIdParamName).value(clientId).notNull().integerGreaterThanZero();
|
||||
}
|
||||
|
||||
final Long productId = fromApiJsonHelper.extractLongNamed(productIdParamName, element);
|
||||
baseDataValidator.reset().parameter(productIdParamName).value(productId).notNull().integerGreaterThanZero();
|
||||
|
||||
if (fromApiJsonHelper.parameterExists(accountNoParamName, element)) {
|
||||
final String accountNo = fromApiJsonHelper.extractStringNamed(accountNoParamName, element);
|
||||
baseDataValidator.reset().parameter(accountNoParamName).value(accountNo).notBlank().notExceedingLengthOf(20);
|
||||
}
|
||||
|
||||
if (fromApiJsonHelper.parameterExists(externalIdParamName, element)) {
|
||||
final String externalId = fromApiJsonHelper.extractStringNamed(externalIdParamName, element);
|
||||
baseDataValidator.reset().parameter(externalIdParamName).value(externalId).notExceedingLengthOf(100);
|
||||
}
|
||||
|
||||
if (fromApiJsonHelper.parameterExists(interestRateParamName, element)) {
|
||||
final BigDecimal interestRate = fromApiJsonHelper.extractBigDecimalWithLocaleNamed(interestRateParamName, element);
|
||||
baseDataValidator.reset().parameter(interestRateParamName).value(interestRate).notNull().zeroOrPositiveAmount();
|
||||
}
|
||||
|
||||
if (fromApiJsonHelper.parameterExists(interestRatePeriodFrequencyTypeParamName, element)) {
|
||||
final Integer interestRatePeriodFrequencyType = fromApiJsonHelper.extractIntegerSansLocaleNamed(
|
||||
interestRatePeriodFrequencyTypeParamName, element);
|
||||
baseDataValidator.reset().parameter(interestRatePeriodFrequencyTypeParamName).value(interestRatePeriodFrequencyType).notNull()
|
||||
.inMinMaxRange(1, 3);
|
||||
}
|
||||
|
||||
if (this.fromApiJsonHelper.parameterExists(minRequiredOpeningBalanceParamName, element)) {
|
||||
final BigDecimal minOpeningBalance = fromApiJsonHelper.extractBigDecimalWithLocaleNamed(minRequiredOpeningBalanceParamName,
|
||||
element);
|
||||
baseDataValidator.reset().parameter(minRequiredOpeningBalanceParamName).value(minOpeningBalance).positiveAmount();
|
||||
}
|
||||
|
||||
if (this.fromApiJsonHelper.parameterExists(lockinPeriodFrequencyParamName, element)) {
|
||||
|
||||
final Integer lockinPeriodFrequency = fromApiJsonHelper.extractIntegerWithLocaleNamed(lockinPeriodFrequencyParamName, element);
|
||||
baseDataValidator.reset().parameter(lockinPeriodFrequencyParamName).value(lockinPeriodFrequency).ignoreIfNull()
|
||||
.positiveAmount();
|
||||
|
||||
if (lockinPeriodFrequency != null) {
|
||||
final Integer lockinPeriodFrequencyType = fromApiJsonHelper.extractIntegerSansLocaleNamed(
|
||||
lockinPeriodFrequencyTypeParamName, element);
|
||||
baseDataValidator.reset().parameter(lockinPeriodFrequencyTypeParamName).value(lockinPeriodFrequencyType).notNull()
|
||||
.inMinMaxRange(1, 3);
|
||||
}
|
||||
}
|
||||
|
||||
if (this.fromApiJsonHelper.parameterExists(lockinPeriodFrequencyTypeParamName, element)) {
|
||||
final Integer lockinPeriodFrequencyType = fromApiJsonHelper.extractIntegerSansLocaleNamed(lockinPeriodFrequencyTypeParamName,
|
||||
element);
|
||||
baseDataValidator.reset().parameter(lockinPeriodFrequencyTypeParamName).value(lockinPeriodFrequencyType).inMinMaxRange(1, 3);
|
||||
|
||||
if (lockinPeriodFrequencyType != null) {
|
||||
final Integer lockinPeriodFrequency = fromApiJsonHelper.extractIntegerWithLocaleNamed(lockinPeriodFrequencyParamName,
|
||||
element);
|
||||
baseDataValidator.reset().parameter(lockinPeriodFrequencyParamName).value(lockinPeriodFrequency).notNull().positiveAmount();
|
||||
}
|
||||
}
|
||||
|
||||
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
||||
}
|
||||
|
||||
public void validateForUpdate(final String json) {
|
||||
|
||||
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
|
||||
|
||||
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
|
||||
fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, SavingsApiConstants.SAVINGS_ACCOUNT_REQUEST_DATA_PARAMETERS);
|
||||
|
||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
|
||||
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
|
||||
.resource(SavingsApiConstants.SAVINGS_ACCOUNT_RESOURCE_NAME);
|
||||
|
||||
final JsonElement element = fromApiJsonHelper.parse(json);
|
||||
|
||||
Long clientId = null;
|
||||
if (fromApiJsonHelper.parameterExists(clientIdParamName, element)) {
|
||||
clientId = fromApiJsonHelper.extractLongNamed(clientIdParamName, element);
|
||||
baseDataValidator.reset().parameter(clientIdParamName).value(clientId).ignoreIfNull().longGreaterThanZero();
|
||||
|
||||
Long groupId = null;
|
||||
if (fromApiJsonHelper.parameterExists(productIdParamName, element)) {
|
||||
groupId = fromApiJsonHelper.extractLongNamed(groupIdParamName, element);
|
||||
baseDataValidator.reset().parameter(groupIdParamName).value(groupId).ignoreIfNull().longGreaterThanZero();
|
||||
}
|
||||
|
||||
if (clientId == null && groupId == null) {
|
||||
// either clientId or groupId must exists if param passed for
|
||||
// update.
|
||||
baseDataValidator.reset().parameter(clientIdParamName).value(clientId).notNull().integerGreaterThanZero();
|
||||
}
|
||||
}
|
||||
|
||||
Long groupId = null;
|
||||
if (fromApiJsonHelper.parameterExists(groupIdParamName, element)) {
|
||||
groupId = fromApiJsonHelper.extractLongNamed(groupIdParamName, element);
|
||||
baseDataValidator.reset().parameter(groupIdParamName).value(groupId).ignoreIfNull().longGreaterThanZero();
|
||||
|
||||
if (fromApiJsonHelper.parameterExists(clientIdParamName, element)) {
|
||||
clientId = fromApiJsonHelper.extractLongNamed(clientIdParamName, element);
|
||||
baseDataValidator.reset().parameter(clientIdParamName).value(clientId).ignoreIfNull().longGreaterThanZero();
|
||||
}
|
||||
|
||||
if (clientId == null && groupId == null) {
|
||||
// either clientId or groupId must exists if param passed for
|
||||
// update.
|
||||
baseDataValidator.reset().parameter(clientIdParamName).value(clientId).notNull().integerGreaterThanZero();
|
||||
}
|
||||
}
|
||||
|
||||
if (fromApiJsonHelper.parameterExists(productIdParamName, element)) {
|
||||
final Long productId = fromApiJsonHelper.extractLongNamed(productIdParamName, element);
|
||||
baseDataValidator.reset().parameter(productIdParamName).value(productId).notNull().integerGreaterThanZero();
|
||||
}
|
||||
|
||||
if (fromApiJsonHelper.parameterExists(accountNoParamName, element)) {
|
||||
final String accountNo = fromApiJsonHelper.extractStringNamed(accountNoParamName, element);
|
||||
baseDataValidator.reset().parameter(accountNoParamName).value(accountNo).notBlank().notExceedingLengthOf(20);
|
||||
}
|
||||
|
||||
if (fromApiJsonHelper.parameterExists(externalIdParamName, element)) {
|
||||
final String externalId = fromApiJsonHelper.extractStringNamed(externalIdParamName, element);
|
||||
baseDataValidator.reset().parameter(externalIdParamName).value(externalId).notExceedingLengthOf(100);
|
||||
}
|
||||
|
||||
if (fromApiJsonHelper.parameterExists(interestRateParamName, element)) {
|
||||
final BigDecimal interestRate = fromApiJsonHelper.extractBigDecimalWithLocaleNamed(interestRateParamName, element);
|
||||
baseDataValidator.reset().parameter(interestRateParamName).value(interestRate).notNull().zeroOrPositiveAmount();
|
||||
}
|
||||
|
||||
if (fromApiJsonHelper.parameterExists(interestRatePeriodFrequencyTypeParamName, element)) {
|
||||
final Integer interestRatePeriodFrequencyType = fromApiJsonHelper.extractIntegerSansLocaleNamed(
|
||||
interestRatePeriodFrequencyTypeParamName, element);
|
||||
baseDataValidator.reset().parameter(interestRatePeriodFrequencyTypeParamName).value(interestRatePeriodFrequencyType).notNull()
|
||||
.inMinMaxRange(1, 3);
|
||||
}
|
||||
|
||||
if (this.fromApiJsonHelper.parameterExists(minRequiredOpeningBalanceParamName, element)) {
|
||||
final BigDecimal minOpeningBalance = fromApiJsonHelper.extractBigDecimalWithLocaleNamed(minRequiredOpeningBalanceParamName,
|
||||
element);
|
||||
baseDataValidator.reset().parameter(minRequiredOpeningBalanceParamName).value(minOpeningBalance).positiveAmount();
|
||||
}
|
||||
|
||||
if (this.fromApiJsonHelper.parameterExists(lockinPeriodFrequencyParamName, element)) {
|
||||
|
||||
final Integer lockinPeriodFrequency = fromApiJsonHelper.extractIntegerWithLocaleNamed(lockinPeriodFrequencyParamName, element);
|
||||
baseDataValidator.reset().parameter(lockinPeriodFrequencyParamName).value(lockinPeriodFrequency).ignoreIfNull()
|
||||
.positiveAmount();
|
||||
|
||||
if (lockinPeriodFrequency != null) {
|
||||
final Integer lockinPeriodFrequencyType = fromApiJsonHelper.extractIntegerSansLocaleNamed(
|
||||
lockinPeriodFrequencyTypeParamName, element);
|
||||
baseDataValidator.reset().parameter(lockinPeriodFrequencyTypeParamName).value(lockinPeriodFrequencyType).notNull()
|
||||
.inMinMaxRange(1, 3);
|
||||
}
|
||||
}
|
||||
|
||||
if (this.fromApiJsonHelper.parameterExists(lockinPeriodFrequencyTypeParamName, element)) {
|
||||
final Integer lockinPeriodFrequencyType = fromApiJsonHelper.extractIntegerSansLocaleNamed(lockinPeriodFrequencyTypeParamName,
|
||||
element);
|
||||
baseDataValidator.reset().parameter(lockinPeriodFrequencyTypeParamName).value(lockinPeriodFrequencyType).inMinMaxRange(1, 3);
|
||||
|
||||
if (lockinPeriodFrequencyType != null) {
|
||||
final Integer lockinPeriodFrequency = fromApiJsonHelper.extractIntegerWithLocaleNamed(lockinPeriodFrequencyParamName,
|
||||
element);
|
||||
baseDataValidator.reset().parameter(lockinPeriodFrequencyParamName).value(lockinPeriodFrequency).notNull().positiveAmount();
|
||||
}
|
||||
}
|
||||
|
||||
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
||||
|
||||
}
|
||||
|
||||
private void throwExceptionIfValidationWarningsExist(final List<ApiParameterError> dataValidationErrors) {
|
||||
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
|
||||
"Validation errors exist.", dataValidationErrors); }
|
||||
}
|
||||
}
|
||||
+119
@@ -0,0 +1,119 @@
|
||||
/**
|
||||
* 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.portfolio.savings.data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Collection;
|
||||
|
||||
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
|
||||
import org.mifosplatform.organisation.monetary.data.CurrencyData;
|
||||
|
||||
/**
|
||||
* Immutable data object represent a savings product.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public class SavingsProductData {
|
||||
|
||||
private final Long id;
|
||||
private final String name;
|
||||
private final String description;
|
||||
private final CurrencyData currency;
|
||||
private final BigDecimal interestRate;
|
||||
private final EnumOptionData interestRatePeriodFrequencyType;
|
||||
private final BigDecimal minRequiredOpeningBalance;
|
||||
private final Integer lockinPeriodFrequency;
|
||||
private final EnumOptionData lockinPeriodFrequencyType;
|
||||
|
||||
// template
|
||||
private final Collection<CurrencyData> currencyOptions;
|
||||
private final Collection<EnumOptionData> interestRatePeriodFrequencyTypeOptions;
|
||||
private final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions;
|
||||
|
||||
public static SavingsProductData template(final CurrencyData currency, final EnumOptionData interestRatePeriodFrequencyType,
|
||||
final Collection<CurrencyData> currencyOptions, final Collection<EnumOptionData> interestRatePeriodFrequencyTypeOptions,
|
||||
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions) {
|
||||
|
||||
final Long id = null;
|
||||
final String name = null;
|
||||
final String description = null;
|
||||
final Integer digitsAfterDecimal = null;
|
||||
final BigDecimal interestRate = null;
|
||||
final BigDecimal minRequiredOpeningBalance = null;
|
||||
final Integer lockinPeriodFrequency = null;
|
||||
final EnumOptionData lockinPeriodFrequencyType = null;
|
||||
|
||||
return new SavingsProductData(id, name, description, currency, interestRate, interestRatePeriodFrequencyType,
|
||||
minRequiredOpeningBalance, lockinPeriodFrequency, lockinPeriodFrequencyType, currencyOptions,
|
||||
interestRatePeriodFrequencyTypeOptions, lockinPeriodFrequencyTypeOptions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link SavingsProductData} that contains and exist
|
||||
* {@link SavingsProductData} data with further template data for dropdowns.
|
||||
*/
|
||||
public static SavingsProductData withTemplate(final SavingsProductData existingProduct, final Collection<CurrencyData> currencyOptions,
|
||||
final Collection<EnumOptionData> interestRatePeriodFrequencyTypeOptions,
|
||||
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions) {
|
||||
|
||||
return new SavingsProductData(existingProduct.id, existingProduct.name, existingProduct.description, existingProduct.currency,
|
||||
existingProduct.interestRate, existingProduct.interestRatePeriodFrequencyType, existingProduct.minRequiredOpeningBalance,
|
||||
existingProduct.lockinPeriodFrequency, existingProduct.lockinPeriodFrequencyType, currencyOptions,
|
||||
interestRatePeriodFrequencyTypeOptions, lockinPeriodFrequencyTypeOptions);
|
||||
}
|
||||
|
||||
public static SavingsProductData instance(final Long id, final String name, final String description, final CurrencyData currency,
|
||||
final BigDecimal interestRate, final EnumOptionData interestRatePeriodFrequencyType,
|
||||
final BigDecimal minRequiredOpeningBalance, final Integer lockinPeriodFrequency, final EnumOptionData lockinPeriodFrequencyType) {
|
||||
|
||||
final Collection<CurrencyData> currencyOptions = null;
|
||||
final Collection<EnumOptionData> interestRatePeriodFrequencyTypeOptions = null;
|
||||
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions = null;
|
||||
|
||||
return new SavingsProductData(id, name, description, currency, interestRate, interestRatePeriodFrequencyType,
|
||||
minRequiredOpeningBalance, lockinPeriodFrequency, lockinPeriodFrequencyType, currencyOptions,
|
||||
interestRatePeriodFrequencyTypeOptions, lockinPeriodFrequencyTypeOptions);
|
||||
}
|
||||
|
||||
public static SavingsProductData lookup(final Long id, final String name) {
|
||||
|
||||
final CurrencyData currency = null;
|
||||
final String description = null;
|
||||
final BigDecimal interestRate = null;
|
||||
final EnumOptionData interestRatePeriodFrequencyType = null;
|
||||
final BigDecimal minRequiredOpeningBalance = null;
|
||||
final Integer lockinPeriodFrequency = null;
|
||||
final EnumOptionData lockinPeriodFrequencyType = null;
|
||||
|
||||
final Collection<CurrencyData> currencyOptions = null;
|
||||
final Collection<EnumOptionData> interestRatePeriodFrequencyTypeOptions = null;
|
||||
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions = null;
|
||||
|
||||
return new SavingsProductData(id, name, description, currency, interestRate, interestRatePeriodFrequencyType,
|
||||
minRequiredOpeningBalance, lockinPeriodFrequency, lockinPeriodFrequencyType, currencyOptions,
|
||||
interestRatePeriodFrequencyTypeOptions, lockinPeriodFrequencyTypeOptions);
|
||||
}
|
||||
|
||||
private SavingsProductData(final Long id, final String name, final String description, final CurrencyData currency,
|
||||
final BigDecimal interestRate, final EnumOptionData interestRatePeriodFrequencyType,
|
||||
final BigDecimal minRequiredOpeningBalance, final Integer lockinPeriodFrequency,
|
||||
final EnumOptionData lockinPeriodFrequencyType, final Collection<CurrencyData> currencyOptions,
|
||||
final Collection<EnumOptionData> interestRatePeriodFrequencyTypeOptions,
|
||||
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
this.currency = currency;
|
||||
this.interestRate = interestRate;
|
||||
this.interestRatePeriodFrequencyType = interestRatePeriodFrequencyType;
|
||||
this.minRequiredOpeningBalance = minRequiredOpeningBalance;
|
||||
this.lockinPeriodFrequency = lockinPeriodFrequency;
|
||||
this.lockinPeriodFrequencyType = lockinPeriodFrequencyType;
|
||||
|
||||
this.currencyOptions = currencyOptions;
|
||||
this.interestRatePeriodFrequencyTypeOptions = interestRatePeriodFrequencyTypeOptions;
|
||||
this.lockinPeriodFrequencyTypeOptions = lockinPeriodFrequencyTypeOptions;
|
||||
}
|
||||
}
|
||||
+172
@@ -0,0 +1,172 @@
|
||||
package org.mifosplatform.portfolio.savings.data;
|
||||
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.SAVINGS_PRODUCT_RESOURCE_NAME;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.SAVINGS_PRODUCT_REQUEST_DATA_PARAMETERS;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.currencyCodeParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.descriptionParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.digitsAfterDecimalParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.interestRateParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.interestRatePeriodFrequencyTypeParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.lockinPeriodFrequencyParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.lockinPeriodFrequencyTypeParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.minRequiredOpeningBalanceParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.nameParamName;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.mifosplatform.infrastructure.core.data.ApiParameterError;
|
||||
import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder;
|
||||
import org.mifosplatform.infrastructure.core.exception.InvalidJsonException;
|
||||
import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException;
|
||||
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
@Component
|
||||
public class SavingsProductDataValidator {
|
||||
|
||||
private final FromJsonHelper fromApiJsonHelper;
|
||||
|
||||
@Autowired
|
||||
public SavingsProductDataValidator(final FromJsonHelper fromApiJsonHelper) {
|
||||
this.fromApiJsonHelper = fromApiJsonHelper;
|
||||
}
|
||||
|
||||
public void validateForCreate(final String json) {
|
||||
|
||||
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
|
||||
|
||||
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
|
||||
fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, SAVINGS_PRODUCT_REQUEST_DATA_PARAMETERS);
|
||||
|
||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
|
||||
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource(SAVINGS_PRODUCT_RESOURCE_NAME);
|
||||
final JsonElement element = fromApiJsonHelper.parse(json);
|
||||
|
||||
final String name = fromApiJsonHelper.extractStringNamed(nameParamName, element);
|
||||
baseDataValidator.reset().parameter(nameParamName).value(name).notBlank().notExceedingLengthOf(100);
|
||||
|
||||
final String description = fromApiJsonHelper.extractStringNamed(descriptionParamName, element);
|
||||
baseDataValidator.reset().parameter(descriptionParamName).value(description).notBlank().notExceedingLengthOf(500);
|
||||
|
||||
final String currencyCode = fromApiJsonHelper.extractStringNamed(currencyCodeParamName, element);
|
||||
baseDataValidator.reset().parameter(currencyCodeParamName).value(currencyCode).notBlank();
|
||||
|
||||
final Integer digitsAfterDecimal = fromApiJsonHelper.extractIntegerSansLocaleNamed(digitsAfterDecimalParamName, element);
|
||||
baseDataValidator.reset().parameter(digitsAfterDecimalParamName).value(digitsAfterDecimal).notNull().inMinMaxRange(0, 6);
|
||||
|
||||
final BigDecimal interestRate = fromApiJsonHelper.extractBigDecimalWithLocaleNamed(interestRateParamName, element);
|
||||
baseDataValidator.reset().parameter(interestRateParamName).value(interestRate).notNull().zeroOrPositiveAmount();
|
||||
|
||||
final Integer interestRatePeriodFrequencyType = fromApiJsonHelper.extractIntegerSansLocaleNamed(
|
||||
interestRatePeriodFrequencyTypeParamName, element);
|
||||
baseDataValidator.reset().parameter(interestRatePeriodFrequencyTypeParamName).value(interestRatePeriodFrequencyType).notNull()
|
||||
.inMinMaxRange(1, 3);
|
||||
|
||||
if (this.fromApiJsonHelper.parameterExists(minRequiredOpeningBalanceParamName, element)) {
|
||||
final BigDecimal minOpeningBalance = fromApiJsonHelper.extractBigDecimalWithLocaleNamed(minRequiredOpeningBalanceParamName,
|
||||
element);
|
||||
baseDataValidator.reset().parameter(minRequiredOpeningBalanceParamName).value(minOpeningBalance).positiveAmount();
|
||||
}
|
||||
|
||||
if (this.fromApiJsonHelper.parameterExists(lockinPeriodFrequencyParamName, element)) {
|
||||
|
||||
final Integer lockinPeriodFrequency = fromApiJsonHelper.extractIntegerWithLocaleNamed(lockinPeriodFrequencyParamName, element);
|
||||
baseDataValidator.reset().parameter(lockinPeriodFrequencyParamName).value(lockinPeriodFrequency).ignoreIfNull()
|
||||
.positiveAmount();
|
||||
|
||||
if (lockinPeriodFrequency != null) {
|
||||
final Integer lockinPeriodFrequencyType = fromApiJsonHelper.extractIntegerSansLocaleNamed(
|
||||
lockinPeriodFrequencyTypeParamName, element);
|
||||
baseDataValidator.reset().parameter(lockinPeriodFrequencyTypeParamName).value(lockinPeriodFrequencyType).notNull()
|
||||
.inMinMaxRange(1, 3);
|
||||
}
|
||||
}
|
||||
|
||||
if (this.fromApiJsonHelper.parameterExists(lockinPeriodFrequencyTypeParamName, element)) {
|
||||
final Integer lockinPeriodFrequencyType = fromApiJsonHelper.extractIntegerSansLocaleNamed(lockinPeriodFrequencyTypeParamName,
|
||||
element);
|
||||
baseDataValidator.reset().parameter(lockinPeriodFrequencyTypeParamName).value(lockinPeriodFrequencyType).inMinMaxRange(1, 3);
|
||||
|
||||
if (lockinPeriodFrequencyType != null) {
|
||||
final Integer lockinPeriodFrequency = fromApiJsonHelper.extractIntegerWithLocaleNamed(lockinPeriodFrequencyParamName,
|
||||
element);
|
||||
baseDataValidator.reset().parameter(lockinPeriodFrequencyParamName).value(lockinPeriodFrequency).notNull().positiveAmount();
|
||||
}
|
||||
}
|
||||
|
||||
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
||||
}
|
||||
|
||||
public void validateForUpdate(final String json) {
|
||||
|
||||
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
|
||||
|
||||
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
|
||||
fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, SAVINGS_PRODUCT_REQUEST_DATA_PARAMETERS);
|
||||
|
||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
|
||||
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource(SAVINGS_PRODUCT_RESOURCE_NAME);
|
||||
final JsonElement element = fromApiJsonHelper.parse(json);
|
||||
|
||||
if (this.fromApiJsonHelper.parameterExists(nameParamName, element)) {
|
||||
final String name = fromApiJsonHelper.extractStringNamed(nameParamName, element);
|
||||
baseDataValidator.reset().parameter(nameParamName).value(name).notBlank().notExceedingLengthOf(100);
|
||||
}
|
||||
|
||||
if (this.fromApiJsonHelper.parameterExists(descriptionParamName, element)) {
|
||||
final String description = fromApiJsonHelper.extractStringNamed(descriptionParamName, element);
|
||||
baseDataValidator.reset().parameter(descriptionParamName).value(description).notBlank().notExceedingLengthOf(500);
|
||||
}
|
||||
|
||||
if (this.fromApiJsonHelper.parameterExists(currencyCodeParamName, element)) {
|
||||
final String currencyCode = fromApiJsonHelper.extractStringNamed(currencyCodeParamName, element);
|
||||
baseDataValidator.reset().parameter(currencyCodeParamName).value(currencyCode).notBlank();
|
||||
}
|
||||
|
||||
if (this.fromApiJsonHelper.parameterExists(digitsAfterDecimalParamName, element)) {
|
||||
final Integer digitsAfterDecimal = fromApiJsonHelper.extractIntegerSansLocaleNamed(digitsAfterDecimalParamName, element);
|
||||
baseDataValidator.reset().parameter(digitsAfterDecimalParamName).value(digitsAfterDecimal).notNull().inMinMaxRange(0, 6);
|
||||
}
|
||||
|
||||
if (this.fromApiJsonHelper.parameterExists(interestRateParamName, element)) {
|
||||
final BigDecimal interestRate = fromApiJsonHelper.extractBigDecimalWithLocaleNamed(interestRateParamName, element);
|
||||
baseDataValidator.reset().parameter(interestRateParamName).value(interestRate).notNull().zeroOrPositiveAmount();
|
||||
}
|
||||
|
||||
if (this.fromApiJsonHelper.parameterExists(interestRatePeriodFrequencyTypeParamName, element)) {
|
||||
final Integer interestRatePeriodFrequencyType = fromApiJsonHelper.extractIntegerSansLocaleNamed(
|
||||
interestRatePeriodFrequencyTypeParamName, element);
|
||||
baseDataValidator.reset().parameter(interestRatePeriodFrequencyTypeParamName).value(interestRatePeriodFrequencyType).notNull()
|
||||
.inMinMaxRange(1, 3);
|
||||
}
|
||||
|
||||
if (this.fromApiJsonHelper.parameterExists(lockinPeriodFrequencyParamName, element)) {
|
||||
|
||||
final Integer lockinPeriodFrequency = fromApiJsonHelper.extractIntegerWithLocaleNamed(lockinPeriodFrequencyParamName, element);
|
||||
baseDataValidator.reset().parameter(lockinPeriodFrequencyParamName).value(lockinPeriodFrequency).ignoreIfNull()
|
||||
.positiveAmount();
|
||||
}
|
||||
|
||||
if (this.fromApiJsonHelper.parameterExists(lockinPeriodFrequencyTypeParamName, element)) {
|
||||
final Integer lockinPeriodFrequencyType = fromApiJsonHelper.extractIntegerSansLocaleNamed(lockinPeriodFrequencyTypeParamName,
|
||||
element);
|
||||
baseDataValidator.reset().parameter(lockinPeriodFrequencyTypeParamName).value(lockinPeriodFrequencyType).inMinMaxRange(1, 3);
|
||||
}
|
||||
|
||||
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
||||
}
|
||||
|
||||
private void throwExceptionIfValidationWarningsExist(final List<ApiParameterError> dataValidationErrors) {
|
||||
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
|
||||
"Validation errors exist.", dataValidationErrors); }
|
||||
}
|
||||
}
|
||||
+235
@@ -0,0 +1,235 @@
|
||||
/**
|
||||
* 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.portfolio.savings.domain;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Embedded;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.Table;
|
||||
import javax.persistence.Transient;
|
||||
import javax.persistence.UniqueConstraint;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
import org.mifosplatform.infrastructure.security.service.RandomPasswordGenerator;
|
||||
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
|
||||
import org.mifosplatform.organisation.monetary.domain.Money;
|
||||
import org.mifosplatform.portfolio.client.domain.Client;
|
||||
import org.mifosplatform.portfolio.group.domain.Group;
|
||||
import org.mifosplatform.portfolio.loanproduct.domain.PeriodFrequencyType;
|
||||
import org.mifosplatform.portfolio.savings.api.SavingsApiConstants;
|
||||
import org.springframework.data.jpa.domain.AbstractPersistable;
|
||||
|
||||
@Entity
|
||||
@Table(name = "m_savings_account", uniqueConstraints = { @UniqueConstraint(columnNames = { "account_no" }, name = "sa_account_no_UNIQUE"),
|
||||
@UniqueConstraint(columnNames = { "external_id" }, name = "sa_external_id_UNIQUE") })
|
||||
public class SavingsAccount extends AbstractPersistable<Long> {
|
||||
|
||||
@Column(name = "account_no", length = 20, unique = true, nullable = false)
|
||||
private String accountNumber;
|
||||
|
||||
@Column(name = "external_id")
|
||||
private String externalId;
|
||||
|
||||
@ManyToOne(optional = true)
|
||||
@JoinColumn(name = "client_id", nullable = true)
|
||||
private Client client;
|
||||
|
||||
@ManyToOne(optional = true)
|
||||
@JoinColumn(name = "group_id", nullable = true)
|
||||
private Group group;
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "product_id", nullable = false)
|
||||
private SavingsProduct product;
|
||||
|
||||
@Embedded
|
||||
private MonetaryCurrency currency;
|
||||
|
||||
@Column(name = "nominal_interest_rate_per_period", scale = 6, precision = 19, nullable = false)
|
||||
private BigDecimal interestRate;
|
||||
|
||||
@Column(name = "nominal_interest_rate_period_frequency_enum", nullable = false)
|
||||
private Integer interestRatePeriodFrequencyType;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Column(name = "annual_nominal_interest_rate", scale = 6, precision = 19, nullable = false)
|
||||
private BigDecimal annualInterestRate;
|
||||
|
||||
@Column(name = "min_required_opening_balance", scale = 6, precision = 19, nullable = false)
|
||||
private BigDecimal minRequiredOpeningBalance;
|
||||
|
||||
@Column(name = "lockin_period_frequency", nullable = false)
|
||||
private Integer lockinPeriodFrequency;
|
||||
|
||||
@Column(name = "lockin_period_frequency_enum", nullable = false)
|
||||
private Integer lockinPeriodFrequencyType;
|
||||
|
||||
@Transient
|
||||
private boolean accountNumberRequiresAutoGeneration = false;
|
||||
|
||||
protected SavingsAccount() {
|
||||
//
|
||||
}
|
||||
|
||||
public static SavingsAccount createNewAccount(final Client client, final Group group, final SavingsProduct product,
|
||||
final String accountNo, final String externalId, final BigDecimal interestRate,
|
||||
final PeriodFrequencyType interestRatePeriodFrequencyType, final BigDecimal annualInterestRate,
|
||||
final BigDecimal minRequiredOpeningBalance, final Integer lockinPeriodFrequency,
|
||||
final PeriodFrequencyType lockinPeriodFrequencyType) {
|
||||
|
||||
return new SavingsAccount(client, group, product, accountNo, externalId, interestRate, interestRatePeriodFrequencyType,
|
||||
annualInterestRate, minRequiredOpeningBalance, lockinPeriodFrequency, lockinPeriodFrequencyType);
|
||||
}
|
||||
|
||||
private SavingsAccount(final Client client, final Group group, final SavingsProduct product, final String accountNo,
|
||||
final String externalId, final BigDecimal interestRate, final PeriodFrequencyType interestRatePeriodFrequencyType,
|
||||
final BigDecimal annualInterestRate, final BigDecimal minRequiredOpeningBalance, final Integer lockinPeriodFrequency,
|
||||
final PeriodFrequencyType lockinPeriodFrequencyType) {
|
||||
this.client = client;
|
||||
this.group = group;
|
||||
this.product = product;
|
||||
if (StringUtils.isBlank(accountNo)) {
|
||||
this.accountNumber = new RandomPasswordGenerator(19).generate();
|
||||
this.accountNumberRequiresAutoGeneration = true;
|
||||
} else {
|
||||
this.accountNumber = accountNo;
|
||||
}
|
||||
this.currency = product.currency();
|
||||
this.externalId = externalId;
|
||||
this.interestRate = interestRate;
|
||||
this.interestRatePeriodFrequencyType = interestRatePeriodFrequencyType.getValue();
|
||||
this.annualInterestRate = annualInterestRate;
|
||||
this.minRequiredOpeningBalance = minRequiredOpeningBalance;
|
||||
this.lockinPeriodFrequency = lockinPeriodFrequency;
|
||||
if (lockinPeriodFrequencyType != null) {
|
||||
this.lockinPeriodFrequencyType = lockinPeriodFrequencyType.getValue();
|
||||
}
|
||||
}
|
||||
|
||||
public void update(final JsonCommand command, final Map<String, Object> actualChanges) {
|
||||
|
||||
final String localeAsInput = command.locale();
|
||||
|
||||
if (command.isChangeInStringParameterNamed(SavingsApiConstants.accountNoParamName, this.accountNumber)) {
|
||||
final String newValue = command.stringValueOfParameterNamed(SavingsApiConstants.accountNoParamName);
|
||||
actualChanges.put(SavingsApiConstants.accountNoParamName, newValue);
|
||||
this.accountNumber = StringUtils.defaultIfEmpty(newValue, null);
|
||||
}
|
||||
|
||||
if (command.isChangeInStringParameterNamed(SavingsApiConstants.externalIdParamName, this.externalId)) {
|
||||
final String newValue = command.stringValueOfParameterNamed(SavingsApiConstants.externalIdParamName);
|
||||
actualChanges.put(SavingsApiConstants.externalIdParamName, newValue);
|
||||
this.externalId = StringUtils.defaultIfEmpty(newValue, null);
|
||||
}
|
||||
|
||||
if (command.isChangeInLongParameterNamed(SavingsApiConstants.clientIdParamName, clientId())) {
|
||||
final Long newValue = command.longValueOfParameterNamed(SavingsApiConstants.clientIdParamName);
|
||||
actualChanges.put(SavingsApiConstants.clientIdParamName, newValue);
|
||||
}
|
||||
|
||||
if (command.isChangeInLongParameterNamed(SavingsApiConstants.groupIdParamName, groupId())) {
|
||||
final Long newValue = command.longValueOfParameterNamed(SavingsApiConstants.groupIdParamName);
|
||||
actualChanges.put(SavingsApiConstants.groupIdParamName, newValue);
|
||||
}
|
||||
|
||||
if (command.isChangeInLongParameterNamed(SavingsApiConstants.productIdParamName, this.product.getId())) {
|
||||
final Long newValue = command.longValueOfParameterNamed(SavingsApiConstants.productIdParamName);
|
||||
actualChanges.put(SavingsApiConstants.productIdParamName, newValue);
|
||||
}
|
||||
|
||||
if (command.isChangeInBigDecimalParameterNamed(SavingsApiConstants.interestRateParamName, this.interestRate)) {
|
||||
final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(SavingsApiConstants.interestRateParamName);
|
||||
actualChanges.put(SavingsApiConstants.interestRateParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
this.interestRate = newValue;
|
||||
}
|
||||
|
||||
if (command.isChangeInIntegerParameterNamed(SavingsApiConstants.interestRatePeriodFrequencyTypeParamName,
|
||||
this.interestRatePeriodFrequencyType)) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(SavingsApiConstants.interestRatePeriodFrequencyTypeParamName);
|
||||
actualChanges.put(SavingsApiConstants.interestRatePeriodFrequencyTypeParamName, newValue);
|
||||
this.interestRatePeriodFrequencyType = PeriodFrequencyType.fromInt(newValue).getValue();
|
||||
}
|
||||
|
||||
if (command.isChangeInBigDecimalParameterNamed(SavingsApiConstants.minRequiredOpeningBalanceParamName,
|
||||
this.minRequiredOpeningBalance)) {
|
||||
final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(SavingsApiConstants.minRequiredOpeningBalanceParamName);
|
||||
actualChanges.put(SavingsApiConstants.minRequiredOpeningBalanceParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
this.minRequiredOpeningBalance = Money.of(this.currency, newValue).getAmount();
|
||||
}
|
||||
|
||||
if (command.isChangeInIntegerParameterNamed(SavingsApiConstants.lockinPeriodFrequencyParamName, this.lockinPeriodFrequency)) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(SavingsApiConstants.lockinPeriodFrequencyParamName);
|
||||
actualChanges.put(SavingsApiConstants.lockinPeriodFrequencyParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
this.lockinPeriodFrequency = newValue;
|
||||
}
|
||||
|
||||
if (command.isChangeInIntegerParameterNamed(SavingsApiConstants.lockinPeriodFrequencyTypeParamName, this.lockinPeriodFrequencyType)) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(SavingsApiConstants.lockinPeriodFrequencyTypeParamName);
|
||||
actualChanges.put(SavingsApiConstants.lockinPeriodFrequencyTypeParamName, newValue);
|
||||
if (newValue != null) {
|
||||
this.lockinPeriodFrequencyType = PeriodFrequencyType.fromInt(newValue).getValue();
|
||||
} else {
|
||||
this.lockinPeriodFrequencyType = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void update(final Client client) {
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
public void update(final Group group) {
|
||||
this.group = group;
|
||||
}
|
||||
|
||||
public void update(final SavingsProduct product) {
|
||||
this.product = product;
|
||||
}
|
||||
|
||||
public void updateAccountNo(final String newAccountNo) {
|
||||
this.accountNumber = newAccountNo;
|
||||
this.accountNumberRequiresAutoGeneration = false;
|
||||
}
|
||||
|
||||
public boolean isAccountNumberRequiresAutoGeneration() {
|
||||
return this.accountNumberRequiresAutoGeneration;
|
||||
}
|
||||
|
||||
public Long officeId() {
|
||||
Long officeId = null;
|
||||
if (this.client != null) {
|
||||
officeId = this.client.officeId();
|
||||
} else {
|
||||
officeId = this.group.officeId();
|
||||
}
|
||||
return officeId;
|
||||
}
|
||||
|
||||
public Long clientId() {
|
||||
Long id = null;
|
||||
if (this.client != null) {
|
||||
id = this.client.getId();
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
public Long groupId() {
|
||||
Long id = null;
|
||||
if (this.group != null) {
|
||||
id = this.group.getId();
|
||||
}
|
||||
return id;
|
||||
}
|
||||
}
|
||||
+132
@@ -0,0 +1,132 @@
|
||||
/**
|
||||
* 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.portfolio.savings.domain;
|
||||
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.interestRateParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.interestRatePeriodFrequencyTypeParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.lockinPeriodFrequencyParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.lockinPeriodFrequencyTypeParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.minRequiredOpeningBalanceParamName;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
|
||||
import org.mifosplatform.portfolio.client.domain.Client;
|
||||
import org.mifosplatform.portfolio.client.domain.ClientRepository;
|
||||
import org.mifosplatform.portfolio.client.exception.ClientNotFoundException;
|
||||
import org.mifosplatform.portfolio.group.domain.Group;
|
||||
import org.mifosplatform.portfolio.group.domain.GroupRepository;
|
||||
import org.mifosplatform.portfolio.group.exception.GroupNotFoundException;
|
||||
import org.mifosplatform.portfolio.loanaccount.loanschedule.domain.AprCalculator;
|
||||
import org.mifosplatform.portfolio.loanproduct.domain.PeriodFrequencyType;
|
||||
import org.mifosplatform.portfolio.savings.exception.SavingsProductNotFoundException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
|
||||
@Service
|
||||
public class SavingsAccountAssembler {
|
||||
|
||||
private final ClientRepository clientRepository;
|
||||
private final GroupRepository groupRepository;
|
||||
private final SavingsProductRepository savingProductRepository;
|
||||
private final FromJsonHelper fromApiJsonHelper;
|
||||
private final AprCalculator aprCalculator;
|
||||
|
||||
@Autowired
|
||||
public SavingsAccountAssembler(final ClientRepository clientRepository, final GroupRepository groupRepository,
|
||||
final SavingsProductRepository savingProductRepository, final AprCalculator aprCalculator,
|
||||
final FromJsonHelper fromApiJsonHelper) {
|
||||
this.clientRepository = clientRepository;
|
||||
this.groupRepository = groupRepository;
|
||||
this.savingProductRepository = savingProductRepository;
|
||||
this.aprCalculator = aprCalculator;
|
||||
this.fromApiJsonHelper = fromApiJsonHelper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assembles a new {@link SavingsAccount} from JSON details passed in
|
||||
* request inheriting details where relevant from chosen
|
||||
* {@link SavingsProduct}.
|
||||
*/
|
||||
public SavingsAccount assembleFrom(final JsonCommand command) {
|
||||
|
||||
final JsonElement element = command.parsedJson();
|
||||
|
||||
final String accountNo = fromApiJsonHelper.extractStringNamed("accountNo", element);
|
||||
final String externalId = fromApiJsonHelper.extractStringNamed("externalId", element);
|
||||
final Long productId = fromApiJsonHelper.extractLongNamed("productId", element);
|
||||
|
||||
final SavingsProduct product = this.savingProductRepository.findOne(productId);
|
||||
if (product == null) { throw new SavingsProductNotFoundException(productId); }
|
||||
|
||||
final Long clientId = fromApiJsonHelper.extractLongNamed("clientId", element);
|
||||
final Long groupId = fromApiJsonHelper.extractLongNamed("groupId", element);
|
||||
|
||||
Client client = null;
|
||||
Group group = null;
|
||||
if (clientId != null) {
|
||||
client = this.clientRepository.findOne(clientId);
|
||||
if (client == null || client.isDeleted()) { throw new ClientNotFoundException(clientId); }
|
||||
}
|
||||
|
||||
if (groupId != null) {
|
||||
group = this.groupRepository.findOne(groupId);
|
||||
if (group == null || group.isDeleted()) { throw new GroupNotFoundException(groupId); }
|
||||
}
|
||||
|
||||
BigDecimal interestRate = null;
|
||||
if (command.parameterExists(interestRateParamName)) {
|
||||
interestRate = command.bigDecimalValueOfParameterNamed(interestRateParamName);
|
||||
} else {
|
||||
interestRate = product.interestRate();
|
||||
}
|
||||
|
||||
PeriodFrequencyType interestRatePeriodFrequencyType = null;
|
||||
Integer interestRatePeriodFrequencyTypeValue = null;
|
||||
if (command.parameterExists(interestRatePeriodFrequencyTypeParamName)) {
|
||||
interestRatePeriodFrequencyTypeValue = command.integerValueOfParameterNamed(interestRatePeriodFrequencyTypeParamName);
|
||||
if (interestRatePeriodFrequencyTypeValue != null) {
|
||||
interestRatePeriodFrequencyType = PeriodFrequencyType.fromInt(interestRatePeriodFrequencyTypeValue);
|
||||
}
|
||||
} else {
|
||||
interestRatePeriodFrequencyType = product.interestRatePeriodFrequencyType();
|
||||
}
|
||||
|
||||
final BigDecimal annualInterestRate = this.aprCalculator.calculateFrom(interestRatePeriodFrequencyType, interestRate);
|
||||
|
||||
BigDecimal minRequiredOpeningBalance = null;
|
||||
if (command.parameterExists(minRequiredOpeningBalanceParamName)) {
|
||||
minRequiredOpeningBalance = command.bigDecimalValueOfParameterNamed(minRequiredOpeningBalanceParamName);
|
||||
} else {
|
||||
minRequiredOpeningBalance = product.minRequiredOpeningBalance();
|
||||
}
|
||||
|
||||
Integer lockinPeriodFrequency = null;
|
||||
if (command.parameterExists(lockinPeriodFrequencyParamName)) {
|
||||
lockinPeriodFrequency = command.integerValueOfParameterNamed(lockinPeriodFrequencyParamName);
|
||||
} else {
|
||||
lockinPeriodFrequency = product.lockinPeriodFrequency();
|
||||
}
|
||||
|
||||
PeriodFrequencyType lockinPeriodFrequencyType = null;
|
||||
Integer lockinPeriodFrequencyTypeValue = null;
|
||||
if (command.parameterExists(lockinPeriodFrequencyTypeParamName)) {
|
||||
lockinPeriodFrequencyTypeValue = command.integerValueOfParameterNamed(lockinPeriodFrequencyTypeParamName);
|
||||
if (lockinPeriodFrequencyTypeValue != null) {
|
||||
lockinPeriodFrequencyType = PeriodFrequencyType.fromInt(lockinPeriodFrequencyTypeValue);
|
||||
}
|
||||
} else {
|
||||
lockinPeriodFrequencyType = product.lockinPeriodFrequencyType();
|
||||
}
|
||||
|
||||
return SavingsAccount.createNewAccount(client, group, product, accountNo, externalId, interestRate,
|
||||
interestRatePeriodFrequencyType, annualInterestRate, minRequiredOpeningBalance, lockinPeriodFrequency,
|
||||
lockinPeriodFrequencyType);
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -3,11 +3,11 @@
|
||||
* 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.portfolio.savingsaccount.domain;
|
||||
package org.mifosplatform.portfolio.savings.domain;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||
|
||||
public interface SavingAccountRepository extends JpaRepository<SavingAccount, Long>, JpaSpecificationExecutor<SavingAccount> {
|
||||
public interface SavingsAccountRepository extends JpaRepository<SavingsAccount, Long>, JpaSpecificationExecutor<SavingsAccount> {
|
||||
|
||||
}
|
||||
+215
@@ -0,0 +1,215 @@
|
||||
/**
|
||||
* 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.portfolio.savings.domain;
|
||||
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.currencyCodeParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.descriptionParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.digitsAfterDecimalParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.interestRateParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.interestRatePeriodFrequencyTypeParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.localeParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.lockinPeriodFrequencyParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.lockinPeriodFrequencyTypeParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.minRequiredOpeningBalanceParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.nameParamName;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Embedded;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
|
||||
import org.mifosplatform.organisation.monetary.domain.Money;
|
||||
import org.mifosplatform.portfolio.loanproduct.domain.PeriodFrequencyType;
|
||||
import org.mifosplatform.portfolio.savings.exception.InvalidSavingsProductSettingsException;
|
||||
import org.springframework.data.jpa.domain.AbstractPersistable;
|
||||
|
||||
@Entity
|
||||
@Table(name = "m_savings_product")
|
||||
public class SavingsProduct extends AbstractPersistable<Long> {
|
||||
|
||||
@Column(name = "name", nullable = false)
|
||||
private String name;
|
||||
|
||||
@Column(name = "description", length = 500, nullable = false)
|
||||
private String description;
|
||||
|
||||
@Embedded
|
||||
private MonetaryCurrency currency;
|
||||
|
||||
@Column(name = "nominal_interest_rate_per_period", scale = 6, precision = 19, nullable = false)
|
||||
private BigDecimal interestRate;
|
||||
|
||||
@Column(name = "nominal_interest_rate_period_frequency_enum", nullable = false)
|
||||
private Integer interestRatePeriodFrequencyType;
|
||||
|
||||
@Column(name = "min_required_opening_balance", scale = 6, precision = 19, nullable = false)
|
||||
private BigDecimal minRequiredOpeningBalance;
|
||||
|
||||
@Column(name = "lockin_period_frequency", nullable = false)
|
||||
private Integer lockinPeriodFrequency;
|
||||
|
||||
@Column(name = "lockin_period_frequency_enum", nullable = false)
|
||||
private Integer lockinPeriodFrequencyType;
|
||||
|
||||
public static SavingsProduct createNew(final String name, final String description, final MonetaryCurrency currency,
|
||||
final BigDecimal interestRate, final PeriodFrequencyType interestRatePeriodFrequencyType,
|
||||
final BigDecimal minRequiredOpeningBalance, final Integer lockinPeriodFrequency,
|
||||
final PeriodFrequencyType lockinPeriodFrequencyType) {
|
||||
|
||||
return new SavingsProduct(name, description, currency, interestRate, interestRatePeriodFrequencyType, minRequiredOpeningBalance,
|
||||
lockinPeriodFrequency, lockinPeriodFrequencyType);
|
||||
}
|
||||
|
||||
protected SavingsProduct() {
|
||||
this.name = null;
|
||||
this.description = null;
|
||||
}
|
||||
|
||||
private SavingsProduct(final String name, final String description, final MonetaryCurrency currency, final BigDecimal interestRate,
|
||||
final PeriodFrequencyType interestRatePeriodFrequencyType, final BigDecimal minRequiredOpeningBalance,
|
||||
final Integer lockinPeriodFrequency, final PeriodFrequencyType lockinPeriodFrequencyType) {
|
||||
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
|
||||
this.currency = currency;
|
||||
this.interestRate = interestRate;
|
||||
this.interestRatePeriodFrequencyType = interestRatePeriodFrequencyType.getValue();
|
||||
|
||||
if (minRequiredOpeningBalance != null) {
|
||||
this.minRequiredOpeningBalance = Money.of(currency, minRequiredOpeningBalance).getAmount();
|
||||
}
|
||||
|
||||
this.lockinPeriodFrequency = lockinPeriodFrequency;
|
||||
if (lockinPeriodFrequencyType != null) {
|
||||
this.lockinPeriodFrequencyType = lockinPeriodFrequencyType.getValue();
|
||||
}
|
||||
|
||||
validateLockinDetails();
|
||||
}
|
||||
|
||||
public MonetaryCurrency currency() {
|
||||
return this.currency.copy();
|
||||
}
|
||||
|
||||
public BigDecimal interestRate() {
|
||||
return Money.of(this.currency, this.interestRate).getAmount();
|
||||
}
|
||||
|
||||
public PeriodFrequencyType interestRatePeriodFrequencyType() {
|
||||
PeriodFrequencyType type = null;
|
||||
if (this.interestRatePeriodFrequencyType != null) {
|
||||
type = PeriodFrequencyType.fromInt(this.interestRatePeriodFrequencyType);
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
public BigDecimal minRequiredOpeningBalance() {
|
||||
return this.minRequiredOpeningBalance;
|
||||
}
|
||||
|
||||
public Integer lockinPeriodFrequency() {
|
||||
return this.lockinPeriodFrequency;
|
||||
}
|
||||
|
||||
public PeriodFrequencyType lockinPeriodFrequencyType() {
|
||||
PeriodFrequencyType type = null;
|
||||
if (this.lockinPeriodFrequencyType != null) {
|
||||
type = PeriodFrequencyType.fromInt(this.lockinPeriodFrequencyType);
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
public Map<String, Object> update(final JsonCommand command) {
|
||||
|
||||
final Map<String, Object> actualChanges = new LinkedHashMap<String, Object>(10);
|
||||
|
||||
final String localeAsInput = command.locale();
|
||||
|
||||
if (command.isChangeInStringParameterNamed(nameParamName, this.name)) {
|
||||
final String newValue = command.stringValueOfParameterNamed(nameParamName);
|
||||
actualChanges.put(nameParamName, newValue);
|
||||
this.name = newValue;
|
||||
}
|
||||
|
||||
if (command.isChangeInStringParameterNamed(descriptionParamName, this.description)) {
|
||||
final String newValue = command.stringValueOfParameterNamed(descriptionParamName);
|
||||
actualChanges.put(descriptionParamName, newValue);
|
||||
this.description = newValue;
|
||||
}
|
||||
|
||||
Integer digitsAfterDecimal = this.currency.getDigitsAfterDecimal();
|
||||
if (command.isChangeInIntegerParameterNamed(digitsAfterDecimalParamName, digitsAfterDecimal)) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(digitsAfterDecimalParamName);
|
||||
actualChanges.put(digitsAfterDecimalParamName, newValue);
|
||||
actualChanges.put(localeParamName, localeAsInput);
|
||||
digitsAfterDecimal = newValue;
|
||||
this.currency = new MonetaryCurrency(this.currency.getCode(), digitsAfterDecimal);
|
||||
}
|
||||
|
||||
String currencyCode = this.currency.getCode();
|
||||
if (command.isChangeInStringParameterNamed(currencyCodeParamName, currencyCode)) {
|
||||
final String newValue = command.stringValueOfParameterNamed(currencyCodeParamName);
|
||||
actualChanges.put(currencyCodeParamName, newValue);
|
||||
currencyCode = newValue;
|
||||
this.currency = new MonetaryCurrency(currencyCode, this.currency.getDigitsAfterDecimal());
|
||||
}
|
||||
|
||||
if (command.isChangeInBigDecimalParameterNamed(interestRateParamName, this.interestRate)) {
|
||||
final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(interestRateParamName);
|
||||
actualChanges.put(interestRateParamName, newValue);
|
||||
actualChanges.put(localeParamName, localeAsInput);
|
||||
this.interestRate = newValue;
|
||||
}
|
||||
|
||||
if (command.isChangeInIntegerParameterNamed(interestRatePeriodFrequencyTypeParamName, this.interestRatePeriodFrequencyType)) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(interestRatePeriodFrequencyTypeParamName);
|
||||
actualChanges.put(interestRatePeriodFrequencyTypeParamName, newValue);
|
||||
this.interestRatePeriodFrequencyType = PeriodFrequencyType.fromInt(newValue).getValue();
|
||||
}
|
||||
|
||||
if (command.isChangeInBigDecimalParameterNamed(minRequiredOpeningBalanceParamName, this.minRequiredOpeningBalance)) {
|
||||
final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(minRequiredOpeningBalanceParamName);
|
||||
actualChanges.put(minRequiredOpeningBalanceParamName, newValue);
|
||||
actualChanges.put(localeParamName, localeAsInput);
|
||||
this.minRequiredOpeningBalance = newValue;
|
||||
}
|
||||
|
||||
if (command.isChangeInIntegerParameterNamed(lockinPeriodFrequencyParamName, this.lockinPeriodFrequency)) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(lockinPeriodFrequencyParamName);
|
||||
actualChanges.put(lockinPeriodFrequencyParamName, newValue);
|
||||
actualChanges.put(localeParamName, localeAsInput);
|
||||
this.lockinPeriodFrequency = newValue;
|
||||
}
|
||||
|
||||
if (command.isChangeInIntegerParameterNamed(lockinPeriodFrequencyTypeParamName, this.lockinPeriodFrequencyType)) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(lockinPeriodFrequencyTypeParamName);
|
||||
actualChanges.put(lockinPeriodFrequencyTypeParamName, newValue);
|
||||
this.lockinPeriodFrequencyType = PeriodFrequencyType.fromInt(newValue).getValue();
|
||||
}
|
||||
|
||||
validateLockinDetails();
|
||||
|
||||
return actualChanges;
|
||||
}
|
||||
|
||||
private void validateLockinDetails() {
|
||||
if (isInvalidConfigurationOfLockinSettings()) { throw new InvalidSavingsProductSettingsException(
|
||||
"error.msg.product.savings.invalid.lockin.settings", "Invalid configuration of lock in settings.",
|
||||
lockinPeriodFrequencyParamName); }
|
||||
}
|
||||
|
||||
private boolean isInvalidConfigurationOfLockinSettings() {
|
||||
return (this.lockinPeriodFrequency == null && this.lockinPeriodFrequencyType != null)
|
||||
|| (this.lockinPeriodFrequencyType == null && this.lockinPeriodFrequency != null);
|
||||
}
|
||||
}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
package org.mifosplatform.portfolio.savings.domain;
|
||||
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.currencyCodeParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.descriptionParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.digitsAfterDecimalParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.interestRateParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.interestRatePeriodFrequencyTypeParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.lockinPeriodFrequencyParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.lockinPeriodFrequencyTypeParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.minRequiredOpeningBalanceParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.nameParamName;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
|
||||
import org.mifosplatform.portfolio.loanproduct.domain.PeriodFrequencyType;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class SavingsProductAssembler {
|
||||
|
||||
public SavingsProduct assemble(final JsonCommand command) {
|
||||
|
||||
final String name = command.stringValueOfParameterNamed(nameParamName);
|
||||
final String description = command.stringValueOfParameterNamed(descriptionParamName);
|
||||
|
||||
final String currencyCode = command.stringValueOfParameterNamed(currencyCodeParamName);
|
||||
final Integer digitsAfterDecimal = command.integerValueOfParameterNamed(digitsAfterDecimalParamName);
|
||||
MonetaryCurrency currency = new MonetaryCurrency(currencyCode, digitsAfterDecimal);
|
||||
|
||||
final BigDecimal interestRate = command.bigDecimalValueOfParameterNamed(interestRateParamName);
|
||||
PeriodFrequencyType interestRatePeriodFrequencyType = null;
|
||||
final Integer interestRatePeriodFrequencyTypeValue = command.integerValueOfParameterNamed(interestRatePeriodFrequencyTypeParamName);
|
||||
if (interestRatePeriodFrequencyTypeValue != null) {
|
||||
interestRatePeriodFrequencyType = PeriodFrequencyType.fromInt(interestRatePeriodFrequencyTypeValue);
|
||||
}
|
||||
|
||||
final BigDecimal minRequiredOpeningBalance = command.bigDecimalValueOfParameterNamed(minRequiredOpeningBalanceParamName);
|
||||
|
||||
final Integer lockinPeriodFrequency = command.integerValueOfParameterNamed(lockinPeriodFrequencyParamName);
|
||||
PeriodFrequencyType lockinPeriodFrequencyType = null;
|
||||
final Integer lockinPeriodFrequencyTypeValue = command.integerValueOfParameterNamed(lockinPeriodFrequencyTypeParamName);
|
||||
if (lockinPeriodFrequencyTypeValue != null) {
|
||||
lockinPeriodFrequencyType = PeriodFrequencyType.fromInt(lockinPeriodFrequencyTypeValue);
|
||||
}
|
||||
|
||||
return SavingsProduct.createNew(name, description, currency, interestRate, interestRatePeriodFrequencyType,
|
||||
minRequiredOpeningBalance, lockinPeriodFrequency, lockinPeriodFrequencyType);
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -3,11 +3,11 @@
|
||||
* 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.portfolio.savingsdepositaccount.domain;
|
||||
package org.mifosplatform.portfolio.savings.domain;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||
|
||||
public interface DepositAccountRepository extends JpaRepository<DepositAccount, Long>, JpaSpecificationExecutor<DepositAccount> {
|
||||
public interface SavingsProductRepository extends JpaRepository<SavingsProduct, Long>, JpaSpecificationExecutor<SavingsProduct> {
|
||||
//
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
package org.mifosplatform.portfolio.savings.exception;
|
||||
|
||||
import org.mifosplatform.infrastructure.core.exception.AbstractPlatformDomainRuleException;
|
||||
|
||||
public class InvalidSavingsProductSettingsException extends AbstractPlatformDomainRuleException {
|
||||
|
||||
public InvalidSavingsProductSettingsException(final String errorCode, final String defaultMessage, final String paramName) {
|
||||
super(errorCode, defaultMessage, paramName);
|
||||
}
|
||||
}
|
||||
+4
-4
@@ -3,13 +3,13 @@
|
||||
* 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.portfolio.savingsdepositaccount.exception;
|
||||
package org.mifosplatform.portfolio.savings.exception;
|
||||
|
||||
import org.mifosplatform.infrastructure.core.exception.AbstractPlatformResourceNotFoundException;
|
||||
|
||||
public class DepositAccountNotFoundException extends AbstractPlatformResourceNotFoundException {
|
||||
public class SavingsAccountNotFoundException extends AbstractPlatformResourceNotFoundException {
|
||||
|
||||
public DepositAccountNotFoundException(final Long id) {
|
||||
super("error.msg.deposit.account.id.invalid", "Deposit account with identifier " + id + " does not exist", id);
|
||||
public SavingsAccountNotFoundException(final Long id) {
|
||||
super("error.msg.saving.account.id.invalid", "Savings account with identifier " + id + " does not exist", id);
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -3,13 +3,13 @@
|
||||
* 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.portfolio.savingsaccountproduct.exception;
|
||||
package org.mifosplatform.portfolio.savings.exception;
|
||||
|
||||
import org.mifosplatform.infrastructure.core.exception.AbstractPlatformResourceNotFoundException;
|
||||
|
||||
public class SavingProductNotFoundException extends AbstractPlatformResourceNotFoundException {
|
||||
public class SavingsProductNotFoundException extends AbstractPlatformResourceNotFoundException {
|
||||
|
||||
public SavingProductNotFoundException(final Long id) {
|
||||
public SavingsProductNotFoundException(final Long id) {
|
||||
super("error.msg.savingproduct.id.invalid", "Saving product with identifier " + id + " does not exist", id);
|
||||
}
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
package org.mifosplatform.portfolio.savings.handler;
|
||||
|
||||
import org.mifosplatform.commands.handler.NewCommandSourceHandler;
|
||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.mifosplatform.portfolio.savings.service.SavingsAccountWritePlatformService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Service
|
||||
public class CreateSavingsAccountCommandHandler implements NewCommandSourceHandler {
|
||||
|
||||
private final SavingsAccountWritePlatformService savingAccountWritePlatformService;
|
||||
|
||||
@Autowired
|
||||
public CreateSavingsAccountCommandHandler(final SavingsAccountWritePlatformService savingAccountWritePlatformService) {
|
||||
this.savingAccountWritePlatformService = savingAccountWritePlatformService;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult processCommand(final JsonCommand command) {
|
||||
return this.savingAccountWritePlatformService.createSavingAccount(command);
|
||||
}
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
package org.mifosplatform.portfolio.savings.handler;
|
||||
|
||||
import org.mifosplatform.commands.handler.NewCommandSourceHandler;
|
||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.mifosplatform.portfolio.savings.service.SavingsProductWritePlatformService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class CreateSavingsProductCommandHandler implements NewCommandSourceHandler {
|
||||
|
||||
private final SavingsProductWritePlatformService writePlatformService;
|
||||
|
||||
@Autowired
|
||||
public CreateSavingsProductCommandHandler(final SavingsProductWritePlatformService writePlatformService) {
|
||||
this.writePlatformService = writePlatformService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandProcessingResult processCommand(final JsonCommand command) {
|
||||
return this.writePlatformService.create(command);
|
||||
}
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
package org.mifosplatform.portfolio.savings.handler;
|
||||
|
||||
import org.mifosplatform.commands.handler.NewCommandSourceHandler;
|
||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.mifosplatform.portfolio.savings.service.SavingsAccountWritePlatformService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Service
|
||||
public class DeleteSavingsAccountCommandHandler implements NewCommandSourceHandler {
|
||||
|
||||
private final SavingsAccountWritePlatformService savingAccountWritePlatformService;
|
||||
|
||||
@Autowired
|
||||
public DeleteSavingsAccountCommandHandler(final SavingsAccountWritePlatformService savingAccountWritePlatformService) {
|
||||
this.savingAccountWritePlatformService = savingAccountWritePlatformService;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult processCommand(final JsonCommand command) {
|
||||
return this.savingAccountWritePlatformService.deleteSavingAccount(command.entityId());
|
||||
}
|
||||
|
||||
}
|
||||
+6
-6
@@ -1,24 +1,24 @@
|
||||
package org.mifosplatform.portfolio.savingsaccountproduct.handler;
|
||||
package org.mifosplatform.portfolio.savings.handler;
|
||||
|
||||
import org.mifosplatform.commands.handler.NewCommandSourceHandler;
|
||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.mifosplatform.portfolio.savingsaccountproduct.service.SavingProductWritePlatformService;
|
||||
import org.mifosplatform.portfolio.savings.service.SavingsProductWritePlatformService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class CreateSavingProductCommandHandler implements NewCommandSourceHandler {
|
||||
public class DeleteSavingsProductCommandHandler implements NewCommandSourceHandler {
|
||||
|
||||
private final SavingProductWritePlatformService savingProductWritePlatformService;
|
||||
private final SavingsProductWritePlatformService savingProductWritePlatformService;
|
||||
|
||||
@Autowired
|
||||
public CreateSavingProductCommandHandler(final SavingProductWritePlatformService savingProductWritePlatformService) {
|
||||
public DeleteSavingsProductCommandHandler(final SavingsProductWritePlatformService savingProductWritePlatformService) {
|
||||
this.savingProductWritePlatformService = savingProductWritePlatformService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandProcessingResult processCommand(final JsonCommand command) {
|
||||
return this.savingProductWritePlatformService.createSavingProduct(command);
|
||||
return this.savingProductWritePlatformService.delete(command.entityId());
|
||||
}
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
package org.mifosplatform.portfolio.savings.handler;
|
||||
|
||||
import org.mifosplatform.commands.handler.NewCommandSourceHandler;
|
||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.mifosplatform.portfolio.savings.service.SavingsAccountWritePlatformService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Service
|
||||
public class UpdateSavingsAccountCommandHandler implements NewCommandSourceHandler {
|
||||
|
||||
private final SavingsAccountWritePlatformService savingAccountWritePlatformService;
|
||||
|
||||
@Autowired
|
||||
public UpdateSavingsAccountCommandHandler(final SavingsAccountWritePlatformService savingAccountWritePlatformService) {
|
||||
this.savingAccountWritePlatformService = savingAccountWritePlatformService;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult processCommand(final JsonCommand command) {
|
||||
return this.savingAccountWritePlatformService.updateSavingAccount(command.entityId(), command);
|
||||
}
|
||||
|
||||
}
|
||||
+6
-6
@@ -1,24 +1,24 @@
|
||||
package org.mifosplatform.portfolio.savingsaccountproduct.handler;
|
||||
package org.mifosplatform.portfolio.savings.handler;
|
||||
|
||||
import org.mifosplatform.commands.handler.NewCommandSourceHandler;
|
||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.mifosplatform.portfolio.savingsaccountproduct.service.SavingProductWritePlatformService;
|
||||
import org.mifosplatform.portfolio.savings.service.SavingsProductWritePlatformService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class DeleteSavingProductCommandHandler implements NewCommandSourceHandler {
|
||||
public class UpdateSavingsProductCommandHandler implements NewCommandSourceHandler {
|
||||
|
||||
private final SavingProductWritePlatformService savingProductWritePlatformService;
|
||||
private final SavingsProductWritePlatformService savingProductWritePlatformService;
|
||||
|
||||
@Autowired
|
||||
public DeleteSavingProductCommandHandler(final SavingProductWritePlatformService savingProductWritePlatformService) {
|
||||
public UpdateSavingsProductCommandHandler(final SavingsProductWritePlatformService savingProductWritePlatformService) {
|
||||
this.savingProductWritePlatformService = savingProductWritePlatformService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandProcessingResult processCommand(final JsonCommand command) {
|
||||
return this.savingProductWritePlatformService.deleteSavingProduct(command.entityId());
|
||||
return this.savingProductWritePlatformService.update(command.entityId(), command);
|
||||
}
|
||||
}
|
||||
+19
@@ -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.portfolio.savings.service;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.mifosplatform.portfolio.savings.data.SavingsAccountData;
|
||||
|
||||
public interface SavingsAccountReadPlatformService {
|
||||
|
||||
Collection<SavingsAccountData> retrieveAll();
|
||||
|
||||
SavingsAccountData retrieveOne(Long accountId);
|
||||
|
||||
SavingsAccountData retrieveTemplate(Long clientId, Long groupId, Long productId);
|
||||
}
|
||||
+289
@@ -0,0 +1,289 @@
|
||||
/**
|
||||
* 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.portfolio.savings.service;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Collection;
|
||||
|
||||
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
|
||||
import org.mifosplatform.infrastructure.core.domain.JdbcSupport;
|
||||
import org.mifosplatform.infrastructure.core.service.TenantAwareRoutingDataSource;
|
||||
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
|
||||
import org.mifosplatform.organisation.monetary.data.CurrencyData;
|
||||
import org.mifosplatform.portfolio.client.data.ClientData;
|
||||
import org.mifosplatform.portfolio.client.service.ClientReadPlatformService;
|
||||
import org.mifosplatform.portfolio.group.data.GroupData;
|
||||
import org.mifosplatform.portfolio.group.service.GroupReadPlatformService;
|
||||
import org.mifosplatform.portfolio.loanproduct.domain.PeriodFrequencyType;
|
||||
import org.mifosplatform.portfolio.savings.data.SavingsAccountData;
|
||||
import org.mifosplatform.portfolio.savings.data.SavingsProductData;
|
||||
import org.mifosplatform.portfolio.savings.exception.SavingsAccountNotFoundException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.dao.EmptyResultDataAccessException;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.core.RowMapper;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountReadPlatformService {
|
||||
|
||||
private final PlatformSecurityContext context;
|
||||
private final JdbcTemplate jdbcTemplate;
|
||||
private final ClientReadPlatformService clientReadPlatformService;
|
||||
private final GroupReadPlatformService groupReadPlatformService;
|
||||
private final SavingsProductReadPlatformService savingsProductReadPlatformService;
|
||||
private final SavingsDropdownReadPlatformService dropdownReadPlatformService;
|
||||
|
||||
@Autowired
|
||||
public SavingsAccountReadPlatformServiceImpl(final PlatformSecurityContext context, final TenantAwareRoutingDataSource dataSource,
|
||||
final ClientReadPlatformService clientReadPlatformService, final GroupReadPlatformService groupReadPlatformService,
|
||||
final SavingsProductReadPlatformService savingProductReadPlatformService,
|
||||
final SavingsDropdownReadPlatformService dropdownReadPlatformService) {
|
||||
this.context = context;
|
||||
this.jdbcTemplate = new JdbcTemplate(dataSource);
|
||||
this.clientReadPlatformService = clientReadPlatformService;
|
||||
this.groupReadPlatformService = groupReadPlatformService;
|
||||
this.savingsProductReadPlatformService = savingProductReadPlatformService;
|
||||
this.dropdownReadPlatformService = dropdownReadPlatformService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<SavingsAccountData> retrieveAll() {
|
||||
|
||||
this.context.authenticatedUser();
|
||||
final SavingAccountMapper mapper = new SavingAccountMapper();
|
||||
final String sql = "select " + mapper.schema();
|
||||
return this.jdbcTemplate.query(sql, mapper, new Object[] {});
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public SavingsAccountData retrieveOne(final Long accountId) {
|
||||
|
||||
try {
|
||||
this.context.authenticatedUser();
|
||||
|
||||
final SavingAccountMapper mapper = new SavingAccountMapper();
|
||||
final String sql = "select " + mapper.schema() + " where sa.id = ?";
|
||||
|
||||
return this.jdbcTemplate.queryForObject(sql, mapper, new Object[] { accountId });
|
||||
} catch (EmptyResultDataAccessException e) {
|
||||
throw new SavingsAccountNotFoundException(accountId);
|
||||
}
|
||||
}
|
||||
|
||||
private static final class SavingAccountMapper implements RowMapper<SavingsAccountData> {
|
||||
|
||||
private final String schemaSql;
|
||||
|
||||
public SavingAccountMapper() {
|
||||
final StringBuilder sqlBuilder = new StringBuilder(400);
|
||||
sqlBuilder.append("sa.id as id, sa.account_no as accountNo, sa.external_id as externalId, ");
|
||||
sqlBuilder.append("c.id as clientId, c.display_name as clientName, ");
|
||||
sqlBuilder.append("g.id as groupId, g.name as groupName, ");
|
||||
sqlBuilder.append("sp.id as productId, sp.name as productName, ");
|
||||
sqlBuilder.append("sa.currency_code as currencyCode, sa.currency_digits as currencyDigits, ");
|
||||
sqlBuilder
|
||||
.append("curr.name as currencyName, curr.internationalized_name_code as currencyNameCode, curr.display_symbol as currencyDisplaySymbol, ");
|
||||
sqlBuilder
|
||||
.append("sa.nominal_interest_rate_per_period as interestRate, sa.nominal_interest_rate_period_frequency_enum as interestRatePeriodFrequencyType, ");
|
||||
sqlBuilder.append("sa.annual_nominal_interest_rate as annualInterestRate, ");
|
||||
sqlBuilder.append("sa.min_required_opening_balance as minRequiredOpeningBalance, ");
|
||||
sqlBuilder
|
||||
.append("sa.lockin_period_frequency as lockinPeriodFrequency, sa.lockin_period_frequency_enum as lockinPeriodFrequencyType ");
|
||||
sqlBuilder.append("from m_savings_account sa ");
|
||||
sqlBuilder.append("left outer join m_client c ON c.id = sa.client_id ");
|
||||
sqlBuilder.append("left outer join m_group g ON g.id = sa.group_id ");
|
||||
sqlBuilder.append("join m_savings_product sp ON sa.product_id = sp.id ");
|
||||
sqlBuilder.append("join m_currency curr on curr.code = sa.currency_code ");
|
||||
|
||||
this.schemaSql = sqlBuilder.toString();
|
||||
}
|
||||
|
||||
public String schema() {
|
||||
return this.schemaSql;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SavingsAccountData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {
|
||||
|
||||
final Long id = rs.getLong("id");
|
||||
final String accountNo = rs.getString("accountNo");
|
||||
final String externalId = rs.getString("externalId");
|
||||
|
||||
final Long groupId = rs.getLong("groupId");
|
||||
final String groupName = rs.getString("groupName");
|
||||
final Long clientId = rs.getLong("clientId");
|
||||
final String clientName = rs.getString("clientName");
|
||||
|
||||
final Long productId = rs.getLong("productId");
|
||||
final String productName = rs.getString("productName");
|
||||
|
||||
final String currencyCode = rs.getString("currencyCode");
|
||||
final String currencyName = rs.getString("currencyName");
|
||||
final String currencyNameCode = rs.getString("currencyNameCode");
|
||||
final String currencyDisplaySymbol = rs.getString("currencyDisplaySymbol");
|
||||
final Integer currencyDigits = JdbcSupport.getInteger(rs, "currencyDigits");
|
||||
final CurrencyData currency = new CurrencyData(currencyCode, currencyName, currencyDigits, currencyDisplaySymbol,
|
||||
currencyNameCode);
|
||||
|
||||
final BigDecimal interestRate = rs.getBigDecimal("interestRate");
|
||||
final EnumOptionData interestRatePeriodFrequencyType = SavingsEnumerations.interestRatePeriodFrequencyType(PeriodFrequencyType
|
||||
.fromInt(JdbcSupport.getInteger(rs, "interestRatePeriodFrequencyType")));
|
||||
final BigDecimal annualInterestRate = rs.getBigDecimal("annualInterestRate");
|
||||
|
||||
final BigDecimal minRequiredOpeningBalance = rs.getBigDecimal("minRequiredOpeningBalance");
|
||||
|
||||
final Integer lockinPeriodFrequency = JdbcSupport.getInteger(rs, "lockinPeriodFrequency");
|
||||
EnumOptionData lockinPeriodFrequencyType = null;
|
||||
final Integer lockinPeriodFrequencyTypeValue = JdbcSupport.getInteger(rs, "lockinPeriodFrequencyType");
|
||||
if (lockinPeriodFrequencyTypeValue != null) {
|
||||
lockinPeriodFrequencyType = SavingsEnumerations.interestRatePeriodFrequencyType(PeriodFrequencyType
|
||||
.fromInt(lockinPeriodFrequencyTypeValue));
|
||||
}
|
||||
|
||||
return SavingsAccountData.instance(id, accountNo, externalId, groupId, groupName, clientId, clientName, productId, productName,
|
||||
currency, interestRate, interestRatePeriodFrequencyType, annualInterestRate, minRequiredOpeningBalance,
|
||||
lockinPeriodFrequency, lockinPeriodFrequencyType);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public SavingsAccountData retrieveTemplate(final Long clientId, final Long groupId, final Long productId) {
|
||||
|
||||
context.authenticatedUser();
|
||||
|
||||
ClientData client = null;
|
||||
if (clientId != null) {
|
||||
client = this.clientReadPlatformService.retrieveIndividualClient(clientId);
|
||||
}
|
||||
|
||||
GroupData group = null;
|
||||
if (groupId != null) {
|
||||
group = this.groupReadPlatformService.retrieveGroup(groupId);
|
||||
}
|
||||
|
||||
final Collection<SavingsProductData> productOptions = this.savingsProductReadPlatformService.retrieveAllForLookup();
|
||||
SavingsAccountData template = null;
|
||||
if (productId != null) {
|
||||
|
||||
SavingAccountTemplateMapper mapper = new SavingAccountTemplateMapper(client, group);
|
||||
|
||||
final String sql = "select " + mapper.schema() + " where sp.id = ?";
|
||||
template = this.jdbcTemplate.queryForObject(sql, mapper, new Object[] { productId });
|
||||
|
||||
final Collection<EnumOptionData> interestRatePeriodFrequencyTypeOptions = this.dropdownReadPlatformService
|
||||
.retrieveInterestRatePeriodFrequencyTypeOptions();
|
||||
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions = this.dropdownReadPlatformService
|
||||
.retrieveLockinPeriodFrequencyTypeOptions();
|
||||
|
||||
template = SavingsAccountData.withTemplateOptions(template, productOptions, interestRatePeriodFrequencyTypeOptions,
|
||||
lockinPeriodFrequencyTypeOptions);
|
||||
} else {
|
||||
|
||||
String clientName = null;
|
||||
if (client != null) {
|
||||
clientName = client.displayName();
|
||||
}
|
||||
|
||||
String groupName = null;
|
||||
if (group != null) {
|
||||
groupName = group.getName();
|
||||
}
|
||||
|
||||
template = SavingsAccountData.withClientTemplate(clientId, clientName, groupId, groupName);
|
||||
|
||||
final Collection<EnumOptionData> interestRatePeriodFrequencyTypeOptions = null;
|
||||
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions = null;
|
||||
template = SavingsAccountData.withTemplateOptions(template, productOptions, interestRatePeriodFrequencyTypeOptions,
|
||||
lockinPeriodFrequencyTypeOptions);
|
||||
}
|
||||
|
||||
return template;
|
||||
}
|
||||
|
||||
private static final class SavingAccountTemplateMapper implements RowMapper<SavingsAccountData> {
|
||||
|
||||
private final ClientData client;
|
||||
private final GroupData group;
|
||||
|
||||
private final String schemaSql;
|
||||
|
||||
public SavingAccountTemplateMapper(final ClientData client, final GroupData group) {
|
||||
this.client = client;
|
||||
this.group = group;
|
||||
|
||||
final StringBuilder sqlBuilder = new StringBuilder(400);
|
||||
sqlBuilder.append("sp.id as productId, sp.name as productName, ");
|
||||
sqlBuilder.append("sp.currency_code as currencyCode, sp.currency_digits as currencyDigits, ");
|
||||
sqlBuilder.append("curr.name as currencyName, curr.internationalized_name_code as currencyNameCode, ");
|
||||
sqlBuilder.append("curr.display_symbol as currencyDisplaySymbol, ");
|
||||
sqlBuilder.append("sp.nominal_interest_rate_per_period as interestRate, ");
|
||||
sqlBuilder.append("sp.nominal_interest_rate_period_frequency_enum as interestRatePeriodFrequencyType, ");
|
||||
sqlBuilder.append("sp.min_required_opening_balance as minRequiredOpeningBalance, ");
|
||||
sqlBuilder.append("sp.lockin_period_frequency as lockinPeriodFrequency, ");
|
||||
sqlBuilder.append("sp.lockin_period_frequency_enum as lockinPeriodFrequencyType ");
|
||||
sqlBuilder.append("from m_savings_product sp ");
|
||||
sqlBuilder.append("join m_currency curr on curr.code = sp.currency_code ");
|
||||
|
||||
this.schemaSql = sqlBuilder.toString();
|
||||
}
|
||||
|
||||
public String schema() {
|
||||
return this.schemaSql;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SavingsAccountData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {
|
||||
|
||||
final Long productId = rs.getLong("productId");
|
||||
final String productName = rs.getString("productName");
|
||||
|
||||
final String currencyCode = rs.getString("currencyCode");
|
||||
final String currencyName = rs.getString("currencyName");
|
||||
final String currencyNameCode = rs.getString("currencyNameCode");
|
||||
final String currencyDisplaySymbol = rs.getString("currencyDisplaySymbol");
|
||||
final Integer currencyDigits = JdbcSupport.getInteger(rs, "currencyDigits");
|
||||
final CurrencyData currency = new CurrencyData(currencyCode, currencyName, currencyDigits, currencyDisplaySymbol,
|
||||
currencyNameCode);
|
||||
|
||||
final BigDecimal interestRate = rs.getBigDecimal("interestRate");
|
||||
final EnumOptionData interestRatePeriodFrequencyType = SavingsEnumerations.interestRatePeriodFrequencyType(PeriodFrequencyType
|
||||
.fromInt(JdbcSupport.getInteger(rs, "interestRatePeriodFrequencyType")));
|
||||
final BigDecimal annualInterestRate = null;
|
||||
|
||||
final BigDecimal minRequiredOpeningBalance = rs.getBigDecimal("minRequiredOpeningBalance");
|
||||
|
||||
final Integer lockinPeriodFrequency = JdbcSupport.getInteger(rs, "lockinPeriodFrequency");
|
||||
EnumOptionData lockinPeriodFrequencyType = null;
|
||||
final Integer lockinPeriodFrequencyTypeValue = JdbcSupport.getInteger(rs, "lockinPeriodFrequencyType");
|
||||
if (lockinPeriodFrequencyTypeValue != null) {
|
||||
lockinPeriodFrequencyType = SavingsEnumerations.interestRatePeriodFrequencyType(PeriodFrequencyType
|
||||
.fromInt(lockinPeriodFrequencyTypeValue));
|
||||
}
|
||||
|
||||
Long clientId = null;
|
||||
String clientName = null;
|
||||
if (client != null) {
|
||||
clientId = client.id();
|
||||
clientName = client.displayName();
|
||||
}
|
||||
|
||||
Long groupId = null;
|
||||
String groupName = null;
|
||||
if (group != null) {
|
||||
groupId = group.getId();
|
||||
groupName = group.getName();
|
||||
}
|
||||
|
||||
return SavingsAccountData.instance(null, null, null, groupId, groupName, clientId, clientName, productId, productName,
|
||||
currency, interestRate, interestRatePeriodFrequencyType, annualInterestRate, minRequiredOpeningBalance,
|
||||
lockinPeriodFrequency, lockinPeriodFrequencyType);
|
||||
}
|
||||
}
|
||||
}
|
||||
+22
@@ -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.portfolio.savings.service;
|
||||
|
||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||
|
||||
public interface SavingsAccountWritePlatformService {
|
||||
|
||||
CommandProcessingResult createSavingAccount(JsonCommand command);
|
||||
|
||||
CommandProcessingResult updateSavingAccount(Long accountId, JsonCommand command);
|
||||
|
||||
CommandProcessingResult deposit(JsonCommand command);
|
||||
|
||||
CommandProcessingResult withdraw(JsonCommand command);
|
||||
|
||||
CommandProcessingResult deleteSavingAccount(Long accountId);
|
||||
}
|
||||
+253
@@ -0,0 +1,253 @@
|
||||
/**
|
||||
* 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.portfolio.savings.service;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResultBuilder;
|
||||
import org.mifosplatform.infrastructure.core.exception.PlatformDataIntegrityException;
|
||||
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
|
||||
import org.mifosplatform.portfolio.client.domain.AccountNumberGenerator;
|
||||
import org.mifosplatform.portfolio.client.domain.AccountNumberGeneratorFactory;
|
||||
import org.mifosplatform.portfolio.client.domain.Client;
|
||||
import org.mifosplatform.portfolio.client.domain.ClientRepository;
|
||||
import org.mifosplatform.portfolio.client.exception.ClientNotFoundException;
|
||||
import org.mifosplatform.portfolio.group.domain.Group;
|
||||
import org.mifosplatform.portfolio.group.domain.GroupRepository;
|
||||
import org.mifosplatform.portfolio.group.exception.GroupNotFoundException;
|
||||
import org.mifosplatform.portfolio.savings.api.SavingsApiConstants;
|
||||
import org.mifosplatform.portfolio.savings.data.SavingsAccountDataValidator;
|
||||
import org.mifosplatform.portfolio.savings.domain.SavingsAccount;
|
||||
import org.mifosplatform.portfolio.savings.domain.SavingsAccountAssembler;
|
||||
import org.mifosplatform.portfolio.savings.domain.SavingsAccountRepository;
|
||||
import org.mifosplatform.portfolio.savings.domain.SavingsProduct;
|
||||
import org.mifosplatform.portfolio.savings.domain.SavingsProductRepository;
|
||||
import org.mifosplatform.portfolio.savings.exception.SavingsAccountNotFoundException;
|
||||
import org.mifosplatform.portfolio.savings.exception.SavingsProductNotFoundException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Service
|
||||
public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements SavingsAccountWritePlatformService {
|
||||
|
||||
private final static Logger logger = LoggerFactory.getLogger(SavingsAccountWritePlatformServiceJpaRepositoryImpl.class);
|
||||
|
||||
private final PlatformSecurityContext context;
|
||||
private final SavingsAccountRepository savingAccountRepository;
|
||||
private final SavingsAccountAssembler savingAccountAssembler;
|
||||
private final SavingsAccountDataValidator savingsAccountDataValidator;
|
||||
private final AccountNumberGeneratorFactory accountIdentifierGeneratorFactory;
|
||||
private final ClientRepository clientRepository;
|
||||
private final GroupRepository groupRepository;
|
||||
private final SavingsProductRepository savingsProductRepository;
|
||||
|
||||
@Autowired
|
||||
public SavingsAccountWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context,
|
||||
final SavingsAccountRepository savingAccountRepository, final SavingsAccountAssembler savingAccountAssembler,
|
||||
final SavingsAccountDataValidator savingsAccountDataValidator,
|
||||
final AccountNumberGeneratorFactory accountIdentifierGeneratorFactory, final ClientRepository clientRepository,
|
||||
final GroupRepository groupRepository, final SavingsProductRepository savingsProductRepository) {
|
||||
this.context = context;
|
||||
this.savingAccountRepository = savingAccountRepository;
|
||||
this.savingAccountAssembler = savingAccountAssembler;
|
||||
this.accountIdentifierGeneratorFactory = accountIdentifierGeneratorFactory;
|
||||
this.savingsAccountDataValidator = savingsAccountDataValidator;
|
||||
this.clientRepository = clientRepository;
|
||||
this.groupRepository = groupRepository;
|
||||
this.savingsProductRepository = savingsProductRepository;
|
||||
}
|
||||
|
||||
/*
|
||||
* Guaranteed to throw an exception no matter what the data integrity issue
|
||||
* is.
|
||||
*/
|
||||
private void handleDataIntegrityIssues(final JsonCommand command, final DataAccessException dve) {
|
||||
|
||||
final StringBuilder errorCodeBuilder = new StringBuilder("error.msg.").append(SavingsApiConstants.SAVINGS_ACCOUNT_RESOURCE_NAME);
|
||||
|
||||
final Throwable realCause = dve.getMostSpecificCause();
|
||||
if (realCause.getMessage().contains("sa_account_no_UNIQUE")) {
|
||||
final String accountNo = command.stringValueOfParameterNamed("accountNo");
|
||||
errorCodeBuilder.append(".duplicate.accountNo");
|
||||
throw new PlatformDataIntegrityException(errorCodeBuilder.toString(), "Savings account with accountNo " + accountNo
|
||||
+ " already exists", "accountNo", accountNo);
|
||||
|
||||
} else if (realCause.getMessage().contains("sa_external_id_UNIQUE")) {
|
||||
|
||||
final String externalId = command.stringValueOfParameterNamed("externalId");
|
||||
errorCodeBuilder.append(".duplicate.externalId");
|
||||
throw new PlatformDataIntegrityException(errorCodeBuilder.toString(), "Savings account with externalId " + externalId
|
||||
+ " already exists", "externalId", externalId);
|
||||
}
|
||||
|
||||
errorCodeBuilder.append(".unknown.data.integrity.issue");
|
||||
logger.error(dve.getMessage(), dve);
|
||||
throw new PlatformDataIntegrityException(errorCodeBuilder.toString(), "Unknown data integrity issue with savings account.");
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult createSavingAccount(final JsonCommand command) {
|
||||
try {
|
||||
this.context.authenticatedUser();
|
||||
this.savingsAccountDataValidator.validateForCreate(command.json());
|
||||
|
||||
final SavingsAccount account = this.savingAccountAssembler.assembleFrom(command);
|
||||
this.savingAccountRepository.save(account);
|
||||
|
||||
if (account.isAccountNumberRequiresAutoGeneration()) {
|
||||
final AccountNumberGenerator accountNoGenerator = this.accountIdentifierGeneratorFactory
|
||||
.determineLoanAccountNoGenerator(account.getId());
|
||||
account.updateAccountNo(accountNoGenerator.generate());
|
||||
|
||||
this.savingAccountRepository.save(account);
|
||||
}
|
||||
|
||||
return new CommandProcessingResultBuilder() //
|
||||
.withCommandId(command.commandId()) //
|
||||
.withEntityId(account.getId()) //
|
||||
.withOfficeId(account.officeId()) //
|
||||
.withClientId(account.clientId()) //
|
||||
.withGroupId(account.groupId()) //
|
||||
.build();
|
||||
} catch (DataAccessException dve) {
|
||||
handleDataIntegrityIssues(command, dve);
|
||||
return new CommandProcessingResult(Long.valueOf(-1));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult updateSavingAccount(final Long accountId, final JsonCommand command) {
|
||||
try {
|
||||
this.context.authenticatedUser();
|
||||
this.savingsAccountDataValidator.validateForUpdate(command.json());
|
||||
|
||||
final Map<String, Object> changes = new LinkedHashMap<String, Object>(20);
|
||||
|
||||
final SavingsAccount account = this.savingAccountRepository.findOne(accountId);
|
||||
if (account == null) { throw new SavingsAccountNotFoundException(accountId); }
|
||||
|
||||
account.update(command, changes);
|
||||
|
||||
if (!changes.isEmpty()) {
|
||||
|
||||
if (changes.containsKey(SavingsApiConstants.clientIdParamName)) {
|
||||
final Long clientId = command.longValueOfParameterNamed(SavingsApiConstants.clientIdParamName);
|
||||
if (clientId != null) {
|
||||
final Client client = this.clientRepository.findOne(clientId);
|
||||
if (client == null || client.isDeleted()) { throw new ClientNotFoundException(clientId); }
|
||||
account.update(client);
|
||||
} else {
|
||||
final Client client = null;
|
||||
account.update(client);
|
||||
}
|
||||
}
|
||||
|
||||
if (changes.containsKey(SavingsApiConstants.groupIdParamName)) {
|
||||
final Long groupId = command.longValueOfParameterNamed(SavingsApiConstants.groupIdParamName);
|
||||
if (groupId != null) {
|
||||
final Group group = this.groupRepository.findOne(groupId);
|
||||
if (group == null || group.isDeleted()) { throw new GroupNotFoundException(groupId); }
|
||||
account.update(group);
|
||||
} else {
|
||||
final Group group = null;
|
||||
account.update(group);
|
||||
}
|
||||
}
|
||||
|
||||
if (changes.containsKey(SavingsApiConstants.productIdParamName)) {
|
||||
final Long productId = command.longValueOfParameterNamed(SavingsApiConstants.productIdParamName);
|
||||
final SavingsProduct product = this.savingsProductRepository.findOne(productId);
|
||||
if (product == null) { throw new SavingsProductNotFoundException(productId); }
|
||||
|
||||
account.update(product);
|
||||
}
|
||||
|
||||
this.savingAccountRepository.saveAndFlush(account);
|
||||
}
|
||||
|
||||
return new CommandProcessingResultBuilder() //
|
||||
.withCommandId(command.commandId()) //
|
||||
.withEntityId(account.getId()) //
|
||||
.withOfficeId(account.officeId()) //
|
||||
.withClientId(account.clientId()) //
|
||||
.withGroupId(account.groupId()) //
|
||||
.with(changes) //
|
||||
.build();
|
||||
} catch (DataAccessException dve) {
|
||||
handleDataIntegrityIssues(command, dve);
|
||||
return new CommandProcessingResult(Long.valueOf(-1));
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult deposit(final JsonCommand command) {
|
||||
|
||||
this.context.authenticatedUser();
|
||||
|
||||
SavingsAccount account = this.savingAccountRepository.findOne(command.entityId());
|
||||
if (account == null) { throw new SavingsAccountNotFoundException(command.entityId()); }
|
||||
|
||||
// FIXME - add basic support for deposits
|
||||
|
||||
return new CommandProcessingResultBuilder() //
|
||||
.withEntityId(account.getId()) //
|
||||
.withOfficeId(account.officeId()) //
|
||||
.withClientId(account.clientId()) //
|
||||
.withGroupId(account.groupId()) //
|
||||
.build();
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult withdraw(final JsonCommand command) {
|
||||
|
||||
this.context.authenticatedUser();
|
||||
|
||||
final SavingsAccount account = this.savingAccountRepository.findOne(command.entityId());
|
||||
if (account == null) { throw new SavingsAccountNotFoundException(command.entityId()); }
|
||||
|
||||
// FIXME - add basic support for withdrawals
|
||||
|
||||
this.savingAccountRepository.save(account);
|
||||
|
||||
return new CommandProcessingResultBuilder() //
|
||||
.withEntityId(account.getId()) //
|
||||
.withOfficeId(account.officeId()) //
|
||||
.withClientId(account.clientId()) //
|
||||
.withGroupId(account.groupId()) //
|
||||
.build();
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult deleteSavingAccount(final Long accountId) {
|
||||
|
||||
this.context.authenticatedUser();
|
||||
|
||||
final SavingsAccount account = this.savingAccountRepository.findOne(accountId);
|
||||
if (account == null) { throw new SavingsAccountNotFoundException(accountId); }
|
||||
|
||||
this.savingAccountRepository.delete(account);
|
||||
|
||||
return new CommandProcessingResultBuilder() //
|
||||
.withEntityId(accountId) //
|
||||
.withOfficeId(account.officeId()) //
|
||||
.withClientId(account.clientId()) //
|
||||
.withGroupId(account.groupId()) //
|
||||
.build();
|
||||
}
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
package org.mifosplatform.portfolio.savings.service;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
|
||||
|
||||
public interface SavingsDropdownReadPlatformService {
|
||||
|
||||
Collection<EnumOptionData> retrieveInterestRatePeriodFrequencyTypeOptions();
|
||||
|
||||
Collection<EnumOptionData> retrieveLockinPeriodFrequencyTypeOptions();
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
package org.mifosplatform.portfolio.savings.service;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
|
||||
import org.mifosplatform.portfolio.loanproduct.domain.PeriodFrequencyType;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class SavingsDropdownReadPlatformServiceImpl implements SavingsDropdownReadPlatformService {
|
||||
|
||||
@Override
|
||||
public List<EnumOptionData> retrieveInterestRatePeriodFrequencyTypeOptions() {
|
||||
List<EnumOptionData> allowedInterestRatePeriodFrequencyTypeOptions = Arrays.asList( //
|
||||
SavingsEnumerations.interestRatePeriodFrequencyType(PeriodFrequencyType.MONTHS), //
|
||||
SavingsEnumerations.interestRatePeriodFrequencyType(PeriodFrequencyType.YEARS) //
|
||||
);
|
||||
|
||||
return allowedInterestRatePeriodFrequencyTypeOptions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<EnumOptionData> retrieveLockinPeriodFrequencyTypeOptions() {
|
||||
List<EnumOptionData> allowedLockinPeriodFrequencyTypeOptions = Arrays.asList( //
|
||||
SavingsEnumerations.lockinPeriodFrequencyType(PeriodFrequencyType.DAYS), //
|
||||
SavingsEnumerations.lockinPeriodFrequencyType(PeriodFrequencyType.WEEKS), //
|
||||
SavingsEnumerations.lockinPeriodFrequencyType(PeriodFrequencyType.MONTHS), //
|
||||
SavingsEnumerations.lockinPeriodFrequencyType(PeriodFrequencyType.YEARS) //
|
||||
);
|
||||
|
||||
return allowedLockinPeriodFrequencyTypeOptions;
|
||||
}
|
||||
}
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
/**
|
||||
* 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.portfolio.savings.service;
|
||||
|
||||
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
|
||||
import org.mifosplatform.portfolio.loanproduct.domain.PeriodFrequencyType;
|
||||
|
||||
public class SavingsEnumerations {
|
||||
|
||||
public static EnumOptionData interestRatePeriodFrequencyType(final int id) {
|
||||
return interestRatePeriodFrequencyType(PeriodFrequencyType.fromInt(id));
|
||||
}
|
||||
|
||||
public static EnumOptionData interestRatePeriodFrequencyType(final PeriodFrequencyType type) {
|
||||
final String codePrefix = "savings.interest.rate.";
|
||||
EnumOptionData optionData = new EnumOptionData(PeriodFrequencyType.INVALID.getValue().longValue(),
|
||||
PeriodFrequencyType.INVALID.getCode(), "Invalid");
|
||||
switch (type) {
|
||||
case INVALID:
|
||||
break;
|
||||
case DAYS:
|
||||
optionData = new EnumOptionData(PeriodFrequencyType.DAYS.getValue().longValue(), codePrefix
|
||||
+ PeriodFrequencyType.DAYS.getCode(), "Per day");
|
||||
break;
|
||||
case WEEKS:
|
||||
optionData = new EnumOptionData(PeriodFrequencyType.WEEKS.getValue().longValue(), codePrefix
|
||||
+ PeriodFrequencyType.WEEKS.getCode(), "Per week");
|
||||
break;
|
||||
case MONTHS:
|
||||
optionData = new EnumOptionData(PeriodFrequencyType.MONTHS.getValue().longValue(), codePrefix
|
||||
+ PeriodFrequencyType.MONTHS.getCode(), "Per month");
|
||||
break;
|
||||
case YEARS:
|
||||
optionData = new EnumOptionData(PeriodFrequencyType.YEARS.getValue().longValue(), codePrefix
|
||||
+ PeriodFrequencyType.YEARS.getCode(), "Per year");
|
||||
break;
|
||||
}
|
||||
return optionData;
|
||||
}
|
||||
|
||||
public static EnumOptionData lockinPeriodFrequencyType(final int id) {
|
||||
return lockinPeriodFrequencyType(PeriodFrequencyType.fromInt(id));
|
||||
}
|
||||
|
||||
public static EnumOptionData lockinPeriodFrequencyType(final PeriodFrequencyType type) {
|
||||
final String codePrefix = "savings.lockin.";
|
||||
EnumOptionData optionData = new EnumOptionData(PeriodFrequencyType.INVALID.getValue().longValue(),
|
||||
PeriodFrequencyType.INVALID.getCode(), "Invalid");
|
||||
switch (type) {
|
||||
case INVALID:
|
||||
break;
|
||||
case DAYS:
|
||||
optionData = new EnumOptionData(PeriodFrequencyType.DAYS.getValue().longValue(), codePrefix
|
||||
+ PeriodFrequencyType.DAYS.getCode(), "Days");
|
||||
break;
|
||||
case WEEKS:
|
||||
optionData = new EnumOptionData(PeriodFrequencyType.WEEKS.getValue().longValue(), codePrefix
|
||||
+ PeriodFrequencyType.WEEKS.getCode(), "Weeks");
|
||||
break;
|
||||
case MONTHS:
|
||||
optionData = new EnumOptionData(PeriodFrequencyType.MONTHS.getValue().longValue(), codePrefix
|
||||
+ PeriodFrequencyType.MONTHS.getCode(), "Months");
|
||||
break;
|
||||
case YEARS:
|
||||
optionData = new EnumOptionData(PeriodFrequencyType.YEARS.getValue().longValue(), codePrefix
|
||||
+ PeriodFrequencyType.YEARS.getCode(), "Years");
|
||||
break;
|
||||
}
|
||||
return optionData;
|
||||
}
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
/**
|
||||
* 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.portfolio.savings.service;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.mifosplatform.portfolio.savings.data.SavingsProductData;
|
||||
|
||||
public interface SavingsProductReadPlatformService {
|
||||
|
||||
Collection<SavingsProductData> retrieveAll();
|
||||
|
||||
Collection<SavingsProductData> retrieveAllForLookup();
|
||||
|
||||
SavingsProductData retrieveOne(Long productId);
|
||||
|
||||
}
|
||||
+132
@@ -0,0 +1,132 @@
|
||||
/**
|
||||
* 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.portfolio.savings.service;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Collection;
|
||||
|
||||
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
|
||||
import org.mifosplatform.infrastructure.core.domain.JdbcSupport;
|
||||
import org.mifosplatform.infrastructure.core.service.TenantAwareRoutingDataSource;
|
||||
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
|
||||
import org.mifosplatform.organisation.monetary.data.CurrencyData;
|
||||
import org.mifosplatform.portfolio.loanproduct.domain.PeriodFrequencyType;
|
||||
import org.mifosplatform.portfolio.savings.data.SavingsProductData;
|
||||
import org.mifosplatform.portfolio.savings.exception.SavingsProductNotFoundException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.dao.EmptyResultDataAccessException;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.core.RowMapper;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class SavingsProductReadPlatformServiceImpl implements SavingsProductReadPlatformService {
|
||||
|
||||
private final PlatformSecurityContext context;
|
||||
private final JdbcTemplate jdbcTemplate;
|
||||
private final SavingProductMapper savingsProductRowMapper = new SavingProductMapper();
|
||||
private final SavingProductLookupMapper savingsProductLookupsRowMapper = new SavingProductLookupMapper();
|
||||
|
||||
@Autowired
|
||||
public SavingsProductReadPlatformServiceImpl(final PlatformSecurityContext context, final TenantAwareRoutingDataSource dataSource) {
|
||||
this.context = context;
|
||||
jdbcTemplate = new JdbcTemplate(dataSource);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<SavingsProductData> retrieveAll() {
|
||||
|
||||
this.context.authenticatedUser();
|
||||
|
||||
final String sql = "select " + savingsProductRowMapper.schema();
|
||||
|
||||
return this.jdbcTemplate.query(sql, savingsProductRowMapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<SavingsProductData> retrieveAllForLookup() {
|
||||
|
||||
final String sql = "select " + savingsProductLookupsRowMapper.schema();
|
||||
|
||||
return this.jdbcTemplate.query(sql, savingsProductLookupsRowMapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SavingsProductData retrieveOne(final Long savingProductId) {
|
||||
try {
|
||||
this.context.authenticatedUser();
|
||||
final String sql = "select " + savingsProductRowMapper.schema() + " where sp.id = ?";
|
||||
return this.jdbcTemplate.queryForObject(sql, savingsProductRowMapper, new Object[] { savingProductId });
|
||||
} catch (EmptyResultDataAccessException e) {
|
||||
throw new SavingsProductNotFoundException(savingProductId);
|
||||
}
|
||||
}
|
||||
|
||||
private static final class SavingProductMapper implements RowMapper<SavingsProductData> {
|
||||
|
||||
public String schema() {
|
||||
return "sp.id as id,sp.name as name, sp.description as description, "
|
||||
+ "sp.currency_code as currencyCode, sp.currency_digits as currencyDigits, "
|
||||
+ "curr.name as currencyName, curr.internationalized_name_code as currencyNameCode, curr.display_symbol as currencyDisplaySymbol, "
|
||||
+ "sp.nominal_interest_rate_per_period as interestRate, sp.nominal_interest_rate_period_frequency_enum as interestRatePeriodFrequencyType, "
|
||||
+ "sp.min_required_opening_balance as minRequiredOpeningBalance, "
|
||||
+ "sp.lockin_period_frequency as lockinPeriodFrequency, sp.lockin_period_frequency_enum as lockinPeriodFrequencyType " //
|
||||
+ "from m_savings_product sp " //
|
||||
+ "join m_currency curr on curr.code = sp.currency_code";
|
||||
}
|
||||
|
||||
@Override
|
||||
public SavingsProductData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {
|
||||
|
||||
Long id = rs.getLong("id");
|
||||
String name = rs.getString("name");
|
||||
String description = rs.getString("description");
|
||||
|
||||
String currencyCode = rs.getString("currencyCode");
|
||||
String currencyName = rs.getString("currencyName");
|
||||
String currencyNameCode = rs.getString("currencyNameCode");
|
||||
String currencyDisplaySymbol = rs.getString("currencyDisplaySymbol");
|
||||
Integer currencyDigits = JdbcSupport.getInteger(rs, "currencyDigits");
|
||||
|
||||
final CurrencyData currency = new CurrencyData(currencyCode, currencyName, currencyDigits, currencyDisplaySymbol,
|
||||
currencyNameCode);
|
||||
BigDecimal interestRate = rs.getBigDecimal("interestRate");
|
||||
EnumOptionData interestRatePeriodFrequencyType = SavingsEnumerations.interestRatePeriodFrequencyType(PeriodFrequencyType
|
||||
.fromInt(JdbcSupport.getInteger(rs, "interestRatePeriodFrequencyType")));
|
||||
|
||||
final BigDecimal minRequiredOpeningBalance = rs.getBigDecimal("minRequiredOpeningBalance");
|
||||
|
||||
Integer lockinPeriodFrequency = JdbcSupport.getInteger(rs, "lockinPeriodFrequency");
|
||||
EnumOptionData lockinPeriodFrequencyType = null;
|
||||
final Integer lockinPeriodFrequencyTypeValue = JdbcSupport.getInteger(rs, "lockinPeriodFrequencyType");
|
||||
if (lockinPeriodFrequencyTypeValue != null) {
|
||||
lockinPeriodFrequencyType = SavingsEnumerations.interestRatePeriodFrequencyType(PeriodFrequencyType
|
||||
.fromInt(lockinPeriodFrequencyTypeValue));
|
||||
}
|
||||
|
||||
return SavingsProductData.instance(id, name, description, currency, interestRate, interestRatePeriodFrequencyType,
|
||||
minRequiredOpeningBalance, lockinPeriodFrequency, lockinPeriodFrequencyType);
|
||||
}
|
||||
}
|
||||
|
||||
private static final class SavingProductLookupMapper implements RowMapper<SavingsProductData> {
|
||||
|
||||
public String schema() {
|
||||
return " sp.id as id, sp.name as name from m_savings_product sp";
|
||||
}
|
||||
|
||||
@Override
|
||||
public SavingsProductData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {
|
||||
|
||||
final Long id = rs.getLong("id");
|
||||
final String name = rs.getString("name");
|
||||
|
||||
return SavingsProductData.lookup(id, name);
|
||||
}
|
||||
}
|
||||
}
|
||||
+5
-5
@@ -3,16 +3,16 @@
|
||||
* 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.portfolio.savingsaccountproduct.service;
|
||||
package org.mifosplatform.portfolio.savings.service;
|
||||
|
||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||
|
||||
public interface SavingProductWritePlatformService {
|
||||
public interface SavingsProductWritePlatformService {
|
||||
|
||||
CommandProcessingResult createSavingProduct(JsonCommand command);
|
||||
CommandProcessingResult create(JsonCommand command);
|
||||
|
||||
CommandProcessingResult updateSavingProduct(Long productId, JsonCommand command);
|
||||
CommandProcessingResult update(Long productId, JsonCommand command);
|
||||
|
||||
CommandProcessingResult deleteSavingProduct(Long productId);
|
||||
CommandProcessingResult delete(Long productId);
|
||||
}
|
||||
+131
@@ -0,0 +1,131 @@
|
||||
/**
|
||||
* 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.portfolio.savings.service;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResultBuilder;
|
||||
import org.mifosplatform.infrastructure.core.exception.PlatformDataIntegrityException;
|
||||
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
|
||||
import org.mifosplatform.portfolio.savings.data.SavingsProductDataValidator;
|
||||
import org.mifosplatform.portfolio.savings.domain.SavingsProduct;
|
||||
import org.mifosplatform.portfolio.savings.domain.SavingsProductAssembler;
|
||||
import org.mifosplatform.portfolio.savings.domain.SavingsProductRepository;
|
||||
import org.mifosplatform.portfolio.savings.exception.SavingsProductNotFoundException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Service
|
||||
public class SavingsProductWritePlatformServiceJpaRepositoryImpl implements SavingsProductWritePlatformService {
|
||||
|
||||
private final Logger logger;
|
||||
private final PlatformSecurityContext context;
|
||||
private final SavingsProductRepository savingProductRepository;
|
||||
private final SavingsProductDataValidator fromApiJsonDataValidator;
|
||||
private final SavingsProductAssembler savingsProductAssembler;
|
||||
|
||||
@Autowired
|
||||
public SavingsProductWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context,
|
||||
final SavingsProductRepository savingProductRepository, final SavingsProductDataValidator fromApiJsonDataValidator,
|
||||
final SavingsProductAssembler savingsProductAssembler) {
|
||||
this.context = context;
|
||||
this.savingProductRepository = savingProductRepository;
|
||||
this.fromApiJsonDataValidator = fromApiJsonDataValidator;
|
||||
this.savingsProductAssembler = savingsProductAssembler;
|
||||
this.logger = LoggerFactory.getLogger(SavingsProductWritePlatformServiceJpaRepositoryImpl.class);
|
||||
}
|
||||
|
||||
/*
|
||||
* Guaranteed to throw an exception no matter what the data integrity issue
|
||||
* is.
|
||||
*/
|
||||
private void handleDataIntegrityIssues(final JsonCommand command, final DataAccessException dae) {
|
||||
|
||||
final Throwable realCause = dae.getMostSpecificCause();
|
||||
if (realCause.getMessage().contains("sp_unq_name")) {
|
||||
|
||||
final String name = command.stringValueOfParameterNamed("name");
|
||||
throw new PlatformDataIntegrityException("error.msg.product.savings.duplicate.name", "Savings product with name `" + name
|
||||
+ "` already exists", "name", name);
|
||||
}
|
||||
|
||||
logAsErrorUnexpectedDataIntegrityException(dae);
|
||||
throw new PlatformDataIntegrityException("error.msg.savingsproduct.unknown.data.integrity.issue",
|
||||
"Unknown data integrity issue with resource.");
|
||||
}
|
||||
|
||||
private void logAsErrorUnexpectedDataIntegrityException(final DataAccessException dae) {
|
||||
logger.error(dae.getMessage(), dae);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult create(final JsonCommand command) {
|
||||
|
||||
try {
|
||||
this.context.authenticatedUser();
|
||||
|
||||
this.fromApiJsonDataValidator.validateForCreate(command.json());
|
||||
|
||||
final SavingsProduct product = this.savingsProductAssembler.assemble(command);
|
||||
|
||||
this.savingProductRepository.save(product);
|
||||
|
||||
return new CommandProcessingResultBuilder() //
|
||||
.withEntityId(product.getId()) //
|
||||
.build();
|
||||
} catch (DataAccessException e) {
|
||||
handleDataIntegrityIssues(command, e);
|
||||
return CommandProcessingResult.empty();
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult update(final Long productId, final JsonCommand command) {
|
||||
|
||||
try {
|
||||
this.context.authenticatedUser();
|
||||
this.fromApiJsonDataValidator.validateForUpdate(command.json());
|
||||
|
||||
final SavingsProduct product = this.savingProductRepository.findOne(productId);
|
||||
if (product == null) { throw new SavingsProductNotFoundException(productId); }
|
||||
|
||||
final Map<String, Object> changes = product.update(command);
|
||||
if (!changes.isEmpty()) {
|
||||
this.savingProductRepository.saveAndFlush(product);
|
||||
}
|
||||
|
||||
return new CommandProcessingResultBuilder() //
|
||||
.withEntityId(product.getId()) //
|
||||
.with(changes).build();
|
||||
} catch (DataAccessException e) {
|
||||
handleDataIntegrityIssues(command, e);
|
||||
return CommandProcessingResult.empty();
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult delete(final Long productId) {
|
||||
|
||||
this.context.authenticatedUser();
|
||||
final SavingsProduct product = this.savingProductRepository.findOne(productId);
|
||||
if (product == null) { throw new SavingsProductNotFoundException(productId); }
|
||||
|
||||
this.savingProductRepository.delete(product);
|
||||
|
||||
return new CommandProcessingResultBuilder() //
|
||||
.withEntityId(product.getId()) //
|
||||
.build();
|
||||
}
|
||||
}
|
||||
-330
@@ -1,330 +0,0 @@
|
||||
/**
|
||||
* 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.portfolio.savingsaccount.api;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.DELETE;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.PUT;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.QueryParam;
|
||||
import javax.ws.rs.core.Context;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.UriInfo;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.mifosplatform.commands.domain.CommandWrapper;
|
||||
import org.mifosplatform.commands.service.CommandWrapperBuilder;
|
||||
import org.mifosplatform.commands.service.PortfolioCommandSourceWritePlatformService;
|
||||
import org.mifosplatform.infrastructure.core.api.ApiParameterHelper;
|
||||
import org.mifosplatform.infrastructure.core.api.ApiRequestParameterHelper;
|
||||
import org.mifosplatform.infrastructure.core.api.JsonQuery;
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
|
||||
import org.mifosplatform.infrastructure.core.exception.UnrecognizedQueryParamException;
|
||||
import org.mifosplatform.infrastructure.core.serialization.ApiRequestJsonSerializationSettings;
|
||||
import org.mifosplatform.infrastructure.core.serialization.DefaultToApiJsonSerializer;
|
||||
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
|
||||
import org.mifosplatform.infrastructure.core.serialization.ToApiJsonSerializer;
|
||||
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
|
||||
import org.mifosplatform.organisation.monetary.data.CurrencyData;
|
||||
import org.mifosplatform.organisation.monetary.service.CurrencyReadPlatformService;
|
||||
import org.mifosplatform.portfolio.savingsaccount.data.SavingAccountData;
|
||||
import org.mifosplatform.portfolio.savingsaccount.data.SavingAccountForLookup;
|
||||
import org.mifosplatform.portfolio.savingsaccount.data.SavingAccountTransactionsData;
|
||||
import org.mifosplatform.portfolio.savingsaccount.data.SavingPermissionData;
|
||||
import org.mifosplatform.portfolio.savingsaccount.data.SavingScheduleData;
|
||||
import org.mifosplatform.portfolio.savingsaccount.service.CalculateSavingSchedule;
|
||||
import org.mifosplatform.portfolio.savingsaccount.service.SavingAccountReadPlatformService;
|
||||
import org.mifosplatform.portfolio.savingsaccount.service.SavingAccountWritePlatformService;
|
||||
import org.mifosplatform.portfolio.savingsaccountproduct.data.SavingProductLookup;
|
||||
import org.mifosplatform.portfolio.savingsaccountproduct.domain.SavingFrequencyType;
|
||||
import org.mifosplatform.portfolio.savingsaccountproduct.domain.SavingInterestCalculationMethod;
|
||||
import org.mifosplatform.portfolio.savingsaccountproduct.domain.SavingProductType;
|
||||
import org.mifosplatform.portfolio.savingsaccountproduct.domain.SavingsInterestType;
|
||||
import org.mifosplatform.portfolio.savingsaccountproduct.domain.SavingsLockinPeriodEnum;
|
||||
import org.mifosplatform.portfolio.savingsaccountproduct.service.SavingProductEnumerations;
|
||||
import org.mifosplatform.portfolio.savingsaccountproduct.service.SavingProductReadPlatformService;
|
||||
import org.mifosplatform.portfolio.savingsdepositproduct.domain.TenureTypeEnum;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
|
||||
@Path("/savingaccounts")
|
||||
@Component
|
||||
@Scope("singleton")
|
||||
public class SavingsAccountApiResource {
|
||||
|
||||
private final Set<String> SAVINGS_ACCOUNTS_DATA_PARAMETERS = new HashSet<String>(Arrays.asList("id", "status", "externalId",
|
||||
"clientId", "clientName", "productId", "productName", "productType", "currencyData", "savingsDepostiAmountPerPeriod",
|
||||
"savingsFrequencyType", "totalDepositAmount", "reccuringInterestRate", "savingInterestRate", "interestType",
|
||||
"interestCalculationMethod", "tenure", "tenureType", "projectedCommencementDate", "actualCommencementDate", "maturesOnDate",
|
||||
"projectedInterestAccuredOnMaturity", "actualInterestAccured", "projectedMaturityAmount", "actualMaturityAmount",
|
||||
"outstandingAmount", "preClosureAllowed", "preClosureInterestRate", "withdrawnonDate", "rejectedonDate", "closedonDate",
|
||||
"isLockinPeriodAllowed", "lockinPeriod", "lockinPeriodType", "productOptions", "currencyOptions", "savingsProductTypeOptions",
|
||||
"tenureTypeOptions", "savingFrequencyOptions", "savingsInterestTypeOptions", "lockinPeriodTypeOptions",
|
||||
"interestCalculationOptions", "permissions", "savingScheduleDatas", "dueAmount", "savingScheduleData", "transactions",
|
||||
"interestPostEvery", "interestPostFrequency"));
|
||||
|
||||
private final SavingAccountWritePlatformService savingAccountWritePlatformService;
|
||||
private final SavingAccountReadPlatformService savingAccountReadPlatformService;
|
||||
private final SavingProductReadPlatformService savingProductReadPlatformService;
|
||||
private final CurrencyReadPlatformService currencyReadPlatformService;
|
||||
private final String entityType = "SAVINGSACCOUNT";
|
||||
private final PlatformSecurityContext context;
|
||||
private final CalculateSavingSchedule calculateSavingSchedule;
|
||||
private final ToApiJsonSerializer<SavingAccountData> toApiJsonSerializer;
|
||||
private final ApiRequestParameterHelper apiRequestParameterHelper;
|
||||
private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
|
||||
private final FromJsonHelper fromJsonHelper;
|
||||
private final DefaultToApiJsonSerializer<SavingScheduleData> savingScheduleToApiJsonSerializer;
|
||||
|
||||
@Autowired
|
||||
public SavingsAccountApiResource(final SavingAccountWritePlatformService savingAccountWritePlatformService,
|
||||
final SavingAccountReadPlatformService savingAccountReadPlatformService,
|
||||
final SavingProductReadPlatformService savingProductReadPlatformService,
|
||||
final CurrencyReadPlatformService currencyReadPlatformService, final PlatformSecurityContext context,
|
||||
final CalculateSavingSchedule calculateSavingSchedule, final ToApiJsonSerializer<SavingAccountData> toApiJsonSerializer,
|
||||
final ApiRequestParameterHelper apiRequestParameterHelper,
|
||||
final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService, final FromJsonHelper fromJsonHelper,
|
||||
final DefaultToApiJsonSerializer<SavingScheduleData> savingScheduleToApiJsonSerializer) {
|
||||
this.savingAccountWritePlatformService = savingAccountWritePlatformService;
|
||||
this.savingAccountReadPlatformService = savingAccountReadPlatformService;
|
||||
this.savingProductReadPlatformService = savingProductReadPlatformService;
|
||||
this.currencyReadPlatformService = currencyReadPlatformService;
|
||||
this.context = context;
|
||||
this.calculateSavingSchedule = calculateSavingSchedule;
|
||||
this.toApiJsonSerializer = toApiJsonSerializer;
|
||||
this.apiRequestParameterHelper = apiRequestParameterHelper;
|
||||
this.commandsSourceWritePlatformService = commandsSourceWritePlatformService;
|
||||
this.fromJsonHelper = fromJsonHelper;
|
||||
this.savingScheduleToApiJsonSerializer = savingScheduleToApiJsonSerializer;
|
||||
}
|
||||
|
||||
@POST
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String createSavingAccount(@QueryParam("command") final String commandParam, @Context final UriInfo uriInfo,
|
||||
final String apiRequestBodyAsJson) {
|
||||
|
||||
if (is(commandParam, "calculateSavingSchedule")) {
|
||||
|
||||
final JsonElement parsedQuery = this.fromJsonHelper.parse(apiRequestBodyAsJson);
|
||||
final JsonQuery query = JsonQuery.from(apiRequestBodyAsJson, parsedQuery, this.fromJsonHelper);
|
||||
|
||||
SavingScheduleData savingSchedule = this.calculateSavingSchedule.calculateSavingSchedule(query);
|
||||
|
||||
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
||||
|
||||
return this.savingScheduleToApiJsonSerializer.serialize(settings, savingSchedule, new HashSet<String>());
|
||||
|
||||
}
|
||||
|
||||
final CommandWrapper commandRequest = new CommandWrapperBuilder().createSavingAccount().withJson(apiRequestBodyAsJson).build();
|
||||
|
||||
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
||||
|
||||
return this.toApiJsonSerializer.serialize(result);
|
||||
|
||||
}
|
||||
|
||||
@PUT
|
||||
@Path("{accountId}")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String updateSavingAccount(@PathParam("accountId") final Long accountId, final String apiRequestBodyAsJson) {
|
||||
|
||||
final CommandWrapper commandRequest = new CommandWrapperBuilder().updateSavingAccount(accountId).withJson(apiRequestBodyAsJson)
|
||||
.build();
|
||||
|
||||
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
||||
|
||||
return this.toApiJsonSerializer.serialize(result);
|
||||
}
|
||||
|
||||
@GET
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String retrieveAllDepositAccounts(@Context final UriInfo uriInfo) {
|
||||
|
||||
context.authenticatedUser().validateHasReadPermission(entityType);
|
||||
|
||||
Collection<SavingAccountData> accounts = this.savingAccountReadPlatformService.retrieveAllSavingsAccounts();
|
||||
|
||||
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
||||
|
||||
return this.toApiJsonSerializer.serialize(settings, accounts, SAVINGS_ACCOUNTS_DATA_PARAMETERS);
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("{accountId}")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String retrieveDepositAccount(@PathParam("accountId") final Long accountId, @Context final UriInfo uriInfo) {
|
||||
|
||||
context.authenticatedUser().validateHasReadPermission(entityType);
|
||||
|
||||
SavingPermissionData permissions = null;
|
||||
SavingScheduleData savingScheduleData = null;
|
||||
Collection<SavingAccountTransactionsData> transactions = null;
|
||||
|
||||
SavingAccountData account = this.savingAccountReadPlatformService.retrieveSavingsAccount(accountId);
|
||||
|
||||
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
||||
|
||||
if (settings.isTemplate()) {
|
||||
account = handleTemplateRelatedData(account);
|
||||
}
|
||||
|
||||
Set<String> associationParameters = ApiParameterHelper.extractAssociationsForResponseIfProvided(uriInfo.getQueryParameters());
|
||||
if (!associationParameters.isEmpty()) {
|
||||
if (associationParameters.contains("all")) {
|
||||
associationParameters.addAll(Arrays.asList("savingScheduleData", "transactions"));
|
||||
}
|
||||
|
||||
if (associationParameters.contains("savingScheduleData")) {
|
||||
CurrencyData currencyData = account.getCurrencyData();
|
||||
savingScheduleData = this.savingAccountReadPlatformService.retrieveSavingsAccountSchedule(accountId, currencyData);
|
||||
account = new SavingAccountData(account, savingScheduleData);
|
||||
}
|
||||
if (associationParameters.contains("transactions")) {
|
||||
transactions = this.savingAccountReadPlatformService.retrieveSavingsAccountTransactions(accountId);
|
||||
account = new SavingAccountData(account, transactions);
|
||||
}
|
||||
permissions = this.savingAccountReadPlatformService.retrieveSavingAccountPermissions(account);
|
||||
account = new SavingAccountData(account, permissions);
|
||||
}
|
||||
|
||||
return this.toApiJsonSerializer.serialize(settings, account, SAVINGS_ACCOUNTS_DATA_PARAMETERS);
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("template")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String retrieveNewDepositAccountDetails(@QueryParam("clientId") final Long clientId,
|
||||
@QueryParam("productId") final Long productId, @Context final UriInfo uriInfo) {
|
||||
|
||||
context.authenticatedUser().validateHasReadPermission(entityType);
|
||||
|
||||
SavingAccountData account = this.savingAccountReadPlatformService.retrieveNewSavingsAccountDetails(clientId, productId);
|
||||
account = handleTemplateRelatedData(account);
|
||||
|
||||
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
||||
return this.toApiJsonSerializer.serialize(settings, account, SAVINGS_ACCOUNTS_DATA_PARAMETERS);
|
||||
}
|
||||
|
||||
private SavingAccountData handleTemplateRelatedData(final SavingAccountData account) {
|
||||
|
||||
Collection<SavingProductLookup> productOptions = savingProductReadPlatformService.retrieveAllSavingProductsForLookup();
|
||||
Collection<CurrencyData> currencyOptions = this.currencyReadPlatformService.retrieveAllowedCurrencies();
|
||||
|
||||
EnumOptionData recurring = SavingProductEnumerations.savingProductType(SavingProductType.RECURRING);
|
||||
EnumOptionData regular = SavingProductEnumerations.savingProductType(SavingProductType.REGULAR);
|
||||
List<EnumOptionData> savingsProductTypeOptions = Arrays.asList(recurring, regular);
|
||||
|
||||
EnumOptionData fixed = SavingProductEnumerations.tenureTypeEnum(TenureTypeEnum.FIXED_PERIOD);
|
||||
EnumOptionData perpetual = SavingProductEnumerations.tenureTypeEnum(TenureTypeEnum.PERPETUAL);
|
||||
List<EnumOptionData> tenureTypeOptions = Arrays.asList(fixed, perpetual);
|
||||
|
||||
EnumOptionData monthly = SavingProductEnumerations.interestFrequencyType(SavingFrequencyType.MONTHLY);
|
||||
List<EnumOptionData> savingFrequencyOptions = Arrays.asList(monthly);
|
||||
|
||||
EnumOptionData simple = SavingProductEnumerations.savingInterestType(SavingsInterestType.SIMPLE);
|
||||
EnumOptionData compounding = SavingProductEnumerations.savingInterestType(SavingsInterestType.COMPOUNDING);
|
||||
List<EnumOptionData> savingsInterestTypeOptions = Arrays.asList(simple, compounding);
|
||||
|
||||
EnumOptionData months = SavingProductEnumerations.savingsLockinPeriod(SavingsLockinPeriodEnum.MONTHS);
|
||||
List<EnumOptionData> lockinPeriodTypeOptions = Arrays.asList(months);
|
||||
|
||||
EnumOptionData averagebal = SavingProductEnumerations.savingInterestCalculationMethod(SavingInterestCalculationMethod.AVERAGEBAL);
|
||||
// EnumOptionData minbal =
|
||||
// SavingProductEnumerations.savingInterestCalculationMethod(SavingInterestCalculationMethod.MINBAL);
|
||||
EnumOptionData monthlyCollection = SavingProductEnumerations
|
||||
.savingInterestCalculationMethod(SavingInterestCalculationMethod.MONTHLYCOLLECTION);
|
||||
List<EnumOptionData> interestCalculationOptions = Arrays.asList(averagebal, monthlyCollection);
|
||||
BigDecimal dueAmount = this.savingAccountReadPlatformService.deriveSavingDueAmount(account);
|
||||
return new SavingAccountData(account, productOptions, currencyOptions, savingsProductTypeOptions, tenureTypeOptions,
|
||||
savingFrequencyOptions, savingsInterestTypeOptions, lockinPeriodTypeOptions, interestCalculationOptions, dueAmount);
|
||||
}
|
||||
|
||||
private boolean is(final String commandParam, final String commandValue) {
|
||||
return StringUtils.isNotBlank(commandParam) && commandParam.trim().equalsIgnoreCase(commandValue);
|
||||
}
|
||||
|
||||
@POST
|
||||
@Path("{accountId}")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String savingStateTransitions(@PathParam("accountId") final Long accountId, @QueryParam("command") final String commandParam,
|
||||
final String apiRequestBodyAsJson) {
|
||||
|
||||
CommandWrapperBuilder builder = new CommandWrapperBuilder().withJson(apiRequestBodyAsJson);
|
||||
CommandProcessingResult result = null;
|
||||
|
||||
if (is(commandParam, "approve")) {
|
||||
final CommandWrapper commandRequest = builder.approveSavingAccountApplication(accountId).build();
|
||||
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
||||
} else if (is(commandParam, "depositmoney")) {
|
||||
final CommandWrapper commandRequest = builder.depositOfSavingAmount(accountId).build();
|
||||
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
||||
} else if (is(commandParam, "withdraw")) {
|
||||
final CommandWrapper commandRequest = builder.withdrawSavingAmount(accountId).build();
|
||||
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
||||
} else if (is(commandParam, "reject")) {
|
||||
final CommandWrapper commandRequest = builder.rejectSavingApplication(accountId).build();
|
||||
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
||||
} else if (is(commandParam, "withdrewbyclient")) {
|
||||
final CommandWrapper commandRequest = builder.withdrawSavingApplication(accountId).build();
|
||||
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
||||
} else if (is(commandParam, "undoapproval")) {
|
||||
final CommandWrapper commandRequest = builder.undoApprovalOfSavingApplication(accountId).build();
|
||||
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
||||
} else {
|
||||
throw new UnrecognizedQueryParamException("command", commandParam);
|
||||
}
|
||||
|
||||
return this.toApiJsonSerializer.serialize(result);
|
||||
}
|
||||
|
||||
@DELETE
|
||||
@Path("{accountId}")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String deleteSavingAccount(@PathParam("accountId") final Long accountId) {
|
||||
|
||||
final CommandWrapper commandRequest = new CommandWrapperBuilder().deleteSavingAccount(accountId).build();
|
||||
|
||||
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
||||
|
||||
return this.toApiJsonSerializer.serialize(result);
|
||||
|
||||
}
|
||||
|
||||
@POST
|
||||
@Path("postinterest")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String postInterest() {
|
||||
|
||||
Collection<SavingAccountForLookup> savingAccounts = this.savingAccountReadPlatformService.retrieveSavingAccountsForLookUp();
|
||||
CommandProcessingResult entityIdentifier = this.savingAccountWritePlatformService.postInterest(savingAccounts);
|
||||
return this.toApiJsonSerializer.serialize(entityIdentifier);
|
||||
}
|
||||
|
||||
}
|
||||
-511
@@ -1,511 +0,0 @@
|
||||
/**
|
||||
* 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.portfolio.savingsaccount.data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.joda.time.LocalDate;
|
||||
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
|
||||
import org.mifosplatform.organisation.monetary.data.CurrencyData;
|
||||
import org.mifosplatform.portfolio.savingsaccountproduct.data.SavingProductLookup;
|
||||
|
||||
/**
|
||||
* Immutable data object representing a savings account.
|
||||
*/
|
||||
public class SavingAccountData {
|
||||
|
||||
private final Long id;
|
||||
private final EnumOptionData status;
|
||||
private final String externalId;
|
||||
private final Long clientId;
|
||||
private final String clientName;
|
||||
private final Long productId;
|
||||
private final String productName;
|
||||
private final EnumOptionData productType;
|
||||
private final CurrencyData currencyData;
|
||||
private final BigDecimal savingsDepositAmountPerPeriod;
|
||||
private final EnumOptionData savingsFrequencyType;
|
||||
private final BigDecimal totalDepositAmount;
|
||||
private final BigDecimal recurringInterestRate;
|
||||
private final BigDecimal savingInterestRate;
|
||||
private final EnumOptionData interestType;
|
||||
private final EnumOptionData interestCalculationMethod;
|
||||
private final Integer tenure;
|
||||
private final EnumOptionData tenureType;
|
||||
private final LocalDate projectedCommencementDate;
|
||||
private final LocalDate actualCommencementDate;
|
||||
private final LocalDate maturesOnDate;
|
||||
private final BigDecimal projectedInterestAccuredOnMaturity;
|
||||
private final BigDecimal actualInterestAccured;
|
||||
private final BigDecimal projectedMaturityAmount;
|
||||
private final BigDecimal actualMaturityAmount;
|
||||
private final boolean preClosureAllowed;
|
||||
private final BigDecimal preClosureInterestRate;
|
||||
private final LocalDate withdrawnonDate;
|
||||
private final LocalDate rejectedonDate;
|
||||
private final LocalDate closedonDate;
|
||||
private final boolean isLockinPeriodAllowed;
|
||||
private final Integer lockinPeriod;
|
||||
private final EnumOptionData lockinPeriodType;
|
||||
private final Integer depositEvery;
|
||||
|
||||
private final List<SavingProductLookup> productOptions;
|
||||
private final Collection<CurrencyData> currencyOptions;
|
||||
private final List<EnumOptionData> savingsProductTypeOptions;
|
||||
private final List<EnumOptionData> tenureTypeOptions;
|
||||
private final List<EnumOptionData> savingFrequencyOptions;
|
||||
private final List<EnumOptionData> savingsInterestTypeOptions;
|
||||
private final List<EnumOptionData> lockinPeriodTypeOptions;
|
||||
private final List<EnumOptionData> interestCalculationOptions;
|
||||
|
||||
private final Collection<SavingScheduleData> savingScheduleDatas;
|
||||
private final SavingPermissionData permissions;
|
||||
private final BigDecimal outstandingAmount;
|
||||
private final BigDecimal dueAmount;
|
||||
private final SavingScheduleData savingScheduleData;
|
||||
private final Collection<SavingAccountTransactionsData> transactions;
|
||||
|
||||
private final Integer interestPostEvery;
|
||||
private final EnumOptionData interestPostFrequency;
|
||||
|
||||
public static SavingAccountData createFrom(final Long clientId, final String clientDisplayName) {
|
||||
return new SavingAccountData(clientId, clientDisplayName);
|
||||
}
|
||||
|
||||
public SavingAccountData(final Long id, final EnumOptionData status, final String externalId, final Long clientId,
|
||||
final String clientName, final Long productId, final String productName, final EnumOptionData productType,
|
||||
final CurrencyData currencyData, final BigDecimal savingsDepositAmountPerPeriod, final EnumOptionData savingsFrequencyType,
|
||||
final BigDecimal totalDepositAmount, final BigDecimal recurringInterestRate, final BigDecimal savingInterestRate,
|
||||
final EnumOptionData interestType, final EnumOptionData interestCalculationMethod, final Integer tenure,
|
||||
final EnumOptionData tenureType, final LocalDate projectedCommencementDate, final LocalDate actualCommencementDate,
|
||||
final LocalDate maturesOnDate, final BigDecimal projectedInterestAccuredOnMaturity, final BigDecimal actualInterestAccured,
|
||||
final BigDecimal projectedMaturityAmount, final BigDecimal actualMaturityAmount, final boolean preClosureAllowed,
|
||||
final BigDecimal preClosureInterestRate, final LocalDate withdrawnonDate, final LocalDate rejectedonDate,
|
||||
final LocalDate closedonDate, final boolean isLockinPeriodAllowed, final Integer lockinPeriod,
|
||||
final EnumOptionData lockinPeriodType, final Integer depositEvery, final BigDecimal outstandingAmount,
|
||||
final Integer interestPostEvery, final EnumOptionData interestPostFrequency) {
|
||||
this.id = id;
|
||||
this.status = status;
|
||||
this.externalId = externalId;
|
||||
this.clientId = clientId;
|
||||
this.clientName = clientName;
|
||||
this.productId = productId;
|
||||
this.productName = productName;
|
||||
this.productType = productType;
|
||||
this.currencyData = currencyData;
|
||||
this.savingsDepositAmountPerPeriod = savingsDepositAmountPerPeriod;
|
||||
this.savingsFrequencyType = savingsFrequencyType;
|
||||
this.totalDepositAmount = totalDepositAmount;
|
||||
this.recurringInterestRate = recurringInterestRate;
|
||||
this.savingInterestRate = savingInterestRate;
|
||||
this.interestType = interestType;
|
||||
this.interestCalculationMethod = interestCalculationMethod;
|
||||
this.tenure = tenure;
|
||||
this.tenureType = tenureType;
|
||||
this.projectedCommencementDate = projectedCommencementDate;
|
||||
this.actualCommencementDate = actualCommencementDate;
|
||||
this.maturesOnDate = maturesOnDate;
|
||||
this.projectedInterestAccuredOnMaturity = projectedInterestAccuredOnMaturity;
|
||||
this.actualInterestAccured = actualInterestAccured;
|
||||
this.projectedMaturityAmount = projectedMaturityAmount;
|
||||
this.actualMaturityAmount = actualMaturityAmount;
|
||||
this.preClosureAllowed = preClosureAllowed;
|
||||
this.preClosureInterestRate = preClosureInterestRate;
|
||||
this.withdrawnonDate = withdrawnonDate;
|
||||
this.rejectedonDate = rejectedonDate;
|
||||
this.closedonDate = closedonDate;
|
||||
this.isLockinPeriodAllowed = isLockinPeriodAllowed;
|
||||
this.lockinPeriod = lockinPeriod;
|
||||
this.lockinPeriodType = lockinPeriodType;
|
||||
this.depositEvery = depositEvery;
|
||||
this.productOptions = new ArrayList<SavingProductLookup>();
|
||||
this.currencyOptions = null;
|
||||
this.savingsProductTypeOptions = null;
|
||||
this.tenureTypeOptions = null;
|
||||
this.savingFrequencyOptions = null;
|
||||
this.savingsInterestTypeOptions = null;
|
||||
this.lockinPeriodTypeOptions = null;
|
||||
this.interestCalculationOptions = null;
|
||||
this.savingScheduleDatas = null;
|
||||
this.permissions = null;
|
||||
this.outstandingAmount = outstandingAmount;
|
||||
this.dueAmount = BigDecimal.ZERO;
|
||||
this.savingScheduleData = null;
|
||||
this.transactions = null;
|
||||
this.interestPostEvery = interestPostEvery;
|
||||
this.interestPostFrequency = interestPostFrequency;
|
||||
}
|
||||
|
||||
public SavingAccountData(final Long clientId, final String clientName) {
|
||||
this.id = null;
|
||||
this.status = null;
|
||||
this.externalId = null;
|
||||
this.clientId = clientId;
|
||||
this.clientName = clientName;
|
||||
this.productId = null;
|
||||
this.productName = null;
|
||||
this.productType = null;
|
||||
this.currencyData = new CurrencyData("USD", "US Dollar", 2, "$", "currency.USD");
|
||||
this.savingsDepositAmountPerPeriod = null;
|
||||
this.savingsFrequencyType = null;
|
||||
this.totalDepositAmount = null;
|
||||
this.recurringInterestRate = null;
|
||||
this.savingInterestRate = null;
|
||||
this.interestType = null;
|
||||
this.interestCalculationMethod = null;
|
||||
this.tenure = null;
|
||||
this.tenureType = null;
|
||||
this.projectedCommencementDate = null;
|
||||
this.actualCommencementDate = null;
|
||||
this.maturesOnDate = null;
|
||||
this.projectedInterestAccuredOnMaturity = null;
|
||||
this.actualInterestAccured = null;
|
||||
this.projectedMaturityAmount = null;
|
||||
this.actualMaturityAmount = null;
|
||||
this.preClosureAllowed = false;
|
||||
this.preClosureInterestRate = null;
|
||||
this.withdrawnonDate = null;
|
||||
this.rejectedonDate = null;
|
||||
this.closedonDate = null;
|
||||
this.isLockinPeriodAllowed = false;
|
||||
this.lockinPeriod = null;
|
||||
this.lockinPeriodType = null;
|
||||
this.depositEvery = null;
|
||||
this.productOptions = new ArrayList<SavingProductLookup>();
|
||||
this.currencyOptions = null;
|
||||
this.savingsProductTypeOptions = null;
|
||||
this.tenureTypeOptions = null;
|
||||
this.savingFrequencyOptions = null;
|
||||
this.savingsInterestTypeOptions = null;
|
||||
this.lockinPeriodTypeOptions = null;
|
||||
this.interestCalculationOptions = null;
|
||||
this.savingScheduleDatas = null;
|
||||
this.permissions = null;
|
||||
this.outstandingAmount = BigDecimal.ZERO;
|
||||
this.dueAmount = BigDecimal.ZERO;
|
||||
this.savingScheduleData = null;
|
||||
this.transactions = null;
|
||||
this.interestPostEvery = null;
|
||||
this.interestPostFrequency = null;
|
||||
}
|
||||
|
||||
public SavingAccountData(final SavingAccountData account, final Collection<SavingProductLookup> productOptions,
|
||||
final Collection<CurrencyData> currencyOptions, final List<EnumOptionData> savingsProductTypeOptions,
|
||||
final List<EnumOptionData> tenureTypeOptions, final List<EnumOptionData> savingFrequencyOptions,
|
||||
final List<EnumOptionData> savingsInterestTypeOptions, final List<EnumOptionData> lockinPeriodTypeOptions,
|
||||
final List<EnumOptionData> interestCalculationOptions, final BigDecimal dueAmount) {
|
||||
this.id = account.id;
|
||||
this.status = account.status;
|
||||
this.externalId = account.externalId;
|
||||
this.clientId = account.clientId;
|
||||
this.clientName = account.clientName;
|
||||
this.productId = account.productId;
|
||||
this.productName = account.productName;
|
||||
this.productType = account.productType;
|
||||
this.currencyData = account.currencyData;
|
||||
this.savingsDepositAmountPerPeriod = account.savingsDepositAmountPerPeriod;
|
||||
this.savingsFrequencyType = account.savingsFrequencyType;
|
||||
this.totalDepositAmount = account.totalDepositAmount;
|
||||
this.recurringInterestRate = account.recurringInterestRate;
|
||||
this.savingInterestRate = account.savingInterestRate;
|
||||
this.interestType = account.interestType;
|
||||
this.interestCalculationMethod = account.interestCalculationMethod;
|
||||
this.tenure = account.tenure;
|
||||
this.tenureType = account.tenureType;
|
||||
this.projectedCommencementDate = account.projectedCommencementDate;
|
||||
this.actualCommencementDate = account.actualCommencementDate;
|
||||
this.maturesOnDate = account.maturesOnDate;
|
||||
this.projectedInterestAccuredOnMaturity = account.projectedInterestAccuredOnMaturity;
|
||||
this.actualInterestAccured = account.actualInterestAccured;
|
||||
this.projectedMaturityAmount = account.projectedMaturityAmount;
|
||||
this.actualMaturityAmount = account.actualMaturityAmount;
|
||||
this.preClosureAllowed = account.preClosureAllowed;
|
||||
this.preClosureInterestRate = account.preClosureInterestRate;
|
||||
this.withdrawnonDate = account.withdrawnonDate;
|
||||
this.rejectedonDate = account.rejectedonDate;
|
||||
this.closedonDate = account.closedonDate;
|
||||
this.isLockinPeriodAllowed = account.isLockinPeriodAllowed;
|
||||
this.lockinPeriod = account.lockinPeriod;
|
||||
this.lockinPeriodType = account.lockinPeriodType;
|
||||
this.depositEvery = account.depositEvery;
|
||||
|
||||
this.productOptions = (List<SavingProductLookup>) productOptions;
|
||||
this.currencyOptions = currencyOptions;
|
||||
this.savingsProductTypeOptions = savingsProductTypeOptions;
|
||||
this.tenureTypeOptions = tenureTypeOptions;
|
||||
this.savingFrequencyOptions = savingFrequencyOptions;
|
||||
this.savingsInterestTypeOptions = savingsInterestTypeOptions;
|
||||
this.lockinPeriodTypeOptions = lockinPeriodTypeOptions;
|
||||
this.interestCalculationOptions = interestCalculationOptions;
|
||||
this.dueAmount = dueAmount;
|
||||
|
||||
this.savingScheduleDatas = account.savingScheduleDatas;
|
||||
this.permissions = account.permissions;
|
||||
this.outstandingAmount = account.outstandingAmount;
|
||||
this.savingScheduleData = account.savingScheduleData;
|
||||
this.transactions = account.transactions;
|
||||
this.interestPostEvery = account.interestPostEvery;
|
||||
this.interestPostFrequency = account.interestPostFrequency;
|
||||
}
|
||||
|
||||
public SavingAccountData(final Long clientId, final String clientName, final Long productId, final String productName,
|
||||
final CurrencyData currency, final BigDecimal interestRate, final BigDecimal savingsDepositAmountPerPeriod,
|
||||
final EnumOptionData productType, final EnumOptionData tenureType, final Integer tenure,
|
||||
final EnumOptionData savingsFrequencyType, final EnumOptionData interestType, final EnumOptionData interestCalculationMethod,
|
||||
final boolean lockinPeriodAllowed, final Integer lockinPeriod, final EnumOptionData lockinPeriodType, final Integer depositEvery) {
|
||||
this.id = null;
|
||||
this.status = null;
|
||||
this.externalId = null;
|
||||
this.clientId = clientId;
|
||||
this.clientName = clientName;
|
||||
this.productId = productId;
|
||||
this.productName = productName;
|
||||
this.productType = productType;
|
||||
this.currencyData = currency;
|
||||
this.savingsDepositAmountPerPeriod = savingsDepositAmountPerPeriod;
|
||||
this.savingsFrequencyType = savingsFrequencyType;
|
||||
this.totalDepositAmount = null;
|
||||
this.recurringInterestRate = interestRate;
|
||||
this.savingInterestRate = interestRate;
|
||||
this.interestType = interestType;
|
||||
this.interestCalculationMethod = interestCalculationMethod;
|
||||
this.tenure = tenure;
|
||||
this.tenureType = tenureType;
|
||||
this.projectedCommencementDate = new LocalDate();
|
||||
this.actualCommencementDate = null;
|
||||
this.maturesOnDate = null;
|
||||
this.projectedInterestAccuredOnMaturity = null;
|
||||
this.actualInterestAccured = null;
|
||||
this.projectedMaturityAmount = null;
|
||||
this.actualMaturityAmount = null;
|
||||
this.preClosureAllowed = true;
|
||||
this.preClosureInterestRate = null;
|
||||
this.withdrawnonDate = null;
|
||||
this.rejectedonDate = null;
|
||||
this.closedonDate = null;
|
||||
this.isLockinPeriodAllowed = lockinPeriodAllowed;
|
||||
this.lockinPeriod = lockinPeriod;
|
||||
this.lockinPeriodType = lockinPeriodType;
|
||||
this.depositEvery = depositEvery;
|
||||
this.productOptions = null;
|
||||
this.currencyOptions = null;
|
||||
this.savingsProductTypeOptions = null;
|
||||
this.tenureTypeOptions = null;
|
||||
this.savingFrequencyOptions = null;
|
||||
this.savingsInterestTypeOptions = null;
|
||||
this.lockinPeriodTypeOptions = null;
|
||||
this.interestCalculationOptions = null;
|
||||
this.savingScheduleDatas = null;
|
||||
this.permissions = null;
|
||||
this.outstandingAmount = BigDecimal.ZERO;
|
||||
this.dueAmount = BigDecimal.ZERO;
|
||||
this.savingScheduleData = null;
|
||||
this.transactions = null;
|
||||
this.interestPostEvery = 3;
|
||||
this.interestPostFrequency = savingsFrequencyType;
|
||||
}
|
||||
|
||||
public SavingAccountData(final SavingAccountData account, final SavingPermissionData permissions) {
|
||||
this.id = account.id;
|
||||
this.status = account.status;
|
||||
this.externalId = account.externalId;
|
||||
this.clientId = account.clientId;
|
||||
this.clientName = account.clientName;
|
||||
this.productId = account.productId;
|
||||
this.productName = account.productName;
|
||||
this.productType = account.productType;
|
||||
this.currencyData = account.currencyData;
|
||||
this.savingsDepositAmountPerPeriod = account.savingsDepositAmountPerPeriod;
|
||||
this.savingsFrequencyType = account.savingsFrequencyType;
|
||||
this.totalDepositAmount = account.totalDepositAmount;
|
||||
this.recurringInterestRate = account.recurringInterestRate;
|
||||
this.savingInterestRate = account.savingInterestRate;
|
||||
this.interestType = account.interestType;
|
||||
this.interestCalculationMethod = account.interestCalculationMethod;
|
||||
this.tenure = account.tenure;
|
||||
this.tenureType = account.tenureType;
|
||||
this.projectedCommencementDate = account.projectedCommencementDate;
|
||||
this.actualCommencementDate = account.actualCommencementDate;
|
||||
this.maturesOnDate = account.maturesOnDate;
|
||||
this.projectedInterestAccuredOnMaturity = account.projectedInterestAccuredOnMaturity;
|
||||
this.actualInterestAccured = account.actualInterestAccured;
|
||||
this.projectedMaturityAmount = account.projectedMaturityAmount;
|
||||
this.actualMaturityAmount = account.actualMaturityAmount;
|
||||
this.preClosureAllowed = account.preClosureAllowed;
|
||||
this.preClosureInterestRate = account.preClosureInterestRate;
|
||||
this.withdrawnonDate = account.withdrawnonDate;
|
||||
this.rejectedonDate = account.rejectedonDate;
|
||||
this.closedonDate = account.closedonDate;
|
||||
this.isLockinPeriodAllowed = account.isLockinPeriodAllowed;
|
||||
this.lockinPeriod = account.lockinPeriod;
|
||||
this.lockinPeriodType = account.lockinPeriodType;
|
||||
this.depositEvery = account.depositEvery;
|
||||
|
||||
this.productOptions = account.productOptions;
|
||||
this.currencyOptions = account.currencyOptions;
|
||||
this.savingsProductTypeOptions = account.savingsProductTypeOptions;
|
||||
this.tenureTypeOptions = account.tenureTypeOptions;
|
||||
this.savingFrequencyOptions = account.savingFrequencyOptions;
|
||||
this.savingsInterestTypeOptions = account.savingsInterestTypeOptions;
|
||||
this.lockinPeriodTypeOptions = account.lockinPeriodTypeOptions;
|
||||
this.interestCalculationOptions = account.interestCalculationOptions;
|
||||
this.savingScheduleDatas = account.savingScheduleDatas;
|
||||
this.permissions = permissions;
|
||||
this.outstandingAmount = account.outstandingAmount;
|
||||
this.dueAmount = account.dueAmount;
|
||||
this.savingScheduleData = account.savingScheduleData;
|
||||
this.transactions = account.transactions;
|
||||
this.interestPostEvery = account.interestPostEvery;
|
||||
this.interestPostFrequency = account.interestPostFrequency;
|
||||
}
|
||||
|
||||
public SavingAccountData(final SavingAccountData account, final SavingScheduleData savingScheduleData) {
|
||||
this.id = account.id;
|
||||
this.status = account.status;
|
||||
this.externalId = account.externalId;
|
||||
this.clientId = account.clientId;
|
||||
this.clientName = account.clientName;
|
||||
this.productId = account.productId;
|
||||
this.productName = account.productName;
|
||||
this.productType = account.productType;
|
||||
this.currencyData = account.currencyData;
|
||||
this.savingsDepositAmountPerPeriod = account.savingsDepositAmountPerPeriod;
|
||||
this.savingsFrequencyType = account.savingsFrequencyType;
|
||||
this.totalDepositAmount = account.totalDepositAmount;
|
||||
this.recurringInterestRate = account.recurringInterestRate;
|
||||
this.savingInterestRate = account.savingInterestRate;
|
||||
this.interestType = account.interestType;
|
||||
this.interestCalculationMethod = account.interestCalculationMethod;
|
||||
this.tenure = account.tenure;
|
||||
this.tenureType = account.tenureType;
|
||||
this.projectedCommencementDate = account.projectedCommencementDate;
|
||||
this.actualCommencementDate = account.actualCommencementDate;
|
||||
this.maturesOnDate = account.maturesOnDate;
|
||||
this.projectedInterestAccuredOnMaturity = account.projectedInterestAccuredOnMaturity;
|
||||
this.actualInterestAccured = account.actualInterestAccured;
|
||||
this.projectedMaturityAmount = account.projectedMaturityAmount;
|
||||
this.actualMaturityAmount = account.actualMaturityAmount;
|
||||
this.preClosureAllowed = account.preClosureAllowed;
|
||||
this.preClosureInterestRate = account.preClosureInterestRate;
|
||||
this.withdrawnonDate = account.withdrawnonDate;
|
||||
this.rejectedonDate = account.rejectedonDate;
|
||||
this.closedonDate = account.closedonDate;
|
||||
this.isLockinPeriodAllowed = account.isLockinPeriodAllowed;
|
||||
this.lockinPeriod = account.lockinPeriod;
|
||||
this.lockinPeriodType = account.lockinPeriodType;
|
||||
this.depositEvery = account.depositEvery;
|
||||
|
||||
this.productOptions = account.productOptions;
|
||||
this.currencyOptions = account.currencyOptions;
|
||||
this.savingsProductTypeOptions = account.savingsProductTypeOptions;
|
||||
this.tenureTypeOptions = account.tenureTypeOptions;
|
||||
this.savingFrequencyOptions = account.savingFrequencyOptions;
|
||||
this.savingsInterestTypeOptions = account.savingsInterestTypeOptions;
|
||||
this.lockinPeriodTypeOptions = account.lockinPeriodTypeOptions;
|
||||
this.interestCalculationOptions = account.interestCalculationOptions;
|
||||
this.savingScheduleDatas = account.savingScheduleDatas;
|
||||
this.permissions = account.permissions;
|
||||
this.outstandingAmount = account.outstandingAmount;
|
||||
this.dueAmount = account.dueAmount;
|
||||
this.savingScheduleData = savingScheduleData;
|
||||
this.transactions = account.transactions;
|
||||
this.interestPostEvery = account.interestPostEvery;
|
||||
this.interestPostFrequency = account.interestPostFrequency;
|
||||
}
|
||||
|
||||
public SavingAccountData(final SavingAccountData account, final Collection<SavingAccountTransactionsData> transactions) {
|
||||
this.id = account.id;
|
||||
this.status = account.status;
|
||||
this.externalId = account.externalId;
|
||||
this.clientId = account.clientId;
|
||||
this.clientName = account.clientName;
|
||||
this.productId = account.productId;
|
||||
this.productName = account.productName;
|
||||
this.productType = account.productType;
|
||||
this.currencyData = account.currencyData;
|
||||
this.savingsDepositAmountPerPeriod = account.savingsDepositAmountPerPeriod;
|
||||
this.savingsFrequencyType = account.savingsFrequencyType;
|
||||
this.totalDepositAmount = account.totalDepositAmount;
|
||||
this.recurringInterestRate = account.recurringInterestRate;
|
||||
this.savingInterestRate = account.savingInterestRate;
|
||||
this.interestType = account.interestType;
|
||||
this.interestCalculationMethod = account.interestCalculationMethod;
|
||||
this.tenure = account.tenure;
|
||||
this.tenureType = account.tenureType;
|
||||
this.projectedCommencementDate = account.projectedCommencementDate;
|
||||
this.actualCommencementDate = account.actualCommencementDate;
|
||||
this.maturesOnDate = account.maturesOnDate;
|
||||
this.projectedInterestAccuredOnMaturity = account.projectedInterestAccuredOnMaturity;
|
||||
this.actualInterestAccured = account.actualInterestAccured;
|
||||
this.projectedMaturityAmount = account.projectedMaturityAmount;
|
||||
this.actualMaturityAmount = account.actualMaturityAmount;
|
||||
this.preClosureAllowed = account.preClosureAllowed;
|
||||
this.preClosureInterestRate = account.preClosureInterestRate;
|
||||
this.withdrawnonDate = account.withdrawnonDate;
|
||||
this.rejectedonDate = account.rejectedonDate;
|
||||
this.closedonDate = account.closedonDate;
|
||||
this.isLockinPeriodAllowed = account.isLockinPeriodAllowed;
|
||||
this.lockinPeriod = account.lockinPeriod;
|
||||
this.lockinPeriodType = account.lockinPeriodType;
|
||||
this.depositEvery = account.depositEvery;
|
||||
|
||||
this.productOptions = account.productOptions;
|
||||
this.currencyOptions = account.currencyOptions;
|
||||
this.savingsProductTypeOptions = account.savingsProductTypeOptions;
|
||||
this.tenureTypeOptions = account.tenureTypeOptions;
|
||||
this.savingFrequencyOptions = account.savingFrequencyOptions;
|
||||
this.savingsInterestTypeOptions = account.savingsInterestTypeOptions;
|
||||
this.lockinPeriodTypeOptions = account.lockinPeriodTypeOptions;
|
||||
this.interestCalculationOptions = account.interestCalculationOptions;
|
||||
this.savingScheduleDatas = account.savingScheduleDatas;
|
||||
this.permissions = account.permissions;
|
||||
this.outstandingAmount = account.outstandingAmount;
|
||||
this.dueAmount = account.dueAmount;
|
||||
this.savingScheduleData = account.savingScheduleData;
|
||||
this.transactions = transactions;
|
||||
this.interestPostEvery = account.interestPostEvery;
|
||||
this.interestPostFrequency = account.interestPostFrequency;
|
||||
}
|
||||
|
||||
public EnumOptionData getStatus() {
|
||||
return this.status;
|
||||
}
|
||||
|
||||
public CurrencyData getCurrencyData() {
|
||||
return this.currencyData;
|
||||
}
|
||||
|
||||
public BigDecimal getSavingsDepostiAmountPerPeriod() {
|
||||
return this.savingsDepositAmountPerPeriod;
|
||||
}
|
||||
|
||||
public Integer getTenure() {
|
||||
return this.tenure;
|
||||
}
|
||||
|
||||
public EnumOptionData getTenureType() {
|
||||
return this.tenureType;
|
||||
}
|
||||
|
||||
public LocalDate getActualCommencementDate() {
|
||||
return this.actualCommencementDate;
|
||||
}
|
||||
|
||||
public LocalDate getMaturesOnDate() {
|
||||
return this.maturesOnDate;
|
||||
}
|
||||
|
||||
public Integer getDepositEvery() {
|
||||
return this.depositEvery;
|
||||
}
|
||||
|
||||
public BigDecimal getOutstandingAmount() {
|
||||
return this.outstandingAmount;
|
||||
}
|
||||
}
|
||||
-20
@@ -1,20 +0,0 @@
|
||||
/**
|
||||
* 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.portfolio.savingsaccount.data;
|
||||
|
||||
public class SavingAccountForLookup {
|
||||
|
||||
private final Long id;
|
||||
|
||||
public SavingAccountForLookup(final Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
}
|
||||
-38
@@ -1,38 +0,0 @@
|
||||
/**
|
||||
* 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.portfolio.savingsaccount.data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import org.joda.time.LocalDate;
|
||||
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
|
||||
|
||||
public class SavingAccountTransactionsData {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private final Long id;
|
||||
@SuppressWarnings("unused")
|
||||
private final LocalDate transactionDate;
|
||||
@SuppressWarnings("unused")
|
||||
private final EnumOptionData transactionType;
|
||||
@SuppressWarnings("unused")
|
||||
private final BigDecimal amount;
|
||||
|
||||
public SavingAccountTransactionsData() {
|
||||
this.id = null;
|
||||
this.transactionDate = null;
|
||||
this.transactionType = null;
|
||||
this.amount = BigDecimal.ZERO;
|
||||
}
|
||||
|
||||
public SavingAccountTransactionsData(final Long id, final LocalDate transactionDate, EnumOptionData transactionType, BigDecimal amount){
|
||||
this.id = id;
|
||||
this.transactionDate = transactionDate;
|
||||
this.transactionType = transactionType;
|
||||
this.amount = amount;
|
||||
}
|
||||
|
||||
}
|
||||
-62
@@ -1,62 +0,0 @@
|
||||
/**
|
||||
* 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.portfolio.savingsaccount.data;
|
||||
|
||||
public class SavingPermissionData {
|
||||
|
||||
|
||||
|
||||
private final boolean rejectAllowed;
|
||||
private final boolean withdrawnByApplicantAllowed;
|
||||
private final boolean undoApprovalAllowed;
|
||||
private final boolean pendingApproval;
|
||||
private final boolean renewelAllowed;
|
||||
private final boolean isMaturedDepositAccount;
|
||||
|
||||
private final boolean anyActionOnAccountAllowed;
|
||||
|
||||
public SavingPermissionData(final boolean rejectAllowed, final boolean withdrawnByApplicantAllowed, final boolean undoApprovalAllowed,
|
||||
final boolean pendingApproval, final boolean renewelAllowed, final boolean isMaturedDepositAccount) {
|
||||
this.rejectAllowed = rejectAllowed;
|
||||
this.withdrawnByApplicantAllowed = withdrawnByApplicantAllowed;
|
||||
this.undoApprovalAllowed = undoApprovalAllowed;
|
||||
this.pendingApproval = pendingApproval;
|
||||
this.renewelAllowed = renewelAllowed;
|
||||
this.isMaturedDepositAccount = isMaturedDepositAccount;
|
||||
this.anyActionOnAccountAllowed = isRejectAllowed() || isPendingApproval() || isUndoApprovalAllowed()
|
||||
|| isWithdrawnByApplicantAllowed() || isRenewelAllowed() || isMaturedDepositAccount();
|
||||
}
|
||||
|
||||
public boolean isRejectAllowed() {
|
||||
return rejectAllowed;
|
||||
}
|
||||
|
||||
public boolean isWithdrawnByApplicantAllowed() {
|
||||
return withdrawnByApplicantAllowed;
|
||||
}
|
||||
|
||||
public boolean isUndoApprovalAllowed() {
|
||||
return undoApprovalAllowed;
|
||||
}
|
||||
|
||||
public boolean isPendingApproval() {
|
||||
return pendingApproval;
|
||||
}
|
||||
|
||||
public boolean isAnyActionOnAccountAllowed() {
|
||||
return anyActionOnAccountAllowed;
|
||||
}
|
||||
|
||||
public boolean isRenewelAllowed() {
|
||||
return renewelAllowed;
|
||||
}
|
||||
|
||||
public boolean isMaturedDepositAccount() {
|
||||
return isMaturedDepositAccount;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
-51
@@ -1,51 +0,0 @@
|
||||
/**
|
||||
* 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.portfolio.savingsaccount.data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Collection;
|
||||
|
||||
import org.mifosplatform.organisation.monetary.data.CurrencyData;
|
||||
|
||||
public class SavingScheduleData {
|
||||
|
||||
private final CurrencyData currency;
|
||||
private final BigDecimal cumulativeDepositDue;
|
||||
private final BigDecimal cumulativeDepositPaid;
|
||||
private final BigDecimal cummulativeInterestAccured;
|
||||
private final Collection<SavingSchedulePeriodData> periods;
|
||||
|
||||
public SavingScheduleData(final CurrencyData currency, final BigDecimal cumulativeDepositDue, final BigDecimal cumulativeDepositPaid,
|
||||
final BigDecimal cummulativeInterestAccured, final Collection<SavingSchedulePeriodData> periods) {
|
||||
this.currency = currency;
|
||||
this.cumulativeDepositDue = cumulativeDepositDue;
|
||||
this.cumulativeDepositPaid = cumulativeDepositPaid;
|
||||
this.cummulativeInterestAccured = cummulativeInterestAccured;
|
||||
this.periods = periods;
|
||||
|
||||
}
|
||||
|
||||
public CurrencyData getCurrency() {
|
||||
return this.currency;
|
||||
}
|
||||
|
||||
public BigDecimal getCumulativeDepositDue() {
|
||||
return this.cumulativeDepositDue;
|
||||
}
|
||||
|
||||
public BigDecimal getCumulativeDepositPaid() {
|
||||
return this.cumulativeDepositPaid;
|
||||
}
|
||||
|
||||
public BigDecimal getCummulativeInterestAccured() {
|
||||
return this.cummulativeInterestAccured;
|
||||
}
|
||||
|
||||
public Collection<SavingSchedulePeriodData> getPeriods() {
|
||||
return this.periods;
|
||||
}
|
||||
|
||||
}
|
||||
-53
@@ -1,53 +0,0 @@
|
||||
/**
|
||||
* 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.portfolio.savingsaccount.data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import org.joda.time.LocalDate;
|
||||
|
||||
public class SavingSchedulePeriodData {
|
||||
|
||||
private final Integer period;
|
||||
private final LocalDate dueDate;
|
||||
private final BigDecimal depositDue;
|
||||
private final BigDecimal depositPaid;
|
||||
private final BigDecimal interestAccured;
|
||||
|
||||
public SavingSchedulePeriodData(final Integer period, final LocalDate dueDate, final BigDecimal depositDue, final BigDecimal depositPaid, final BigDecimal interestAccured) {
|
||||
this.period = period;
|
||||
this.dueDate = dueDate;
|
||||
this.depositDue = depositDue;
|
||||
this.depositPaid = depositPaid;
|
||||
this.interestAccured = interestAccured;
|
||||
}
|
||||
|
||||
public static SavingSchedulePeriodData addScheduleInformation(int periodNumber, LocalDate scheduleDate,
|
||||
BigDecimal depositAmountPerPeriod, BigDecimal interestAccured) {
|
||||
return new SavingSchedulePeriodData(periodNumber, scheduleDate, depositAmountPerPeriod, BigDecimal.ZERO, interestAccured);
|
||||
}
|
||||
|
||||
public Integer getPeriod() {
|
||||
return this.period;
|
||||
}
|
||||
|
||||
public LocalDate getDueDate() {
|
||||
return this.dueDate;
|
||||
}
|
||||
|
||||
public BigDecimal getDepositDue() {
|
||||
return this.depositDue;
|
||||
}
|
||||
|
||||
public BigDecimal getDepositPaid() {
|
||||
return this.depositPaid;
|
||||
}
|
||||
|
||||
public BigDecimal getInterestAccured() {
|
||||
return this.interestAccured;
|
||||
}
|
||||
|
||||
}
|
||||
-16
@@ -1,16 +0,0 @@
|
||||
/**
|
||||
* 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.portfolio.savingsaccount.domain;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.joda.time.LocalDate;
|
||||
import org.mifosplatform.portfolio.savingsaccountproduct.domain.SavingFrequencyType;
|
||||
|
||||
public interface DepositScheduleDateGenerator {
|
||||
|
||||
List<LocalDate> generate(LocalDate startDate, Integer paymentPeriods, Integer depositFrequency, SavingFrequencyType savingFrequencyType);
|
||||
}
|
||||
-118
@@ -1,118 +0,0 @@
|
||||
/**
|
||||
* 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.portfolio.savingsaccount.domain;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.MathContext;
|
||||
import java.math.RoundingMode;
|
||||
|
||||
import org.mifosplatform.organisation.monetary.domain.Money;
|
||||
import org.mifosplatform.portfolio.savingsaccountproduct.domain.SavingFrequencyType;
|
||||
import org.mifosplatform.portfolio.savingsaccountproduct.domain.SavingInterestCalculationMethod;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class ReccuringDepositInterestCalculator {
|
||||
|
||||
private final Integer monthsInYear = 12;
|
||||
|
||||
public Money calculateInterestOnMaturityFor(final Money savingsDepositPerPeriod, final Integer tenure,
|
||||
final BigDecimal reccuringInterestRate, final SavingFrequencyType savingFrequencyType,
|
||||
final SavingInterestCalculationMethod savingInterestCalculationMethod, Integer depositEvery) {
|
||||
|
||||
BigDecimal finalAmount = BigDecimal.ZERO;
|
||||
MathContext mc = new MathContext(8, RoundingMode.HALF_EVEN);
|
||||
|
||||
BigDecimal interestRateAsFraction = reccuringInterestRate.divide(BigDecimal.valueOf(100), mc);
|
||||
Integer noofTimesInterestCompoundPerYear = determineIntValue(savingFrequencyType);
|
||||
|
||||
BigDecimal interestRatePerPeriod = BigDecimal.valueOf(interestRateAsFraction.doubleValue()
|
||||
/ noofTimesInterestCompoundPerYear.doubleValue());
|
||||
Integer noOfTimestobeCalculated = tenure / depositEvery;
|
||||
|
||||
if (savingInterestCalculationMethod.isAverageBalance()) {
|
||||
|
||||
BigDecimal termAmount = BigDecimal.ZERO;
|
||||
BigDecimal totalInterest = BigDecimal.ZERO;
|
||||
BigDecimal closingBalance = BigDecimal.ZERO;
|
||||
BigDecimal amountPerPeriod = savingsDepositPerPeriod.getAmount();
|
||||
Integer depositEveryOriginalValue = depositEvery;
|
||||
BigDecimal amountPermonth = BigDecimal.valueOf(amountPerPeriod.doubleValue() / depositEvery.doubleValue());
|
||||
|
||||
while (noOfTimestobeCalculated > 0) {
|
||||
while (depositEvery > 0) {
|
||||
closingBalance = closingBalance.add(amountPermonth);
|
||||
termAmount = termAmount.add(closingBalance);
|
||||
depositEvery--;
|
||||
}
|
||||
|
||||
BigDecimal averageAmount = BigDecimal.valueOf(termAmount.doubleValue() / depositEveryOriginalValue.doubleValue());
|
||||
BigDecimal interestRatePerTerm = BigDecimal.valueOf(interestRateAsFraction.doubleValue() / monthsInYear.doubleValue()
|
||||
* depositEveryOriginalValue.doubleValue());
|
||||
BigDecimal interestperTerm = averageAmount.multiply(interestRatePerTerm);
|
||||
totalInterest = totalInterest.add(interestperTerm);
|
||||
depositEvery = depositEveryOriginalValue;
|
||||
termAmount = BigDecimal.ZERO;
|
||||
noOfTimestobeCalculated--;
|
||||
}
|
||||
finalAmount = closingBalance.add(totalInterest);
|
||||
|
||||
} else if (savingInterestCalculationMethod.isMonthlyCollection()) {
|
||||
/*
|
||||
* // Assuming tenure in months // see
|
||||
* http://www.onemint.com/2012/04/03/
|
||||
* how-to-calculate-interest-on-recurring-deposits/
|
||||
*
|
||||
* A=P(1+r/n)^nt
|
||||
*
|
||||
* A = final amount P = principal amount (initial investment) r =
|
||||
* annual nominal interest rate (as a decimal, not in percentage) n
|
||||
* = number of times the interest is compounded per year t = number
|
||||
* of years
|
||||
*/
|
||||
|
||||
BigDecimal onePlusInterestRatePerPeriod = BigDecimal.ONE.add(interestRatePerPeriod);
|
||||
BigDecimal monthsExpressedInYears;
|
||||
BigDecimal timeforOneCalculationPeriod;
|
||||
BigDecimal amountPerPeriod;
|
||||
Integer tempTenure = tenure;
|
||||
while (noOfTimestobeCalculated > 0) {
|
||||
monthsExpressedInYears = BigDecimal.valueOf(tempTenure.doubleValue() / monthsInYear.doubleValue());
|
||||
timeforOneCalculationPeriod = BigDecimal.valueOf(noofTimesInterestCompoundPerYear * monthsExpressedInYears.doubleValue());
|
||||
amountPerPeriod = savingsDepositPerPeriod.getAmount()
|
||||
.multiply(
|
||||
BigDecimal.valueOf(Math.pow(onePlusInterestRatePerPeriod.doubleValue(),
|
||||
timeforOneCalculationPeriod.doubleValue())));
|
||||
finalAmount = finalAmount.add(amountPerPeriod);
|
||||
noOfTimestobeCalculated--;
|
||||
tempTenure = tempTenure - depositEvery;
|
||||
}
|
||||
}
|
||||
return Money.of(savingsDepositPerPeriod.getCurrency(), finalAmount);
|
||||
}
|
||||
|
||||
private Integer determineIntValue(final SavingFrequencyType frequencyType) {
|
||||
Integer noofTimesInterestCompoundPerYear = Integer.valueOf(0);
|
||||
switch (frequencyType) {
|
||||
case MONTHLY:
|
||||
noofTimesInterestCompoundPerYear = monthsInYear;
|
||||
break;
|
||||
case QUATERLY:
|
||||
noofTimesInterestCompoundPerYear = monthsInYear / 3;
|
||||
break;
|
||||
case HALFYEARLY:
|
||||
noofTimesInterestCompoundPerYear = monthsInYear / 6;
|
||||
break;
|
||||
case YEARLY:
|
||||
noofTimesInterestCompoundPerYear = monthsInYear / 12;
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException("The specified frequency not supported");
|
||||
|
||||
}
|
||||
return noofTimesInterestCompoundPerYear;
|
||||
}
|
||||
}
|
||||
-730
@@ -1,730 +0,0 @@
|
||||
/**
|
||||
* 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.portfolio.savingsaccount.domain;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.MathContext;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import javax.persistence.CascadeType;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Embedded;
|
||||
import javax.persistence.Entity;
|
||||
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.UniqueConstraint;
|
||||
|
||||
import org.hibernate.annotations.LazyCollection;
|
||||
import org.hibernate.annotations.LazyCollectionOption;
|
||||
import org.joda.time.LocalDate;
|
||||
import org.joda.time.Months;
|
||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
import org.mifosplatform.infrastructure.core.domain.AbstractAuditableCustom;
|
||||
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
|
||||
import org.mifosplatform.organisation.monetary.domain.Money;
|
||||
import org.mifosplatform.portfolio.client.domain.Client;
|
||||
import org.mifosplatform.portfolio.loanproduct.domain.PeriodFrequencyType;
|
||||
import org.mifosplatform.portfolio.savingsaccountproduct.domain.SavingFrequencyType;
|
||||
import org.mifosplatform.portfolio.savingsaccountproduct.domain.SavingInterestCalculationMethod;
|
||||
import org.mifosplatform.portfolio.savingsaccountproduct.domain.SavingProduct;
|
||||
import org.mifosplatform.portfolio.savingsaccountproduct.domain.SavingProductType;
|
||||
import org.mifosplatform.portfolio.savingsaccountproduct.domain.SavingsInterestType;
|
||||
import org.mifosplatform.portfolio.savingsdepositaccount.domain.DepositAccountEvent;
|
||||
import org.mifosplatform.portfolio.savingsdepositaccount.domain.DepositAccountStatus;
|
||||
import org.mifosplatform.portfolio.savingsdepositaccount.domain.DepositLifecycleStateMachine;
|
||||
import org.mifosplatform.portfolio.savingsdepositaccount.exception.InvalidDepositStateTransitionException;
|
||||
import org.mifosplatform.portfolio.savingsdepositproduct.domain.TenureTypeEnum;
|
||||
import org.mifosplatform.useradministration.domain.AppUser;
|
||||
|
||||
@Entity
|
||||
@Table(name = "m_saving_account", uniqueConstraints = @UniqueConstraint(name = "saving_acc_external_id", columnNames = { "external_id" }))
|
||||
public class SavingAccount extends AbstractAuditableCustom<AppUser, Long> {
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "client_id", nullable = false)
|
||||
private Client client;
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "product_id")
|
||||
private SavingProduct product;
|
||||
|
||||
@Column(name = "savings_product_type", nullable = false)
|
||||
private Integer savingProductType;
|
||||
|
||||
@Column(name = "external_id")
|
||||
private String externalId;
|
||||
|
||||
@Embedded
|
||||
private MonetaryCurrency currency;
|
||||
|
||||
@Column(name = "deposit_amount_per_period", scale = 6, precision = 19, nullable = false)
|
||||
private BigDecimal savingsDepositAmountPerPeriod;
|
||||
|
||||
@Column(name = "total_deposit_amount", scale = 6, precision = 19, nullable = false)
|
||||
private BigDecimal totalSavingsAmount;
|
||||
|
||||
@Column(name = "reccuring_nominal_interest_rate", scale = 6, precision = 19, nullable = false)
|
||||
private BigDecimal reccuringInterestRate;
|
||||
|
||||
@Column(name = "regular_saving_nominal_interest_rate", scale = 6, precision = 19, nullable = false)
|
||||
private BigDecimal savingInterestRate;
|
||||
|
||||
@Column(name = "tenure", nullable = false)
|
||||
private Integer tenure;
|
||||
|
||||
@Column(name = "tenure_type", nullable = false)
|
||||
private Integer tenureType;
|
||||
|
||||
@Column(name = "frequency", nullable = false)
|
||||
private Integer frequency;
|
||||
|
||||
@Column(name = "interest_type", nullable = false)
|
||||
private Integer interestType;
|
||||
|
||||
@Column(name = "interest_calculation_method")
|
||||
private Integer interestCalculationMethod;
|
||||
|
||||
@Temporal(TemporalType.DATE)
|
||||
@Column(name = "projected_commencement_date")
|
||||
private Date projectedCommencementDate;
|
||||
|
||||
@Temporal(TemporalType.DATE)
|
||||
@Column(name = "actual_commencement_date")
|
||||
private Date actualCommencementDate;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Temporal(TemporalType.DATE)
|
||||
@Column(name = "matures_on_date")
|
||||
private Date maturesOnDate;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Column(name = "projected_interest_accrued_on_maturity", scale = 6, precision = 19, nullable = false)
|
||||
private BigDecimal projectedInterestAccruedOnMaturity;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Column(name = "actual_interest_accrued", scale = 6, precision = 19, nullable = false)
|
||||
private BigDecimal interestAccrued;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Column(name = "projected_total_maturity_amount", scale = 6, precision = 19, nullable = false)
|
||||
private BigDecimal projectedTotalOnMaturity;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Column(name = "actual_total_amount", scale = 6, precision = 19, nullable = false)
|
||||
private BigDecimal total;
|
||||
|
||||
@Column(name = "pre_closure_interest_rate", scale = 6, precision = 19, nullable = false)
|
||||
private BigDecimal preClosureInterestRate;
|
||||
|
||||
@Column(name = "outstanding_amount", scale = 6, precision = 19, nullable = false)
|
||||
private BigDecimal outstandingAmount;
|
||||
|
||||
@Column(name = "is_preclosure_allowed", nullable = false)
|
||||
private final boolean preClosureAllowed = false;
|
||||
|
||||
@Column(name = "is_deleted", nullable = false)
|
||||
private boolean deleted = false;
|
||||
|
||||
@Column(name = "status_enum", nullable = false)
|
||||
private Integer accountStatus;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Temporal(TemporalType.DATE)
|
||||
@Column(name = "closedon_date")
|
||||
private Date closedOnDate;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Temporal(TemporalType.DATE)
|
||||
@Column(name = "rejectedon_date")
|
||||
private Date rejectedOnDate;
|
||||
|
||||
@Temporal(TemporalType.DATE)
|
||||
@Column(name = "withdrawnon_date")
|
||||
private Date withdrawnOnDate;
|
||||
|
||||
@Column(name = "is_lock_in_period_allowed", nullable = false)
|
||||
private boolean isLockinPeriodAllowed = false;
|
||||
|
||||
@Column(name = "lock_in_period", nullable = false)
|
||||
private Integer lockinPeriod;
|
||||
|
||||
@Column(name = "lock_in_period_type", nullable = false)
|
||||
private Integer lockinPeriodType;
|
||||
|
||||
@Column(name = "deposit_every", nullable = false)
|
||||
private Integer payEvery;
|
||||
|
||||
@Column(name = "interest_posting_every", nullable = false)
|
||||
private Integer interestPostEvery;
|
||||
|
||||
@Column(name = "interest_posting_frequency", nullable = false)
|
||||
private Integer interestPostFrequency;
|
||||
|
||||
@Column(name = "interest_posted_amount", scale = 6, precision = 19)
|
||||
private BigDecimal interestPostedAmount;
|
||||
|
||||
@Temporal(TemporalType.DATE)
|
||||
@Column(name = "last_interest_posted_date")
|
||||
private Date lastInterestPostedDate;
|
||||
|
||||
@Temporal(TemporalType.DATE)
|
||||
@Column(name = "next_interest_posting_date")
|
||||
private Date nextInterestPostingDate;
|
||||
|
||||
// see
|
||||
// http://stackoverflow.com/questions/4334970/hibernate-cannot-simultaneously-fetch-multiple-bags
|
||||
@LazyCollection(LazyCollectionOption.FALSE)
|
||||
@OneToMany(cascade = CascadeType.ALL, mappedBy = "savingAccount", orphanRemoval = true)
|
||||
private final List<SavingScheduleInstallments> savingScheduleInstallments = new ArrayList<SavingScheduleInstallments>();
|
||||
|
||||
@OrderBy(value = "id")
|
||||
@LazyCollection(LazyCollectionOption.FALSE)
|
||||
@OneToMany(cascade = CascadeType.ALL, mappedBy = "savingAccount", orphanRemoval = true)
|
||||
private final List<SavingAccountTransaction> savingAccountTransactions = new ArrayList<SavingAccountTransaction>();
|
||||
|
||||
protected SavingAccount() {
|
||||
//
|
||||
}
|
||||
|
||||
public static SavingAccount openNew(final Client client, final SavingProduct product, final String externalId,
|
||||
final Money savingsDeposit, final BigDecimal reccuringInterestRate, final BigDecimal savingInterestRate, final Integer tenure,
|
||||
final LocalDate commencementDate, final TenureTypeEnum tenureTypeEnum, final SavingProductType savingProductType,
|
||||
final SavingFrequencyType savingFrequencyType, final SavingsInterestType interestType,
|
||||
final SavingInterestCalculationMethod savingInterestCalculationMethod, final boolean isLockinPeriodAllowed,
|
||||
final Integer lockinPeriod, final PeriodFrequencyType lockinPeriodType,
|
||||
final ReccuringDepositInterestCalculator reccuringDepositInterestCalculator,
|
||||
final DepositLifecycleStateMachine lifecycleStateMachine, final Integer depositEvery, final Integer interestPostEvery,
|
||||
final Integer interestPostFrequency) {
|
||||
|
||||
Money futureValueOnMaturity = null;
|
||||
if (savingProductType.isReccuring() && tenureTypeEnum.isFixedPeriod()) {
|
||||
futureValueOnMaturity = reccuringDepositInterestCalculator.calculateInterestOnMaturityFor(savingsDeposit, tenure,
|
||||
reccuringInterestRate, savingFrequencyType, savingInterestCalculationMethod, depositEvery);
|
||||
} else if (savingProductType.isReccuring() && tenureTypeEnum.isPerpetual()) {
|
||||
futureValueOnMaturity = savingsDeposit;
|
||||
} else {
|
||||
futureValueOnMaturity = savingsDeposit;
|
||||
}
|
||||
|
||||
return new SavingAccount(client, externalId, product, savingsDeposit, reccuringInterestRate, savingInterestRate, tenure,
|
||||
commencementDate, tenureTypeEnum, savingProductType, savingFrequencyType, interestType, savingInterestCalculationMethod,
|
||||
isLockinPeriodAllowed, lockinPeriod, lockinPeriodType, futureValueOnMaturity, lifecycleStateMachine, depositEvery,
|
||||
interestPostEvery, interestPostFrequency);
|
||||
}
|
||||
|
||||
public SavingAccount(final Client client, final String externalId, final SavingProduct product, final Money savingsDeposit,
|
||||
final BigDecimal reccuringInterestRate, final BigDecimal savingInterestRate, final Integer tenure,
|
||||
final LocalDate commencementDate, final TenureTypeEnum tenureTypeEnum, final SavingProductType savingProductType,
|
||||
final SavingFrequencyType savingFrequencyType, final SavingsInterestType interestType,
|
||||
final SavingInterestCalculationMethod savingInterestCalculationMethod, final boolean isLockinPeriodAllowed,
|
||||
final Integer lockinPeriod, final PeriodFrequencyType lockinPeriodType, final Money futureValueOnMaturity,
|
||||
final DepositLifecycleStateMachine lifecycleStateMachine, final Integer payEvery, final Integer interestPostEvery,
|
||||
final Integer interestPostFrequency) {
|
||||
|
||||
DepositAccountStatus from = null;
|
||||
if (accountStatus != null) {
|
||||
from = DepositAccountStatus.fromInt(accountStatus);
|
||||
}
|
||||
|
||||
DepositAccountStatus statusEnum = lifecycleStateMachine.transition(DepositAccountEvent.DEPOSIT_CREATED, from);
|
||||
accountStatus = statusEnum.getValue();
|
||||
|
||||
this.total = BigDecimal.ZERO;
|
||||
this.preClosureInterestRate = BigDecimal.ZERO;
|
||||
this.totalSavingsAmount = BigDecimal.ZERO;
|
||||
this.interestAccrued = BigDecimal.ZERO;
|
||||
|
||||
this.client = client;
|
||||
this.externalId = externalId;
|
||||
this.product = product;
|
||||
this.savingsDepositAmountPerPeriod = savingsDeposit.getAmount();
|
||||
this.currency = savingsDeposit.getCurrency();
|
||||
this.reccuringInterestRate = reccuringInterestRate;
|
||||
this.savingInterestRate = savingInterestRate;
|
||||
this.tenure = tenure;
|
||||
this.projectedCommencementDate = commencementDate.toDate();
|
||||
this.tenureType = tenureTypeEnum.getValue();
|
||||
this.savingProductType = savingProductType.getValue();
|
||||
this.frequency = savingFrequencyType.getValue();
|
||||
this.interestType = interestType.getValue();
|
||||
this.interestCalculationMethod = savingInterestCalculationMethod.getValue();
|
||||
this.isLockinPeriodAllowed = isLockinPeriodAllowed;
|
||||
this.lockinPeriod = lockinPeriod;
|
||||
this.lockinPeriodType = lockinPeriodType.getValue();
|
||||
this.projectedTotalOnMaturity = futureValueOnMaturity.getAmount();
|
||||
BigDecimal projectedInterestForReccuring = futureValueOnMaturity.getAmount().subtract(
|
||||
BigDecimal.valueOf(savingsDeposit.getAmount().doubleValue() * tenure.doubleValue() / payEvery)); // presently
|
||||
// only
|
||||
// for
|
||||
// months
|
||||
this.projectedInterestAccruedOnMaturity = savingProductType.isReccuring() && tenureTypeEnum.isFixedPeriod() ? projectedInterestForReccuring
|
||||
: BigDecimal.ZERO;
|
||||
this.payEvery = payEvery;
|
||||
this.outstandingAmount = BigDecimal.ZERO;
|
||||
this.interestPostEvery = interestPostEvery;
|
||||
this.interestPostFrequency = interestPostFrequency;
|
||||
}
|
||||
|
||||
public void modifyAccount(final SavingProduct product, final String externalId, final Money savingsDeposit,
|
||||
final BigDecimal reccuringInterestRate, final BigDecimal savingInterestRate, final Integer tenure,
|
||||
final LocalDate commencementDate, final TenureTypeEnum tenureTypeEnum, final SavingProductType savingProductType,
|
||||
final SavingFrequencyType savingFrequencyType, final SavingInterestCalculationMethod savingInterestCalculationMethod,
|
||||
final boolean isLockinPeriodAllowed, final Integer lockinPeriod, final PeriodFrequencyType lockinPeriodType,
|
||||
final ReccuringDepositInterestCalculator reccuringDepositInterestCalculator, final Integer payEvery,
|
||||
final SavingsInterestType interestType, final Integer interestPostEvery, final Integer interestPostFrequency) {
|
||||
|
||||
Money futureValueOnMaturity = null;
|
||||
if (savingProductType.isReccuring() && tenureTypeEnum.isFixedPeriod()) {
|
||||
futureValueOnMaturity = reccuringDepositInterestCalculator.calculateInterestOnMaturityFor(savingsDeposit, tenure,
|
||||
reccuringInterestRate, savingFrequencyType, savingInterestCalculationMethod, payEvery);
|
||||
} else if (savingProductType.isReccuring() && tenureTypeEnum.isPerpetual()) {
|
||||
futureValueOnMaturity = savingsDeposit;
|
||||
} else {
|
||||
futureValueOnMaturity = savingsDeposit;
|
||||
}
|
||||
|
||||
this.product = product;
|
||||
this.externalId = externalId;
|
||||
this.savingsDepositAmountPerPeriod = savingsDeposit.getAmount();
|
||||
this.reccuringInterestRate = reccuringInterestRate;
|
||||
this.savingInterestRate = savingInterestRate;
|
||||
this.tenure = tenure;
|
||||
this.projectedCommencementDate = commencementDate.toDate();
|
||||
this.tenureType = tenureTypeEnum.getValue();
|
||||
this.savingProductType = savingProductType.getValue();
|
||||
this.frequency = savingFrequencyType.getValue();
|
||||
this.interestType = interestType.getValue();
|
||||
this.interestCalculationMethod = savingInterestCalculationMethod.getValue();
|
||||
this.isLockinPeriodAllowed = isLockinPeriodAllowed;
|
||||
this.lockinPeriod = lockinPeriod;
|
||||
this.lockinPeriodType = lockinPeriodType.getValue();
|
||||
this.payEvery = payEvery;
|
||||
this.outstandingAmount = BigDecimal.ZERO;
|
||||
this.interestPostEvery = interestPostEvery;
|
||||
this.interestPostFrequency = interestPostFrequency;
|
||||
this.savingScheduleInstallments.clear();
|
||||
|
||||
this.projectedTotalOnMaturity = futureValueOnMaturity.getAmount();
|
||||
BigDecimal projectedInterestForReccuring = futureValueOnMaturity.getAmount().subtract(
|
||||
BigDecimal.valueOf(savingsDeposit.getAmount().doubleValue() * tenure.doubleValue() / payEvery)); // presently
|
||||
// only
|
||||
// for
|
||||
// months
|
||||
this.projectedInterestAccruedOnMaturity = savingProductType.isReccuring() && tenureTypeEnum.isFixedPeriod() ? projectedInterestForReccuring
|
||||
: BigDecimal.ZERO;
|
||||
}
|
||||
|
||||
public boolean isDeleted() {
|
||||
return this.deleted;
|
||||
}
|
||||
|
||||
public boolean isPendingApproval() {
|
||||
return this.accountStatus.equals(100);
|
||||
}
|
||||
|
||||
public Client getClient() {
|
||||
return client;
|
||||
}
|
||||
|
||||
public SavingProduct getProduct() {
|
||||
return product;
|
||||
}
|
||||
|
||||
public Integer getSavingProductType() {
|
||||
return savingProductType;
|
||||
}
|
||||
|
||||
public String getExternalId() {
|
||||
return externalId;
|
||||
}
|
||||
|
||||
public BigDecimal getSavingsDepositAmountPerPeriod() {
|
||||
return savingsDepositAmountPerPeriod;
|
||||
}
|
||||
|
||||
public BigDecimal getReccuringInterestRate() {
|
||||
return reccuringInterestRate;
|
||||
}
|
||||
|
||||
public BigDecimal getSavingInterestRate() {
|
||||
return savingInterestRate;
|
||||
}
|
||||
|
||||
public Integer getTenure() {
|
||||
return tenure;
|
||||
}
|
||||
|
||||
public Integer getTenureType() {
|
||||
return tenureType;
|
||||
}
|
||||
|
||||
public Integer getFrequency() {
|
||||
return frequency;
|
||||
}
|
||||
|
||||
public Integer getInterestType() {
|
||||
return interestType;
|
||||
}
|
||||
|
||||
public Integer getInterestCalculationMethod() {
|
||||
return interestCalculationMethod;
|
||||
}
|
||||
|
||||
public Date getProjectedCommencementDate() {
|
||||
return projectedCommencementDate;
|
||||
}
|
||||
|
||||
public BigDecimal getPreClosureInterestRate() {
|
||||
return preClosureInterestRate;
|
||||
}
|
||||
|
||||
public boolean isPreClosureAllowed() {
|
||||
return preClosureAllowed;
|
||||
}
|
||||
|
||||
public Date getWithdrawnOnDate() {
|
||||
return withdrawnOnDate;
|
||||
}
|
||||
|
||||
public boolean isLockinPeriodAllowed() {
|
||||
return isLockinPeriodAllowed;
|
||||
}
|
||||
|
||||
public Integer getLockinPeriod() {
|
||||
return lockinPeriod;
|
||||
}
|
||||
|
||||
public Integer getLockinPeriodType() {
|
||||
return lockinPeriodType;
|
||||
}
|
||||
|
||||
public Integer getPayEvery() {
|
||||
return this.payEvery;
|
||||
}
|
||||
|
||||
public BigDecimal getOutstandingAmount() {
|
||||
return this.outstandingAmount;
|
||||
}
|
||||
|
||||
public Integer getInterestPostEvery() {
|
||||
return this.interestPostEvery;
|
||||
}
|
||||
|
||||
public Integer getInterestPostFrequency() {
|
||||
return this.interestPostFrequency;
|
||||
}
|
||||
|
||||
public List<SavingAccountTransaction> getSavingAccountTransactions() {
|
||||
return this.savingAccountTransactions;
|
||||
}
|
||||
|
||||
public void addSavingScheduleInstallment(final SavingScheduleInstallments installment) {
|
||||
installment.updateAccount(this);
|
||||
this.savingScheduleInstallments.add(installment);
|
||||
}
|
||||
|
||||
public void reject(final LocalDate rejectedOn, final DepositLifecycleStateMachine depositLifecycleStateMachine) {
|
||||
|
||||
DepositAccountStatus statusEnum = depositLifecycleStateMachine.transition(DepositAccountEvent.DEPOSIT_REJECTED,
|
||||
DepositAccountStatus.fromInt(this.accountStatus));
|
||||
this.accountStatus = statusEnum.getValue();
|
||||
|
||||
this.maturesOnDate = null;
|
||||
this.rejectedOnDate = rejectedOn.toDateTimeAtCurrentTime().toDate();
|
||||
this.closedOnDate = rejectedOn.toDateTimeAtCurrentTime().toDate();
|
||||
|
||||
if (rejectedOn.isBefore(projectedCommencementDate())) {
|
||||
|
||||
final String errorMessage = "The date on which a saving account is rejected cannot be before its submittal date: "
|
||||
+ projectedCommencementDate().toString();
|
||||
throw new InvalidDepositStateTransitionException("reject", "cannot.be.before.submittal.date", errorMessage, rejectedOn,
|
||||
projectedCommencementDate());
|
||||
|
||||
}
|
||||
if (rejectedOn.isAfter(new LocalDate())) {
|
||||
|
||||
final String errorMessage = "The date on which a saving account is rejected cannot be in the future.";
|
||||
throw new InvalidDepositStateTransitionException("reject", "cannot.be.a.future.date", errorMessage, rejectedOn);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public LocalDate projectedCommencementDate() {
|
||||
LocalDate date = null;
|
||||
if (this.projectedCommencementDate != null) {
|
||||
date = new LocalDate(this.projectedCommencementDate);
|
||||
}
|
||||
return date;
|
||||
}
|
||||
|
||||
public void withdrawnByApplicant(final LocalDate withdrawnOn, final DepositLifecycleStateMachine depositLifecycleStateMachine) {
|
||||
|
||||
DepositAccountStatus statusEnum = depositLifecycleStateMachine.transition(DepositAccountEvent.DEPOSIT_WITHDRAWN,
|
||||
DepositAccountStatus.fromInt(this.accountStatus));
|
||||
this.accountStatus = statusEnum.getValue();
|
||||
|
||||
this.maturesOnDate = null;
|
||||
this.withdrawnOnDate = withdrawnOn.toDateTimeAtCurrentTime().toDate();
|
||||
this.closedOnDate = withdrawnOn.toDateTimeAtCurrentTime().toDate();
|
||||
this.savingScheduleInstallments.clear();
|
||||
|
||||
if (withdrawnOn.isBefore(projectedCommencementDate())) {
|
||||
|
||||
final String errorMessage = "The date on which a deposit is rejected cannot be before its submittal date: "
|
||||
+ projectedCommencementDate().toString();
|
||||
throw new InvalidDepositStateTransitionException("withdrawnbyclient", "cannot.be.before.submittal.date", errorMessage,
|
||||
withdrawnOn, projectedCommencementDate());
|
||||
|
||||
}
|
||||
|
||||
if (withdrawnOn.isAfter(new LocalDate())) {
|
||||
final String errorMessage = "The date on which a deposit is rejected cannot be in the future.";
|
||||
throw new InvalidDepositStateTransitionException("withdrawnbyclient", "cannot.be.a.future.date", errorMessage, withdrawnOn);
|
||||
}
|
||||
}
|
||||
|
||||
public void undoSavingAccountApproval(final DepositLifecycleStateMachine depositLifecycleStateMachine) {
|
||||
DepositAccountStatus statusEnum = depositLifecycleStateMachine.transition(DepositAccountEvent.DEPOSIT_APPROVAL_UNDO,
|
||||
DepositAccountStatus.fromInt(this.accountStatus));
|
||||
this.accountStatus = statusEnum.getValue();
|
||||
this.savingScheduleInstallments.clear();
|
||||
this.closedOnDate = new Date();
|
||||
}
|
||||
|
||||
public void approveSavingAccount(final LocalDate approvalDate, final BigDecimal savingsDepositAmountPerPeriod,
|
||||
final BigDecimal recurringInterestRate, final BigDecimal savingInterestRate, final Integer interestType, final Integer tenure,
|
||||
final Integer tenureType, final Integer frequency, final Integer payEvery,
|
||||
final DepositLifecycleStateMachine depositLifecycleStateMachine,
|
||||
final ReccuringDepositInterestCalculator reccuringDepositInterestCalculator, final Integer interestPostEvery,
|
||||
final Integer interestPostFrequency) {
|
||||
|
||||
DepositAccountStatus statusEnum = depositLifecycleStateMachine.transition(DepositAccountEvent.DEPOSIT_APPROVED,
|
||||
DepositAccountStatus.fromInt(this.accountStatus));
|
||||
this.accountStatus = statusEnum.getValue();
|
||||
|
||||
Money savingsAmountPerPeriod = Money.of(currency, savingsDepositAmountPerPeriod);
|
||||
TenureTypeEnum tenureTypeEnum = TenureTypeEnum.fromInt(tenureType);
|
||||
SavingFrequencyType savingFrequencyType = SavingFrequencyType.fromInt(frequency);
|
||||
SavingInterestCalculationMethod interestCalculationMethod = SavingInterestCalculationMethod.fromInt(this.interestCalculationMethod);
|
||||
|
||||
Money futureValueOnMaturity = null;
|
||||
if (SavingProductType.fromInt(this.savingProductType).isReccuring() && tenureTypeEnum.isFixedPeriod()) {
|
||||
futureValueOnMaturity = reccuringDepositInterestCalculator.calculateInterestOnMaturityFor(savingsAmountPerPeriod, tenure,
|
||||
recurringInterestRate, savingFrequencyType, interestCalculationMethod, payEvery);
|
||||
} else if (SavingProductType.fromInt(this.savingProductType).isReccuring() && tenureTypeEnum.isPerpetual()) {
|
||||
futureValueOnMaturity = savingsAmountPerPeriod;
|
||||
} else {
|
||||
futureValueOnMaturity = savingsAmountPerPeriod;
|
||||
}
|
||||
|
||||
this.actualCommencementDate = approvalDate.toDate();
|
||||
this.savingsDepositAmountPerPeriod = savingsDepositAmountPerPeriod;
|
||||
this.reccuringInterestRate = recurringInterestRate;
|
||||
this.savingInterestRate = savingInterestRate;
|
||||
this.interestType = interestType;
|
||||
this.tenure = tenure;
|
||||
this.tenureType = tenureType;
|
||||
this.frequency = frequency;
|
||||
this.payEvery = payEvery;
|
||||
this.savingScheduleInstallments.clear();
|
||||
this.total = futureValueOnMaturity.getAmount();
|
||||
BigDecimal interestForReccuring = futureValueOnMaturity.getAmount().subtract(
|
||||
BigDecimal.valueOf(savingsDepositAmountPerPeriod.doubleValue() * tenure.doubleValue() / payEvery.doubleValue())); // presently
|
||||
// only
|
||||
// for
|
||||
// months
|
||||
this.interestAccrued = SavingProductType.fromInt(this.savingProductType).isReccuring() && tenureTypeEnum.isFixedPeriod() ? interestForReccuring
|
||||
: BigDecimal.ZERO;
|
||||
this.interestPostEvery = interestPostEvery;
|
||||
this.interestPostFrequency = interestPostFrequency;
|
||||
|
||||
// for interest posting initializing
|
||||
this.lastInterestPostedDate = this.actualCommencementDate;
|
||||
this.nextInterestPostingDate = new LocalDate(this.lastInterestPostedDate).plusMonths(this.interestPostEvery).toDate();
|
||||
this.interestPostedAmount = BigDecimal.ZERO;
|
||||
}
|
||||
|
||||
public void depositMoney(final JsonCommand command) {
|
||||
|
||||
final BigDecimal depositAmountCommandValue = command.bigDecimalValueOfParameterNamed("savingsDepositAmountPerPeriod");
|
||||
final LocalDate depositDateCommandValue = command.localDateValueOfParameterNamed("depositDate");
|
||||
|
||||
BigDecimal depositAmount = BigDecimal.ZERO;
|
||||
BigDecimal remainAmountToBePaid = BigDecimal.ZERO;
|
||||
BigDecimal commandRemainDepositAmount = depositAmountCommandValue;
|
||||
|
||||
SavingAccountTransaction savingAccountTransaction = SavingAccountTransaction.deposit(depositAmountCommandValue,
|
||||
depositDateCommandValue);
|
||||
savingAccountTransaction.updateAccount(this);
|
||||
this.savingAccountTransactions.add(savingAccountTransaction);
|
||||
this.outstandingAmount = this.outstandingAmount.add(depositAmountCommandValue);
|
||||
this.totalSavingsAmount = this.totalSavingsAmount.add(depositAmountCommandValue);
|
||||
|
||||
if (SavingProductType.fromInt(this.savingProductType).isReccuring() && TenureTypeEnum.fromInt(tenureType).isFixedPeriod()) {
|
||||
for (SavingScheduleInstallments savingScheduleInstallment : this.savingScheduleInstallments) {
|
||||
if (!savingScheduleInstallment.isCompleted()) {
|
||||
depositAmount = savingScheduleInstallment.getDeposit();
|
||||
remainAmountToBePaid = depositAmount.subtract(savingScheduleInstallment.getDepositPaid());
|
||||
if (remainAmountToBePaid.doubleValue() > 0) {
|
||||
if (commandRemainDepositAmount.doubleValue() > 0) {
|
||||
if (commandRemainDepositAmount.doubleValue() >= remainAmountToBePaid.doubleValue()) {
|
||||
savingScheduleInstallment.setDepositPaid(remainAmountToBePaid.add(savingScheduleInstallment
|
||||
.getDepositPaid()));
|
||||
savingScheduleInstallment.setPaymentDate(depositDateCommandValue.toDate());
|
||||
savingScheduleInstallment.setCompleted(true);
|
||||
commandRemainDepositAmount = commandRemainDepositAmount.subtract(remainAmountToBePaid);
|
||||
} else if (commandRemainDepositAmount.doubleValue() < remainAmountToBePaid.doubleValue()) {
|
||||
savingScheduleInstallment.setDepositPaid(commandRemainDepositAmount.add(savingScheduleInstallment
|
||||
.getDepositPaid()));
|
||||
savingScheduleInstallment.setPaymentDate(depositDateCommandValue.toDate());
|
||||
commandRemainDepositAmount = BigDecimal.ZERO;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (SavingScheduleInstallments savingScheduleInstallment : this.savingScheduleInstallments) {
|
||||
savingScheduleInstallment.setDepositPaid(remainAmountToBePaid.add(savingScheduleInstallment.getDepositPaid()));
|
||||
savingScheduleInstallment.setPaymentDate(depositDateCommandValue.toDate());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isActive() {
|
||||
return DepositAccountStatus.fromInt(this.accountStatus).isActive();
|
||||
}
|
||||
|
||||
public void withdrawAmount(final BigDecimal amount, final LocalDate transactionDate) {
|
||||
this.outstandingAmount = this.outstandingAmount.subtract(amount);
|
||||
SavingAccountTransaction savingAccountTransaction = SavingAccountTransaction.withdraw(amount, transactionDate);
|
||||
savingAccountTransaction.updateAccount(this);
|
||||
this.savingAccountTransactions.add(savingAccountTransaction);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete is a <i>soft delete</i>. Updates flag on account so it wont appear
|
||||
* in query/report results.
|
||||
*
|
||||
* Any fields with unique constraints and prepended with id of record.
|
||||
*/
|
||||
public void delete() {
|
||||
this.deleted = true;
|
||||
this.externalId = this.getId() + "_" + this.externalId;
|
||||
}
|
||||
|
||||
public void postInterest() {
|
||||
|
||||
LocalDate lastInterestPostedDate = getLastInterestPostedDate();
|
||||
// LocalDate nextInterestPostingDate = getNextInterestPostedDate();
|
||||
// SavingInterestCalculationMethod savingInterestCalculationMethod =
|
||||
// SavingInterestCalculationMethod
|
||||
// .fromInt(this.interestCalculationMethod);
|
||||
|
||||
Integer monthsForInterestCalculation = Months.monthsBetween(lastInterestPostedDate, new LocalDate()).getMonths();
|
||||
Integer postInterestItereations = monthsForInterestCalculation / this.interestPostEvery;
|
||||
MathContext mc = new MathContext(8, RoundingMode.HALF_EVEN);
|
||||
BigDecimal interestRateAsFraction = reccuringInterestRate.divide(BigDecimal.valueOf(100), mc);
|
||||
final Integer monthsInYear = 12;
|
||||
|
||||
BigDecimal totalDepositedAmount = BigDecimal.ZERO;
|
||||
BigDecimal totalWithdrawableAmount = BigDecimal.ZERO;
|
||||
BigDecimal totalOutstandingAmount = BigDecimal.ZERO;
|
||||
boolean isOutstandingAmountCalculated = false;
|
||||
|
||||
while (postInterestItereations > 0) {
|
||||
lastInterestPostedDate = getLastInterestPostedDate();
|
||||
// nextInterestPostingDate = getNextInterestPostedDate();
|
||||
LocalDate transactionStartDate = lastInterestPostedDate;
|
||||
|
||||
BigDecimal termTotalAmount = BigDecimal.ZERO;
|
||||
BigDecimal averageBalanceForTerm = BigDecimal.ZERO;
|
||||
|
||||
for (int i = 0; i < interestPostEvery; i++) {
|
||||
// default for months here
|
||||
LocalDate transactionEndDate = transactionStartDate.plusMonths(1);
|
||||
BigDecimal depositedAmount = BigDecimal.ZERO;
|
||||
BigDecimal withdrawableAmount = BigDecimal.ZERO;
|
||||
BigDecimal outstandingAmount = BigDecimal.ZERO;
|
||||
|
||||
for (SavingAccountTransaction savingAccountTransaction : this.savingAccountTransactions) {
|
||||
LocalDate actualTransactionDate = savingAccountTransaction.getTransactionDate();
|
||||
if (actualTransactionDate != null
|
||||
&& (actualTransactionDate.isAfter(transactionStartDate) || actualTransactionDate.isEqual(transactionStartDate))) {
|
||||
if (actualTransactionDate.isBefore(transactionEndDate)) {
|
||||
if (savingAccountTransaction.getTypeOf().isDeposit()) {
|
||||
depositedAmount = depositedAmount.add(savingAccountTransaction.getAmount());
|
||||
} else if (savingAccountTransaction.getTypeOf().isWithdraw()) {
|
||||
withdrawableAmount = withdrawableAmount.add(savingAccountTransaction.getAmount());
|
||||
}
|
||||
}
|
||||
} else if (actualTransactionDate != null && (actualTransactionDate.isBefore(transactionStartDate))) {
|
||||
if (!isOutstandingAmountCalculated) {
|
||||
if (savingAccountTransaction.getTypeOf().isDeposit()) {
|
||||
depositedAmount = depositedAmount.add(savingAccountTransaction.getAmount());
|
||||
} else if (savingAccountTransaction.getTypeOf().isWithdraw()) {
|
||||
withdrawableAmount = withdrawableAmount.add(savingAccountTransaction.getAmount());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
outstandingAmount = depositedAmount.subtract(withdrawableAmount);
|
||||
totalDepositedAmount = totalDepositedAmount.add(depositedAmount);
|
||||
totalWithdrawableAmount = totalWithdrawableAmount.add(withdrawableAmount);
|
||||
totalOutstandingAmount = totalOutstandingAmount.add(outstandingAmount);
|
||||
termTotalAmount = termTotalAmount.add(totalOutstandingAmount);
|
||||
transactionStartDate = transactionEndDate;
|
||||
isOutstandingAmountCalculated = true;
|
||||
|
||||
}
|
||||
// TODO - HUGO - calculate interest on calculation method
|
||||
|
||||
// if (savingInterestCalculationMethod.isAverageBalance()) {
|
||||
averageBalanceForTerm = BigDecimal.valueOf(termTotalAmount.doubleValue() / this.interestPostEvery);
|
||||
BigDecimal interestRatePerTerm = BigDecimal.valueOf(interestRateAsFraction.doubleValue() / monthsInYear.doubleValue()
|
||||
* this.interestPostEvery.doubleValue());
|
||||
BigDecimal interestPerTerm = averageBalanceForTerm.multiply(interestRatePerTerm);
|
||||
this.interestPostedAmount = this.interestPostedAmount.add(interestPerTerm);
|
||||
totalOutstandingAmount = totalOutstandingAmount.add(interestPerTerm);
|
||||
// } else if(savingInterestCalculationMethod.isMonthlyCollection()){
|
||||
|
||||
// }
|
||||
this.outstandingAmount = this.outstandingAmount.add(interestPerTerm);
|
||||
this.lastInterestPostedDate = getNextInterestPostedDate().toDate();
|
||||
this.nextInterestPostingDate = getNextInterestPostedDate().plusMonths(this.interestPostEvery).toDate();
|
||||
postInterestItereations--;
|
||||
}
|
||||
}
|
||||
|
||||
private final LocalDate getLastInterestPostedDate() {
|
||||
LocalDate lastInterestPostedDate;
|
||||
if (this.lastInterestPostedDate == null) {
|
||||
lastInterestPostedDate = new LocalDate(this.actualCommencementDate);
|
||||
} else {
|
||||
lastInterestPostedDate = new LocalDate(this.lastInterestPostedDate);
|
||||
}
|
||||
return lastInterestPostedDate;
|
||||
}
|
||||
|
||||
private final LocalDate getNextInterestPostedDate() {
|
||||
LocalDate nextInterestPostingDate;
|
||||
if (this.nextInterestPostingDate == null) {
|
||||
nextInterestPostingDate = new LocalDate(this.nextInterestPostingDate).plusMonths(this.interestPostEvery);
|
||||
} else {
|
||||
nextInterestPostingDate = new LocalDate(this.nextInterestPostingDate);
|
||||
}
|
||||
return nextInterestPostingDate;
|
||||
}
|
||||
}
|
||||
-96
@@ -1,96 +0,0 @@
|
||||
/**
|
||||
* 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.portfolio.savingsaccount.domain;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
|
||||
import javax.persistence.CascadeType;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.OneToOne;
|
||||
import javax.persistence.Table;
|
||||
import javax.persistence.Temporal;
|
||||
import javax.persistence.TemporalType;
|
||||
|
||||
import org.joda.time.LocalDate;
|
||||
import org.mifosplatform.infrastructure.core.domain.AbstractAuditableCustom;
|
||||
import org.mifosplatform.portfolio.savingsdepositaccount.domain.DepositAccountTransactionType;
|
||||
import org.mifosplatform.useradministration.domain.AppUser;
|
||||
|
||||
@Entity
|
||||
@Table(name = "m_saving_account_transaction")
|
||||
public class SavingAccountTransaction extends AbstractAuditableCustom<AppUser, Long> {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@ManyToOne(optional = false)
|
||||
@JoinColumn(name = "saving_account_id", nullable = false)
|
||||
private SavingAccount savingAccount;
|
||||
|
||||
@Column(name = "transaction_type_enum", nullable = false)
|
||||
private Integer typeOf;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@OneToOne(optional = true, cascade = { CascadeType.PERSIST })
|
||||
@JoinColumn(name = "contra_id")
|
||||
private SavingAccountTransaction contra;
|
||||
|
||||
@Temporal(TemporalType.DATE)
|
||||
@Column(name = "transaction_date", nullable = false)
|
||||
private final Date transactionDate;
|
||||
|
||||
@Column(name = "amount", scale = 6, precision = 19, nullable = false)
|
||||
private final BigDecimal amount;
|
||||
|
||||
public SavingAccountTransaction() {
|
||||
this.transactionDate = null;
|
||||
this.amount = BigDecimal.ZERO;
|
||||
}
|
||||
|
||||
public SavingAccountTransaction(final DepositAccountTransactionType transactionType, final BigDecimal amount,
|
||||
final LocalDate paymentDate) {
|
||||
this.typeOf = transactionType.getValue();
|
||||
this.amount = amount;
|
||||
this.transactionDate = paymentDate.toDate();
|
||||
}
|
||||
|
||||
public static SavingAccountTransaction deposit(final BigDecimal amount, final LocalDate paymentDate) {
|
||||
return new SavingAccountTransaction(DepositAccountTransactionType.DEPOSIT, amount == null ? new BigDecimal(0) : amount, paymentDate);
|
||||
}
|
||||
|
||||
public static SavingAccountTransaction withdraw(final BigDecimal amount, final LocalDate paymentDate) {
|
||||
return new SavingAccountTransaction(DepositAccountTransactionType.WITHDRAW, amount == null ? new BigDecimal(0) : amount,
|
||||
paymentDate);
|
||||
}
|
||||
|
||||
public static SavingAccountTransaction postInterest(final BigDecimal amount, final LocalDate paymentDate) {
|
||||
return new SavingAccountTransaction(DepositAccountTransactionType.INTEREST_POSTING, amount == null ? new BigDecimal(0) : amount,
|
||||
paymentDate);
|
||||
}
|
||||
|
||||
public void updateAccount(final SavingAccount savingAccount) {
|
||||
this.savingAccount = savingAccount;
|
||||
}
|
||||
|
||||
public DepositAccountTransactionType getTypeOf() {
|
||||
return DepositAccountTransactionType.fromInt(this.typeOf);
|
||||
}
|
||||
|
||||
public BigDecimal getAmount() {
|
||||
return this.amount;
|
||||
}
|
||||
|
||||
public LocalDate getTransactionDate() {
|
||||
LocalDate transactionDate = null;
|
||||
if (this.transactionDate != null) {
|
||||
transactionDate = new LocalDate(this.transactionDate);
|
||||
}
|
||||
return transactionDate;
|
||||
}
|
||||
|
||||
}
|
||||
-109
@@ -1,109 +0,0 @@
|
||||
/**
|
||||
* 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.portfolio.savingsaccount.domain;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.Table;
|
||||
import javax.persistence.Temporal;
|
||||
import javax.persistence.TemporalType;
|
||||
|
||||
import org.mifosplatform.infrastructure.core.domain.AbstractAuditableCustom;
|
||||
import org.mifosplatform.useradministration.domain.AppUser;
|
||||
|
||||
@Entity
|
||||
@Table(name = "m_saving_schedule")
|
||||
public class SavingScheduleInstallments extends AbstractAuditableCustom<AppUser, Long> {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@ManyToOne(optional = false)
|
||||
@JoinColumn(name = "saving_account_id", nullable = false)
|
||||
private SavingAccount savingAccount;
|
||||
|
||||
@Temporal(TemporalType.DATE)
|
||||
@Column(name = "duedate", nullable = false)
|
||||
private final Date dueDate;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Column(name = "installment", nullable = false)
|
||||
private final Integer installmentNumber;
|
||||
|
||||
@Column(name = "deposit", scale = 6, precision = 19, nullable = false)
|
||||
private BigDecimal deposit;
|
||||
|
||||
@Temporal(TemporalType.DATE)
|
||||
@Column(name = "payment_date", nullable = true)
|
||||
private Date paymentDate;
|
||||
|
||||
@Column(name = "deposit_paid", scale = 6, precision = 19, nullable = true)
|
||||
private BigDecimal depositPaid;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Column(name = "interest_accured", scale = 6, precision = 19, nullable = true)
|
||||
private BigDecimal interstAccured;
|
||||
|
||||
@Column(name = "completed_derived", nullable = false)
|
||||
private boolean completed;
|
||||
|
||||
public SavingScheduleInstallments() {
|
||||
this.dueDate = null;
|
||||
this.installmentNumber = null;
|
||||
this.paymentDate = null;
|
||||
}
|
||||
|
||||
public SavingScheduleInstallments(SavingAccount account, Date dueDate, Integer installmentNumber, BigDecimal deposit,
|
||||
BigDecimal interstAccured) {
|
||||
this.savingAccount = account;
|
||||
this.dueDate = dueDate;
|
||||
this.installmentNumber = installmentNumber;
|
||||
this.deposit = deposit;
|
||||
this.paymentDate = null;
|
||||
this.depositPaid = BigDecimal.ZERO;
|
||||
this.completed = false;
|
||||
this.interstAccured = interstAccured;
|
||||
}
|
||||
|
||||
public void updateAccount(SavingAccount account) {
|
||||
this.savingAccount = account;
|
||||
}
|
||||
|
||||
public Date getPaymentDate() {
|
||||
return this.paymentDate;
|
||||
}
|
||||
|
||||
public void setPaymentDate(Date paymentDate) {
|
||||
this.paymentDate = paymentDate;
|
||||
}
|
||||
|
||||
public BigDecimal getDepositPaid() {
|
||||
return this.depositPaid;
|
||||
}
|
||||
|
||||
public void setDepositPaid(BigDecimal depositPaid) {
|
||||
this.depositPaid = depositPaid;
|
||||
}
|
||||
|
||||
public Date getDueDate() {
|
||||
return this.dueDate;
|
||||
}
|
||||
|
||||
public BigDecimal getDeposit() {
|
||||
return this.deposit;
|
||||
}
|
||||
|
||||
public boolean isCompleted() {
|
||||
return this.completed;
|
||||
}
|
||||
|
||||
public void setCompleted(boolean completed) {
|
||||
this.completed = completed;
|
||||
}
|
||||
}
|
||||
-15
@@ -1,15 +0,0 @@
|
||||
/**
|
||||
* 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.portfolio.savingsaccount.exception;
|
||||
|
||||
import org.mifosplatform.infrastructure.core.exception.AbstractPlatformResourceNotFoundException;
|
||||
|
||||
public class SavingAccountNotFoundException extends AbstractPlatformResourceNotFoundException {
|
||||
|
||||
public SavingAccountNotFoundException(final Long id) {
|
||||
super("error.msg.saving.account.id.invalid", "Saving account with identifier " + id + " does not exist", id);
|
||||
}
|
||||
}
|
||||
-24
@@ -1,24 +0,0 @@
|
||||
package org.mifosplatform.portfolio.savingsaccount.handler;
|
||||
|
||||
import org.mifosplatform.commands.handler.NewCommandSourceHandler;
|
||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.mifosplatform.portfolio.savingsaccount.service.SavingAccountWritePlatformService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class ApproveSavingAccountCommandHandler implements NewCommandSourceHandler {
|
||||
|
||||
private final SavingAccountWritePlatformService savingAccountWritePlatformService;
|
||||
|
||||
@Autowired
|
||||
public ApproveSavingAccountCommandHandler(final SavingAccountWritePlatformService savingAccountWritePlatformService) {
|
||||
this.savingAccountWritePlatformService = savingAccountWritePlatformService;
|
||||
}
|
||||
@Override
|
||||
public CommandProcessingResult processCommand(JsonCommand command) {
|
||||
return this.savingAccountWritePlatformService.approveSavingAccount(command);
|
||||
}
|
||||
|
||||
}
|
||||
-25
@@ -1,25 +0,0 @@
|
||||
package org.mifosplatform.portfolio.savingsaccount.handler;
|
||||
|
||||
import org.mifosplatform.commands.handler.NewCommandSourceHandler;
|
||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.mifosplatform.portfolio.savingsaccount.service.SavingAccountWritePlatformService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class CreateSavingAccountCommandHandler implements NewCommandSourceHandler {
|
||||
|
||||
private final SavingAccountWritePlatformService savingAccountWritePlatformService;
|
||||
|
||||
@Autowired
|
||||
public CreateSavingAccountCommandHandler(final SavingAccountWritePlatformService savingAccountWritePlatformService) {
|
||||
this.savingAccountWritePlatformService = savingAccountWritePlatformService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandProcessingResult processCommand(JsonCommand command) {
|
||||
return this.savingAccountWritePlatformService.createSavingAccount(command);
|
||||
}
|
||||
|
||||
}
|
||||
-25
@@ -1,25 +0,0 @@
|
||||
package org.mifosplatform.portfolio.savingsaccount.handler;
|
||||
|
||||
import org.mifosplatform.commands.handler.NewCommandSourceHandler;
|
||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.mifosplatform.portfolio.savingsaccount.service.SavingAccountWritePlatformService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class DeleteSavingAccountCommandHandler implements NewCommandSourceHandler {
|
||||
|
||||
private final SavingAccountWritePlatformService savingAccountWritePlatformService;
|
||||
|
||||
@Autowired
|
||||
public DeleteSavingAccountCommandHandler(final SavingAccountWritePlatformService savingAccountWritePlatformService) {
|
||||
this.savingAccountWritePlatformService = savingAccountWritePlatformService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandProcessingResult processCommand(JsonCommand command) {
|
||||
return this.savingAccountWritePlatformService.deleteSavingAccount(command.entityId());
|
||||
}
|
||||
|
||||
}
|
||||
-25
@@ -1,25 +0,0 @@
|
||||
package org.mifosplatform.portfolio.savingsaccount.handler;
|
||||
|
||||
import org.mifosplatform.commands.handler.NewCommandSourceHandler;
|
||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.mifosplatform.portfolio.savingsaccount.service.SavingAccountWritePlatformService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class DepositSavingAmountCommandHandler implements NewCommandSourceHandler {
|
||||
|
||||
private final SavingAccountWritePlatformService savingAccountWritePlatformService;
|
||||
|
||||
@Autowired
|
||||
public DepositSavingAmountCommandHandler(final SavingAccountWritePlatformService savingAccountWritePlatformService) {
|
||||
this.savingAccountWritePlatformService = savingAccountWritePlatformService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandProcessingResult processCommand(JsonCommand command) {
|
||||
return this.savingAccountWritePlatformService.depositMoney(command);
|
||||
}
|
||||
|
||||
}
|
||||
-25
@@ -1,25 +0,0 @@
|
||||
package org.mifosplatform.portfolio.savingsaccount.handler;
|
||||
|
||||
import org.mifosplatform.commands.handler.NewCommandSourceHandler;
|
||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.mifosplatform.portfolio.savingsaccount.service.SavingAccountWritePlatformService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class RejectSavingAccountCommandHandler implements NewCommandSourceHandler {
|
||||
|
||||
private final SavingAccountWritePlatformService savingAccountWritePlatformService;
|
||||
|
||||
@Autowired
|
||||
public RejectSavingAccountCommandHandler(final SavingAccountWritePlatformService savingAccountWritePlatformService) {
|
||||
this.savingAccountWritePlatformService = savingAccountWritePlatformService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandProcessingResult processCommand(JsonCommand command) {
|
||||
return this.savingAccountWritePlatformService.rejectSavingApplication(command);
|
||||
}
|
||||
|
||||
}
|
||||
-25
@@ -1,25 +0,0 @@
|
||||
package org.mifosplatform.portfolio.savingsaccount.handler;
|
||||
|
||||
import org.mifosplatform.commands.handler.NewCommandSourceHandler;
|
||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.mifosplatform.portfolio.savingsaccount.service.SavingAccountWritePlatformService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class UndoApprovalSavingAccountCommandHandler implements NewCommandSourceHandler {
|
||||
|
||||
private final SavingAccountWritePlatformService savingAccountWritePlatformService;
|
||||
|
||||
@Autowired
|
||||
public UndoApprovalSavingAccountCommandHandler(final SavingAccountWritePlatformService savingAccountWritePlatformService) {
|
||||
this.savingAccountWritePlatformService = savingAccountWritePlatformService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandProcessingResult processCommand(JsonCommand command) {
|
||||
return this.savingAccountWritePlatformService.undoSavingAccountApproval(command);
|
||||
}
|
||||
|
||||
}
|
||||
-25
@@ -1,25 +0,0 @@
|
||||
package org.mifosplatform.portfolio.savingsaccount.handler;
|
||||
|
||||
import org.mifosplatform.commands.handler.NewCommandSourceHandler;
|
||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.mifosplatform.portfolio.savingsaccount.service.SavingAccountWritePlatformService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class UpdateSavingAccountCommandHandler implements NewCommandSourceHandler {
|
||||
|
||||
private final SavingAccountWritePlatformService savingAccountWritePlatformService;
|
||||
|
||||
@Autowired
|
||||
public UpdateSavingAccountCommandHandler(final SavingAccountWritePlatformService savingAccountWritePlatformService) {
|
||||
this.savingAccountWritePlatformService = savingAccountWritePlatformService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandProcessingResult processCommand(JsonCommand command) {
|
||||
return this.savingAccountWritePlatformService.updateSavingAccount(command.entityId(), command);
|
||||
}
|
||||
|
||||
}
|
||||
-24
@@ -1,24 +0,0 @@
|
||||
package org.mifosplatform.portfolio.savingsaccount.handler;
|
||||
|
||||
import org.mifosplatform.commands.handler.NewCommandSourceHandler;
|
||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.mifosplatform.portfolio.savingsaccount.service.SavingAccountWritePlatformService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class WithdrawSavingAmountCommandHandler implements NewCommandSourceHandler {
|
||||
|
||||
private final SavingAccountWritePlatformService savingAccountWritePlatformService;
|
||||
|
||||
@Autowired
|
||||
public WithdrawSavingAmountCommandHandler(final SavingAccountWritePlatformService savingAccountWritePlatformService) {
|
||||
this.savingAccountWritePlatformService = savingAccountWritePlatformService;
|
||||
}
|
||||
@Override
|
||||
public CommandProcessingResult processCommand(JsonCommand command) {
|
||||
return this.savingAccountWritePlatformService.withdrawSavingAmount(command);
|
||||
}
|
||||
|
||||
}
|
||||
-25
@@ -1,25 +0,0 @@
|
||||
package org.mifosplatform.portfolio.savingsaccount.handler;
|
||||
|
||||
import org.mifosplatform.commands.handler.NewCommandSourceHandler;
|
||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.mifosplatform.portfolio.savingsaccount.service.SavingAccountWritePlatformService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class WithdrawSavingApplicationCommandHandler implements NewCommandSourceHandler {
|
||||
|
||||
private final SavingAccountWritePlatformService savingAccountWritePlatformService;
|
||||
|
||||
@Autowired
|
||||
public WithdrawSavingApplicationCommandHandler(final SavingAccountWritePlatformService savingAccountWritePlatformService) {
|
||||
this.savingAccountWritePlatformService = savingAccountWritePlatformService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandProcessingResult processCommand(JsonCommand command) {
|
||||
return this.savingAccountWritePlatformService.withdrawSavingApplication(command);
|
||||
}
|
||||
|
||||
}
|
||||
-131
@@ -1,131 +0,0 @@
|
||||
package org.mifosplatform.portfolio.savingsaccount.serialization;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
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.mifosplatform.infrastructure.core.data.ApiParameterError;
|
||||
import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder;
|
||||
import org.mifosplatform.infrastructure.core.exception.InvalidJsonException;
|
||||
import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException;
|
||||
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
@Component
|
||||
public final class CalculateSavingScheduleQueryFromApiJsonHelper {
|
||||
|
||||
final Set<String> supportedParams = new HashSet<String>(Arrays.asList("clientId", "productId", "externalId",
|
||||
"savingsDepositAmountPerPeriod", "recurringInterestRate", "savingInterestRate", "tenure", "commencementDate", "locale",
|
||||
"dateFormat", "isLockinPeriodAllowed", "lockinPeriod", "lockinPeriodType", "tenureType", "frequency", "interestType",
|
||||
"interestCalculationMethod", "minimumBalanceForWithdrawal", "isPartialDepositAllowed", "depositEvery", "interestPostEvery",
|
||||
"interestPostFrequency"));
|
||||
|
||||
private final FromJsonHelper fromApiJsonHelper;
|
||||
|
||||
@Autowired
|
||||
public CalculateSavingScheduleQueryFromApiJsonHelper(final FromJsonHelper fromApiJsonHelper) {
|
||||
this.fromApiJsonHelper = fromApiJsonHelper;
|
||||
}
|
||||
|
||||
public void validate(final String json) {
|
||||
|
||||
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
|
||||
|
||||
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
|
||||
fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParams);
|
||||
|
||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
|
||||
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("saving.account");
|
||||
|
||||
final JsonElement element = fromApiJsonHelper.parse(json);
|
||||
|
||||
final Long productId = fromApiJsonHelper.extractLongNamed("productId", element);
|
||||
baseDataValidator.reset().parameter("productId").value(productId).notNull();
|
||||
|
||||
final BigDecimal savingsDepositAmountPerPeriod = fromApiJsonHelper.extractBigDecimalWithLocaleNamed(
|
||||
"savingsDepositAmountPerPeriod", element);
|
||||
baseDataValidator.reset().parameter("savingsDepositAmountPerPeriod").value(savingsDepositAmountPerPeriod).notNull()
|
||||
.zeroOrPositiveAmount();
|
||||
|
||||
final BigDecimal recurringInterestRate = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("recurringInterestRate", element);
|
||||
baseDataValidator.reset().parameter("recurringInterestRate").value(recurringInterestRate).notNull().zeroOrPositiveAmount();
|
||||
|
||||
final BigDecimal savingInterestRate = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("savingInterestRate", element);
|
||||
baseDataValidator.reset().parameter("savingInterestRate").value(savingInterestRate).notNull().zeroOrPositiveAmount();
|
||||
|
||||
final Integer tenure = fromApiJsonHelper.extractIntegerNamed("tenure", element, Locale.getDefault());
|
||||
baseDataValidator.reset().parameter("tenure").value(tenure).notNull();
|
||||
|
||||
final LocalDate commencementDate = fromApiJsonHelper.extractLocalDateNamed("commencementDate", element);
|
||||
baseDataValidator.reset().parameter("commencementDate").value(commencementDate).notNull();
|
||||
|
||||
final Boolean isLockinPeriodAllowedCommandValue = fromApiJsonHelper.extractBooleanNamed("isLockinPeriodAllowed", element);
|
||||
baseDataValidator.reset().parameter("isLockinPeriodAllowed").value(isLockinPeriodAllowedCommandValue)
|
||||
.trueOrFalseRequired(isBooleanValueUpdated(isLockinPeriodAllowedCommandValue));
|
||||
|
||||
final Integer lockinPeriod = fromApiJsonHelper.extractIntegerNamed("lockinPeriod", element, Locale.getDefault());
|
||||
baseDataValidator.reset().parameter("lockinPeriod").value(lockinPeriod).notNull().zeroOrPositiveAmount();
|
||||
|
||||
final Integer lockinPeriodType = fromApiJsonHelper.extractIntegerNamed("lockinPeriodType", element, Locale.getDefault());
|
||||
baseDataValidator.reset().parameter("lockinPeriodType").value(lockinPeriodType).notNull().inMinMaxRange(1, 3);
|
||||
|
||||
final Integer tenureType = fromApiJsonHelper.extractIntegerNamed("tenureType", element, Locale.getDefault());
|
||||
baseDataValidator.reset().parameter("tenureType").value(tenureType).ignoreIfNull();
|
||||
|
||||
final Integer frequency = fromApiJsonHelper.extractIntegerNamed("frequency", element, Locale.getDefault());
|
||||
baseDataValidator.reset().parameter("frequency").value(frequency).ignoreIfNull();
|
||||
|
||||
final Integer interestType = fromApiJsonHelper.extractIntegerNamed("interestType", element, Locale.getDefault());
|
||||
baseDataValidator.reset().parameter("interestType").value(interestType).ignoreIfNull();
|
||||
|
||||
final Integer interestCalculationMethod = fromApiJsonHelper.extractIntegerNamed("interestCalculationMethod", element,
|
||||
Locale.getDefault());
|
||||
baseDataValidator.reset().parameter("interestCalculationMethod").value(interestCalculationMethod).ignoreIfNull();
|
||||
|
||||
final BigDecimal minimumBalanceForWithdrawal = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("minimumBalanceForWithdrawal",
|
||||
element);
|
||||
baseDataValidator.reset().parameter("minimumBalanceForWithdrawal").value(minimumBalanceForWithdrawal).ignoreIfNull()
|
||||
.zeroOrPositiveAmount();
|
||||
|
||||
final Boolean isPartialDepositAllowedCommandValue = fromApiJsonHelper.extractBooleanNamed("isPartialDepositAllowed", element);
|
||||
baseDataValidator.reset().parameter("isPartialDepositAllowed").value(isPartialDepositAllowedCommandValue)
|
||||
.trueOrFalseRequired(isBooleanValueUpdated(isPartialDepositAllowedCommandValue)).ignoreIfNull();
|
||||
|
||||
final Integer depositEvery = fromApiJsonHelper.extractIntegerNamed("depositEvery", element, Locale.getDefault());
|
||||
baseDataValidator.reset().parameter("depositEvery").value(depositEvery).notNull().zeroOrPositiveAmount();
|
||||
|
||||
final Integer interestPostEvery = fromApiJsonHelper.extractIntegerNamed("interestPostEvery", element, Locale.getDefault());
|
||||
baseDataValidator.reset().parameter("interestPostEvery").value(interestPostEvery).notNull().zeroOrPositiveAmount();
|
||||
|
||||
final Integer interestPostFrequency = fromApiJsonHelper.extractIntegerNamed("interestPostFrequency", element, Locale.getDefault());
|
||||
baseDataValidator.reset().parameter("interestPostFrequency").value(interestPostFrequency).notNull().zeroOrPositiveAmount();
|
||||
|
||||
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
||||
}
|
||||
|
||||
private Boolean isBooleanValueUpdated(final Boolean actualValue) {
|
||||
Boolean isUpdated = false;
|
||||
if (actualValue != null) {
|
||||
isUpdated = true;
|
||||
}
|
||||
return isUpdated;
|
||||
}
|
||||
|
||||
private void throwExceptionIfValidationWarningsExist(final List<ApiParameterError> dataValidationErrors) {
|
||||
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
|
||||
"Validation errors exist.", dataValidationErrors); }
|
||||
}
|
||||
|
||||
}
|
||||
-216
@@ -1,216 +0,0 @@
|
||||
package org.mifosplatform.portfolio.savingsaccount.serialization;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
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.mifosplatform.infrastructure.core.data.ApiParameterError;
|
||||
import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder;
|
||||
import org.mifosplatform.infrastructure.core.exception.InvalidJsonException;
|
||||
import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException;
|
||||
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
@Component
|
||||
public class SavingAccountCommandFromApiJsonDeserializer {
|
||||
|
||||
final Set<String> supportedParams = new HashSet<String>(Arrays.asList("clientId", "productId", "externalId", "currencyCode",
|
||||
"digitsAfterDecimal", "savingsDepositAmountPerPeriod", "recurringInterestRate", "savingInterestRate", "tenure",
|
||||
"commencementDate", "locale", "dateFormat", "isLockinPeriodAllowed", "lockinPeriod", "lockinPeriodType", "tenureType",
|
||||
"frequency", "interestType", "interestCalculationMethod", "minimumBalanceForWithdrawal", "isPartialDepositAllowed",
|
||||
"depositEvery", "interestPostEvery", "interestPostFrequency"));
|
||||
|
||||
private final FromJsonHelper fromApiJsonHelper;
|
||||
|
||||
@Autowired
|
||||
public SavingAccountCommandFromApiJsonDeserializer(final FromJsonHelper fromApiJsonHelper) {
|
||||
this.fromApiJsonHelper = fromApiJsonHelper;
|
||||
}
|
||||
|
||||
public void validateForCreate(final String json) {
|
||||
|
||||
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
|
||||
|
||||
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
|
||||
fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParams);
|
||||
|
||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
|
||||
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("saving.account");
|
||||
|
||||
final JsonElement element = fromApiJsonHelper.parse(json);
|
||||
|
||||
final Long clientId = fromApiJsonHelper.extractLongNamed("clientId", element);
|
||||
baseDataValidator.reset().parameter("clientId").value(clientId).notNull();
|
||||
|
||||
final Long productId = fromApiJsonHelper.extractLongNamed("productId", element);
|
||||
baseDataValidator.reset().parameter("productId").value(productId).notNull();
|
||||
|
||||
final String externalId = fromApiJsonHelper.extractStringNamed("externalId", element);
|
||||
baseDataValidator.reset().parameter("externalId").value(externalId).ignoreIfNull().notExceedingLengthOf(100);
|
||||
|
||||
final BigDecimal savingsDepositAmountPerPeriod = fromApiJsonHelper.extractBigDecimalWithLocaleNamed(
|
||||
"savingsDepositAmountPerPeriod", element);
|
||||
baseDataValidator.reset().parameter("savingsDepositAmountPerPeriod").value(savingsDepositAmountPerPeriod).notNull()
|
||||
.zeroOrPositiveAmount();
|
||||
|
||||
final BigDecimal recurringInterestRate = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("recurringInterestRate", element);
|
||||
baseDataValidator.reset().parameter("recurringInterestRate").value(recurringInterestRate).notNull().zeroOrPositiveAmount();
|
||||
|
||||
final BigDecimal savingInterestRate = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("savingInterestRate", element);
|
||||
baseDataValidator.reset().parameter("savingInterestRate").value(savingInterestRate).notNull().zeroOrPositiveAmount();
|
||||
|
||||
final Integer tenure = fromApiJsonHelper.extractIntegerNamed("tenure", element, Locale.getDefault());
|
||||
baseDataValidator.reset().parameter("tenure").value(tenure).notNull();
|
||||
|
||||
final LocalDate commencementDate = fromApiJsonHelper.extractLocalDateNamed("commencementDate", element);
|
||||
baseDataValidator.reset().parameter("commencementDate").value(commencementDate).notNull();
|
||||
|
||||
final Boolean isLockinPeriodAllowedCommandValue = fromApiJsonHelper.extractBooleanNamed("isLockinPeriodAllowed", element);
|
||||
baseDataValidator.reset().parameter("isLockinPeriodAllowed").value(isLockinPeriodAllowedCommandValue)
|
||||
.trueOrFalseRequired(isBooleanValueUpdated(isLockinPeriodAllowedCommandValue));
|
||||
|
||||
final Integer lockinPeriod = fromApiJsonHelper.extractIntegerNamed("lockinPeriod", element, Locale.getDefault());
|
||||
baseDataValidator.reset().parameter("lockinPeriod").value(lockinPeriod).notNull().zeroOrPositiveAmount();
|
||||
|
||||
final Integer lockinPeriodType = fromApiJsonHelper.extractIntegerNamed("lockinPeriodType", element, Locale.getDefault());
|
||||
baseDataValidator.reset().parameter("lockinPeriodType").value(lockinPeriodType).notNull().inMinMaxRange(1, 3);
|
||||
|
||||
final Integer tenureType = fromApiJsonHelper.extractIntegerNamed("tenureType", element, Locale.getDefault());
|
||||
baseDataValidator.reset().parameter("tenureType").value(tenureType).ignoreIfNull();
|
||||
|
||||
final Integer frequency = fromApiJsonHelper.extractIntegerNamed("frequency", element, Locale.getDefault());
|
||||
baseDataValidator.reset().parameter("frequency").value(frequency).ignoreIfNull();
|
||||
|
||||
final Integer interestType = fromApiJsonHelper.extractIntegerNamed("interestType", element, Locale.getDefault());
|
||||
baseDataValidator.reset().parameter("interestType").value(interestType).ignoreIfNull();
|
||||
|
||||
final Integer interestCalculationMethod = fromApiJsonHelper.extractIntegerNamed("interestCalculationMethod", element,
|
||||
Locale.getDefault());
|
||||
baseDataValidator.reset().parameter("interestCalculationMethod").value(interestCalculationMethod).ignoreIfNull();
|
||||
|
||||
final BigDecimal minimumBalanceForWithdrawal = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("minimumBalanceForWithdrawal",
|
||||
element);
|
||||
baseDataValidator.reset().parameter("minimumBalanceForWithdrawal").value(minimumBalanceForWithdrawal).ignoreIfNull()
|
||||
.zeroOrPositiveAmount();
|
||||
|
||||
final Boolean isPartialDepositAllowedCommandValue = fromApiJsonHelper.extractBooleanNamed("isPartialDepositAllowed", element);
|
||||
baseDataValidator.reset().parameter("isPartialDepositAllowed").value(isPartialDepositAllowedCommandValue)
|
||||
.trueOrFalseRequired(isBooleanValueUpdated(isPartialDepositAllowedCommandValue)).ignoreIfNull();
|
||||
|
||||
final Integer depositEvery = fromApiJsonHelper.extractIntegerNamed("depositEvery", element, Locale.getDefault());
|
||||
baseDataValidator.reset().parameter("depositEvery").value(depositEvery).notNull().zeroOrPositiveAmount();
|
||||
|
||||
final Integer interestPostEvery = fromApiJsonHelper.extractIntegerNamed("interestPostEvery", element, Locale.getDefault());
|
||||
baseDataValidator.reset().parameter("interestPostEvery").value(interestPostEvery).notNull().zeroOrPositiveAmount();
|
||||
|
||||
final Integer interestPostFrequency = fromApiJsonHelper.extractIntegerNamed("interestPostFrequency", element, Locale.getDefault());
|
||||
baseDataValidator.reset().parameter("interestPostFrequency").value(interestPostFrequency).notNull().zeroOrPositiveAmount();
|
||||
|
||||
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
||||
}
|
||||
|
||||
public void validateForUpdate(final String json) {
|
||||
|
||||
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
|
||||
|
||||
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
|
||||
fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParams);
|
||||
|
||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
|
||||
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("saving.account");
|
||||
|
||||
final JsonElement element = fromApiJsonHelper.parse(json);
|
||||
|
||||
final Long productId = fromApiJsonHelper.extractLongNamed("productId", element);
|
||||
baseDataValidator.reset().parameter("productId").value(productId).ignoreIfNull();
|
||||
|
||||
final String externalId = fromApiJsonHelper.extractStringNamed("externalId", element);
|
||||
baseDataValidator.reset().parameter("externalId").value(externalId).ignoreIfNull().notExceedingLengthOf(100);
|
||||
|
||||
final BigDecimal savingsDepositAmountPerPeriod = fromApiJsonHelper.extractBigDecimalWithLocaleNamed(
|
||||
"savingsDepositAmountPerPeriod", element);
|
||||
baseDataValidator.reset().parameter("savingsDepositAmountPerPeriod").value(savingsDepositAmountPerPeriod).ignoreIfNull()
|
||||
.zeroOrPositiveAmount();
|
||||
|
||||
final BigDecimal recurringInterestRate = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("recurringInterestRate", element);
|
||||
baseDataValidator.reset().parameter("recurringInterestRate").value(recurringInterestRate).ignoreIfNull().zeroOrPositiveAmount();
|
||||
|
||||
final BigDecimal savingInterestRate = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("savingInterestRate", element);
|
||||
baseDataValidator.reset().parameter("savingInterestRate").value(savingInterestRate).ignoreIfNull().zeroOrPositiveAmount();
|
||||
|
||||
final Integer tenure = fromApiJsonHelper.extractIntegerNamed("tenure", element, Locale.getDefault());
|
||||
baseDataValidator.reset().parameter("tenure").value(tenure).ignoreIfNull();
|
||||
|
||||
final LocalDate commencementDate = fromApiJsonHelper.extractLocalDateNamed("commencementDate", element);
|
||||
baseDataValidator.reset().parameter("commencementDate").value(commencementDate).ignoreIfNull();
|
||||
|
||||
final Boolean isLockinPeriodAllowedCommandValue = fromApiJsonHelper.extractBooleanNamed("isLockinPeriodAllowed", element);
|
||||
baseDataValidator.reset().parameter("isLockinPeriodAllowed").value(isLockinPeriodAllowedCommandValue)
|
||||
.trueOrFalseRequired(isBooleanValueUpdated(isLockinPeriodAllowedCommandValue));
|
||||
|
||||
final Integer lockinPeriod = fromApiJsonHelper.extractIntegerNamed("lockinPeriod", element, Locale.getDefault());
|
||||
baseDataValidator.reset().parameter("lockinPeriod").value(lockinPeriod).ignoreIfNull().zeroOrPositiveAmount();
|
||||
|
||||
final Integer lockinPeriodType = fromApiJsonHelper.extractIntegerNamed("lockinPeriodType", element, Locale.getDefault());
|
||||
baseDataValidator.reset().parameter("lockinPeriodType").value(lockinPeriodType).ignoreIfNull().inMinMaxRange(1, 3);
|
||||
|
||||
final Integer tenureType = fromApiJsonHelper.extractIntegerNamed("tenureType", element, Locale.getDefault());
|
||||
baseDataValidator.reset().parameter("tenureType").value(tenureType).ignoreIfNull();
|
||||
|
||||
final Integer frequency = fromApiJsonHelper.extractIntegerNamed("frequency", element, Locale.getDefault());
|
||||
baseDataValidator.reset().parameter("frequency").value(frequency).ignoreIfNull();
|
||||
|
||||
final Integer interestType = fromApiJsonHelper.extractIntegerNamed("interestType", element, Locale.getDefault());
|
||||
baseDataValidator.reset().parameter("interestType").value(interestType).ignoreIfNull();
|
||||
|
||||
final Integer interestCalculationMethod = fromApiJsonHelper.extractIntegerNamed("interestCalculationMethod", element,
|
||||
Locale.getDefault());
|
||||
baseDataValidator.reset().parameter("interestCalculationMethod").value(interestCalculationMethod).ignoreIfNull();
|
||||
|
||||
final BigDecimal minimumBalanceForWithdrawal = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("minimumBalanceForWithdrawal",
|
||||
element);
|
||||
baseDataValidator.reset().parameter("minimumBalanceForWithdrawal").value(minimumBalanceForWithdrawal).ignoreIfNull()
|
||||
.zeroOrPositiveAmount();
|
||||
|
||||
final Boolean isPartialDepositAllowedCommandValue = fromApiJsonHelper.extractBooleanNamed("isPartialDepositAllowed", element);
|
||||
baseDataValidator.reset().parameter("isPartialDepositAllowed").value(isPartialDepositAllowedCommandValue)
|
||||
.trueOrFalseRequired(isBooleanValueUpdated(isPartialDepositAllowedCommandValue)).ignoreIfNull();
|
||||
|
||||
final Integer depositEvery = fromApiJsonHelper.extractIntegerNamed("depositEvery", element, Locale.getDefault());
|
||||
baseDataValidator.reset().parameter("depositEvery").value(depositEvery).ignoreIfNull().zeroOrPositiveAmount();
|
||||
|
||||
final Integer interestPostEvery = fromApiJsonHelper.extractIntegerNamed("interestPostEvery", element, Locale.getDefault());
|
||||
baseDataValidator.reset().parameter("interestPostEvery").value(interestPostEvery).ignoreIfNull().zeroOrPositiveAmount();
|
||||
|
||||
final Integer interestPostFrequency = fromApiJsonHelper.extractIntegerNamed("interestPostFrequency", element, Locale.getDefault());
|
||||
baseDataValidator.reset().parameter("interestPostFrequency").value(interestPostFrequency).ignoreIfNull().zeroOrPositiveAmount();
|
||||
|
||||
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
||||
|
||||
}
|
||||
|
||||
private Boolean isBooleanValueUpdated(final Boolean actualValue) {
|
||||
Boolean isUpdated = false;
|
||||
if (actualValue != null) {
|
||||
isUpdated = true;
|
||||
}
|
||||
return isUpdated;
|
||||
}
|
||||
|
||||
private void throwExceptionIfValidationWarningsExist(final List<ApiParameterError> dataValidationErrors) {
|
||||
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
|
||||
"Validation errors exist.", dataValidationErrors); }
|
||||
}
|
||||
}
|
||||
-153
@@ -1,153 +0,0 @@
|
||||
package org.mifosplatform.portfolio.savingsaccount.serialization;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
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.mifosplatform.infrastructure.core.data.ApiParameterError;
|
||||
import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder;
|
||||
import org.mifosplatform.infrastructure.core.exception.InvalidJsonException;
|
||||
import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException;
|
||||
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
@Component
|
||||
public class SavingAccountStateTransitionCommandFromApiJsonDeserializer {
|
||||
|
||||
private final Set<String> supportedParams = new HashSet<String>(Arrays.asList("locale", "dateFormat", "commencementDate", "eventDate",
|
||||
"savingsDepositAmountPerPeriod", "minimumBalanceForWithdrawal", "recurringInterestRate", "savingInterestRate", "depositDate",
|
||||
"interestType", "tenure", "tenureType", "frequency", "payEvery", "note", "interestPostEvery", "interestPostFrequency"));
|
||||
|
||||
private final FromJsonHelper fromApiJsonHelper;
|
||||
|
||||
@Autowired
|
||||
public SavingAccountStateTransitionCommandFromApiJsonDeserializer(final FromJsonHelper fromApiJsonHelper) {
|
||||
this.fromApiJsonHelper = fromApiJsonHelper;
|
||||
}
|
||||
|
||||
public void validateForApprove(final String json) {
|
||||
|
||||
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
|
||||
|
||||
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
|
||||
fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParams);
|
||||
|
||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
|
||||
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("saving.account.transition");
|
||||
|
||||
final JsonElement element = fromApiJsonHelper.parse(json);
|
||||
|
||||
final LocalDate commencementDate = fromApiJsonHelper.extractLocalDateNamed("commencementDate", element);
|
||||
baseDataValidator.reset().parameter("commencementDate").value(commencementDate).notNull();
|
||||
|
||||
final BigDecimal savingsDepositAmountPerPeriod = fromApiJsonHelper.extractBigDecimalWithLocaleNamed(
|
||||
"savingsDepositAmountPerPeriod", element);
|
||||
baseDataValidator.reset().parameter("savingsDepositAmountPerPeriod").value(savingsDepositAmountPerPeriod).ignoreIfNull()
|
||||
.zeroOrPositiveAmount();
|
||||
|
||||
final BigDecimal minimumBalanceForWithdrawal = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("minimumBalanceForWithdrawal",
|
||||
element);
|
||||
baseDataValidator.reset().parameter("minimumBalanceForWithdrawal").value(minimumBalanceForWithdrawal).ignoreIfNull()
|
||||
.zeroOrPositiveAmount();
|
||||
|
||||
final BigDecimal recurringInterestRate = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("recurringInterestRate", element);
|
||||
baseDataValidator.reset().parameter("recurringInterestRate").value(recurringInterestRate).ignoreIfNull().zeroOrPositiveAmount();
|
||||
|
||||
final BigDecimal savingInterestRate = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("savingInterestRate", element);
|
||||
baseDataValidator.reset().parameter("savingInterestRate").value(savingInterestRate).ignoreIfNull().zeroOrPositiveAmount();
|
||||
|
||||
final Integer interestType = fromApiJsonHelper.extractIntegerNamed("interestType", element, Locale.getDefault());
|
||||
baseDataValidator.reset().parameter("interestType").value(interestType).ignoreIfNull().zeroOrPositiveAmount();
|
||||
|
||||
final Integer tenureType = fromApiJsonHelper.extractIntegerNamed("tenureType", element, Locale.getDefault());
|
||||
baseDataValidator.reset().parameter("tenureType").value(tenureType).ignoreIfNull().zeroOrPositiveAmount();
|
||||
|
||||
final Integer tenure = fromApiJsonHelper.extractIntegerNamed("tenure", element, Locale.getDefault());
|
||||
baseDataValidator.reset().parameter("tenure").value(tenure).ignoreIfNull().zeroOrPositiveAmount();
|
||||
|
||||
final Integer frequency = fromApiJsonHelper.extractIntegerNamed("frequency", element, Locale.getDefault());
|
||||
baseDataValidator.reset().parameter("frequency").value(frequency).ignoreIfNull().zeroOrPositiveAmount();
|
||||
|
||||
final Integer depositEvery = fromApiJsonHelper.extractIntegerNamed("payEvery", element, Locale.getDefault());
|
||||
baseDataValidator.reset().parameter("payEvery").value(depositEvery).ignoreIfNull().zeroOrPositiveAmount();
|
||||
|
||||
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
||||
}
|
||||
|
||||
public void validateForReject(final String json) {
|
||||
|
||||
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
|
||||
|
||||
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
|
||||
fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParams);
|
||||
|
||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
|
||||
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("saving.account.transition");
|
||||
|
||||
final JsonElement element = fromApiJsonHelper.parse(json);
|
||||
|
||||
final LocalDate eventDate = fromApiJsonHelper.extractLocalDateNamed("eventDate", element);
|
||||
baseDataValidator.reset().parameter("eventDate").value(eventDate).notNull();
|
||||
|
||||
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
||||
}
|
||||
|
||||
public void validateForWithdrawApplication(final String json) {
|
||||
|
||||
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
|
||||
|
||||
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
|
||||
fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParams);
|
||||
|
||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
|
||||
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("saving.account.transition");
|
||||
|
||||
final JsonElement element = fromApiJsonHelper.parse(json);
|
||||
|
||||
final LocalDate eventDate = fromApiJsonHelper.extractLocalDateNamed("eventDate", element);
|
||||
baseDataValidator.reset().parameter("eventDate").value(eventDate).notNull();
|
||||
|
||||
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
||||
}
|
||||
|
||||
public void validateForDepositAmount(final String json) {
|
||||
|
||||
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
|
||||
|
||||
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
|
||||
fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParams);
|
||||
|
||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
|
||||
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
|
||||
.resource("saving.account.transaction.deposit");
|
||||
|
||||
final JsonElement element = fromApiJsonHelper.parse(json);
|
||||
|
||||
final LocalDate depositDate = fromApiJsonHelper.extractLocalDateNamed("depositDate", element);
|
||||
baseDataValidator.reset().parameter("depositDate").value(depositDate).notNull();
|
||||
|
||||
final BigDecimal savingsDepositAmountPerPeriod = fromApiJsonHelper.extractBigDecimalWithLocaleNamed(
|
||||
"savingsDepositAmountPerPeriod", element);
|
||||
baseDataValidator.reset().parameter("savingsDepositAmountPerPeriod").value(savingsDepositAmountPerPeriod).notNull()
|
||||
.zeroOrPositiveAmount();
|
||||
|
||||
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
||||
}
|
||||
|
||||
private void throwExceptionIfValidationWarningsExist(final List<ApiParameterError> dataValidationErrors) {
|
||||
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
|
||||
"Validation errors exist.", dataValidationErrors); }
|
||||
}
|
||||
}
|
||||
-14
@@ -1,14 +0,0 @@
|
||||
/**
|
||||
* 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.portfolio.savingsaccount.service;
|
||||
|
||||
import org.mifosplatform.infrastructure.core.api.JsonQuery;
|
||||
import org.mifosplatform.portfolio.savingsaccount.data.SavingScheduleData;
|
||||
|
||||
public interface CalculateSavingSchedule {
|
||||
SavingScheduleData calculateSavingSchedule(JsonQuery query);
|
||||
}
|
||||
|
||||
-42
@@ -1,42 +0,0 @@
|
||||
/**
|
||||
* 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.portfolio.savingsaccount.service;
|
||||
|
||||
import org.mifosplatform.infrastructure.core.api.JsonQuery;
|
||||
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
|
||||
import org.mifosplatform.portfolio.savingsaccount.data.SavingScheduleData;
|
||||
import org.mifosplatform.portfolio.savingsaccount.serialization.CalculateSavingScheduleQueryFromApiJsonHelper;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class CalculateSavingScheduleImpl implements CalculateSavingSchedule {
|
||||
|
||||
private final PlatformSecurityContext context;
|
||||
private final CalculateSavingScheduleQueryFromApiJsonHelper fromApiJsonDeserializer;
|
||||
private final SavingScheduleAssembler savingScheduleAssembler;
|
||||
|
||||
@Autowired
|
||||
public CalculateSavingScheduleImpl(final PlatformSecurityContext context,
|
||||
final CalculateSavingScheduleQueryFromApiJsonHelper fromApiJsonDeserializer,
|
||||
final SavingScheduleAssembler savingScheduleAssembler) {
|
||||
this.context = context;
|
||||
this.fromApiJsonDeserializer = fromApiJsonDeserializer;
|
||||
this.savingScheduleAssembler = savingScheduleAssembler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SavingScheduleData calculateSavingSchedule(final JsonQuery query) {
|
||||
|
||||
context.authenticatedUser();
|
||||
|
||||
this.fromApiJsonDeserializer.validate(query.json());
|
||||
|
||||
return this.savingScheduleAssembler.fromJson(query.parsedJson());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
-57
@@ -1,57 +0,0 @@
|
||||
/**
|
||||
* 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.portfolio.savingsaccount.service;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.joda.time.LocalDate;
|
||||
import org.mifosplatform.portfolio.savingsaccount.domain.DepositScheduleDateGenerator;
|
||||
import org.mifosplatform.portfolio.savingsaccountproduct.domain.SavingFrequencyType;
|
||||
|
||||
public class DefaultDepositScheduleDateGenerator implements DepositScheduleDateGenerator {
|
||||
|
||||
@Override
|
||||
public List<LocalDate> generate(LocalDate scheuleStartDate, Integer paymentPeriods, Integer depositFrequency,
|
||||
SavingFrequencyType savingFrequencyType) {
|
||||
|
||||
List<LocalDate> duePaymentPeriodDates = new ArrayList<LocalDate>(depositFrequency);
|
||||
LocalDate startDate = scheuleStartDate;
|
||||
|
||||
for (int period = 1; period <= paymentPeriods; period++) {
|
||||
|
||||
LocalDate duePaymentPeriodDate = startDate;
|
||||
if (period == 1) {
|
||||
duePaymentPeriodDate = startDate;
|
||||
} else {
|
||||
switch (savingFrequencyType) {
|
||||
case DAILY:
|
||||
duePaymentPeriodDate = startDate.plusDays(depositFrequency);
|
||||
break;
|
||||
case MONTHLY:
|
||||
duePaymentPeriodDate = startDate.plusMonths(depositFrequency);
|
||||
break;
|
||||
case QUATERLY:
|
||||
duePaymentPeriodDate = startDate.plusMonths(3*depositFrequency);
|
||||
break;
|
||||
case HALFYEARLY:
|
||||
duePaymentPeriodDate = startDate.plusMonths(6*depositFrequency);
|
||||
break;
|
||||
case YEARLY:
|
||||
duePaymentPeriodDate = startDate.plusYears(depositFrequency);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
duePaymentPeriodDates.add(duePaymentPeriodDate);
|
||||
startDate = duePaymentPeriodDate;
|
||||
}
|
||||
|
||||
return duePaymentPeriodDates;
|
||||
}
|
||||
|
||||
}
|
||||
-512
@@ -1,512 +0,0 @@
|
||||
/**
|
||||
* 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.portfolio.savingsaccount.service;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.joda.time.LocalDate;
|
||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
|
||||
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
|
||||
import org.mifosplatform.organisation.monetary.domain.Money;
|
||||
import org.mifosplatform.portfolio.client.domain.Client;
|
||||
import org.mifosplatform.portfolio.client.domain.ClientRepository;
|
||||
import org.mifosplatform.portfolio.client.exception.ClientNotFoundException;
|
||||
import org.mifosplatform.portfolio.loanproduct.domain.PeriodFrequencyType;
|
||||
import org.mifosplatform.portfolio.savingsaccount.data.SavingScheduleData;
|
||||
import org.mifosplatform.portfolio.savingsaccount.data.SavingSchedulePeriodData;
|
||||
import org.mifosplatform.portfolio.savingsaccount.domain.ReccuringDepositInterestCalculator;
|
||||
import org.mifosplatform.portfolio.savingsaccount.domain.SavingAccount;
|
||||
import org.mifosplatform.portfolio.savingsaccount.domain.SavingScheduleInstallments;
|
||||
import org.mifosplatform.portfolio.savingsaccountproduct.domain.SavingFrequencyType;
|
||||
import org.mifosplatform.portfolio.savingsaccountproduct.domain.SavingInterestCalculationMethod;
|
||||
import org.mifosplatform.portfolio.savingsaccountproduct.domain.SavingProduct;
|
||||
import org.mifosplatform.portfolio.savingsaccountproduct.domain.SavingProductRepository;
|
||||
import org.mifosplatform.portfolio.savingsaccountproduct.domain.SavingProductType;
|
||||
import org.mifosplatform.portfolio.savingsaccountproduct.domain.SavingsInterestType;
|
||||
import org.mifosplatform.portfolio.savingsaccountproduct.exception.SavingProductNotFoundException;
|
||||
import org.mifosplatform.portfolio.savingsdepositaccount.domain.DepositAccountStatus;
|
||||
import org.mifosplatform.portfolio.savingsdepositaccount.domain.DepositLifecycleStateMachine;
|
||||
import org.mifosplatform.portfolio.savingsdepositaccount.domain.DepositLifecycleStateMachineImpl;
|
||||
import org.mifosplatform.portfolio.savingsdepositaccount.exception.DepositAccountTransactionsException;
|
||||
import org.mifosplatform.portfolio.savingsdepositproduct.domain.TenureTypeEnum;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
|
||||
@Service
|
||||
public class SavingAccountAssembler {
|
||||
|
||||
private final ClientRepository clientRepository;
|
||||
private final SavingProductRepository savingProductRepository;
|
||||
private final ReccuringDepositInterestCalculator reccuringDepositInterestCalculator;
|
||||
private final FromJsonHelper fromApiJsonHelper;
|
||||
private final SavingScheduleAssembler savingScheduleAssembler;
|
||||
|
||||
@Autowired
|
||||
public SavingAccountAssembler(final ClientRepository clientRepository, final SavingProductRepository savingProductRepository,
|
||||
final ReccuringDepositInterestCalculator reccuringDepositInterestCalculator, final FromJsonHelper fromApiJsonHelper,
|
||||
final SavingScheduleAssembler savingScheduleAssembler) {
|
||||
this.clientRepository = clientRepository;
|
||||
this.savingProductRepository = savingProductRepository;
|
||||
this.reccuringDepositInterestCalculator = reccuringDepositInterestCalculator;
|
||||
this.fromApiJsonHelper = fromApiJsonHelper;
|
||||
this.savingScheduleAssembler = savingScheduleAssembler;
|
||||
}
|
||||
|
||||
public SavingAccount assembleFrom(final JsonCommand command) {
|
||||
|
||||
final JsonElement element = command.parsedJson();
|
||||
final Long clientId = fromApiJsonHelper.extractLongNamed("clientId", element);
|
||||
final Long productId = fromApiJsonHelper.extractLongNamed("productId", element);
|
||||
final String externalId = fromApiJsonHelper.extractStringNamed("externalId", element);
|
||||
final String currencyCode = command.stringValueOfParameterNamed("currencyCode");
|
||||
final Integer digitsAfterDecimal = command.integerValueOfParameterNamed("digitsAfterDecimal");
|
||||
final BigDecimal savingsDepositAmountPerPeriod = command.bigDecimalValueOfParameterNamed("savingsDepositAmountPerPeriod");
|
||||
final BigDecimal recurringInterestRate = command.bigDecimalValueOfParameterNamed("recurringInterestRate");
|
||||
final BigDecimal savingInterestRateCommandValue = command.bigDecimalValueOfParameterNamed("savingInterestRate");
|
||||
final Integer tenureCommandValue = command.integerValueOfParameterNamed("tenure");
|
||||
final LocalDate commencementDate = command.localDateValueOfParameterNamed("commencementDate");
|
||||
final Integer lockinPeriodTypeCommandValue = command.integerValueOfParameterNamed("lockinPeriodType");
|
||||
final boolean isLockinPeriodAllowedCommandValue = command.booleanPrimitiveValueOfParameterNamed("isLockinPeriodAllowed");
|
||||
final Integer lockinPeriodCommandValue = command.integerValueOfParameterNamed("lockinPeriod");
|
||||
final Integer tenureTypeCommandValue = command.integerValueOfParameterNamed("tenureType");
|
||||
final Integer frequencyCommandValue = command.integerValueOfParameterNamed("frequency");
|
||||
final Integer interestTypeCommandValue = command.integerValueOfParameterNamed("interestType");
|
||||
final Integer interestCalculationMethodCommandValue = command.integerValueOfParameterNamed("interestCalculationMethod");
|
||||
// final BigDecimal minimumBalanceForWithdrawal =
|
||||
// command.bigDecimalValueOfParameterNamed("minimumBalanceForWithdrawal");
|
||||
// final boolean isPartialDepositAllowed =
|
||||
// command.booleanPrimitiveValueOfParameterNamed("isPartialDepositAllowed");
|
||||
final Integer depositEvery = command.integerValueOfParameterNamed("depositEvery");
|
||||
final Integer interestPostEvery = command.integerValueOfParameterNamed("interestPostEvery");
|
||||
final Integer interestPostFrequencyCommandValue = command.integerValueOfParameterNamed("interestPostFrequency");
|
||||
|
||||
Client client = this.clientRepository.findOne(clientId);
|
||||
if (client == null || client.isDeleted()) { throw new ClientNotFoundException(clientId); }
|
||||
|
||||
SavingProduct product = this.savingProductRepository.findOne(productId);
|
||||
if (product == null || product.isDeleted()) { throw new SavingProductNotFoundException(productId); }
|
||||
|
||||
MonetaryCurrency currency = product.getCurrency();
|
||||
if (currencyCode != null) currency = new MonetaryCurrency(currencyCode, currency.getDigitsAfterDecimal());
|
||||
if (digitsAfterDecimal != null) currency = new MonetaryCurrency(currency.getCode(), digitsAfterDecimal);
|
||||
|
||||
Money savingsDeposit = Money.of(currency, product.getSavingProductRelatedDetail().getSavingsDepositAmount());
|
||||
if (savingsDepositAmountPerPeriod != null) {
|
||||
savingsDeposit = Money.of(currency, savingsDepositAmountPerPeriod);
|
||||
}
|
||||
|
||||
Integer tenure = product.getSavingProductRelatedDetail().getTenure();
|
||||
if (tenureCommandValue != null) {
|
||||
tenure = tenureCommandValue;
|
||||
}
|
||||
|
||||
TenureTypeEnum tenureTypeEnum = TenureTypeEnum.fromInt(product.getSavingProductRelatedDetail().getTenureType());
|
||||
if (tenureTypeCommandValue != null) {
|
||||
tenureTypeEnum = TenureTypeEnum.fromInt(tenureTypeCommandValue);
|
||||
}
|
||||
|
||||
SavingProductType savingProductType = SavingProductType.fromInt(product.getSavingProductRelatedDetail().getSavingProductType());
|
||||
|
||||
SavingFrequencyType savingFrequencyType = SavingFrequencyType.fromInt(product.getSavingProductRelatedDetail().getFrequency());
|
||||
if (frequencyCommandValue != null) {
|
||||
savingFrequencyType = SavingFrequencyType.fromInt(frequencyCommandValue);
|
||||
}
|
||||
|
||||
SavingInterestCalculationMethod savingInterestCalculationMethod = SavingInterestCalculationMethod.fromInt(product
|
||||
.getSavingProductRelatedDetail().getInterestCalculationMethod());
|
||||
if (interestCalculationMethodCommandValue != null) {
|
||||
savingInterestCalculationMethod = SavingInterestCalculationMethod.fromInt(interestCalculationMethodCommandValue);
|
||||
}
|
||||
|
||||
SavingsInterestType interestType = SavingsInterestType.fromInt(product.getSavingProductRelatedDetail().getInterestType());
|
||||
if (interestTypeCommandValue != null) {
|
||||
interestType = SavingsInterestType.fromInt(interestTypeCommandValue);
|
||||
}
|
||||
|
||||
BigDecimal savingInterestRate = product.getInterestRate();
|
||||
if (savingInterestRateCommandValue != null) savingInterestRate = savingInterestRateCommandValue;
|
||||
|
||||
boolean isLockinPeriodAllowed = product.getSavingProductRelatedDetail().isLockinPeriodAllowed();
|
||||
if (isBooleanValueUpdated(isLockinPeriodAllowedCommandValue)) {
|
||||
isLockinPeriodAllowed = isLockinPeriodAllowedCommandValue;
|
||||
}
|
||||
|
||||
Integer lockinPeriod = product.getSavingProductRelatedDetail().getLockinPeriod();
|
||||
if (lockinPeriodCommandValue != null) {
|
||||
lockinPeriod = lockinPeriodCommandValue;
|
||||
}
|
||||
|
||||
PeriodFrequencyType lockinPeriodType = PeriodFrequencyType.fromInt(product.getSavingProductRelatedDetail().getLockinPeriodType());
|
||||
if (lockinPeriodTypeCommandValue != null) {
|
||||
lockinPeriodType = PeriodFrequencyType.fromInt(lockinPeriodTypeCommandValue);
|
||||
}
|
||||
|
||||
Integer interestPostFrequency = PeriodFrequencyType.fromInt(interestPostFrequencyCommandValue).getValue();
|
||||
|
||||
SavingAccount account = SavingAccount.openNew(client, product, externalId, savingsDeposit, recurringInterestRate,
|
||||
savingInterestRate, tenure, commencementDate, tenureTypeEnum, savingProductType, savingFrequencyType, interestType,
|
||||
savingInterestCalculationMethod, isLockinPeriodAllowed, lockinPeriod, lockinPeriodType,
|
||||
this.reccuringDepositInterestCalculator, defaultDepositLifecycleStateMachine(), depositEvery, interestPostEvery,
|
||||
interestPostFrequency);
|
||||
|
||||
SavingScheduleData savingScheduleData = this.savingScheduleAssembler.fromJson(element);
|
||||
for (SavingSchedulePeriodData savingSchedulePeriodData : savingScheduleData.getPeriods()) {
|
||||
|
||||
final SavingScheduleInstallments installment = new SavingScheduleInstallments(account, savingSchedulePeriodData.getDueDate()
|
||||
.toDate(), savingSchedulePeriodData.getPeriod(), savingSchedulePeriodData.getDepositDue(),
|
||||
savingSchedulePeriodData.getInterestAccured());
|
||||
account.addSavingScheduleInstallment(installment);
|
||||
}
|
||||
|
||||
return account;
|
||||
}
|
||||
|
||||
public Map<String, Object> assembleFrom(final JsonCommand command, final SavingAccount account) {
|
||||
|
||||
JsonElement element = command.parsedJson();
|
||||
Map<String, Object> actualChanges = new LinkedHashMap<String, Object>(20);
|
||||
final String localeAsInput = command.locale();
|
||||
|
||||
SavingProduct product = account.getProduct();
|
||||
final String productIdParamName = "productId";
|
||||
if (command.isChangeInLongParameterNamed(productIdParamName, product.getId())) {
|
||||
final Long newValue = command.longValueOfParameterNamed(productIdParamName);
|
||||
if (newValue != null) {
|
||||
product = this.savingProductRepository.findOne(newValue);
|
||||
actualChanges.put("productId", newValue);
|
||||
if (product == null || product.isDeleted()) throw new SavingProductNotFoundException(newValue);
|
||||
}
|
||||
}
|
||||
|
||||
String externalId = account.getExternalId();
|
||||
final String externalIdParamName = "externalId";
|
||||
if (command.isChangeInStringParameterNamed(externalIdParamName, externalId)) {
|
||||
final String newValue = command.stringValueOfParameterNamed(externalIdParamName);
|
||||
actualChanges.put(externalIdParamName, newValue);
|
||||
externalId = newValue;
|
||||
}
|
||||
|
||||
Money savingsDeposit = Money.of(product.getCurrency(), account.getSavingsDepositAmountPerPeriod());
|
||||
|
||||
final String savingsDepositAmountPerPeriodParamName = "savingsDepositAmountPerPeriod";
|
||||
if (command.isChangeInBigDecimalParameterNamed(savingsDepositAmountPerPeriodParamName, savingsDeposit.getAmount())) {
|
||||
final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(savingsDepositAmountPerPeriodParamName);
|
||||
actualChanges.put(savingsDepositAmountPerPeriodParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
savingsDeposit = Money.of(savingsDeposit.getCurrency(), newValue);
|
||||
}
|
||||
|
||||
Integer tenure = account.getTenure();
|
||||
final String tenureParamName = "tenure";
|
||||
if (command.isChangeInIntegerParameterNamed(tenureParamName, tenure)) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(tenureParamName);
|
||||
actualChanges.put(tenureParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
tenure = newValue;
|
||||
}
|
||||
|
||||
LocalDate commencementDate = new LocalDate(account.getProjectedCommencementDate());
|
||||
final String commencementDateParamName = "commencementDate";
|
||||
if (command.isChangeInLocalDateParameterNamed("commencementDate", commencementDate)) {
|
||||
final LocalDate newValue = command.localDateValueOfParameterNamed(commencementDateParamName);
|
||||
actualChanges.put(commencementDateParamName, newValue);
|
||||
commencementDate = newValue;
|
||||
}
|
||||
|
||||
TenureTypeEnum tenureTypeEnum = TenureTypeEnum.fromInt(account.getTenureType());
|
||||
final String tenureTypeParamName = "tenureType";
|
||||
if (command.isChangeInIntegerParameterNamed(tenureTypeParamName, tenureTypeEnum.getValue())) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(tenureTypeParamName);
|
||||
actualChanges.put(tenureTypeParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
tenureTypeEnum = TenureTypeEnum.fromInt(newValue);
|
||||
}
|
||||
|
||||
SavingProductType savingProductType = SavingProductType.fromInt(account.getSavingProductType());
|
||||
|
||||
SavingFrequencyType savingFrequencyType = SavingFrequencyType.fromInt(account.getFrequency());
|
||||
final String frequencyParamName = "frequency";
|
||||
if (command.isChangeInIntegerParameterNamed(frequencyParamName, savingFrequencyType.getValue())) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(frequencyParamName);
|
||||
actualChanges.put(frequencyParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
savingFrequencyType = SavingFrequencyType.fromInt(newValue);
|
||||
}
|
||||
|
||||
SavingInterestCalculationMethod savingInterestCalculationMethod = SavingInterestCalculationMethod.fromInt(account
|
||||
.getInterestCalculationMethod());
|
||||
final String interestCalculationMethodParamName = "interestCalculationMethod";
|
||||
if (command.isChangeInIntegerParameterNamed(interestCalculationMethodParamName, savingInterestCalculationMethod.getValue())) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(interestCalculationMethodParamName);
|
||||
actualChanges.put(interestCalculationMethodParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
savingInterestCalculationMethod = SavingInterestCalculationMethod.fromInt(newValue);
|
||||
}
|
||||
|
||||
BigDecimal reccuringInterestRate = account.getReccuringInterestRate();
|
||||
final String reccuringInterestRateParamName = "reccuringInterestRate";
|
||||
if (command.isChangeInBigDecimalParameterNamed(reccuringInterestRateParamName, reccuringInterestRate)) {
|
||||
final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(reccuringInterestRateParamName);
|
||||
actualChanges.put(reccuringInterestRateParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
reccuringInterestRate = newValue;
|
||||
}
|
||||
|
||||
BigDecimal savingInterestRate = account.getSavingInterestRate();
|
||||
final String savingInterestRateParamName = "savingInterestRate";
|
||||
if (command.isChangeInBigDecimalParameterNamed(savingInterestRateParamName, savingInterestRate)) {
|
||||
final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(savingInterestRateParamName);
|
||||
actualChanges.put(savingInterestRateParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
savingInterestRate = newValue;
|
||||
}
|
||||
|
||||
Boolean isLockinPeriodAllowed = account.isLockinPeriodAllowed();
|
||||
final String isLockinPeriodAllowedParamName = "isLockinPeriodAllowed";
|
||||
if (command.isChangeInBooleanParameterNamed(isLockinPeriodAllowedParamName, isLockinPeriodAllowed)) {
|
||||
final Boolean newValue = command.booleanObjectValueOfParameterNamed(isLockinPeriodAllowedParamName);
|
||||
actualChanges.put(isLockinPeriodAllowedParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
isLockinPeriodAllowed = newValue;
|
||||
}
|
||||
|
||||
Integer lockinPeriod = account.getLockinPeriod();
|
||||
final String lockinPeriodParamName = "lockinPeriod";
|
||||
if (command.isChangeInIntegerParameterNamed(lockinPeriodParamName, lockinPeriod)) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(lockinPeriodParamName);
|
||||
actualChanges.put(lockinPeriodParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
lockinPeriod = newValue;
|
||||
}
|
||||
|
||||
PeriodFrequencyType lockinPeriodType = PeriodFrequencyType.fromInt(account.getLockinPeriodType());
|
||||
final String lockinPeriodTypeParamName = "lockinPeriodType";
|
||||
if (command.isChangeInIntegerParameterNamed(lockinPeriodTypeParamName, lockinPeriodType.getValue())) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(lockinPeriodTypeParamName);
|
||||
actualChanges.put(lockinPeriodTypeParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
lockinPeriodType = PeriodFrequencyType.fromInt(newValue);
|
||||
}
|
||||
|
||||
Integer payEvery = account.getPayEvery();
|
||||
final String depositEveryParamName = "depositEvery";
|
||||
if (command.isChangeInIntegerParameterNamed(depositEveryParamName, payEvery)) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(depositEveryParamName);
|
||||
actualChanges.put(depositEveryParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
payEvery = newValue;
|
||||
}
|
||||
|
||||
SavingsInterestType interestType = SavingsInterestType.fromInt(product.getSavingProductRelatedDetail().getInterestType());
|
||||
final String interestTypeParamName = "interestType";
|
||||
if (command.isChangeInIntegerParameterNamed(interestTypeParamName, interestType.getValue())) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(interestTypeParamName);
|
||||
actualChanges.put(interestTypeParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
interestType = SavingsInterestType.fromInt(newValue);
|
||||
}
|
||||
|
||||
Integer interestPostEvery = account.getInterestPostEvery();
|
||||
final String interestPostEveryParamName = "interestPostEvery";
|
||||
if (command.isChangeInIntegerParameterNamed(interestPostEveryParamName, interestPostEvery)) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(interestPostEveryParamName);
|
||||
actualChanges.put(interestPostEveryParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
interestPostEvery = newValue;
|
||||
}
|
||||
|
||||
Integer interestPostFrequency = account.getInterestPostFrequency();
|
||||
final String interestPostFrequencyParamName = "interestPostFrequency";
|
||||
if (command.isChangeInIntegerParameterNamed(interestPostFrequencyParamName, interestPostFrequency)) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(interestPostFrequencyParamName);
|
||||
actualChanges.put(interestPostFrequencyParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
interestPostFrequency = PeriodFrequencyType.fromInt(newValue).getValue();
|
||||
}
|
||||
|
||||
account.modifyAccount(product, externalId, savingsDeposit, reccuringInterestRate, savingInterestRate, tenure, commencementDate,
|
||||
tenureTypeEnum, savingProductType, savingFrequencyType, savingInterestCalculationMethod, isLockinPeriodAllowed,
|
||||
lockinPeriod, lockinPeriodType, this.reccuringDepositInterestCalculator, payEvery, interestType, interestPostEvery,
|
||||
interestPostFrequency);
|
||||
|
||||
SavingScheduleData savingScheduleData = this.savingScheduleAssembler.fromJson(element);
|
||||
for (SavingSchedulePeriodData savingSchedulePeriodData : savingScheduleData.getPeriods()) {
|
||||
|
||||
final SavingScheduleInstallments installment = new SavingScheduleInstallments(account, savingSchedulePeriodData.getDueDate()
|
||||
.toDate(), savingSchedulePeriodData.getPeriod(), savingSchedulePeriodData.getDepositDue(),
|
||||
savingSchedulePeriodData.getInterestAccured());
|
||||
account.addSavingScheduleInstallment(installment);
|
||||
}
|
||||
|
||||
return actualChanges;
|
||||
|
||||
}
|
||||
|
||||
private DepositLifecycleStateMachine defaultDepositLifecycleStateMachine() {
|
||||
List<DepositAccountStatus> allowedDepositStatuses = Arrays.asList(DepositAccountStatus.values());
|
||||
return new DepositLifecycleStateMachineImpl(allowedDepositStatuses);
|
||||
}
|
||||
|
||||
public Map<String, Object> approveSavingAccount(final JsonCommand command, final SavingAccount account) {
|
||||
|
||||
JsonElement element = command.parsedJson();
|
||||
Map<String, Object> actualChanges = new LinkedHashMap<String, Object>(20);
|
||||
final String localeAsInput = command.locale();
|
||||
|
||||
LocalDate approvalDate = account.projectedCommencementDate();
|
||||
final String commencementDateParamName = "commencementDate";
|
||||
if (command.isChangeInLocalDateParameterNamed("commencementDate", approvalDate)) {
|
||||
final LocalDate newValue = command.localDateValueOfParameterNamed(commencementDateParamName);
|
||||
actualChanges.put(commencementDateParamName, newValue);
|
||||
approvalDate = newValue;
|
||||
}
|
||||
|
||||
BigDecimal savingsDepositAmountPerPeriod = account.getSavingsDepositAmountPerPeriod();
|
||||
final String savingsDepositAmountPerPeriodParamName = "savingsDepositAmountPerPeriod";
|
||||
if (command.isChangeInBigDecimalParameterNamed(savingsDepositAmountPerPeriodParamName, savingsDepositAmountPerPeriod)) {
|
||||
final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(savingsDepositAmountPerPeriodParamName);
|
||||
actualChanges.put(savingsDepositAmountPerPeriodParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
savingsDepositAmountPerPeriod = newValue;
|
||||
}
|
||||
|
||||
BigDecimal recurringInterestRate = account.getReccuringInterestRate();
|
||||
final String reccuringInterestRateParamName = "reccuringInterestRate";
|
||||
if (command.isChangeInBigDecimalParameterNamed(reccuringInterestRateParamName, recurringInterestRate)) {
|
||||
final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(reccuringInterestRateParamName);
|
||||
actualChanges.put(reccuringInterestRateParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
recurringInterestRate = newValue;
|
||||
}
|
||||
|
||||
BigDecimal savingInterestRate = account.getSavingInterestRate();
|
||||
final String savingInterestRateParamName = "savingInterestRate";
|
||||
if (command.isChangeInBigDecimalParameterNamed(savingInterestRateParamName, savingInterestRate)) {
|
||||
final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(savingInterestRateParamName);
|
||||
actualChanges.put(savingInterestRateParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
savingInterestRate = newValue;
|
||||
}
|
||||
|
||||
Integer interestType = account.getInterestType();
|
||||
final String interestTypeParamName = "interestType";
|
||||
if (command.isChangeInIntegerParameterNamed(interestTypeParamName, interestType)) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(interestTypeParamName);
|
||||
actualChanges.put(interestTypeParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
interestType = SavingsInterestType.fromInt(newValue).getValue();
|
||||
}
|
||||
|
||||
Integer tenure = account.getTenure();
|
||||
final String tenureParamName = "tenure";
|
||||
if (command.isChangeInIntegerParameterNamed(tenureParamName, tenure)) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(tenureParamName);
|
||||
actualChanges.put(tenureParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
tenure = newValue;
|
||||
}
|
||||
|
||||
Integer tenureType = account.getTenureType();
|
||||
final String tenureTypeParamName = "tenureType";
|
||||
if (command.isChangeInIntegerParameterNamed(tenureTypeParamName, tenureType)) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(tenureTypeParamName);
|
||||
actualChanges.put(tenureTypeParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
tenureType = TenureTypeEnum.fromInt(newValue).getValue();
|
||||
}
|
||||
|
||||
Integer frequency = account.getFrequency();
|
||||
final String frequencyParamName = "frequency";
|
||||
if (command.isChangeInIntegerParameterNamed(frequencyParamName, frequency)) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(frequencyParamName);
|
||||
actualChanges.put(frequencyParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
frequency = SavingFrequencyType.fromInt(newValue).getValue();
|
||||
}
|
||||
|
||||
Integer depositEvery = account.getPayEvery();
|
||||
final String depositEveryParamName = "depositEvery";
|
||||
if (command.isChangeInIntegerParameterNamed(depositEveryParamName, depositEvery)) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(depositEveryParamName);
|
||||
actualChanges.put(depositEveryParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
depositEvery = newValue;
|
||||
}
|
||||
|
||||
Integer interestPostEvery = account.getInterestPostEvery();
|
||||
final String interestPostEveryParamName = "interestPostEvery";
|
||||
if (command.isChangeInIntegerParameterNamed(interestPostEveryParamName, interestPostEvery)) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(interestPostEveryParamName);
|
||||
actualChanges.put(interestPostEveryParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
interestPostEvery = newValue;
|
||||
}
|
||||
|
||||
Integer interestPostFrequency = account.getInterestPostFrequency();
|
||||
final String interestPostFrequencyParamName = "interestPostFrequency";
|
||||
if (command.isChangeInIntegerParameterNamed(interestPostFrequencyParamName, interestPostFrequency)) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(interestPostFrequencyParamName);
|
||||
actualChanges.put(interestPostFrequencyParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
interestPostFrequency = PeriodFrequencyType.fromInt(newValue).getValue();
|
||||
}
|
||||
|
||||
account.approveSavingAccount(approvalDate, savingsDepositAmountPerPeriod, recurringInterestRate, savingInterestRate, interestType,
|
||||
tenure, tenureType, frequency, depositEvery, defaultDepositLifecycleStateMachine(),
|
||||
this.reccuringDepositInterestCalculator, interestPostEvery, interestPostFrequency);
|
||||
|
||||
/*
|
||||
* CalculateSavingScheduleCommand calculateSavingScheduleCommand = new
|
||||
* CalculateSavingScheduleCommand(account.getProduct().getId(),
|
||||
* savingsDepositAmountPerPeriod, payEvery, frequency,
|
||||
* recurringInterestRate, approvalDate,
|
||||
* tenure,tenureType,interestPostEvery
|
||||
* ,interestPostFrequency,account.getInterestCalculationMethod());
|
||||
*/
|
||||
|
||||
SavingScheduleData savingScheduleData = this.savingScheduleAssembler.calculateSavingSchedule(element, account);
|
||||
for (SavingSchedulePeriodData savingSchedulePeriodData : savingScheduleData.getPeriods()) {
|
||||
|
||||
final SavingScheduleInstallments installment = new SavingScheduleInstallments(account, savingSchedulePeriodData.getDueDate()
|
||||
.toDate(), savingSchedulePeriodData.getPeriod(), savingSchedulePeriodData.getDepositDue(),
|
||||
savingSchedulePeriodData.getInterestAccured());
|
||||
account.addSavingScheduleInstallment(installment);
|
||||
}
|
||||
|
||||
return actualChanges;
|
||||
}
|
||||
|
||||
public void withdrawSavingAccountMoney(final JsonCommand command, final SavingAccount account) {
|
||||
|
||||
LocalDate transactionDate = command.localDateValueOfParameterNamed("transactionDate");
|
||||
BigDecimal withdraAmount = command.bigDecimalValueOfParameterNamed("amount");
|
||||
if (withdraAmount.doubleValue() > account.getOutstandingAmount().doubleValue()) { throw new DepositAccountTransactionsException(
|
||||
"deposit.transaction.interest.withdrawal.exceed", "You can Withdraw " + account.getOutstandingAmount() + " only"); }
|
||||
|
||||
account.withdrawAmount(withdraAmount, transactionDate);
|
||||
|
||||
}
|
||||
|
||||
public void postInterest(final SavingAccount account) {
|
||||
account.postInterest();
|
||||
}
|
||||
|
||||
private Boolean isBooleanValueUpdated(final Boolean actualValue) {
|
||||
Boolean isUpdated = false;
|
||||
if (actualValue != null) {
|
||||
isUpdated = true;
|
||||
}
|
||||
return isUpdated;
|
||||
}
|
||||
|
||||
}
|
||||
-35
@@ -1,35 +0,0 @@
|
||||
/**
|
||||
* 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.portfolio.savingsaccount.service;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Collection;
|
||||
|
||||
import org.mifosplatform.organisation.monetary.data.CurrencyData;
|
||||
import org.mifosplatform.portfolio.savingsaccount.data.SavingAccountData;
|
||||
import org.mifosplatform.portfolio.savingsaccount.data.SavingAccountForLookup;
|
||||
import org.mifosplatform.portfolio.savingsaccount.data.SavingAccountTransactionsData;
|
||||
import org.mifosplatform.portfolio.savingsaccount.data.SavingPermissionData;
|
||||
import org.mifosplatform.portfolio.savingsaccount.data.SavingScheduleData;
|
||||
|
||||
public interface SavingAccountReadPlatformService {
|
||||
|
||||
Collection<SavingAccountData> retrieveAllSavingsAccounts();
|
||||
|
||||
SavingAccountData retrieveSavingsAccount(Long accountId);
|
||||
|
||||
SavingAccountData retrieveNewSavingsAccountDetails(Long clientId, Long productId);
|
||||
|
||||
SavingPermissionData retrieveSavingAccountPermissions(SavingAccountData data);
|
||||
|
||||
BigDecimal deriveSavingDueAmount(SavingAccountData account);
|
||||
|
||||
SavingScheduleData retrieveSavingsAccountSchedule(Long accountId, CurrencyData currencyData);
|
||||
|
||||
Collection<SavingAccountForLookup> retrieveSavingAccountsForLookUp();
|
||||
|
||||
Collection<SavingAccountTransactionsData> retrieveSavingsAccountTransactions(Long accountId);
|
||||
}
|
||||
-342
@@ -1,342 +0,0 @@
|
||||
/**
|
||||
* 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.portfolio.savingsaccount.service;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.joda.time.LocalDate;
|
||||
import org.joda.time.Months;
|
||||
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
|
||||
import org.mifosplatform.infrastructure.core.domain.JdbcSupport;
|
||||
import org.mifosplatform.infrastructure.core.service.TenantAwareRoutingDataSource;
|
||||
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
|
||||
import org.mifosplatform.organisation.monetary.data.CurrencyData;
|
||||
import org.mifosplatform.portfolio.client.data.ClientData;
|
||||
import org.mifosplatform.portfolio.client.service.ClientReadPlatformService;
|
||||
import org.mifosplatform.portfolio.savingsaccount.data.SavingAccountData;
|
||||
import org.mifosplatform.portfolio.savingsaccount.data.SavingAccountForLookup;
|
||||
import org.mifosplatform.portfolio.savingsaccount.data.SavingAccountTransactionsData;
|
||||
import org.mifosplatform.portfolio.savingsaccount.data.SavingPermissionData;
|
||||
import org.mifosplatform.portfolio.savingsaccount.data.SavingScheduleData;
|
||||
import org.mifosplatform.portfolio.savingsaccount.data.SavingSchedulePeriodData;
|
||||
import org.mifosplatform.portfolio.savingsaccountproduct.data.SavingProductData;
|
||||
import org.mifosplatform.portfolio.savingsaccountproduct.data.SavingProductLookup;
|
||||
import org.mifosplatform.portfolio.savingsaccountproduct.service.SavingProductEnumerations;
|
||||
import org.mifosplatform.portfolio.savingsaccountproduct.service.SavingProductReadPlatformService;
|
||||
import org.mifosplatform.portfolio.savingsdepositaccount.service.DepositAccountEnumerations;
|
||||
import org.mifosplatform.portfolio.savingsdepositaccount.service.DepositAccountTransactionEnumerations;
|
||||
import org.mifosplatform.portfolio.savingsdepositproduct.domain.TenureTypeEnum;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.core.RowMapper;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class SavingAccountReadPlatformServiceImpl implements SavingAccountReadPlatformService {
|
||||
|
||||
private final PlatformSecurityContext context;
|
||||
private final JdbcTemplate jdbcTemplate;
|
||||
private final ClientReadPlatformService clientReadPlatformService;
|
||||
private final SavingProductReadPlatformService savingProductReadPlatformService;
|
||||
|
||||
@Autowired
|
||||
public SavingAccountReadPlatformServiceImpl(final PlatformSecurityContext context, final TenantAwareRoutingDataSource dataSource,
|
||||
final ClientReadPlatformService clientReadPlatformService,
|
||||
final SavingProductReadPlatformService savingProductReadPlatformService) {
|
||||
this.context = context;
|
||||
this.jdbcTemplate = new JdbcTemplate(dataSource);
|
||||
this.clientReadPlatformService = clientReadPlatformService;
|
||||
this.savingProductReadPlatformService = savingProductReadPlatformService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<SavingAccountData> retrieveAllSavingsAccounts() {
|
||||
|
||||
this.context.authenticatedUser();
|
||||
SavingAccountMapper mapper = new SavingAccountMapper();
|
||||
String sql = "select " + mapper.schema() + " where sa.is_deleted=0";
|
||||
return this.jdbcTemplate.query(sql, mapper, new Object[] {});
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public SavingAccountData retrieveSavingsAccount(final Long accountId) {
|
||||
|
||||
this.context.authenticatedUser();
|
||||
SavingAccountMapper mapper = new SavingAccountMapper();
|
||||
String sql = "select " + mapper.schema() + " where sa.id = ? and sa.is_deleted=0";
|
||||
SavingAccountData savingAccountData = this.jdbcTemplate.queryForObject(sql, mapper, new Object[] { accountId });
|
||||
|
||||
return savingAccountData;
|
||||
}
|
||||
|
||||
private static final class SavingAccountMapper implements RowMapper<SavingAccountData> {
|
||||
|
||||
public String schema() {
|
||||
return "sa.id AS id, sa.status_enum AS status, sa.external_id AS externalId,"
|
||||
+ " sa.client_id AS clientId, sa.product_id AS productId, sa.deposit_amount_per_period AS savingsDepostiAmountPerPeriod,"
|
||||
+ " sa.savings_product_type AS savingsProductType, sa.currency_code AS currencyCode, sa.currency_digits AS currencyDigits,"
|
||||
+ " sa.total_deposit_amount AS totalDepositAmount, sa.reccuring_nominal_interest_rate AS reccuringInterestRate,"
|
||||
+ " sa.regular_saving_nominal_interest_rate AS savingInterestRate, sa.tenure AS tenure, sa.tenure_type AS tenureType,"
|
||||
+ " sa.frequency AS savingsFrequencyType, sa.interest_type AS interestType, sa.interest_calculation_method AS interestCalculationMethod,"
|
||||
+ " sa.projected_commencement_date AS projectedCommencementDate, sa.actual_commencement_date AS actualCommencementDate,"
|
||||
+ " sa.matures_on_date AS maturesOnDate, sa.projected_interest_accrued_on_maturity AS projectedInterestAccuredOnMaturity,"
|
||||
+ " sa.actual_interest_accrued AS actualInterestAccured, sa.projected_total_maturity_amount AS projectedTotalMaturityAmount,"
|
||||
+ " sa.actual_total_amount AS actualTotalAmount, sa.is_preclosure_allowed AS isPreclosureAllowed, sa.outstanding_amount as outstandingAmount, "
|
||||
+ " sa.pre_closure_interest_rate AS preClosureInterestRate, sa.is_lock_in_period_allowed AS isLockinPeriodAllowed,"
|
||||
+ " sa.lock_in_period AS lockinPeriod, sa.lock_in_period_type AS lockinPeriodType, sa.withdrawnon_date AS withdrawnonDate,"
|
||||
+ " sa.rejectedon_date AS rejectedonDate, sa.closedon_date AS closedonDate, ps.name AS productName, sa.deposit_every as depositEvery, "
|
||||
+ " sa.interest_posting_every AS interestPostEvery, sa.interest_posting_frequency AS interestPostFrequency, "
|
||||
+ " c.firstname AS firstname, c.lastname AS lastname, curr.name AS currencyName, "
|
||||
+ " curr.internationalized_name_code AS currencyNameCode, curr.display_symbol AS currencyDisplaySymbol "
|
||||
+ " FROM m_saving_account sa " + " JOIN m_client c ON c.id = sa.client_id"
|
||||
+ " JOIN m_currency curr ON curr.code = sa.currency_code " + " JOIN m_product_savings ps ON sa.product_id = ps.id ";
|
||||
}
|
||||
|
||||
@Override
|
||||
public SavingAccountData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {
|
||||
|
||||
Long id = rs.getLong("id");
|
||||
String externalId = rs.getString("externalId");
|
||||
Long clientId = rs.getLong("clientId");
|
||||
String clientName = rs.getString("firstname") + " " + rs.getString("lastname");
|
||||
|
||||
Long productId = rs.getLong("productId");
|
||||
String productName = rs.getString("productName");
|
||||
EnumOptionData productType = SavingProductEnumerations.savingProductType(JdbcSupport.getInteger(rs, "savingsProductType"));
|
||||
|
||||
Integer statusId = JdbcSupport.getInteger(rs, "status");
|
||||
EnumOptionData status = DepositAccountEnumerations.status(statusId);
|
||||
|
||||
String currencyCode = rs.getString("currencyCode");
|
||||
String currencyName = rs.getString("currencyName");
|
||||
String currencyNameCode = rs.getString("currencyNameCode");
|
||||
String currencyDisplaySymbol = rs.getString("currencyDisplaySymbol");
|
||||
Integer currencyDigits = JdbcSupport.getInteger(rs, "currencyDigits");
|
||||
CurrencyData currencyData = new CurrencyData(currencyCode, currencyName, currencyDigits, currencyDisplaySymbol,
|
||||
currencyNameCode);
|
||||
|
||||
BigDecimal savingsDepostiAmountPerPeriod = rs.getBigDecimal("savingsDepostiAmountPerPeriod");
|
||||
EnumOptionData savingsFrequencyType = SavingProductEnumerations.interestFrequencyType(JdbcSupport.getInteger(rs,
|
||||
"savingsFrequencyType"));
|
||||
BigDecimal totalDepositAmount = rs.getBigDecimal("totalDepositAmount");
|
||||
|
||||
BigDecimal reccuringInterestRate = rs.getBigDecimal("reccuringInterestRate");
|
||||
BigDecimal savingInterestRate = rs.getBigDecimal("savingInterestRate");
|
||||
EnumOptionData interestType = SavingProductEnumerations.savingInterestType(JdbcSupport.getInteger(rs, "interestType"));
|
||||
EnumOptionData interestCalculationMethod = SavingProductEnumerations.savingInterestCalculationMethod(JdbcSupport.getInteger(rs,
|
||||
"interestCalculationMethod"));
|
||||
|
||||
Integer tenure = JdbcSupport.getInteger(rs, "tenure");
|
||||
EnumOptionData tenureType = SavingProductEnumerations.tenureTypeEnum(JdbcSupport.getInteger(rs, "tenureType"));
|
||||
|
||||
LocalDate projectedCommencementDate = JdbcSupport.getLocalDate(rs, "projectedCommencementDate");
|
||||
LocalDate actualCommencementDate = JdbcSupport.getLocalDate(rs, "actualCommencementDate");
|
||||
LocalDate maturesOnDate = JdbcSupport.getLocalDate(rs, "maturesOnDate");
|
||||
BigDecimal projectedInterestAccuredOnMaturity = rs.getBigDecimal("projectedInterestAccuredOnMaturity");
|
||||
BigDecimal actualInterestAccured = rs.getBigDecimal("actualInterestAccured");
|
||||
|
||||
BigDecimal projectedMaturityAmount = rs.getBigDecimal("projectedTotalMaturityAmount");
|
||||
BigDecimal actualMaturityAmount = rs.getBigDecimal("actualTotalAmount");
|
||||
|
||||
boolean preClosureAllowed = rs.getBoolean("isPreclosureAllowed");
|
||||
BigDecimal preClosureInterestRate = rs.getBigDecimal("preClosureInterestRate");
|
||||
BigDecimal outstandingAmount = rs.getBigDecimal("outstandingAmount");
|
||||
|
||||
LocalDate withdrawnonDate = JdbcSupport.getLocalDate(rs, "withdrawnonDate");
|
||||
LocalDate rejectedonDate = JdbcSupport.getLocalDate(rs, "rejectedonDate");
|
||||
LocalDate closedonDate = JdbcSupport.getLocalDate(rs, "closedonDate");
|
||||
|
||||
boolean isLockinPeriodAllowed = rs.getBoolean("isLockinPeriodAllowed");
|
||||
Integer lockinPeriod = JdbcSupport.getInteger(rs, "lockinPeriod");
|
||||
Integer lockinPeriodTypeValue = JdbcSupport.getInteger(rs, "lockinPeriodType");
|
||||
EnumOptionData lockinPeriodType = SavingProductEnumerations.savingsLockinPeriod(lockinPeriodTypeValue);
|
||||
Integer depositEvery = JdbcSupport.getInteger(rs, "depositEvery");
|
||||
|
||||
Integer interestPostEvery = JdbcSupport.getInteger(rs, "interestPostEvery");
|
||||
EnumOptionData interestPostFrequency = SavingProductEnumerations.interestFrequencyType(JdbcSupport.getInteger(rs,
|
||||
"interestPostFrequency"));
|
||||
|
||||
return new SavingAccountData(id, status, externalId, clientId, clientName, productId, productName, productType, currencyData,
|
||||
savingsDepostiAmountPerPeriod, savingsFrequencyType, totalDepositAmount, reccuringInterestRate, savingInterestRate,
|
||||
interestType, interestCalculationMethod, tenure, tenureType, projectedCommencementDate, actualCommencementDate,
|
||||
maturesOnDate, projectedInterestAccuredOnMaturity, actualInterestAccured, projectedMaturityAmount,
|
||||
actualMaturityAmount, preClosureAllowed, preClosureInterestRate, withdrawnonDate, rejectedonDate, closedonDate,
|
||||
isLockinPeriodAllowed, lockinPeriod, lockinPeriodType, depositEvery, outstandingAmount, interestPostEvery,
|
||||
interestPostFrequency);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public SavingAccountData retrieveNewSavingsAccountDetails(final Long clientId, final Long productId) {
|
||||
|
||||
context.authenticatedUser();
|
||||
ClientData clientAccount = this.clientReadPlatformService.retrieveIndividualClient(clientId);
|
||||
SavingAccountData accountData = null;
|
||||
Collection<SavingProductLookup> savingProducts = this.savingProductReadPlatformService.retrieveAllSavingProductsForLookup();
|
||||
|
||||
if (productId != null && productId != -1) {
|
||||
SavingProductData selectedProduct = findSavingProductById(savingProducts, productId);
|
||||
|
||||
CurrencyData currency = selectedProduct.getCurrency();
|
||||
|
||||
accountData = new SavingAccountData(clientAccount.id(), clientAccount.displayName(), selectedProduct.getId(),
|
||||
selectedProduct.getName(), currency, selectedProduct.getInterestRate(), selectedProduct.getSavingsDepositAmount(),
|
||||
selectedProduct.getSavingProductType(), selectedProduct.getTenureType(), selectedProduct.getTenure(),
|
||||
selectedProduct.getSavingFrequencyType(), selectedProduct.getInterestType(),
|
||||
selectedProduct.getInterestCalculationMethod(), selectedProduct.isLockinPeriodAllowed(),
|
||||
selectedProduct.getLockinPeriod(), selectedProduct.getLockinPeriodType(), selectedProduct.getDepositEvery());
|
||||
|
||||
} else {
|
||||
accountData = SavingAccountData.createFrom(clientAccount.id(), clientAccount.displayName());
|
||||
}
|
||||
return accountData;
|
||||
}
|
||||
|
||||
private SavingProductData findSavingProductById(final Collection<SavingProductLookup> savingProducts, final Long productId) {
|
||||
SavingProductData match = this.savingProductReadPlatformService.retrieveNewSavingProductDetails();
|
||||
for (SavingProductLookup savingProductLookup : savingProducts) {
|
||||
if (savingProductLookup.hasId(productId)) {
|
||||
match = this.savingProductReadPlatformService.retrieveSavingProduct(savingProductLookup.getId());
|
||||
break;
|
||||
}
|
||||
}
|
||||
return match;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SavingPermissionData retrieveSavingAccountPermissions(final SavingAccountData savingAccountData) {
|
||||
boolean pendingApproval = (savingAccountData.getStatus().getId().equals(100L));
|
||||
boolean undoApprovalAllowed = (savingAccountData.getStatus().getId().equals(300L));
|
||||
boolean renewelAllowed = false;
|
||||
if (savingAccountData.getMaturesOnDate() != null && savingAccountData.getTenureType().equals(TenureTypeEnum.FIXED_PERIOD)) {
|
||||
if (new LocalDate().isAfter(savingAccountData.getMaturesOnDate())) {
|
||||
renewelAllowed = true;
|
||||
}
|
||||
}
|
||||
boolean rejectAllowed = pendingApproval;
|
||||
boolean withdrawnByApplicantAllowed = pendingApproval;
|
||||
boolean isMaturedDepositAccount = (savingAccountData.getStatus().getId().equals(700L));
|
||||
return new SavingPermissionData(rejectAllowed, withdrawnByApplicantAllowed, undoApprovalAllowed, pendingApproval, renewelAllowed,
|
||||
isMaturedDepositAccount);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Override
|
||||
public BigDecimal deriveSavingDueAmount(final SavingAccountData account) {
|
||||
|
||||
BigDecimal dueAmount = BigDecimal.ZERO;
|
||||
EnumOptionData status = account.getStatus();
|
||||
LocalDate date = account.getActualCommencementDate();
|
||||
|
||||
if (account.getStatus() != null && account.getActualCommencementDate() != null) {
|
||||
BigDecimal amountPerPeriod = account.getSavingsDepostiAmountPerPeriod();
|
||||
Integer tenure = account.getTenure();
|
||||
Integer depositEvery = account.getDepositEvery();
|
||||
Integer noOfPeriods = tenure / depositEvery;
|
||||
Integer noOfMonths = Months.monthsBetween(date, new LocalDate()).getMonths();
|
||||
Integer noOfPeriodsExistedTillDate = noOfMonths / depositEvery;
|
||||
BigDecimal totalAmountToBePaidTillDate = BigDecimal.valueOf(noOfPeriodsExistedTillDate.doubleValue()
|
||||
* amountPerPeriod.doubleValue());
|
||||
dueAmount = dueAmount.add(BigDecimal.valueOf(totalAmountToBePaidTillDate.doubleValue()
|
||||
- account.getOutstandingAmount().doubleValue()));
|
||||
|
||||
}
|
||||
dueAmount = dueAmount.doubleValue() < 0 ? BigDecimal.ZERO : dueAmount;
|
||||
return dueAmount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SavingScheduleData retrieveSavingsAccountSchedule(final Long accountId, final CurrencyData currency) {
|
||||
this.context.authenticatedUser();
|
||||
SavingAccountScheduleMapper mapper = new SavingAccountScheduleMapper();
|
||||
String sql = "Select " + mapper.savingScheduleSchema() + " where ss.saving_account_id =? order by ss.installment";
|
||||
List<SavingSchedulePeriodData> periods = this.jdbcTemplate.query(sql, mapper, new Object[] { accountId });
|
||||
BigDecimal cumulativeDepositDue = BigDecimal.ZERO;
|
||||
BigDecimal cumulativeDepositPaid = BigDecimal.ZERO;
|
||||
BigDecimal cummulativeInterestAccured = BigDecimal.ZERO;
|
||||
for (SavingSchedulePeriodData data : periods) {
|
||||
cumulativeDepositDue = cumulativeDepositDue.add(data.getDepositDue());
|
||||
cumulativeDepositPaid = cumulativeDepositPaid.add(data.getDepositPaid());
|
||||
cummulativeInterestAccured = cummulativeInterestAccured.add(data.getInterestAccured());
|
||||
}
|
||||
SavingScheduleData scheduleData = new SavingScheduleData(currency, cumulativeDepositDue, cumulativeDepositPaid,
|
||||
cummulativeInterestAccured, periods);
|
||||
return scheduleData;
|
||||
}
|
||||
|
||||
public static final class SavingAccountScheduleMapper implements RowMapper<SavingSchedulePeriodData> {
|
||||
|
||||
public String savingScheduleSchema() {
|
||||
return "ss.id as id, ss.saving_account_id as savingAccountId, ss.duedate as dueDate, ss.installment as installment, "
|
||||
+ " ss.deposit as deposit, ss.payment_date as paymentDate, ss.deposit_paid as depositPaid, "
|
||||
+ " ss.completed_derived as completedDerived, ss.interest_accured AS interestAccured FROM m_saving_schedule ss";
|
||||
}
|
||||
|
||||
@Override
|
||||
public SavingSchedulePeriodData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {
|
||||
|
||||
LocalDate dueDate = JdbcSupport.getLocalDate(rs, "dueDate");
|
||||
Integer installment = JdbcSupport.getInteger(rs, "installment");
|
||||
BigDecimal depositDue = rs.getBigDecimal("deposit");
|
||||
BigDecimal depositPaid = rs.getBigDecimal("depositPaid");
|
||||
BigDecimal interestAccured = rs.getBigDecimal("interestAccured");
|
||||
|
||||
return new SavingSchedulePeriodData(installment, dueDate, depositDue, depositPaid, interestAccured);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<SavingAccountForLookup> retrieveSavingAccountsForLookUp() {
|
||||
SavingAccountLookupMapper mapper = new SavingAccountLookupMapper();
|
||||
String sql = "select " + mapper.schema();
|
||||
return this.jdbcTemplate.query(sql, mapper, new Object[] {});
|
||||
}
|
||||
|
||||
private static final class SavingAccountLookupMapper implements RowMapper<SavingAccountForLookup> {
|
||||
|
||||
public String schema() {
|
||||
return " sa.id as id from m_saving_account sa where sa.is_deleted=0 and sa.status_enum=300";
|
||||
}
|
||||
|
||||
@Override
|
||||
public SavingAccountForLookup mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {
|
||||
Long id = rs.getLong("id");
|
||||
return new SavingAccountForLookup(id);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<SavingAccountTransactionsData> retrieveSavingsAccountTransactions(final Long accountId) {
|
||||
this.context.authenticatedUser();
|
||||
SavingAccountTransactionMapper savingAccountTransactionMapper = new SavingAccountTransactionMapper();
|
||||
String sql = "select " + savingAccountTransactionMapper.schema() + " where stxn.saving_account_id = ? ";
|
||||
return jdbcTemplate.query(sql, savingAccountTransactionMapper, new Object[] { accountId });
|
||||
}
|
||||
|
||||
private static final class SavingAccountTransactionMapper implements RowMapper<SavingAccountTransactionsData> {
|
||||
|
||||
public String schema() {
|
||||
return "stxn.id as id, stxn.transaction_type_enum as type, stxn.transaction_date as transactionDate, stxn.amount as amount FROM m_saving_account_transaction stxn";
|
||||
}
|
||||
|
||||
@Override
|
||||
public SavingAccountTransactionsData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {
|
||||
Long id = rs.getLong("id");
|
||||
LocalDate transactionDate = JdbcSupport.getLocalDate(rs, "transactionDate");
|
||||
Integer transactionTypeValue = JdbcSupport.getInteger(rs, "type");
|
||||
EnumOptionData transactionType = DepositAccountTransactionEnumerations.depositType(transactionTypeValue);
|
||||
BigDecimal amount = rs.getBigDecimal("amount");
|
||||
return new SavingAccountTransactionsData(id, transactionDate, transactionType, amount);
|
||||
}
|
||||
}
|
||||
}
|
||||
-36
@@ -1,36 +0,0 @@
|
||||
/**
|
||||
* 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.portfolio.savingsaccount.service;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.mifosplatform.portfolio.savingsaccount.data.SavingAccountForLookup;
|
||||
|
||||
public interface SavingAccountWritePlatformService {
|
||||
|
||||
CommandProcessingResult createSavingAccount(JsonCommand command);
|
||||
|
||||
CommandProcessingResult updateSavingAccount(Long accountId, JsonCommand command);
|
||||
|
||||
CommandProcessingResult rejectSavingApplication(JsonCommand command);
|
||||
|
||||
CommandProcessingResult withdrawSavingApplication(JsonCommand command);
|
||||
|
||||
CommandProcessingResult undoSavingAccountApproval(JsonCommand undoCommand);
|
||||
|
||||
CommandProcessingResult approveSavingAccount(JsonCommand command);
|
||||
|
||||
CommandProcessingResult depositMoney(JsonCommand command);
|
||||
|
||||
CommandProcessingResult withdrawSavingAmount(JsonCommand command);
|
||||
|
||||
CommandProcessingResult deleteSavingAccount(Long accountId);
|
||||
|
||||
CommandProcessingResult postInterest(Collection<SavingAccountForLookup> savingAccounts);
|
||||
|
||||
}
|
||||
-327
@@ -1,327 +0,0 @@
|
||||
/**
|
||||
* 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.portfolio.savingsaccount.service;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.joda.time.LocalDate;
|
||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResultBuilder;
|
||||
import org.mifosplatform.infrastructure.core.exception.PlatformDataIntegrityException;
|
||||
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
|
||||
import org.mifosplatform.portfolio.note.domain.Note;
|
||||
import org.mifosplatform.portfolio.note.domain.NoteRepository;
|
||||
import org.mifosplatform.portfolio.savingsaccount.data.SavingAccountForLookup;
|
||||
import org.mifosplatform.portfolio.savingsaccount.domain.SavingAccount;
|
||||
import org.mifosplatform.portfolio.savingsaccount.domain.SavingAccountRepository;
|
||||
import org.mifosplatform.portfolio.savingsaccount.exception.SavingAccountNotFoundException;
|
||||
import org.mifosplatform.portfolio.savingsaccount.serialization.SavingAccountCommandFromApiJsonDeserializer;
|
||||
import org.mifosplatform.portfolio.savingsaccount.serialization.SavingAccountStateTransitionCommandFromApiJsonDeserializer;
|
||||
import org.mifosplatform.portfolio.savingsdepositaccount.domain.DepositAccountStatus;
|
||||
import org.mifosplatform.portfolio.savingsdepositaccount.domain.DepositLifecycleStateMachine;
|
||||
import org.mifosplatform.portfolio.savingsdepositaccount.domain.DepositLifecycleStateMachineImpl;
|
||||
import org.mifosplatform.portfolio.savingsdepositaccount.exception.InvalidSavingStateTransitionException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.dao.DataIntegrityViolationException;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Service
|
||||
public class SavingAccountWritePlatformServiceJpaRepositoryImpl implements SavingAccountWritePlatformService {
|
||||
|
||||
private final static Logger logger = LoggerFactory.getLogger(SavingAccountWritePlatformServiceJpaRepositoryImpl.class);
|
||||
|
||||
private final PlatformSecurityContext context;
|
||||
private final SavingAccountRepository savingAccountRepository;
|
||||
private final SavingAccountAssembler savingAccountAssembler;
|
||||
private final NoteRepository noteRepository;
|
||||
private final SavingAccountCommandFromApiJsonDeserializer fromApiJsonDeserializer;
|
||||
private final SavingAccountStateTransitionCommandFromApiJsonDeserializer savingAccountStateTransitionCommandFromApiJsonDeserializer;
|
||||
|
||||
@Autowired
|
||||
public SavingAccountWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context,
|
||||
final SavingAccountRepository savingAccountRepository, final SavingAccountAssembler savingAccountAssembler,
|
||||
final NoteRepository noteRepository,
|
||||
final SavingAccountCommandFromApiJsonDeserializer fromApiJsonDeserializer,
|
||||
final SavingAccountStateTransitionCommandFromApiJsonDeserializer savingAccountStateTransitionCommandFromApiJsonDeserializer) {
|
||||
this.context = context;
|
||||
this.savingAccountRepository = savingAccountRepository;
|
||||
this.savingAccountAssembler = savingAccountAssembler;
|
||||
this.noteRepository = noteRepository;
|
||||
this.fromApiJsonDeserializer = fromApiJsonDeserializer;
|
||||
this.savingAccountStateTransitionCommandFromApiJsonDeserializer = savingAccountStateTransitionCommandFromApiJsonDeserializer;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult createSavingAccount(final JsonCommand command) {
|
||||
try {
|
||||
this.context.authenticatedUser();
|
||||
this.fromApiJsonDeserializer.validateForCreate(command.json());
|
||||
|
||||
SavingAccount account = this.savingAccountAssembler.assembleFrom(command);
|
||||
this.savingAccountRepository.save(account);
|
||||
|
||||
return new CommandProcessingResultBuilder() //
|
||||
.withEntityId(account.getId()) //
|
||||
.build();
|
||||
} catch (DataIntegrityViolationException dve) {
|
||||
handleDataIntegrityIssues(command, dve);
|
||||
return new CommandProcessingResult(Long.valueOf(-1));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandProcessingResult updateSavingAccount(final Long accountId, final JsonCommand command) {
|
||||
try {
|
||||
this.context.authenticatedUser();
|
||||
this.fromApiJsonDeserializer.validateForUpdate(command.json());
|
||||
|
||||
Map<String, Object> changes = new LinkedHashMap<String, Object>(20);;
|
||||
|
||||
SavingAccount account = this.savingAccountRepository.findOne(accountId);
|
||||
if (account == null || account.isDeleted()) { throw new SavingAccountNotFoundException(accountId); }
|
||||
if (account.isPendingApproval()) {
|
||||
changes = this.savingAccountAssembler.assembleFrom(command, account);
|
||||
this.savingAccountRepository.save(account);
|
||||
}
|
||||
return new CommandProcessingResultBuilder() //
|
||||
.withEntityId(account.getId()) //
|
||||
.with(changes)
|
||||
.build();
|
||||
} catch (DataIntegrityViolationException dve) {
|
||||
handleDataIntegrityIssues(command, dve);
|
||||
return new CommandProcessingResult(Long.valueOf(-1));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Guaranteed to throw an exception no matter what the data integrity issue
|
||||
* is.
|
||||
*/
|
||||
private void handleDataIntegrityIssues(final JsonCommand command, final DataIntegrityViolationException dve) {
|
||||
|
||||
Throwable realCause = dve.getMostSpecificCause();
|
||||
if (realCause.getMessage().contains("saving_acc_external_id")) {
|
||||
final String externalId = command.stringValueOfParameterNamed("externalId");
|
||||
throw new PlatformDataIntegrityException(
|
||||
"error.msg.saving.account.duplicate.externalId", "Saving account with externalId " + externalId
|
||||
+ " already exists", "externalId", externalId); }
|
||||
|
||||
logger.error(dve.getMessage(), dve);
|
||||
throw new PlatformDataIntegrityException("error.msg.saving.account.unknown.data.integrity.issue",
|
||||
"Unknown data integrity issue with resource.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandProcessingResult rejectSavingApplication(JsonCommand command) {
|
||||
|
||||
this.context.authenticatedUser();
|
||||
this.savingAccountStateTransitionCommandFromApiJsonDeserializer.validateForReject(command.json());
|
||||
|
||||
SavingAccount account = this.savingAccountRepository.findOne(command.entityId());
|
||||
if (account == null || account.isDeleted()) {
|
||||
throw new SavingAccountNotFoundException(command.entityId());
|
||||
}
|
||||
LocalDate eventDate = command.localDateValueOfParameterNamed("eventDate");
|
||||
if (this.isBeforeToday(eventDate)) {
|
||||
final String errorMessage = "User has no authority to reject saving with a date in the past. ";
|
||||
|
||||
throw new InvalidSavingStateTransitionException("reject", "cannot.be.before.submittal.date", errorMessage, account.projectedCommencementDate(), eventDate);
|
||||
}
|
||||
account.reject(eventDate, defaultDepositLifecycleStateMachine());
|
||||
this.savingAccountRepository.save(account);
|
||||
|
||||
String noteText = command.stringValueOfParameterNamed("note");
|
||||
if (StringUtils.isNotBlank(noteText)) {
|
||||
Note note = Note.savingNote(account, noteText);
|
||||
this.noteRepository.save(note);
|
||||
}
|
||||
|
||||
return new CommandProcessingResultBuilder() //
|
||||
.withEntityId(account.getId()) //
|
||||
.build();
|
||||
}
|
||||
|
||||
private DepositLifecycleStateMachine defaultDepositLifecycleStateMachine() {
|
||||
List<DepositAccountStatus> allowedDepositStatuses = Arrays.asList(DepositAccountStatus.values());
|
||||
return new DepositLifecycleStateMachineImpl(allowedDepositStatuses);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandProcessingResult withdrawSavingApplication(JsonCommand command) {
|
||||
this.context.authenticatedUser();
|
||||
this.savingAccountStateTransitionCommandFromApiJsonDeserializer.validateForWithdrawApplication(command.json());
|
||||
|
||||
SavingAccount account = this.savingAccountRepository.findOne(command.entityId());
|
||||
if (account == null || account.isDeleted()) {
|
||||
throw new SavingAccountNotFoundException(command.entityId());
|
||||
}
|
||||
LocalDate eventDate = command.localDateValueOfParameterNamed("eventDate");
|
||||
if (this.isBeforeToday(eventDate)) {
|
||||
final String errorMessage = "User has no authority to withdraw saving with a date in the past. ";
|
||||
|
||||
throw new InvalidSavingStateTransitionException("reject", "cannot.be.before.submittal.date", errorMessage, account.projectedCommencementDate(), eventDate);
|
||||
}
|
||||
|
||||
account.withdrawnByApplicant(eventDate, defaultDepositLifecycleStateMachine());
|
||||
this.savingAccountRepository.save(account);
|
||||
|
||||
String noteText = command.stringValueOfParameterNamed("note");
|
||||
if (StringUtils.isNotBlank(noteText)) {
|
||||
Note note = Note.savingNote(account, noteText);
|
||||
this.noteRepository.save(note);
|
||||
}
|
||||
|
||||
return new CommandProcessingResultBuilder() //
|
||||
.withEntityId(account.getId()) //
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandProcessingResult undoSavingAccountApproval(JsonCommand command) {
|
||||
|
||||
this.context.authenticatedUser();
|
||||
SavingAccount account = this.savingAccountRepository.findOne(command.entityId());
|
||||
if (account == null || account.isDeleted()) {
|
||||
throw new SavingAccountNotFoundException(command.getLoanId());
|
||||
}
|
||||
account.undoSavingAccountApproval(defaultDepositLifecycleStateMachine());
|
||||
this.savingAccountRepository.save(account);
|
||||
|
||||
String noteText = command.stringValueOfParameterNamed("note");
|
||||
if (StringUtils.isNotBlank(noteText)) {
|
||||
Note note = Note.savingNote(account, noteText);
|
||||
this.noteRepository.save(note);
|
||||
}
|
||||
|
||||
return new CommandProcessingResultBuilder() //
|
||||
.withEntityId(account.getId()) //
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandProcessingResult approveSavingAccount(JsonCommand command) {
|
||||
|
||||
this.context.authenticatedUser();
|
||||
this.savingAccountStateTransitionCommandFromApiJsonDeserializer.validateForApprove(command.json());
|
||||
|
||||
SavingAccount account = this.savingAccountRepository.findOne(command.entityId());
|
||||
if (account == null || account.isDeleted()) {
|
||||
throw new SavingAccountNotFoundException(command.entityId());
|
||||
}
|
||||
LocalDate approvalDate = command.localDateValueOfParameterNamed("commencementDate");
|
||||
if (approvalDate.isBefore(account.projectedCommencementDate())) {
|
||||
final String errorMessage = "The date on which a saving is approved cannot be before its submittal date: "
|
||||
+ approvalDate.toString();
|
||||
|
||||
throw new InvalidSavingStateTransitionException("approval", "cannot.be.before.submittal.date", errorMessage,
|
||||
account.projectedCommencementDate(), approvalDate);
|
||||
}
|
||||
Map<String, Object> changes = this.savingAccountAssembler.approveSavingAccount(command,account);
|
||||
this.savingAccountRepository.save(account);
|
||||
|
||||
String noteText = command.stringValueOfParameterNamed("note");
|
||||
if (StringUtils.isNotBlank(noteText)) {
|
||||
Note note = Note.savingNote(account, noteText);
|
||||
this.noteRepository.save(note);
|
||||
}
|
||||
|
||||
return new CommandProcessingResultBuilder() //
|
||||
.withEntityId(account.getId()) //
|
||||
.with(changes)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandProcessingResult depositMoney(JsonCommand command) {
|
||||
|
||||
this.context.authenticatedUser();
|
||||
this.savingAccountStateTransitionCommandFromApiJsonDeserializer.validateForDepositAmount(command.json());
|
||||
|
||||
SavingAccount account = this.savingAccountRepository.findOne(command.entityId());
|
||||
if (account == null || account.isDeleted()) {
|
||||
throw new SavingAccountNotFoundException(command.entityId());
|
||||
}
|
||||
|
||||
if (account.isActive())
|
||||
account.depositMoney(command);
|
||||
this.savingAccountRepository.save(account);
|
||||
String noteText = command.stringValueOfParameterNamed("note");
|
||||
if (StringUtils.isNotBlank(noteText)) {
|
||||
Note note = Note.savingNote(account, noteText);
|
||||
this.noteRepository.save(note);
|
||||
}
|
||||
return new CommandProcessingResultBuilder() //
|
||||
.withEntityId(account.getId()) //
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandProcessingResult withdrawSavingAmount(JsonCommand command) {
|
||||
|
||||
this.context.authenticatedUser();
|
||||
SavingAccount account = this.savingAccountRepository.findOne(command.entityId());
|
||||
if (account == null || account.isDeleted()) {
|
||||
throw new SavingAccountNotFoundException(command.entityId());
|
||||
}
|
||||
if (account.isActive())
|
||||
this.savingAccountAssembler.withdrawSavingAccountMoney(command,account);
|
||||
this.savingAccountRepository.save(account);
|
||||
String noteText = command.stringValueOfParameterNamed("note");
|
||||
if (StringUtils.isNotBlank(noteText)) {
|
||||
Note note = Note.savingNote(account, noteText);
|
||||
this.noteRepository.save(note);
|
||||
}
|
||||
return new CommandProcessingResultBuilder() //
|
||||
.withEntityId(account.getId()) //
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandProcessingResult deleteSavingAccount(Long accountId) {
|
||||
this.context.authenticatedUser();
|
||||
SavingAccount account = this.savingAccountRepository.findOne(accountId);
|
||||
if (account == null || account.isDeleted()) {
|
||||
throw new SavingAccountNotFoundException(accountId);
|
||||
}
|
||||
account.delete();
|
||||
this.savingAccountRepository.save(account);
|
||||
return new CommandProcessingResultBuilder() //
|
||||
.withEntityId(account.getId()) //
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandProcessingResult postInterest(Collection<SavingAccountForLookup> savingAccounts) {
|
||||
this.context.authenticatedUser();
|
||||
try {
|
||||
for(SavingAccountForLookup accountForLookup : savingAccounts ){
|
||||
SavingAccount account = this.savingAccountRepository.findOne(accountForLookup.getId());
|
||||
if (account == null || account.isDeleted()) { throw new SavingAccountNotFoundException(accountForLookup.getId()); }
|
||||
this.savingAccountAssembler.postInterest(account);
|
||||
this.savingAccountRepository.save(account);
|
||||
}
|
||||
return new CommandProcessingResultBuilder() //
|
||||
.withEntityId(Long.valueOf(savingAccounts.size())) //
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
return new CommandProcessingResult(Long.valueOf(-1));
|
||||
}
|
||||
}
|
||||
private boolean isBeforeToday(final LocalDate date) {
|
||||
return date.isBefore(new LocalDate());
|
||||
}
|
||||
}
|
||||
-139
@@ -1,139 +0,0 @@
|
||||
package org.mifosplatform.portfolio.savingsaccount.service;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
|
||||
import org.joda.time.LocalDate;
|
||||
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
|
||||
import org.mifosplatform.organisation.monetary.data.CurrencyData;
|
||||
import org.mifosplatform.organisation.monetary.domain.ApplicationCurrency;
|
||||
import org.mifosplatform.organisation.monetary.domain.ApplicationCurrencyRepository;
|
||||
import org.mifosplatform.portfolio.savingsaccount.data.SavingScheduleData;
|
||||
import org.mifosplatform.portfolio.savingsaccount.data.SavingSchedulePeriodData;
|
||||
import org.mifosplatform.portfolio.savingsaccount.domain.SavingAccount;
|
||||
import org.mifosplatform.portfolio.savingsaccountproduct.domain.SavingFrequencyType;
|
||||
import org.mifosplatform.portfolio.savingsaccountproduct.domain.SavingInterestCalculationMethod;
|
||||
import org.mifosplatform.portfolio.savingsaccountproduct.domain.SavingProduct;
|
||||
import org.mifosplatform.portfolio.savingsaccountproduct.domain.SavingProductRepository;
|
||||
import org.mifosplatform.portfolio.savingsaccountproduct.domain.SavingProductType;
|
||||
import org.mifosplatform.portfolio.savingsaccountproduct.exception.SavingProductNotFoundException;
|
||||
import org.mifosplatform.portfolio.savingsdepositproduct.domain.TenureTypeEnum;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
|
||||
@Service
|
||||
public class SavingScheduleAssembler {
|
||||
|
||||
private final FromJsonHelper fromApiJsonHelper;
|
||||
private final SavingProductRepository savingProductRepository;
|
||||
private final SavingScheduleGenerator savingScheduleGenerator;
|
||||
private final ApplicationCurrencyRepository applicationCurrencyRepository;
|
||||
|
||||
@Autowired
|
||||
public SavingScheduleAssembler( final FromJsonHelper fromApiJsonHelper,
|
||||
final SavingProductRepository savingProductRepository,
|
||||
final ApplicationCurrencyRepository applicationCurrencyRepository) {
|
||||
this.fromApiJsonHelper = fromApiJsonHelper;
|
||||
this.savingProductRepository = savingProductRepository;
|
||||
this.savingScheduleGenerator = new SavingScheduleGenerator();
|
||||
this.applicationCurrencyRepository = applicationCurrencyRepository;
|
||||
}
|
||||
|
||||
public SavingScheduleData fromJson(JsonElement element) {
|
||||
|
||||
SavingScheduleData savingScheduleData = null;
|
||||
|
||||
final Long productId = fromApiJsonHelper.extractLongNamed("productId", element);
|
||||
final Integer depositEvery = fromApiJsonHelper.extractIntegerWithLocaleNamed("depositEvery", element);
|
||||
final LocalDate scheduleStartDate = fromApiJsonHelper.extractLocalDateNamed("commencementDate", element);
|
||||
final BigDecimal interestRate = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed("recurringInterestRate", element);
|
||||
final BigDecimal depositAmountPerPeriod = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed("savingsDepositAmountPerPeriod", element);
|
||||
final Integer tenure = this.fromApiJsonHelper.extractIntegerWithLocaleNamed("tenure", element);
|
||||
|
||||
final Integer tenureTypeCommandValue = this.fromApiJsonHelper.extractIntegerWithLocaleNamed("tenureType", element);
|
||||
TenureTypeEnum tenureType = TenureTypeEnum.fromInt(tenureTypeCommandValue);
|
||||
final Integer frequencyCommandValue = this.fromApiJsonHelper.extractIntegerWithLocaleNamed("frequency", element);
|
||||
SavingFrequencyType savingFrequencyType = SavingFrequencyType.fromInt(frequencyCommandValue);
|
||||
//final Integer interestTypeCommandValue = this.fromApiJsonHelper.extractIntegerWithLocaleNamed("interestType", element);
|
||||
//SavingsInterestType interestType = SavingsInterestType.fromInt(interestTypeCommandValue);
|
||||
final Integer interestCalculationMethodCommandValue = this.fromApiJsonHelper.extractIntegerWithLocaleNamed("interestCalculationMethod", element);
|
||||
SavingInterestCalculationMethod interestCalculationMethod = SavingInterestCalculationMethod.fromInt(interestCalculationMethodCommandValue);
|
||||
|
||||
final SavingProduct savingProduct = this.savingProductRepository.findOne(productId);
|
||||
if (savingProduct == null) throw new SavingProductNotFoundException(productId);
|
||||
final ApplicationCurrency applicationCurrency = this.applicationCurrencyRepository.findOneByCode(savingProduct.getCurrency().getCode());
|
||||
|
||||
SavingProductType savingProductType = SavingProductType.fromInt(savingProduct.getSavingProductRelatedDetail().getSavingProductType());
|
||||
|
||||
if (savingProductType.isReccuring() && tenureType.isFixedPeriod()) {
|
||||
savingScheduleData = savingScheduleGenerator.generate(scheduleStartDate, depositAmountPerPeriod,
|
||||
depositEvery, savingFrequencyType, savingProduct, tenure, applicationCurrency,interestRate,interestCalculationMethod);
|
||||
} else {
|
||||
final Collection<SavingSchedulePeriodData> periods = new ArrayList<SavingSchedulePeriodData>();
|
||||
CurrencyData currencyData = new CurrencyData(applicationCurrency.getCode(), applicationCurrency.getName(),
|
||||
savingProduct.getCurrency().getDigitsAfterDecimal(), applicationCurrency.getDisplaySymbol(), applicationCurrency.getNameCode());
|
||||
SavingSchedulePeriodData installment = SavingSchedulePeriodData.addScheduleInformation(1, new LocalDate(scheduleStartDate).plusMonths(depositEvery), depositAmountPerPeriod, BigDecimal.ZERO);
|
||||
periods.add(installment);
|
||||
savingScheduleData = new SavingScheduleData(currencyData, depositAmountPerPeriod, BigDecimal.ZERO, BigDecimal.ZERO, periods);
|
||||
}
|
||||
|
||||
return savingScheduleData;
|
||||
}
|
||||
|
||||
public SavingScheduleData calculateSavingSchedule(JsonElement element, SavingAccount account) {
|
||||
|
||||
SavingScheduleData savingScheduleData = null;
|
||||
|
||||
SavingProduct savingProduct = account.getProduct();
|
||||
SavingProductType savingProductType = SavingProductType.fromInt(account.getSavingProductType());
|
||||
SavingInterestCalculationMethod interestCalculationMethod = SavingInterestCalculationMethod.fromInt(account.getInterestCalculationMethod());
|
||||
|
||||
TenureTypeEnum tenureType = TenureTypeEnum.fromInt(account.getTenureType());
|
||||
final Integer tenureTypeCommandValue = this.fromApiJsonHelper.extractIntegerWithLocaleNamed("tenureType", element);
|
||||
if (tenureTypeCommandValue != null) tenureType = TenureTypeEnum.fromInt(tenureTypeCommandValue);
|
||||
|
||||
LocalDate scheduleStartDate = new LocalDate(account.getProjectedCommencementDate());
|
||||
final LocalDate commencementDate = fromApiJsonHelper.extractLocalDateNamed("commencementDate", element);
|
||||
if (commencementDate != null) scheduleStartDate = commencementDate ;
|
||||
|
||||
BigDecimal depositAmountPerPeriod = account.getSavingsDepositAmountPerPeriod();
|
||||
final BigDecimal savingsDepositAmountPerPeriod = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed("savingsDepositAmountPerPeriod", element);
|
||||
if (savingsDepositAmountPerPeriod != null ) depositAmountPerPeriod = savingsDepositAmountPerPeriod;
|
||||
|
||||
Integer depositEvery = account.getPayEvery();
|
||||
final Integer depositEveryCommandValue = fromApiJsonHelper.extractIntegerWithLocaleNamed("depositEvery", element);
|
||||
if (depositEveryCommandValue != null ) depositEvery = depositEveryCommandValue;
|
||||
|
||||
SavingFrequencyType savingFrequencyType = SavingFrequencyType.fromInt(account.getFrequency());
|
||||
final Integer frequencyCommandValue = this.fromApiJsonHelper.extractIntegerWithLocaleNamed("frequency", element);
|
||||
if (frequencyCommandValue != null ) savingFrequencyType = SavingFrequencyType.fromInt(frequencyCommandValue);
|
||||
|
||||
Integer tenure = account.getTenure();
|
||||
final Integer tenureCommandValue = this.fromApiJsonHelper.extractIntegerWithLocaleNamed("tenure", element);
|
||||
if (tenureCommandValue != null ) tenure = tenureCommandValue;
|
||||
|
||||
BigDecimal interestRate = account.getReccuringInterestRate();
|
||||
final BigDecimal recurringInterestRate = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed("recurringInterestRate", element);
|
||||
if (recurringInterestRate != null ) interestRate = recurringInterestRate;
|
||||
|
||||
final ApplicationCurrency applicationCurrency = this.applicationCurrencyRepository.findOneByCode(savingProduct.getCurrency().getCode());
|
||||
|
||||
if (savingProductType.isReccuring() && tenureType.isFixedPeriod()) {
|
||||
savingScheduleData = savingScheduleGenerator.generate(scheduleStartDate, depositAmountPerPeriod,
|
||||
depositEvery, savingFrequencyType, savingProduct, tenure, applicationCurrency,interestRate,interestCalculationMethod);
|
||||
} else {
|
||||
final Collection<SavingSchedulePeriodData> periods = new ArrayList<SavingSchedulePeriodData>();
|
||||
CurrencyData currencyData = new CurrencyData(applicationCurrency.getCode(), applicationCurrency.getName(),
|
||||
savingProduct.getCurrency().getDigitsAfterDecimal(), applicationCurrency.getDisplaySymbol(), applicationCurrency.getNameCode());
|
||||
SavingSchedulePeriodData installment = SavingSchedulePeriodData.addScheduleInformation(1, new LocalDate(scheduleStartDate).plusMonths(depositEvery), depositAmountPerPeriod, BigDecimal.ZERO);
|
||||
periods.add(installment);
|
||||
savingScheduleData = new SavingScheduleData(currencyData, depositAmountPerPeriod, BigDecimal.ZERO, BigDecimal.ZERO, periods);
|
||||
}
|
||||
|
||||
return savingScheduleData;
|
||||
}
|
||||
|
||||
}
|
||||
-130
@@ -1,130 +0,0 @@
|
||||
/**
|
||||
* 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.portfolio.savingsaccount.service;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.MathContext;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.joda.time.LocalDate;
|
||||
import org.mifosplatform.organisation.monetary.data.CurrencyData;
|
||||
import org.mifosplatform.organisation.monetary.domain.ApplicationCurrency;
|
||||
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
|
||||
import org.mifosplatform.organisation.monetary.domain.Money;
|
||||
import org.mifosplatform.portfolio.savingsaccount.data.SavingScheduleData;
|
||||
import org.mifosplatform.portfolio.savingsaccount.data.SavingSchedulePeriodData;
|
||||
import org.mifosplatform.portfolio.savingsaccount.domain.DepositScheduleDateGenerator;
|
||||
import org.mifosplatform.portfolio.savingsaccountproduct.domain.SavingFrequencyType;
|
||||
import org.mifosplatform.portfolio.savingsaccountproduct.domain.SavingInterestCalculationMethod;
|
||||
import org.mifosplatform.portfolio.savingsaccountproduct.domain.SavingProduct;
|
||||
|
||||
public class SavingScheduleGenerator {
|
||||
|
||||
private final DepositScheduleDateGenerator scheduledDateGenerator = new DefaultDepositScheduleDateGenerator();
|
||||
private final Integer monthsInYear = 12;
|
||||
|
||||
public SavingScheduleData generate(final LocalDate scheduleStartDate, final BigDecimal depositAmountPerPeriod,
|
||||
final Integer depositFrequency, final SavingFrequencyType savingFrequencyType, final SavingProduct savingProduct,
|
||||
final Integer tenure, final ApplicationCurrency applicationCurrency, final BigDecimal interestRate, final SavingInterestCalculationMethod interestCalculationMethod) {
|
||||
|
||||
LocalDate startDate = scheduleStartDate;
|
||||
int periodNumber = 1;
|
||||
|
||||
Integer paymentPeriods = tenure / depositFrequency;
|
||||
final Collection<SavingSchedulePeriodData> periods = new ArrayList<SavingSchedulePeriodData>();
|
||||
final List<LocalDate> scheduledDates = this.scheduledDateGenerator.generate(startDate, paymentPeriods, depositFrequency,
|
||||
savingFrequencyType);
|
||||
final MonetaryCurrency currency = savingProduct.getCurrency();
|
||||
final Money depositAmount = Money.of(currency, depositAmountPerPeriod);
|
||||
Money totalDeposit = Money.zero(currency);
|
||||
|
||||
|
||||
MathContext mc = new MathContext(8, RoundingMode.HALF_EVEN);
|
||||
BigDecimal interestRateAsFraction = interestRate.divide(BigDecimal.valueOf(100), mc);
|
||||
Integer noofTimesInterestCompoundPerYear = determineIntValue(savingFrequencyType);
|
||||
BigDecimal interestRatePerPeriod = BigDecimal.valueOf(interestRateAsFraction.doubleValue()/ noofTimesInterestCompoundPerYear.doubleValue());
|
||||
BigDecimal onePlusInterestRatePerPeriod = BigDecimal.ONE.add(interestRatePerPeriod);
|
||||
BigDecimal cummulativeDepositPaid = BigDecimal.ZERO;
|
||||
BigDecimal cummulativeInterestAccured = BigDecimal.ZERO;
|
||||
Integer tempTenure = tenure;
|
||||
|
||||
BigDecimal termAmount = BigDecimal.ZERO;
|
||||
BigDecimal totalInterest = BigDecimal.ZERO;
|
||||
BigDecimal closingBalance = BigDecimal.ZERO;
|
||||
|
||||
for (LocalDate scheduleDate : scheduledDates) {
|
||||
|
||||
if (interestCalculationMethod.isMonthlyCollection()) {
|
||||
BigDecimal monthsExpressedInYears = BigDecimal.valueOf(tempTenure.doubleValue() / monthsInYear.doubleValue());
|
||||
BigDecimal timeforOneCalculationPeriod = BigDecimal.valueOf(noofTimesInterestCompoundPerYear * monthsExpressedInYears.doubleValue());
|
||||
BigDecimal amountPerPeriod = depositAmountPerPeriod.multiply(BigDecimal.valueOf(Math.pow(onePlusInterestRatePerPeriod.doubleValue(), timeforOneCalculationPeriod.doubleValue())));
|
||||
BigDecimal interestAccured = amountPerPeriod.subtract(depositAmountPerPeriod);
|
||||
|
||||
totalDeposit = totalDeposit.plus(depositAmount);
|
||||
cummulativeInterestAccured = cummulativeInterestAccured.add(interestAccured);
|
||||
SavingSchedulePeriodData installment = SavingSchedulePeriodData.addScheduleInformation(periodNumber, scheduleDate,
|
||||
depositAmount.getAmount(), interestAccured);
|
||||
periods.add(installment);
|
||||
periodNumber++;
|
||||
tempTenure = tempTenure - depositFrequency;
|
||||
} else if (interestCalculationMethod.isAverageBalance()){
|
||||
|
||||
BigDecimal amountPerPeriod = depositAmount.getAmount();
|
||||
Integer depositEveryOriginalValue = depositFrequency;
|
||||
BigDecimal amountPermonth = BigDecimal.valueOf(amountPerPeriod.doubleValue()/depositFrequency.doubleValue());
|
||||
|
||||
while (depositEveryOriginalValue > 0) {
|
||||
closingBalance = closingBalance.add(amountPermonth);
|
||||
termAmount = termAmount.add(closingBalance);
|
||||
depositEveryOriginalValue--;
|
||||
}
|
||||
|
||||
BigDecimal averageAmount = BigDecimal.valueOf(termAmount.doubleValue()/depositFrequency.doubleValue());
|
||||
BigDecimal interestRatePerTerm = BigDecimal.valueOf(interestRateAsFraction.doubleValue()/monthsInYear.doubleValue()*depositFrequency.doubleValue());
|
||||
BigDecimal interestAccured = averageAmount.multiply(interestRatePerTerm);
|
||||
totalInterest = totalInterest.add(interestAccured);
|
||||
depositEveryOriginalValue = depositFrequency;
|
||||
termAmount = BigDecimal.ZERO;
|
||||
|
||||
totalDeposit = totalDeposit.plus(depositAmount);
|
||||
cummulativeInterestAccured = totalInterest;
|
||||
SavingSchedulePeriodData installment = SavingSchedulePeriodData.addScheduleInformation(periodNumber, scheduleDate,
|
||||
depositAmount.getAmount(), interestAccured);
|
||||
periods.add(installment);
|
||||
periodNumber++;
|
||||
}
|
||||
}
|
||||
CurrencyData currencyData = new CurrencyData(applicationCurrency.getCode(), applicationCurrency.getName(),
|
||||
currency.getDigitsAfterDecimal(), applicationCurrency.getDisplaySymbol(), applicationCurrency.getNameCode());
|
||||
|
||||
return new SavingScheduleData(currencyData, totalDeposit.getAmount(),cummulativeDepositPaid, cummulativeInterestAccured, periods);
|
||||
}
|
||||
|
||||
private Integer determineIntValue(SavingFrequencyType frequencyType){
|
||||
Integer noofTimesInterestCompoundPerYear = Integer.valueOf(0);
|
||||
switch (frequencyType) {
|
||||
case MONTHLY:
|
||||
noofTimesInterestCompoundPerYear = monthsInYear;
|
||||
break;
|
||||
case QUATERLY:
|
||||
noofTimesInterestCompoundPerYear = monthsInYear / 3;
|
||||
break;
|
||||
case HALFYEARLY:
|
||||
noofTimesInterestCompoundPerYear = monthsInYear / 6;
|
||||
break;
|
||||
case YEARLY:
|
||||
noofTimesInterestCompoundPerYear = monthsInYear / 12;
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException("The specified frequency not supported");
|
||||
|
||||
}
|
||||
return noofTimesInterestCompoundPerYear;
|
||||
}
|
||||
}
|
||||
-207
@@ -1,207 +0,0 @@
|
||||
/**
|
||||
* 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.portfolio.savingsaccountproduct.api;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.DELETE;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.PUT;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.core.Context;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.UriInfo;
|
||||
|
||||
import org.mifosplatform.commands.domain.CommandWrapper;
|
||||
import org.mifosplatform.commands.service.CommandWrapperBuilder;
|
||||
import org.mifosplatform.commands.service.PortfolioCommandSourceWritePlatformService;
|
||||
import org.mifosplatform.infrastructure.core.api.ApiRequestParameterHelper;
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
|
||||
import org.mifosplatform.infrastructure.core.serialization.ApiRequestJsonSerializationSettings;
|
||||
import org.mifosplatform.infrastructure.core.serialization.DefaultToApiJsonSerializer;
|
||||
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
|
||||
import org.mifosplatform.organisation.monetary.data.CurrencyData;
|
||||
import org.mifosplatform.organisation.monetary.service.CurrencyReadPlatformService;
|
||||
import org.mifosplatform.portfolio.savingsaccountproduct.data.SavingProductData;
|
||||
import org.mifosplatform.portfolio.savingsaccountproduct.domain.SavingFrequencyType;
|
||||
import org.mifosplatform.portfolio.savingsaccountproduct.domain.SavingInterestCalculationMethod;
|
||||
import org.mifosplatform.portfolio.savingsaccountproduct.domain.SavingProductType;
|
||||
import org.mifosplatform.portfolio.savingsaccountproduct.domain.SavingsInterestType;
|
||||
import org.mifosplatform.portfolio.savingsaccountproduct.domain.SavingsLockinPeriodEnum;
|
||||
import org.mifosplatform.portfolio.savingsaccountproduct.service.SavingProductEnumerations;
|
||||
import org.mifosplatform.portfolio.savingsaccountproduct.service.SavingProductReadPlatformService;
|
||||
import org.mifosplatform.portfolio.savingsdepositproduct.domain.TenureTypeEnum;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Path("/savingproducts")
|
||||
@Component
|
||||
@Scope("singleton")
|
||||
public class SavingProductsApiResource {
|
||||
|
||||
private final Set<String> SAVINGS_PRODUCT_DATA_PARAMETERS = new HashSet<String>(Arrays.asList("currencyOptions", "id", "createdOn",
|
||||
"lastModifedOn", "locale", "name", "description", "currencyCode", "digitsAfterDecimal", "interstRate", "minInterestRate",
|
||||
"maxInterestRate", "savingsDepositAmount", "savingProductType", "tenureType", "tenure", "frequency", "interestType",
|
||||
"interestCalculationMethod", "minimumBalanceForWithdrawal", "isPartialDepositAllowed", "isLockinPeriodAllowed", "lockinPeriod",
|
||||
"lockinPeriodType", "currencyOptions", "savingsProductTypeOptions", "tenureTypeOptions", "depositEvery",
|
||||
"savingFrequencyOptions", "savingsInterestTypeOptions", "lockinPeriodTypeOptions", "interestCalculationOptions"));
|
||||
|
||||
private final SavingProductReadPlatformService savingProductReadPlatformService;
|
||||
private final CurrencyReadPlatformService currencyReadPlatformService;
|
||||
private final String entityType = "SAVINGSPRODUCT";
|
||||
private final PlatformSecurityContext context;
|
||||
private final DefaultToApiJsonSerializer<SavingProductData> toApiJsonSerializer;
|
||||
private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
|
||||
private final ApiRequestParameterHelper apiRequestParameterHelper;
|
||||
|
||||
@Autowired
|
||||
public SavingProductsApiResource(final SavingProductReadPlatformService savingProductReadPlatformService,
|
||||
final CurrencyReadPlatformService currencyReadPlatformService, final PlatformSecurityContext context,
|
||||
final DefaultToApiJsonSerializer<SavingProductData> toApiJsonSerializer,
|
||||
final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService,
|
||||
final ApiRequestParameterHelper apiRequestParameterHelper) {
|
||||
this.savingProductReadPlatformService = savingProductReadPlatformService;
|
||||
this.currencyReadPlatformService = currencyReadPlatformService;
|
||||
this.context = context;
|
||||
this.toApiJsonSerializer = toApiJsonSerializer;
|
||||
this.commandsSourceWritePlatformService = commandsSourceWritePlatformService;
|
||||
this.apiRequestParameterHelper = apiRequestParameterHelper;
|
||||
}
|
||||
|
||||
@POST
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String createSavingProduct(final String apiRequestBodyAsJson) {
|
||||
|
||||
final CommandWrapper commandRequest = new CommandWrapperBuilder().createSavingProduct().withJson(apiRequestBodyAsJson).build();
|
||||
|
||||
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
||||
|
||||
return this.toApiJsonSerializer.serialize(result);
|
||||
|
||||
}
|
||||
|
||||
@PUT
|
||||
@Path("{productId}")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String updateSavingProduct(@PathParam("productId") final Long productId, final String apiRequestBodyAsJson) {
|
||||
|
||||
final CommandWrapper commandRequest = new CommandWrapperBuilder().updateSavingProduct(productId).withJson(apiRequestBodyAsJson)
|
||||
.build();
|
||||
|
||||
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
||||
|
||||
return this.toApiJsonSerializer.serialize(result);
|
||||
|
||||
}
|
||||
|
||||
@GET
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String retrieveAllSavingProducts(@Context final UriInfo uriInfo) {
|
||||
|
||||
context.authenticatedUser().validateHasReadPermission(entityType);
|
||||
|
||||
Collection<SavingProductData> products = this.savingProductReadPlatformService.retrieveAllSavingProducts();
|
||||
|
||||
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
||||
|
||||
return this.toApiJsonSerializer.serialize(settings, products, SAVINGS_PRODUCT_DATA_PARAMETERS);
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("{productId}")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String retrieveSavingProductDetails(@PathParam("productId") final Long productId, @Context final UriInfo uriInfo) {
|
||||
|
||||
context.authenticatedUser().validateHasReadPermission(entityType);
|
||||
|
||||
SavingProductData savingProduct = this.savingProductReadPlatformService.retrieveSavingProduct(productId);
|
||||
|
||||
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
||||
|
||||
if (settings.isTemplate()) {
|
||||
savingProduct = handleTemplateRelatedData(savingProduct);
|
||||
}
|
||||
|
||||
return this.toApiJsonSerializer.serialize(settings, savingProduct, SAVINGS_PRODUCT_DATA_PARAMETERS);
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("template")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String retrieveNewSavingProductDetails(@Context final UriInfo uriInfo) {
|
||||
|
||||
context.authenticatedUser().validateHasReadPermission(entityType);
|
||||
|
||||
SavingProductData savingProduct = this.savingProductReadPlatformService.retrieveNewSavingProductDetails();
|
||||
|
||||
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
||||
|
||||
savingProduct = handleTemplateRelatedData(savingProduct);
|
||||
|
||||
return this.toApiJsonSerializer.serialize(settings, savingProduct, SAVINGS_PRODUCT_DATA_PARAMETERS);
|
||||
}
|
||||
|
||||
private SavingProductData handleTemplateRelatedData(final SavingProductData savingProduct) {
|
||||
|
||||
Collection<CurrencyData> currencyOptions = this.currencyReadPlatformService.retrieveAllowedCurrencies();
|
||||
|
||||
EnumOptionData reccuring = SavingProductEnumerations.savingProductType(SavingProductType.RECURRING);
|
||||
EnumOptionData regular = SavingProductEnumerations.savingProductType(SavingProductType.REGULAR);
|
||||
List<EnumOptionData> savingsProductTypeOptions = Arrays.asList(reccuring, regular);
|
||||
|
||||
EnumOptionData fixed = SavingProductEnumerations.tenureTypeEnum(TenureTypeEnum.FIXED_PERIOD);
|
||||
EnumOptionData perpetual = SavingProductEnumerations.tenureTypeEnum(TenureTypeEnum.PERPETUAL);
|
||||
List<EnumOptionData> tenureTypeOptions = Arrays.asList(fixed, perpetual);
|
||||
|
||||
EnumOptionData monthly = SavingProductEnumerations.interestFrequencyType(SavingFrequencyType.MONTHLY);
|
||||
List<EnumOptionData> savingFrequencyOptions = Arrays.asList(monthly);
|
||||
|
||||
EnumOptionData simple = SavingProductEnumerations.savingInterestType(SavingsInterestType.SIMPLE);
|
||||
EnumOptionData compounding = SavingProductEnumerations.savingInterestType(SavingsInterestType.COMPOUNDING);
|
||||
List<EnumOptionData> savingsInterestTypeOptions = Arrays.asList(simple, compounding);
|
||||
|
||||
EnumOptionData months = SavingProductEnumerations.savingsLockinPeriod(SavingsLockinPeriodEnum.MONTHS);
|
||||
List<EnumOptionData> lockinPeriodTypeOptions = Arrays.asList(months);
|
||||
|
||||
EnumOptionData averagebal = SavingProductEnumerations.savingInterestCalculationMethod(SavingInterestCalculationMethod.AVERAGEBAL);
|
||||
EnumOptionData minbal = SavingProductEnumerations.savingInterestCalculationMethod(SavingInterestCalculationMethod.MINBAL);
|
||||
EnumOptionData monthlyCollection = SavingProductEnumerations
|
||||
.savingInterestCalculationMethod(SavingInterestCalculationMethod.MONTHLYCOLLECTION);
|
||||
List<EnumOptionData> interestCalculationOptions = Arrays.asList(averagebal, minbal, monthlyCollection);
|
||||
|
||||
return new SavingProductData(savingProduct, currencyOptions, savingsProductTypeOptions, tenureTypeOptions, savingFrequencyOptions,
|
||||
savingsInterestTypeOptions, lockinPeriodTypeOptions, interestCalculationOptions);
|
||||
}
|
||||
|
||||
@DELETE
|
||||
@Path("{productId}")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String deleteProduct(@PathParam("productId") final Long productId) {
|
||||
|
||||
final CommandWrapper commandRequest = new CommandWrapperBuilder().deleteSavingProduct(productId).build();
|
||||
|
||||
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
||||
|
||||
return this.toApiJsonSerializer.serialize(result);
|
||||
|
||||
}
|
||||
}
|
||||
-279
@@ -1,279 +0,0 @@
|
||||
/**
|
||||
* 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.portfolio.savingsaccountproduct.data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.joda.time.DateTime;
|
||||
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
|
||||
import org.mifosplatform.organisation.monetary.data.CurrencyData;
|
||||
import org.mifosplatform.portfolio.savingsaccountproduct.domain.SavingFrequencyType;
|
||||
import org.mifosplatform.portfolio.savingsaccountproduct.domain.SavingInterestCalculationMethod;
|
||||
import org.mifosplatform.portfolio.savingsaccountproduct.domain.SavingProductType;
|
||||
import org.mifosplatform.portfolio.savingsaccountproduct.domain.SavingsInterestType;
|
||||
import org.mifosplatform.portfolio.savingsaccountproduct.domain.SavingsLockinPeriodEnum;
|
||||
import org.mifosplatform.portfolio.savingsaccountproduct.service.SavingProductEnumerations;
|
||||
import org.mifosplatform.portfolio.savingsdepositproduct.domain.TenureTypeEnum;
|
||||
|
||||
public class SavingProductData implements Serializable {
|
||||
|
||||
private final Long id;
|
||||
private final String name;
|
||||
private final String description;
|
||||
private final CurrencyData currency;
|
||||
private final Integer digitsAfterDecimal;
|
||||
|
||||
private final BigDecimal interestRate;
|
||||
private final BigDecimal minInterestRate;
|
||||
private final BigDecimal maxInterestRate;
|
||||
private final BigDecimal savingsDepositAmount;
|
||||
private final EnumOptionData savingProductType;
|
||||
private final EnumOptionData tenureType;
|
||||
private final Integer tenure;
|
||||
private final EnumOptionData savingFrequencyType;
|
||||
private final EnumOptionData interestType;
|
||||
private final EnumOptionData interestCalculationMethod;
|
||||
private final BigDecimal minimumBalanceForWithdrawal;
|
||||
private final boolean isPartialDepositAllowed;
|
||||
private final boolean isLockinPeriodAllowed;
|
||||
private final Integer lockinPeriod;
|
||||
private final EnumOptionData lockinPeriodType;
|
||||
|
||||
private DateTime createdOn;
|
||||
private DateTime lastModifedOn;
|
||||
private final Integer depositEvery;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private Collection<CurrencyData> currencyOptions = new ArrayList<CurrencyData>();
|
||||
private List<EnumOptionData> savingsProductTypeOptions = new ArrayList<EnumOptionData>();
|
||||
private List<EnumOptionData> tenureTypeOptions = new ArrayList<EnumOptionData>();
|
||||
private List<EnumOptionData> savingFrequencyOptions = new ArrayList<EnumOptionData>();
|
||||
private List<EnumOptionData> savingsInterestTypeOptions = new ArrayList<EnumOptionData>();
|
||||
private List<EnumOptionData> lockinPeriodTypeOptions = new ArrayList<EnumOptionData>();
|
||||
private List<EnumOptionData> interestCalculationOptions = new ArrayList<EnumOptionData>();
|
||||
|
||||
public SavingProductData() {
|
||||
this.createdOn = new DateTime();
|
||||
this.lastModifedOn = new DateTime();
|
||||
this.id = null;
|
||||
this.name = null;
|
||||
this.description = null;
|
||||
this.interestRate = BigDecimal.ZERO;
|
||||
this.minInterestRate = BigDecimal.ZERO;
|
||||
this.maxInterestRate = BigDecimal.ZERO;
|
||||
this.currency = new CurrencyData("USD", "US Dollar", 2, "$", "currency.USD");
|
||||
this.digitsAfterDecimal = Integer.valueOf(2);
|
||||
this.savingsDepositAmount = BigDecimal.ZERO;
|
||||
this.savingProductType = SavingProductEnumerations.savingProductType(SavingProductType.RECURRING);
|
||||
this.tenureType = SavingProductEnumerations.tenureTypeEnum(TenureTypeEnum.FIXED_PERIOD);
|
||||
this.tenure = Integer.valueOf(12);
|
||||
this.savingFrequencyType = SavingProductEnumerations.interestFrequencyType(SavingFrequencyType.MONTHLY);
|
||||
this.interestType = SavingProductEnumerations.savingInterestType(SavingsInterestType.COMPOUNDING);
|
||||
this.interestCalculationMethod = SavingProductEnumerations
|
||||
.savingInterestCalculationMethod(SavingInterestCalculationMethod.AVERAGEBAL);
|
||||
this.minimumBalanceForWithdrawal = BigDecimal.valueOf(100);
|
||||
this.isPartialDepositAllowed = false;
|
||||
this.isLockinPeriodAllowed = false;
|
||||
this.lockinPeriod = Integer.valueOf(0);
|
||||
this.lockinPeriodType = SavingProductEnumerations.savingsLockinPeriod(SavingsLockinPeriodEnum.MONTHS);
|
||||
this.depositEvery = Integer.valueOf(3);
|
||||
}
|
||||
|
||||
public SavingProductData(DateTime createdOn, DateTime lastModifedOn, Long id, String name, String description, BigDecimal interestRate,
|
||||
BigDecimal minInterestRate, BigDecimal maxInterestRate, CurrencyData currency, Integer digitsAfterDecimal,
|
||||
BigDecimal savingsDepositAmount, EnumOptionData savingProductType, EnumOptionData tenureType, Integer tenure,
|
||||
EnumOptionData savingFrequencyType, EnumOptionData savingInterestType, EnumOptionData interestCalculationMethod,
|
||||
BigDecimal minimumBalanceForWithdrawal, boolean isPartialDepositAllowed, boolean isLockinPeriodAllowed, Integer lockinPeriod,
|
||||
EnumOptionData lockinPeriodType, Integer depositEvery) {
|
||||
this.createdOn = createdOn;
|
||||
this.lastModifedOn = lastModifedOn;
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
this.interestRate = interestRate;
|
||||
this.minInterestRate = minInterestRate;
|
||||
this.maxInterestRate = maxInterestRate;
|
||||
this.currency = currency;
|
||||
this.digitsAfterDecimal = digitsAfterDecimal;
|
||||
this.savingsDepositAmount = savingsDepositAmount;
|
||||
this.savingProductType = savingProductType;
|
||||
this.tenureType = tenureType;
|
||||
this.tenure = tenure;
|
||||
this.savingFrequencyType = savingFrequencyType;
|
||||
this.interestType = savingInterestType;
|
||||
this.interestCalculationMethod = interestCalculationMethod;
|
||||
this.minimumBalanceForWithdrawal = minimumBalanceForWithdrawal;
|
||||
this.isPartialDepositAllowed = isPartialDepositAllowed;
|
||||
this.isLockinPeriodAllowed = isLockinPeriodAllowed;
|
||||
this.lockinPeriod = lockinPeriod;
|
||||
this.lockinPeriodType = lockinPeriodType;
|
||||
this.depositEvery = depositEvery;
|
||||
}
|
||||
|
||||
public SavingProductData(SavingProductData product, Collection<CurrencyData> currencyOptions,
|
||||
List<EnumOptionData> savingsProductTypeOptions, List<EnumOptionData> tenureTypeOptions,
|
||||
List<EnumOptionData> savingFrequencyOptions, List<EnumOptionData> savingsInterestTypeOptions,
|
||||
List<EnumOptionData> lockinPeriodTypeOptions, List<EnumOptionData> interestCalculationOptions) {
|
||||
|
||||
this.createdOn = product.getCreatedOn();
|
||||
this.lastModifedOn = product.getLastModifedOn();
|
||||
this.id = product.getId();
|
||||
this.name = product.getName();
|
||||
this.description = product.getDescription();
|
||||
this.interestRate = product.getInterestRate();
|
||||
this.minInterestRate = product.getMinInterestRate();
|
||||
this.maxInterestRate = product.getMaxInterestRate();
|
||||
this.currency = product.getCurrency();
|
||||
this.digitsAfterDecimal = product.getDigitsAfterDecimal();
|
||||
this.savingsDepositAmount = product.getSavingsDepositAmount();
|
||||
this.savingProductType = product.getSavingProductType();
|
||||
this.tenureType = product.getTenureType();
|
||||
this.tenure = product.getTenure();
|
||||
this.savingFrequencyType = product.getSavingFrequencyType();
|
||||
this.interestType = product.getInterestType();
|
||||
this.interestCalculationMethod = product.getInterestCalculationMethod();
|
||||
this.minimumBalanceForWithdrawal = product.getMinimumBalanceForWithdrawal();
|
||||
this.isPartialDepositAllowed = product.isPartialDepositAllowed();
|
||||
this.isLockinPeriodAllowed = product.isLockinPeriodAllowed();
|
||||
this.lockinPeriod = product.getLockinPeriod();
|
||||
this.lockinPeriodType = product.getLockinPeriodType();
|
||||
this.depositEvery = product.getDepositEvery();
|
||||
|
||||
this.currencyOptions = currencyOptions;
|
||||
this.savingsProductTypeOptions = savingsProductTypeOptions;
|
||||
this.tenureTypeOptions = tenureTypeOptions;
|
||||
this.savingFrequencyOptions = savingFrequencyOptions;
|
||||
this.savingsInterestTypeOptions = savingsInterestTypeOptions;
|
||||
this.lockinPeriodTypeOptions = lockinPeriodTypeOptions;
|
||||
this.interestCalculationOptions = interestCalculationOptions;
|
||||
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public CurrencyData getCurrency() {
|
||||
return currency;
|
||||
}
|
||||
|
||||
public Integer getDigitsAfterDecimal() {
|
||||
return digitsAfterDecimal;
|
||||
}
|
||||
|
||||
public BigDecimal getInterestRate() {
|
||||
return interestRate;
|
||||
}
|
||||
|
||||
public BigDecimal getMinInterestRate() {
|
||||
return minInterestRate;
|
||||
}
|
||||
|
||||
public BigDecimal getMaxInterestRate() {
|
||||
return maxInterestRate;
|
||||
}
|
||||
|
||||
public BigDecimal getSavingsDepositAmount() {
|
||||
return savingsDepositAmount;
|
||||
}
|
||||
|
||||
public EnumOptionData getSavingProductType() {
|
||||
return savingProductType;
|
||||
}
|
||||
|
||||
public EnumOptionData getTenureType() {
|
||||
return tenureType;
|
||||
}
|
||||
|
||||
public Integer getTenure() {
|
||||
return tenure;
|
||||
}
|
||||
|
||||
public EnumOptionData getInterestType() {
|
||||
return interestType;
|
||||
}
|
||||
|
||||
public EnumOptionData getInterestCalculationMethod() {
|
||||
return interestCalculationMethod;
|
||||
}
|
||||
|
||||
public BigDecimal getMinimumBalanceForWithdrawal() {
|
||||
return minimumBalanceForWithdrawal;
|
||||
}
|
||||
|
||||
public boolean isPartialDepositAllowed() {
|
||||
return isPartialDepositAllowed;
|
||||
}
|
||||
|
||||
public boolean isLockinPeriodAllowed() {
|
||||
return isLockinPeriodAllowed;
|
||||
}
|
||||
|
||||
public Integer getLockinPeriod() {
|
||||
return lockinPeriod;
|
||||
}
|
||||
|
||||
public EnumOptionData getLockinPeriodType() {
|
||||
return lockinPeriodType;
|
||||
}
|
||||
|
||||
public DateTime getCreatedOn() {
|
||||
return createdOn;
|
||||
}
|
||||
|
||||
public DateTime getLastModifedOn() {
|
||||
return lastModifedOn;
|
||||
}
|
||||
|
||||
public void setCurrencyOptions(Collection<CurrencyData> currencyOptions) {
|
||||
this.currencyOptions = currencyOptions;
|
||||
}
|
||||
|
||||
public EnumOptionData getSavingFrequencyType() {
|
||||
return savingFrequencyType;
|
||||
}
|
||||
|
||||
public List<EnumOptionData> getSavingsProductTypeOptions() {
|
||||
return savingsProductTypeOptions;
|
||||
}
|
||||
|
||||
public List<EnumOptionData> getTenureTypeOptions() {
|
||||
return tenureTypeOptions;
|
||||
}
|
||||
|
||||
public List<EnumOptionData> getSavingFrequencyOptions() {
|
||||
return savingFrequencyOptions;
|
||||
}
|
||||
|
||||
public List<EnumOptionData> getSavingsInterestTypeOptions() {
|
||||
return savingsInterestTypeOptions;
|
||||
}
|
||||
|
||||
public List<EnumOptionData> getLockinPeriodTypeOptions() {
|
||||
return lockinPeriodTypeOptions;
|
||||
}
|
||||
|
||||
public List<EnumOptionData> getInterestCalculationOptions() {
|
||||
return interestCalculationOptions;
|
||||
}
|
||||
|
||||
public Integer getDepositEvery() {
|
||||
return this.depositEvery;
|
||||
}
|
||||
|
||||
}
|
||||
-37
@@ -1,37 +0,0 @@
|
||||
/**
|
||||
* 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.portfolio.savingsaccountproduct.data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class SavingProductLookup implements Serializable {
|
||||
|
||||
private final Long id;
|
||||
private final String name;
|
||||
|
||||
public SavingProductLookup() {
|
||||
this.id = null;
|
||||
this.name = null;
|
||||
}
|
||||
|
||||
public SavingProductLookup(final Long id, final String name) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public boolean hasId(final Long matchingId) {
|
||||
return this.id.equals(matchingId);
|
||||
}
|
||||
|
||||
}
|
||||
-59
@@ -1,59 +0,0 @@
|
||||
/**
|
||||
* 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.portfolio.savingsaccountproduct.domain;
|
||||
|
||||
public enum SavingFrequencyType {
|
||||
|
||||
INVALID(0, "savingFrequencyType.invalid"), //
|
||||
DAILY(1, "savingFrequencyType.daily"), //
|
||||
MONTHLY(2, "savingFrequencyType.monthly"), //
|
||||
QUATERLY(3, "savingFrequencyType.quaterly"), //
|
||||
HALFYEARLY(4, "savingFrequencyType.halfyearly"), //
|
||||
YEARLY(5, "savingFrequencyType.yearly");
|
||||
|
||||
private final Integer value;
|
||||
private final String code;
|
||||
|
||||
private SavingFrequencyType(final Integer value, final String code) {
|
||||
this.value = value;
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public Integer getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public static SavingFrequencyType fromInt(final Integer frequency) {
|
||||
|
||||
SavingFrequencyType savingFrequencyType = SavingFrequencyType.INVALID;
|
||||
switch (frequency) {
|
||||
case 1:
|
||||
savingFrequencyType = SavingFrequencyType.DAILY;
|
||||
break;
|
||||
case 2:
|
||||
savingFrequencyType = SavingFrequencyType.MONTHLY;
|
||||
break;
|
||||
case 3:
|
||||
savingFrequencyType = SavingFrequencyType.QUATERLY;
|
||||
break;
|
||||
case 4:
|
||||
savingFrequencyType = SavingFrequencyType.HALFYEARLY;
|
||||
break;
|
||||
case 5:
|
||||
savingFrequencyType = SavingFrequencyType.YEARLY;
|
||||
break;
|
||||
default:
|
||||
savingFrequencyType = SavingFrequencyType.INVALID;
|
||||
break;
|
||||
}
|
||||
return savingFrequencyType;
|
||||
}
|
||||
|
||||
}
|
||||
-58
@@ -1,58 +0,0 @@
|
||||
/**
|
||||
* 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.portfolio.savingsaccountproduct.domain;
|
||||
|
||||
public enum SavingInterestCalculationMethod {
|
||||
|
||||
INVALID(0, "savinginterest.calculation.method.invalid"), //
|
||||
AVERAGEBAL(1, "savinginterest.calculation.method.averagebal"), //
|
||||
MINBAL(2, "savinginterest.calculation.method.minbal"), //
|
||||
MONTHLYCOLLECTION(3, "savinginterest.calculation.method.monthlycllection");
|
||||
|
||||
private final Integer value;
|
||||
private final String code;
|
||||
|
||||
private SavingInterestCalculationMethod(final Integer value, final String code) {
|
||||
this.value = value;
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public Integer getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public static SavingInterestCalculationMethod fromInt(final Integer frequency) {
|
||||
|
||||
SavingInterestCalculationMethod savingInterestCalculationMethod = SavingInterestCalculationMethod.INVALID;
|
||||
switch (frequency) {
|
||||
case 1:
|
||||
savingInterestCalculationMethod = SavingInterestCalculationMethod.AVERAGEBAL;
|
||||
break;
|
||||
case 2:
|
||||
savingInterestCalculationMethod = SavingInterestCalculationMethod.MINBAL;
|
||||
break;
|
||||
case 3:
|
||||
savingInterestCalculationMethod = SavingInterestCalculationMethod.MONTHLYCOLLECTION;
|
||||
break;
|
||||
default:
|
||||
savingInterestCalculationMethod = SavingInterestCalculationMethod.INVALID;
|
||||
break;
|
||||
}
|
||||
return savingInterestCalculationMethod;
|
||||
}
|
||||
|
||||
public boolean isAverageBalance() {
|
||||
return this.value.equals(SavingInterestCalculationMethod.AVERAGEBAL.value);
|
||||
}
|
||||
|
||||
public boolean isMonthlyCollection() {
|
||||
return this.value.equals(SavingInterestCalculationMethod.MONTHLYCOLLECTION.value);
|
||||
}
|
||||
}
|
||||
-142
@@ -1,142 +0,0 @@
|
||||
/**
|
||||
* 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.portfolio.savingsaccountproduct.domain;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Embedded;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
import org.mifosplatform.infrastructure.core.domain.AbstractAuditableCustom;
|
||||
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
|
||||
import org.mifosplatform.portfolio.loanproduct.domain.PeriodFrequencyType;
|
||||
import org.mifosplatform.portfolio.savingsdepositproduct.domain.TenureTypeEnum;
|
||||
import org.mifosplatform.useradministration.domain.AppUser;
|
||||
|
||||
@Entity
|
||||
@Table(name = "m_product_savings")
|
||||
public class SavingProduct extends AbstractAuditableCustom<AppUser, Long> {
|
||||
|
||||
@Column(name = "name", nullable = false)
|
||||
private String name;
|
||||
|
||||
@Column(name = "description")
|
||||
private String description;
|
||||
|
||||
@Column(name = "is_deleted", nullable = false)
|
||||
private boolean deleted = false;
|
||||
|
||||
@Embedded
|
||||
private final SavingProductRelatedDetail savingProductRelatedDetail;
|
||||
|
||||
protected SavingProduct() {
|
||||
this.name = null;
|
||||
this.description = null;
|
||||
this.savingProductRelatedDetail = null;
|
||||
}
|
||||
|
||||
public SavingProduct(final String name, final String description, final MonetaryCurrency currency, final BigDecimal interestRate,
|
||||
final BigDecimal minInterestRate, final BigDecimal maxInterestRate, final BigDecimal savingsDepositAmount,
|
||||
final Integer depositEvery, final SavingProductType savingProductType, final TenureTypeEnum tenureType, final Integer tenure,
|
||||
final SavingFrequencyType savingFrequencyType, final SavingsInterestType savingsInterestType,
|
||||
final SavingInterestCalculationMethod savingInterestCalculationMethod, final BigDecimal minimumBalanceForWithdrawal,
|
||||
final boolean isPartialDepositAllowed, final boolean isLockinPeriodAllowed, final Integer lockinPeriod,
|
||||
final PeriodFrequencyType lockinPeriodType) {
|
||||
|
||||
this.name = name.trim();
|
||||
if (StringUtils.isNotBlank(description)) {
|
||||
this.description = description.trim();
|
||||
} else {
|
||||
this.description = null;
|
||||
}
|
||||
this.savingProductRelatedDetail = new SavingProductRelatedDetail(currency, interestRate, minInterestRate, maxInterestRate,
|
||||
savingsDepositAmount, depositEvery, savingProductType, tenureType, tenure, savingFrequencyType, savingsInterestType,
|
||||
savingInterestCalculationMethod, minimumBalanceForWithdrawal, isPartialDepositAllowed, isLockinPeriodAllowed, lockinPeriod,
|
||||
lockinPeriodType);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return this.description;
|
||||
}
|
||||
|
||||
public MonetaryCurrency getCurrency() {
|
||||
return this.savingProductRelatedDetail.getCurrency();
|
||||
}
|
||||
|
||||
public BigDecimal getInterestRate() {
|
||||
return this.savingProductRelatedDetail.getInterestRate();
|
||||
}
|
||||
|
||||
public BigDecimal getMinimumBalance() {
|
||||
return this.savingProductRelatedDetail.getMinimumBalance();
|
||||
}
|
||||
|
||||
public boolean isDeleted() {
|
||||
return deleted;
|
||||
}
|
||||
|
||||
public void delete() {
|
||||
this.deleted = true;
|
||||
}
|
||||
|
||||
public SavingProductRelatedDetail getSavingProductRelatedDetail() {
|
||||
return savingProductRelatedDetail;
|
||||
}
|
||||
|
||||
public Map<String, Object> update(final JsonCommand command) {
|
||||
|
||||
final Map<String, Object> actualChanges = new LinkedHashMap<String, Object>(20);
|
||||
|
||||
final String nameParamName = "name";
|
||||
if (command.isChangeInStringParameterNamed(nameParamName, this.name)) {
|
||||
final String newValue = command.stringValueOfParameterNamed(nameParamName);
|
||||
actualChanges.put(nameParamName, newValue);
|
||||
this.name = newValue;
|
||||
}
|
||||
|
||||
final String descriptionParamName = "description";
|
||||
if (command.isChangeInStringParameterNamed(descriptionParamName, this.description)) {
|
||||
final String newValue = command.stringValueOfParameterNamed(descriptionParamName);
|
||||
actualChanges.put(descriptionParamName, newValue);
|
||||
this.description = newValue;
|
||||
}
|
||||
|
||||
return this.savingProductRelatedDetail.update(command, actualChanges);
|
||||
}
|
||||
|
||||
public static SavingProduct assembleFromJson(final JsonCommand command, final MonetaryCurrency currency,
|
||||
final SavingProductType savingProductType, final TenureTypeEnum tenureType, final SavingFrequencyType savingFrequencyType,
|
||||
final SavingsInterestType interestType, final SavingInterestCalculationMethod savingInterestCalculationMethod,
|
||||
final PeriodFrequencyType lockinPeriodType) {
|
||||
|
||||
final String name = command.stringValueOfParameterNamed("name");
|
||||
final String description = command.stringValueOfParameterNamed("description");
|
||||
final BigDecimal interestRate = command.bigDecimalValueOfParameterNamed("interestRate");
|
||||
final BigDecimal minInterestRate = command.bigDecimalValueOfParameterNamed("minInterestRate");
|
||||
final BigDecimal maxInterestRate = command.bigDecimalValueOfParameterNamed("maxInterestRate");
|
||||
final BigDecimal savingsDepositAmount = command.bigDecimalValueOfParameterNamed("savingsDepositAmount");
|
||||
final Integer tenure = command.integerValueOfParameterNamed("tenure");
|
||||
final BigDecimal minimumBalanceForWithdrawal = command.bigDecimalValueOfParameterNamed("minimumBalanceForWithdrawal");
|
||||
final boolean isPartialDepositAllowed = command.booleanPrimitiveValueOfParameterNamed("isPartialDepositAllowed");
|
||||
final boolean isLockinPeriodAllowed = command.booleanPrimitiveValueOfParameterNamed("isLockinPeriodAllowed");
|
||||
final Integer lockinPeriod = command.integerValueOfParameterNamed("lockinPeriod");
|
||||
final Integer depositEvery = command.integerValueOfParameterNamed("depositEvery");
|
||||
|
||||
return new SavingProduct(name, description, currency, interestRate, minInterestRate, maxInterestRate, savingsDepositAmount,
|
||||
depositEvery, savingProductType, tenureType, tenure, savingFrequencyType, interestType, savingInterestCalculationMethod,
|
||||
minimumBalanceForWithdrawal, isPartialDepositAllowed, isLockinPeriodAllowed, lockinPeriod, lockinPeriodType);
|
||||
}
|
||||
}
|
||||
-310
@@ -1,310 +0,0 @@
|
||||
/**
|
||||
* 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.portfolio.savingsaccountproduct.domain;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Embeddable;
|
||||
import javax.persistence.Embedded;
|
||||
|
||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
|
||||
import org.mifosplatform.portfolio.loanproduct.domain.PeriodFrequencyType;
|
||||
import org.mifosplatform.portfolio.savingsdepositproduct.domain.TenureTypeEnum;
|
||||
|
||||
@Embeddable
|
||||
public class SavingProductRelatedDetail {
|
||||
|
||||
@Embedded
|
||||
private MonetaryCurrency currency;
|
||||
|
||||
@Column(name = "interest_rate", scale = 6, precision = 19, nullable = false)
|
||||
private BigDecimal interestRate;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Column(name = "min_interest_rate", scale = 6, precision = 19, nullable = false)
|
||||
private BigDecimal minInterestRate;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Column(name = "max_interest_rate", scale = 6, precision = 19, nullable = false)
|
||||
private BigDecimal maxInterestRate;
|
||||
|
||||
@Column(name = "savings_deposit_amount", scale = 6, precision = 19, nullable = false)
|
||||
private BigDecimal savingsDepositAmount;
|
||||
|
||||
@Column(name = "deposit_every")
|
||||
private Integer depositEvery;
|
||||
|
||||
@Column(name = "savings_product_type", nullable = false)
|
||||
private Integer savingProductType;
|
||||
|
||||
@Column(name = "tenure_type", nullable = false)
|
||||
private Integer tenureType;
|
||||
|
||||
@Column(name = "tenure", nullable = false)
|
||||
private Integer tenure;
|
||||
|
||||
@Column(name = "frequency", nullable = false)
|
||||
private Integer frequency;
|
||||
|
||||
@Column(name = "interest_type", nullable = false)
|
||||
private Integer interestType;
|
||||
|
||||
@Column(name = "interest_calculation_method")
|
||||
private Integer interestCalculationMethod;
|
||||
|
||||
@Column(name = "min_bal_for_withdrawal", scale = 6, precision = 19, nullable = false)
|
||||
private BigDecimal minimumBalanceForWithdrawal;
|
||||
|
||||
@Column(name = "is_partial_deposit_allowed", nullable = false)
|
||||
private boolean isPartialDepositAllowed;
|
||||
|
||||
@Column(name = "is_lock_in_period_allowed", nullable = false)
|
||||
private boolean isLockinPeriodAllowed;
|
||||
|
||||
@Column(name = "lock_in_period", nullable = false)
|
||||
private Integer lockinPeriod;
|
||||
|
||||
@Column(name = "lock_in_period_type", nullable = false)
|
||||
private Integer lockinPeriodType;
|
||||
|
||||
public SavingProductRelatedDetail() {
|
||||
this.interestRate = null;
|
||||
this.savingsDepositAmount = null;
|
||||
}
|
||||
|
||||
public SavingProductRelatedDetail(final MonetaryCurrency currency, final BigDecimal interestRate, final BigDecimal minInterestRate,
|
||||
final BigDecimal maxInterestRate, final BigDecimal savingsDepositAmount, final Integer depositEvery,
|
||||
final SavingProductType savingProductType, final TenureTypeEnum tenureType, final Integer tenure,
|
||||
final SavingFrequencyType frequency, final SavingsInterestType interestType,
|
||||
final SavingInterestCalculationMethod interestCalculationMethod, final BigDecimal minimumBalanceForWithdrawal,
|
||||
final boolean isPartialDepositAllowed, final boolean isLockinPeriodAllowed, final Integer lockinPeriod,
|
||||
final PeriodFrequencyType lockinPeriodType) {
|
||||
this.currency = currency;
|
||||
this.interestRate = interestRate;
|
||||
this.minInterestRate = minInterestRate;
|
||||
this.maxInterestRate = maxInterestRate;
|
||||
this.savingsDepositAmount = savingsDepositAmount;
|
||||
this.depositEvery = depositEvery;
|
||||
this.savingProductType = savingProductType.getValue();
|
||||
this.tenureType = tenureType.getValue();
|
||||
this.tenure = tenure;
|
||||
this.frequency = frequency.getValue();
|
||||
this.interestType = interestType.getValue();
|
||||
this.interestCalculationMethod = interestCalculationMethod.getValue();
|
||||
this.minimumBalanceForWithdrawal = minimumBalanceForWithdrawal;
|
||||
this.isPartialDepositAllowed = isPartialDepositAllowed;
|
||||
this.isLockinPeriodAllowed = isLockinPeriodAllowed;
|
||||
this.lockinPeriod = lockinPeriod;
|
||||
this.lockinPeriodType = lockinPeriodType.getValue();
|
||||
}
|
||||
|
||||
public MonetaryCurrency getCurrency() {
|
||||
return this.currency.copy();
|
||||
}
|
||||
|
||||
public BigDecimal getInterestRate() {
|
||||
return BigDecimal.valueOf(Double.valueOf(this.interestRate.stripTrailingZeros().toString()));
|
||||
}
|
||||
|
||||
public BigDecimal getMinimumBalance() {
|
||||
return BigDecimal.valueOf(Double.valueOf(this.savingsDepositAmount.stripTrailingZeros().toString()));
|
||||
}
|
||||
|
||||
public Map<String, Object> update(final JsonCommand command, final Map<String, Object> actualChanges) {
|
||||
|
||||
final String localeAsInput = command.locale();
|
||||
|
||||
Integer digitsAfterDecimal = this.currency.getDigitsAfterDecimal();
|
||||
final String digitsAfterDecimalParamName = "digitsAfterDecimal";
|
||||
if (command.isChangeInIntegerParameterNamed(digitsAfterDecimalParamName, digitsAfterDecimal)) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(digitsAfterDecimalParamName);
|
||||
actualChanges.put(digitsAfterDecimalParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
digitsAfterDecimal = newValue;
|
||||
this.currency = new MonetaryCurrency(this.currency.getCode(), digitsAfterDecimal);
|
||||
}
|
||||
|
||||
String currencyCode = this.currency.getCode();
|
||||
final String currencyCodeParamName = "currencyCode";
|
||||
if (command.isChangeInStringParameterNamed(currencyCodeParamName, currencyCode)) {
|
||||
final String newValue = command.stringValueOfParameterNamed(currencyCodeParamName);
|
||||
actualChanges.put(currencyCodeParamName, newValue);
|
||||
currencyCode = newValue;
|
||||
this.currency = new MonetaryCurrency(currencyCode, this.currency.getDigitsAfterDecimal());
|
||||
}
|
||||
|
||||
final String interestRateParamName = "interestRate";
|
||||
if (command.isChangeInBigDecimalParameterNamed(interestRateParamName, this.interestRate)) {
|
||||
final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(interestRateParamName);
|
||||
actualChanges.put(interestRateParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
this.interestRate = newValue;
|
||||
}
|
||||
|
||||
final String savingsDepositAmountParamName = "savingsDepositAmount";
|
||||
if (command.isChangeInBigDecimalParameterNamed(savingsDepositAmountParamName, this.savingsDepositAmount)) {
|
||||
final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(savingsDepositAmountParamName);
|
||||
actualChanges.put(savingsDepositAmountParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
this.savingsDepositAmount = newValue;
|
||||
}
|
||||
|
||||
final String depositEveryParamName = "depositEvery";
|
||||
if (command.isChangeInIntegerParameterNamed(depositEveryParamName, this.depositEvery)) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(depositEveryParamName);
|
||||
actualChanges.put(depositEveryParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
this.depositEvery = newValue;
|
||||
}
|
||||
|
||||
final String savingProductTypeParamName = "savingProductType";
|
||||
if (command.isChangeInIntegerParameterNamed(savingProductTypeParamName, this.savingProductType)) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(savingProductTypeParamName);
|
||||
actualChanges.put(savingProductTypeParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
this.savingProductType = SavingProductType.fromInt(newValue).getValue();
|
||||
}
|
||||
|
||||
final String tenureTypeParamName = "tenureType";
|
||||
if (command.isChangeInIntegerParameterNamed(tenureTypeParamName, this.tenureType)) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(tenureTypeParamName);
|
||||
actualChanges.put(tenureTypeParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
this.tenureType = TenureTypeEnum.fromInt(newValue).getValue();
|
||||
}
|
||||
|
||||
final String tenureParamName = "tenure";
|
||||
if (command.isChangeInIntegerParameterNamed(tenureParamName, this.tenure)) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(tenureParamName);
|
||||
actualChanges.put(tenureParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
this.tenure = newValue;
|
||||
}
|
||||
|
||||
final String frequencyParamName = "frequency";
|
||||
if (command.isChangeInIntegerParameterNamed(frequencyParamName, this.frequency)) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(frequencyParamName);
|
||||
actualChanges.put(frequencyParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
this.frequency = SavingFrequencyType.fromInt(newValue).getValue();
|
||||
}
|
||||
|
||||
final String interestTypeParamName = "interestType";
|
||||
if (command.isChangeInIntegerParameterNamed(interestTypeParamName, this.interestType)) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(interestTypeParamName);
|
||||
actualChanges.put(interestTypeParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
this.interestType = SavingsInterestType.fromInt(newValue).getValue();
|
||||
}
|
||||
|
||||
final String interestCalculationMethodParamName = "interestCalculationMethod";
|
||||
if (command.isChangeInIntegerParameterNamed(interestCalculationMethodParamName, this.interestCalculationMethod)) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(interestCalculationMethodParamName);
|
||||
actualChanges.put(interestCalculationMethodParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
this.interestCalculationMethod = SavingInterestCalculationMethod.fromInt(newValue).getValue();
|
||||
}
|
||||
|
||||
final String minimumBalanceForWithdrawalParamName = "minimumBalanceForWithdrawal";
|
||||
if (command.isChangeInBigDecimalParameterNamed(minimumBalanceForWithdrawalParamName, this.minimumBalanceForWithdrawal)) {
|
||||
final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(minimumBalanceForWithdrawalParamName);
|
||||
actualChanges.put(minimumBalanceForWithdrawalParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
this.minimumBalanceForWithdrawal = newValue;
|
||||
}
|
||||
|
||||
final String isPartialDepositAllowedParamName = "isPartialDepositAllowed";
|
||||
if (command.isChangeInBooleanParameterNamed(isPartialDepositAllowedParamName, this.isPartialDepositAllowed)) {
|
||||
final Boolean newValue = command.booleanObjectValueOfParameterNamed(isPartialDepositAllowedParamName);
|
||||
actualChanges.put(isPartialDepositAllowedParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
this.isPartialDepositAllowed = newValue;
|
||||
}
|
||||
|
||||
final String isLockinPeriodAllowedParamName = "isLockinPeriodAllowed";
|
||||
if (command.isChangeInBooleanParameterNamed(isLockinPeriodAllowedParamName, this.isLockinPeriodAllowed)) {
|
||||
final Boolean newValue = command.booleanObjectValueOfParameterNamed(isLockinPeriodAllowedParamName);
|
||||
actualChanges.put(isLockinPeriodAllowedParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
this.isLockinPeriodAllowed = newValue;
|
||||
}
|
||||
|
||||
final String lockinPeriodParamName = "lockinPeriod";
|
||||
if (command.isChangeInIntegerParameterNamed(lockinPeriodParamName, this.lockinPeriod)) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(lockinPeriodParamName);
|
||||
actualChanges.put(lockinPeriodParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
this.lockinPeriod = newValue;
|
||||
}
|
||||
|
||||
final String lockinPeriodTypeParamName = "lockinPeriodType";
|
||||
if (command.isChangeInIntegerParameterNamed(lockinPeriodTypeParamName, this.lockinPeriodType)) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(lockinPeriodTypeParamName);
|
||||
actualChanges.put(lockinPeriodTypeParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
this.lockinPeriodType = PeriodFrequencyType.fromInt(newValue).getValue();
|
||||
}
|
||||
|
||||
return actualChanges;
|
||||
|
||||
}
|
||||
|
||||
public BigDecimal getSavingsDepositAmount() {
|
||||
return savingsDepositAmount;
|
||||
}
|
||||
|
||||
public Integer getDepositEvery() {
|
||||
return this.depositEvery;
|
||||
}
|
||||
|
||||
public Integer getSavingProductType() {
|
||||
return savingProductType;
|
||||
}
|
||||
|
||||
public Integer getTenureType() {
|
||||
return tenureType;
|
||||
}
|
||||
|
||||
public Integer getTenure() {
|
||||
return tenure;
|
||||
}
|
||||
|
||||
public Integer getFrequency() {
|
||||
return frequency;
|
||||
}
|
||||
|
||||
public Integer getInterestType() {
|
||||
return interestType;
|
||||
}
|
||||
|
||||
public Integer getInterestCalculationMethod() {
|
||||
return interestCalculationMethod;
|
||||
}
|
||||
|
||||
public BigDecimal getMinimumBalanceForWithdrawal() {
|
||||
return minimumBalanceForWithdrawal;
|
||||
}
|
||||
|
||||
public boolean isPartialDepositAllowed() {
|
||||
return isPartialDepositAllowed;
|
||||
}
|
||||
|
||||
public boolean isLockinPeriodAllowed() {
|
||||
return isLockinPeriodAllowed;
|
||||
}
|
||||
|
||||
public Integer getLockinPeriod() {
|
||||
return lockinPeriod;
|
||||
}
|
||||
|
||||
public Integer getLockinPeriodType() {
|
||||
return lockinPeriodType;
|
||||
}
|
||||
|
||||
}
|
||||
-13
@@ -1,13 +0,0 @@
|
||||
/**
|
||||
* 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.portfolio.savingsaccountproduct.domain;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||
|
||||
public interface SavingProductRepository extends JpaRepository<SavingProduct, Long>, JpaSpecificationExecutor<SavingProduct> {
|
||||
//
|
||||
}
|
||||
-55
@@ -1,55 +0,0 @@
|
||||
/**
|
||||
* 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.portfolio.savingsaccountproduct.domain;
|
||||
|
||||
public enum SavingProductType {
|
||||
|
||||
INVALID(0, "savingProductType.invalid"), //
|
||||
RECURRING(1, "savingProductType.reccuring"), //
|
||||
REGULAR(2, "savingProductType.regular");
|
||||
|
||||
private final Integer value;
|
||||
private final String code;
|
||||
|
||||
private SavingProductType(final Integer value, final String code) {
|
||||
this.value = value;
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public Integer getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public static SavingProductType fromInt(final Integer frequency) {
|
||||
|
||||
SavingProductType savingProductType = SavingProductType.INVALID;
|
||||
switch (frequency) {
|
||||
case 1:
|
||||
savingProductType = SavingProductType.RECURRING;
|
||||
break;
|
||||
case 2:
|
||||
savingProductType = SavingProductType.REGULAR;
|
||||
break;
|
||||
default:
|
||||
savingProductType = SavingProductType.INVALID;
|
||||
break;
|
||||
}
|
||||
return savingProductType;
|
||||
}
|
||||
|
||||
public boolean isReccuring() {
|
||||
return this.value.equals(SavingProductType.RECURRING.getValue());
|
||||
}
|
||||
|
||||
public boolean isRegular() {
|
||||
return this.value.equals(SavingProductType.REGULAR.getValue());
|
||||
}
|
||||
|
||||
}
|
||||
-46
@@ -1,46 +0,0 @@
|
||||
/**
|
||||
* 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.portfolio.savingsaccountproduct.domain;
|
||||
|
||||
public enum SavingsInterestType {
|
||||
|
||||
INVALID(0, "savingsInterestType.invalid"), //
|
||||
SIMPLE(1, "savingsInterestType.simple"), //
|
||||
COMPOUNDING(2, "savingsInterestType.compounding");
|
||||
|
||||
private final Integer value;
|
||||
private final String code;
|
||||
|
||||
private SavingsInterestType(final Integer value, final String code) {
|
||||
this.value = value;
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public Integer getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public static SavingsInterestType fromInt(final Integer frequency) {
|
||||
|
||||
SavingsInterestType savingsInterestType = SavingsInterestType.INVALID;
|
||||
switch (frequency) {
|
||||
case 1:
|
||||
savingsInterestType = SavingsInterestType.SIMPLE;
|
||||
break;
|
||||
case 2:
|
||||
savingsInterestType = SavingsInterestType.COMPOUNDING;
|
||||
break;
|
||||
default:
|
||||
savingsInterestType = SavingsInterestType.INVALID;
|
||||
break;
|
||||
}
|
||||
return savingsInterestType;
|
||||
}
|
||||
}
|
||||
-55
@@ -1,55 +0,0 @@
|
||||
/**
|
||||
* 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.portfolio.savingsaccountproduct.domain;
|
||||
|
||||
public enum SavingsLockinPeriodEnum {
|
||||
|
||||
DAYS(0, "lockin.period.type.days"), //
|
||||
WEEKS(1, "lockin.period.type.weeks"), //
|
||||
MONTHS(2, "lockin.period.type.months"), //
|
||||
YEARS(3, "lockin.period.type.years"), //
|
||||
INVALID(4, "lockin.period.type.invalid");
|
||||
|
||||
private final Integer value;
|
||||
private final String code;
|
||||
|
||||
private SavingsLockinPeriodEnum(final Integer value, final String code) {
|
||||
this.value = value;
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public Integer getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public static SavingsLockinPeriodEnum fromInt(final Integer frequency) {
|
||||
|
||||
SavingsLockinPeriodEnum lockinPeriodType = SavingsLockinPeriodEnum.INVALID;
|
||||
switch (frequency) {
|
||||
case 0:
|
||||
lockinPeriodType = SavingsLockinPeriodEnum.DAYS;
|
||||
break;
|
||||
case 1:
|
||||
lockinPeriodType = SavingsLockinPeriodEnum.WEEKS;
|
||||
break;
|
||||
case 2:
|
||||
lockinPeriodType = SavingsLockinPeriodEnum.MONTHS;
|
||||
break;
|
||||
case 3:
|
||||
lockinPeriodType = SavingsLockinPeriodEnum.YEARS;
|
||||
break;
|
||||
default:
|
||||
lockinPeriodType = SavingsLockinPeriodEnum.INVALID;
|
||||
break;
|
||||
}
|
||||
return lockinPeriodType;
|
||||
}
|
||||
|
||||
}
|
||||
-24
@@ -1,24 +0,0 @@
|
||||
package org.mifosplatform.portfolio.savingsaccountproduct.handler;
|
||||
|
||||
import org.mifosplatform.commands.handler.NewCommandSourceHandler;
|
||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.mifosplatform.portfolio.savingsaccountproduct.service.SavingProductWritePlatformService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class UpdateSavingProductCommandHandler implements NewCommandSourceHandler {
|
||||
|
||||
private final SavingProductWritePlatformService savingProductWritePlatformService;
|
||||
|
||||
@Autowired
|
||||
public UpdateSavingProductCommandHandler(final SavingProductWritePlatformService savingProductWritePlatformService) {
|
||||
this.savingProductWritePlatformService = savingProductWritePlatformService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandProcessingResult processCommand(final JsonCommand command) {
|
||||
return this.savingProductWritePlatformService.updateSavingProduct(command.entityId(), command);
|
||||
}
|
||||
}
|
||||
-214
@@ -1,214 +0,0 @@
|
||||
package org.mifosplatform.portfolio.savingsaccountproduct.serialization;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.mifosplatform.infrastructure.core.data.ApiParameterError;
|
||||
import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder;
|
||||
import org.mifosplatform.infrastructure.core.exception.InvalidJsonException;
|
||||
import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException;
|
||||
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
@Component
|
||||
public class SavingProductCommandFromApiJsonDeserializer {
|
||||
|
||||
private final Set<String> supportedParams = new HashSet<String>(Arrays.asList("locale", "name", "description", "currencyCode",
|
||||
"digitsAfterDecimal", "interestRate", "minInterestRate", "maxInterestRate", "savingsDepositAmount", "savingProductType",
|
||||
"tenureType", "tenure", "frequency", "interestType", "interestCalculationMethod", "minimumBalanceForWithdrawal",
|
||||
"isPartialDepositAllowed", "isLockinPeriodAllowed", "lockinPeriod", "lockinPeriodType", "depositEvery"));
|
||||
|
||||
private final FromJsonHelper fromApiJsonHelper;
|
||||
|
||||
@Autowired
|
||||
public SavingProductCommandFromApiJsonDeserializer(final FromJsonHelper fromApiJsonHelper) {
|
||||
this.fromApiJsonHelper = fromApiJsonHelper;
|
||||
}
|
||||
|
||||
public void validateForCreate(final String json) {
|
||||
|
||||
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
|
||||
|
||||
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
|
||||
fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParams);
|
||||
|
||||
List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
|
||||
DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("product");
|
||||
final JsonElement element = fromApiJsonHelper.parse(json);
|
||||
|
||||
final String name = fromApiJsonHelper.extractStringNamed("name", element);
|
||||
baseDataValidator.reset().parameter("name").value(name).notBlank().notExceedingLengthOf(100);
|
||||
|
||||
final String description = fromApiJsonHelper.extractStringNamed("description", element);
|
||||
baseDataValidator.reset().parameter("description").value(description).notExceedingLengthOf(500);
|
||||
|
||||
final String currencyCode = fromApiJsonHelper.extractStringNamed("currencyCode", element);
|
||||
baseDataValidator.reset().parameter("currencyCode").value(currencyCode).notBlank();
|
||||
|
||||
final Integer digitsAfterDecimal = fromApiJsonHelper.extractIntegerNamed("digitsAfterDecimal", element, Locale.getDefault());
|
||||
baseDataValidator.reset().parameter("digitsAfterDecimal").value(digitsAfterDecimal).notNull().inMinMaxRange(0, 6);
|
||||
|
||||
final BigDecimal interestRate = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("interestRate", element);
|
||||
baseDataValidator.reset().parameter("interestRate").value(interestRate).notNull().zeroOrPositiveAmount();
|
||||
|
||||
final BigDecimal minInterestRate = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("minInterestRate", element);
|
||||
baseDataValidator.reset().parameter("minInterestRate").value(minInterestRate).notNull().zeroOrPositiveAmount();
|
||||
|
||||
final BigDecimal maxInterestRate = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("maxInterestRate", element);
|
||||
baseDataValidator.reset().parameter("maxInterestRate").value(maxInterestRate).notNull().zeroOrPositiveAmount();
|
||||
|
||||
baseDataValidator.reset().parameter("minInterestRate").comapareMinAndMaxOfTwoBigDecmimalNos(minInterestRate, maxInterestRate);
|
||||
baseDataValidator.reset().parameter("interestRate").comapareMinAndMaxOfTwoBigDecmimalNos(interestRate, maxInterestRate);
|
||||
baseDataValidator.reset().parameter("minInterestRate").comapareMinAndMaxOfTwoBigDecmimalNos(minInterestRate, interestRate);
|
||||
|
||||
final BigDecimal savingsDepositAmount = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("savingsDepositAmount", element);
|
||||
baseDataValidator.reset().parameter("savingsDepositAmount").value(savingsDepositAmount).notNull().zeroOrPositiveAmount();
|
||||
|
||||
final Integer savingProductType = fromApiJsonHelper.extractIntegerNamed("savingProductType", element, Locale.getDefault());
|
||||
baseDataValidator.reset().parameter("savingProductType").value(savingProductType).notNull();
|
||||
|
||||
final Integer tenureType = fromApiJsonHelper.extractIntegerNamed("tenureType", element, Locale.getDefault());
|
||||
baseDataValidator.reset().parameter("tenureType").value(tenureType).notNull();
|
||||
|
||||
final Integer tenure = fromApiJsonHelper.extractIntegerNamed("tenure", element, Locale.getDefault());
|
||||
baseDataValidator.reset().parameter("tenure").value(tenure).notNull();
|
||||
|
||||
final Integer frequency = fromApiJsonHelper.extractIntegerNamed("frequency", element, Locale.getDefault());
|
||||
baseDataValidator.reset().parameter("frequency").value(frequency).notNull();
|
||||
|
||||
final Integer interestType = fromApiJsonHelper.extractIntegerNamed("interestType", element, Locale.getDefault());
|
||||
baseDataValidator.reset().parameter("interestType").value(interestType).notNull();
|
||||
|
||||
final Integer interestCalculationMethod = fromApiJsonHelper.extractIntegerNamed("interestCalculationMethod", element,
|
||||
Locale.getDefault());
|
||||
baseDataValidator.reset().parameter("interestCalculationMethod").value(interestCalculationMethod).notNull();
|
||||
|
||||
final BigDecimal minimumBalanceForWithdrawal = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("minimumBalanceForWithdrawal",
|
||||
element);
|
||||
baseDataValidator.reset().parameter("minimumBalanceForWithdrawal").value(minimumBalanceForWithdrawal).notNull()
|
||||
.zeroOrPositiveAmount();
|
||||
|
||||
final Boolean isPartialDepositAllowedCommandValue = fromApiJsonHelper.extractBooleanNamed("isPartialDepositAllowed", element);
|
||||
baseDataValidator.reset().parameter("isPartialDepositAllowed").value(isPartialDepositAllowedCommandValue)
|
||||
.trueOrFalseRequired(isBooleanValueUpdated(isPartialDepositAllowedCommandValue)).notNull();
|
||||
|
||||
final Boolean isLockinPeriodAllowedCommandValue = fromApiJsonHelper.extractBooleanNamed("isLockinPeriodAllowed", element);
|
||||
baseDataValidator.reset().parameter("isLockinPeriodAllowed").value(isLockinPeriodAllowedCommandValue)
|
||||
.trueOrFalseRequired(isBooleanValueUpdated(isLockinPeriodAllowedCommandValue));
|
||||
|
||||
final Integer lockinPeriod = fromApiJsonHelper.extractIntegerNamed("lockinPeriod", element, Locale.getDefault());
|
||||
baseDataValidator.reset().parameter("lockinPeriod").value(lockinPeriod).notNull().zeroOrPositiveAmount();
|
||||
|
||||
final Integer lockinPeriodType = fromApiJsonHelper.extractIntegerNamed("lockinPeriodType", element, Locale.getDefault());
|
||||
baseDataValidator.reset().parameter("lockinPeriodType").value(lockinPeriodType).notNull().inMinMaxRange(1, 3);
|
||||
|
||||
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
||||
|
||||
}
|
||||
|
||||
public void validateForUpdate(final String json) {
|
||||
|
||||
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
|
||||
|
||||
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
|
||||
fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParams);
|
||||
|
||||
List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
|
||||
DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("product");
|
||||
final JsonElement element = fromApiJsonHelper.parse(json);
|
||||
|
||||
final String name = fromApiJsonHelper.extractStringNamed("name", element);
|
||||
baseDataValidator.reset().parameter("name").value(name).ignoreIfNull().notBlank().notExceedingLengthOf(100);
|
||||
|
||||
final String description = fromApiJsonHelper.extractStringNamed("description", element);
|
||||
baseDataValidator.reset().parameter("description").value(description).notExceedingLengthOf(500);
|
||||
|
||||
final String currencyCode = fromApiJsonHelper.extractStringNamed("currencyCode", element);
|
||||
baseDataValidator.reset().parameter("currencyCode").value(currencyCode).ignoreIfNull().notBlank();
|
||||
|
||||
final Integer digitsAfterDecimal = fromApiJsonHelper.extractIntegerNamed("digitsAfterDecimal", element, Locale.getDefault());
|
||||
baseDataValidator.reset().parameter("digitsAfterDecimal").value(digitsAfterDecimal).ignoreIfNull().inMinMaxRange(0, 6);
|
||||
|
||||
final BigDecimal interestRate = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("interestRate", element);
|
||||
baseDataValidator.reset().parameter("interestRate").value(interestRate).ignoreIfNull().zeroOrPositiveAmount();
|
||||
|
||||
final BigDecimal minInterestRate = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("minInterestRate", element);
|
||||
baseDataValidator.reset().parameter("minInterestRate").value(minInterestRate).ignoreIfNull().zeroOrPositiveAmount();
|
||||
|
||||
final BigDecimal maxInterestRate = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("maxInterestRate", element);
|
||||
baseDataValidator.reset().parameter("maxInterestRate").value(maxInterestRate).ignoreIfNull().zeroOrPositiveAmount();
|
||||
|
||||
baseDataValidator.reset().parameter("minInterestRate").comapareMinAndMaxOfTwoBigDecmimalNos(minInterestRate, maxInterestRate);
|
||||
baseDataValidator.reset().parameter("interestRate").comapareMinAndMaxOfTwoBigDecmimalNos(interestRate, maxInterestRate);
|
||||
baseDataValidator.reset().parameter("minInterestRate").comapareMinAndMaxOfTwoBigDecmimalNos(minInterestRate, interestRate);
|
||||
|
||||
final BigDecimal savingsDepositAmount = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("savingsDepositAmount", element);
|
||||
baseDataValidator.reset().parameter("savingsDepositAmount").value(savingsDepositAmount).ignoreIfNull().zeroOrPositiveAmount();
|
||||
|
||||
final Integer savingProductType = fromApiJsonHelper.extractIntegerNamed("savingProductType", element, Locale.getDefault());
|
||||
baseDataValidator.reset().parameter("savingProductType").value(savingProductType).ignoreIfNull();
|
||||
|
||||
final Integer tenureType = fromApiJsonHelper.extractIntegerNamed("tenureType", element, Locale.getDefault());
|
||||
baseDataValidator.reset().parameter("tenureType").value(tenureType).ignoreIfNull();
|
||||
|
||||
final Integer tenure = fromApiJsonHelper.extractIntegerNamed("tenure", element, Locale.getDefault());
|
||||
baseDataValidator.reset().parameter("tenure").value(tenure).ignoreIfNull().integerGreaterThanZero();
|
||||
|
||||
final Integer frequency = fromApiJsonHelper.extractIntegerNamed("frequency", element, Locale.getDefault());
|
||||
baseDataValidator.reset().parameter("frequency").value(frequency).ignoreIfNull();
|
||||
|
||||
final Integer interestType = fromApiJsonHelper.extractIntegerNamed("interestType", element, Locale.getDefault());
|
||||
baseDataValidator.reset().parameter("interestType").value(interestType).ignoreIfNull();
|
||||
|
||||
final Integer interestCalculationMethod = fromApiJsonHelper.extractIntegerNamed("interestCalculationMethod", element,
|
||||
Locale.getDefault());
|
||||
baseDataValidator.reset().parameter("interestCalculationMethod").value(interestCalculationMethod).ignoreIfNull();
|
||||
|
||||
final BigDecimal minimumBalanceForWithdrawal = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("minimumBalanceForWithdrawal",
|
||||
element);
|
||||
baseDataValidator.reset().parameter("minimumBalanceForWithdrawal").value(minimumBalanceForWithdrawal).ignoreIfNull()
|
||||
.zeroOrPositiveAmount();
|
||||
|
||||
final Boolean isPartialDepositAllowedCommandValue = fromApiJsonHelper.extractBooleanNamed("isPartialDepositAllowed", element);
|
||||
baseDataValidator.reset().parameter("isPartialDepositAllowed").value(isPartialDepositAllowedCommandValue)
|
||||
.trueOrFalseRequired(isBooleanValueUpdated(isPartialDepositAllowedCommandValue)).ignoreIfNull();
|
||||
|
||||
final Boolean isLockinPeriodAllowedCommandValue = fromApiJsonHelper.extractBooleanNamed("isLockinPeriodAllowed", element);
|
||||
baseDataValidator.reset().parameter("isLockinPeriodAllowed").value(isLockinPeriodAllowedCommandValue)
|
||||
.trueOrFalseRequired(isBooleanValueUpdated(isLockinPeriodAllowedCommandValue)).ignoreIfNull();
|
||||
|
||||
final Integer lockinPeriod = fromApiJsonHelper.extractIntegerNamed("lockinPeriod", element, Locale.getDefault());
|
||||
baseDataValidator.reset().parameter("lockinPeriod").value(lockinPeriod).ignoreIfNull().zeroOrPositiveAmount();
|
||||
|
||||
final Integer lockinPeriodType = fromApiJsonHelper.extractIntegerNamed("lockinPeriodType", element, Locale.getDefault());
|
||||
baseDataValidator.reset().parameter("lockinPeriodType").value(lockinPeriodType).ignoreIfNull().inMinMaxRange(1, 3);
|
||||
|
||||
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
||||
|
||||
}
|
||||
|
||||
private void throwExceptionIfValidationWarningsExist(final List<ApiParameterError> dataValidationErrors) {
|
||||
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
|
||||
"Validation errors exist.", dataValidationErrors); }
|
||||
}
|
||||
|
||||
private Boolean isBooleanValueUpdated(final Boolean actualValue) {
|
||||
Boolean isUpdated = false;
|
||||
if (actualValue != null) {
|
||||
isUpdated = true;
|
||||
}
|
||||
return isUpdated;
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user