MIFOSX-247: basic savings functions for deposit and withdrawal.
This commit is contained in:
+71
-85
@@ -13,6 +13,7 @@ public class CommandWrapper {
|
||||
private final Long groupId;
|
||||
private final Long clientId;
|
||||
private final Long loanId;
|
||||
private final Long savingsId;
|
||||
private final String actionName;
|
||||
private final String entityName;
|
||||
private final String taskPermissionName;
|
||||
@@ -41,6 +42,7 @@ public class CommandWrapper {
|
||||
this.groupId = null;
|
||||
this.clientId = null;
|
||||
this.loanId = null;
|
||||
this.savingsId = null;
|
||||
this.actionName = actionName;
|
||||
this.entityName = entityName;
|
||||
this.taskPermissionName = actionName + "_" + entityName;
|
||||
@@ -55,14 +57,16 @@ public class CommandWrapper {
|
||||
|
||||
}
|
||||
|
||||
public CommandWrapper(final Long officeId, final Long groupId, final Long clientId, final Long loanId, final String actionName,
|
||||
final String entityName, final Long entityId, final Long subentityId, final Long codeId,
|
||||
final String supportedEntityType, final Long supportedEntityId, final String href, final String json, final String transactionId) {
|
||||
public CommandWrapper(final Long officeId, final Long groupId, final Long clientId, final Long loanId, final Long savingsId,
|
||||
final String actionName, final String entityName, final Long entityId, final Long subentityId,
|
||||
final Long codeId, final String supportedEntityType, final Long supportedEntityId, final String href, final String json,
|
||||
final String transactionId) {
|
||||
this.commandId = null;
|
||||
this.officeId = officeId;
|
||||
this.groupId = groupId;
|
||||
this.clientId = clientId;
|
||||
this.loanId = loanId;
|
||||
this.savingsId = savingsId;
|
||||
this.actionName = actionName;
|
||||
this.entityName = entityName;
|
||||
this.taskPermissionName = actionName + "_" + entityName;
|
||||
@@ -107,11 +111,11 @@ public class CommandWrapper {
|
||||
public String getTaskPermissionName() {
|
||||
return this.taskPermissionName;
|
||||
}
|
||||
|
||||
public Long getCodeId(){
|
||||
|
||||
public Long getCodeId() {
|
||||
return this.codeId;
|
||||
}
|
||||
|
||||
|
||||
public String getHref() {
|
||||
return this.href;
|
||||
}
|
||||
@@ -119,7 +123,7 @@ public class CommandWrapper {
|
||||
public String getJson() {
|
||||
return this.json;
|
||||
}
|
||||
|
||||
|
||||
public String getTransactionId() {
|
||||
return this.transactionId;
|
||||
}
|
||||
@@ -148,6 +152,10 @@ public class CommandWrapper {
|
||||
return this.loanId;
|
||||
}
|
||||
|
||||
public Long getSavingsId() {
|
||||
return this.savingsId;
|
||||
}
|
||||
|
||||
public Long getSupportedEntityId() {
|
||||
return this.supportedEntityId;
|
||||
}
|
||||
@@ -177,7 +185,7 @@ public class CommandWrapper {
|
||||
public boolean isUpdateRolePermissions() {
|
||||
return this.actionName.equalsIgnoreCase("PERMISSIONS") && this.entityId != null;
|
||||
}
|
||||
|
||||
|
||||
public boolean isConfigurationResource() {
|
||||
return this.entityName.equalsIgnoreCase("CONFIGURATION");
|
||||
}
|
||||
@@ -205,27 +213,27 @@ public class CommandWrapper {
|
||||
public boolean isCodeValueResource() {
|
||||
return this.entityName.equalsIgnoreCase("CODEVALUE");
|
||||
}
|
||||
|
||||
|
||||
public boolean isStaffResource() {
|
||||
return this.entityName.equalsIgnoreCase("STAFF");
|
||||
}
|
||||
|
||||
|
||||
public boolean isGuarantorResource() {
|
||||
return this.entityName.equalsIgnoreCase("GUARANTOR");
|
||||
}
|
||||
|
||||
|
||||
public boolean isGLAccountResource() {
|
||||
return this.entityName.equalsIgnoreCase("GLACCOUNT");
|
||||
}
|
||||
|
||||
|
||||
public boolean isGLClosureResource() {
|
||||
return this.entityName.equalsIgnoreCase("GLCLOSURE");
|
||||
}
|
||||
|
||||
|
||||
public boolean isJournalEntryResource() {
|
||||
return this.entityName.equalsIgnoreCase("JOURNALENTRY");
|
||||
}
|
||||
|
||||
|
||||
public boolean isRevertJournalEntry() {
|
||||
return this.actionName.equalsIgnoreCase("REVERSE") && this.entityName.equalsIgnoreCase("JOURNALENTRY");
|
||||
}
|
||||
@@ -265,7 +273,7 @@ public class CommandWrapper {
|
||||
public boolean isLoanResource() {
|
||||
return this.entityName.equalsIgnoreCase("LOAN");
|
||||
}
|
||||
|
||||
|
||||
public boolean isLoanChargeResource() {
|
||||
return this.entityName.equalsIgnoreCase("LOANCHARGE");
|
||||
}
|
||||
@@ -341,7 +349,7 @@ public class CommandWrapper {
|
||||
public boolean isRemoveLoanOfficer() {
|
||||
return this.actionName.equalsIgnoreCase("REMOVELOANOFFICER") && this.entityName.equalsIgnoreCase("LOAN");
|
||||
}
|
||||
|
||||
|
||||
public boolean isBulkUpdateLoanOfficer() {
|
||||
return this.actionName.equalsIgnoreCase("BULKREASSIGN") && this.entityName.equalsIgnoreCase("LOAN");
|
||||
}
|
||||
@@ -354,7 +362,7 @@ public class CommandWrapper {
|
||||
/* also covers case of deleting all of a one to many*/
|
||||
return isDatatableResource() && isDeleteOperation() && this.subentityId == null;
|
||||
}
|
||||
|
||||
|
||||
public boolean isDeleteMultiple() {
|
||||
return isDatatableResource() && isDeleteOperation() && this.subentityId != null;
|
||||
}
|
||||
@@ -362,7 +370,7 @@ public class CommandWrapper {
|
||||
public boolean isUpdateOneToOne() {
|
||||
return isDatatableResource() && isUpdateOperation() && this.subentityId == null;
|
||||
}
|
||||
|
||||
|
||||
public boolean isUpdateMultiple() {
|
||||
return isDatatableResource() && isUpdateOperation() && this.subentityId != null;
|
||||
}
|
||||
@@ -370,7 +378,7 @@ public class CommandWrapper {
|
||||
public boolean isUnassignStaff() {
|
||||
return this.actionName.equalsIgnoreCase("UNASSIGNSTAFF") && this.entityName.equalsIgnoreCase("GROUP");
|
||||
}
|
||||
|
||||
|
||||
public String commandName() {
|
||||
return this.actionName + "_" + this.entityName;
|
||||
}
|
||||
@@ -379,96 +387,74 @@ public class CommandWrapper {
|
||||
return this.isUserResource() && isUpdate() && loggedInUserId.equals(this.entityId);
|
||||
}
|
||||
|
||||
public boolean isDepositProductResource() {
|
||||
return this.entityName.equalsIgnoreCase("DEPOSITPRODUCT");
|
||||
}
|
||||
public boolean isDepositProductResource() {
|
||||
return this.entityName.equalsIgnoreCase("DEPOSITPRODUCT");
|
||||
}
|
||||
|
||||
public boolean isDepositAccountResource() {
|
||||
return this.entityName.equalsIgnoreCase("DEPOSITACCOUNT");
|
||||
}
|
||||
public boolean isDepositAccountResource() {
|
||||
return this.entityName.equalsIgnoreCase("DEPOSITACCOUNT");
|
||||
}
|
||||
|
||||
public boolean isApprovalOfDeposit() {
|
||||
return this.actionName.equalsIgnoreCase("APPROVE") && this.entityName.equalsIgnoreCase("DEPOSITACCOUNT");
|
||||
}
|
||||
public boolean isApprovalOfDeposit() {
|
||||
return this.actionName.equalsIgnoreCase("APPROVE") && this.entityName.equalsIgnoreCase("DEPOSITACCOUNT");
|
||||
}
|
||||
|
||||
public boolean isWithdrawDepositAmount() {
|
||||
return this.actionName.equalsIgnoreCase("WITHDRAWAL") && this.entityName.equalsIgnoreCase("DEPOSITACCOUNT");
|
||||
}
|
||||
public boolean isWithdrawDepositAmount() {
|
||||
return this.actionName.equalsIgnoreCase("WITHDRAWAL") && this.entityName.equalsIgnoreCase("DEPOSITACCOUNT");
|
||||
}
|
||||
|
||||
public boolean isWithdrawInterest() {
|
||||
return this.actionName.equalsIgnoreCase("INTEREST") && this.entityName.equalsIgnoreCase("DEPOSITACCOUNT");
|
||||
}
|
||||
public boolean isWithdrawInterest() {
|
||||
return this.actionName.equalsIgnoreCase("INTEREST") && this.entityName.equalsIgnoreCase("DEPOSITACCOUNT");
|
||||
}
|
||||
|
||||
public boolean isRenewOfDepositApplicaion() {
|
||||
return this.actionName.equalsIgnoreCase("RENEW") && this.entityName.equalsIgnoreCase("DEPOSITACCOUNT");
|
||||
}
|
||||
public boolean isRenewOfDepositApplicaion() {
|
||||
return this.actionName.equalsIgnoreCase("RENEW") && this.entityName.equalsIgnoreCase("DEPOSITACCOUNT");
|
||||
}
|
||||
|
||||
public boolean isRejectionOfDepositApplicaion() {
|
||||
return this.actionName.equalsIgnoreCase("REJECT") && this.entityName.equalsIgnoreCase("DEPOSITACCOUNT");
|
||||
}
|
||||
public boolean isRejectionOfDepositApplicaion() {
|
||||
return this.actionName.equalsIgnoreCase("REJECT") && this.entityName.equalsIgnoreCase("DEPOSITACCOUNT");
|
||||
}
|
||||
|
||||
public boolean isWithdrawByApplicant() {
|
||||
return this.actionName.equalsIgnoreCase("WITHDRAW") && this.entityName.equalsIgnoreCase("DEPOSITACCOUNT");
|
||||
}
|
||||
public boolean isWithdrawByApplicant() {
|
||||
return this.actionName.equalsIgnoreCase("WITHDRAW") && this.entityName.equalsIgnoreCase("DEPOSITACCOUNT");
|
||||
}
|
||||
|
||||
public boolean isUndoApprovalOfDepositApplication() {
|
||||
return this.actionName.equalsIgnoreCase("APPROVALUNDO") && this.entityName.equalsIgnoreCase("DEPOSITACCOUNT");
|
||||
}
|
||||
public boolean isUndoApprovalOfDepositApplication() {
|
||||
return this.actionName.equalsIgnoreCase("APPROVALUNDO") && this.entityName.equalsIgnoreCase("DEPOSITACCOUNT");
|
||||
}
|
||||
|
||||
public boolean isSavingProductResource() {
|
||||
return this.entityName.equalsIgnoreCase("SAVINGSPRODUCT");
|
||||
}
|
||||
public boolean isSavingsProductResource() {
|
||||
return this.entityName.equalsIgnoreCase("SAVINGSPRODUCT");
|
||||
}
|
||||
|
||||
public boolean isSavingAccountResource() {
|
||||
return this.entityName.equalsIgnoreCase("SAVINGSACCOUNT");
|
||||
}
|
||||
public boolean isSavingsAccountResource() {
|
||||
return this.entityName.equalsIgnoreCase("SAVINGSACCOUNT");
|
||||
}
|
||||
|
||||
public boolean isApprovalOfSaving() {
|
||||
return this.actionName.equalsIgnoreCase("APPROVE") && this.entityName.equalsIgnoreCase("SAVINGSACCOUNT");
|
||||
}
|
||||
public boolean isSavingsAccountDeposit() {
|
||||
return this.actionName.equalsIgnoreCase("DEPOSIT") && this.entityName.equalsIgnoreCase("SAVINGSACCOUNT");
|
||||
}
|
||||
|
||||
public boolean isSavingAccountDeposit() {
|
||||
return this.actionName.equalsIgnoreCase("DEPOSIT") && this.entityName.equalsIgnoreCase("SAVINGSACCOUNT");
|
||||
}
|
||||
public boolean isSavingsAccountWithdrawal() {
|
||||
return this.actionName.equalsIgnoreCase("WITHDRAWAL") && this.entityName.equalsIgnoreCase("SAVINGSACCOUNT");
|
||||
}
|
||||
|
||||
public boolean isRejectOfSavingAccount() {
|
||||
return this.actionName.equalsIgnoreCase("REJECT") && this.entityName.equalsIgnoreCase("SAVINGSACCOUNT");
|
||||
}
|
||||
|
||||
public boolean isWithdrawSavingAmount() {
|
||||
return this.actionName.equalsIgnoreCase("WITHDRAWAL") && this.entityName.equalsIgnoreCase("SAVINGSACCOUNT");
|
||||
}
|
||||
|
||||
public boolean isWithdrawOfSavingApplicatin() {
|
||||
return this.actionName.equalsIgnoreCase("WITHDRAW") && this.entityName.equalsIgnoreCase("SAVINGSACCOUNT");
|
||||
}
|
||||
|
||||
public boolean isUndoApprovalOfSavingAccount() {
|
||||
return this.actionName.equalsIgnoreCase("APPROVALUNDO") && this.entityName.equalsIgnoreCase("SAVINGSACCOUNT");
|
||||
}
|
||||
|
||||
|
||||
|
||||
public boolean isCalendarResource() {
|
||||
return this.entityName.equalsIgnoreCase("CALENDAR");
|
||||
}
|
||||
|
||||
|
||||
public boolean isNoteResource() {
|
||||
boolean isnoteResource = false;
|
||||
if(this.entityName.equalsIgnoreCase("CLIENTNOTE") ||
|
||||
this.entityName.equalsIgnoreCase("LOANNOTE") ||
|
||||
this.entityName.equalsIgnoreCase("LOANTRANSACTIONNOTE") ||
|
||||
this.entityName.equalsIgnoreCase("DEPOSITNOTE") ||
|
||||
this.entityName.equalsIgnoreCase("SAVINGNOTE") ||
|
||||
this.entityName.equalsIgnoreCase("GROUPNOTE")){
|
||||
if (this.entityName.equalsIgnoreCase("CLIENTNOTE") || this.entityName.equalsIgnoreCase("LOANNOTE")
|
||||
|| this.entityName.equalsIgnoreCase("LOANTRANSACTIONNOTE") || this.entityName.equalsIgnoreCase("DEPOSITNOTE")
|
||||
|| this.entityName.equalsIgnoreCase("SAVINGNOTE") || this.entityName.equalsIgnoreCase("GROUPNOTE")) {
|
||||
isnoteResource = true;
|
||||
}
|
||||
return isnoteResource;
|
||||
}
|
||||
|
||||
|
||||
public boolean isGroupResource() {
|
||||
return this.entityName.equalsIgnoreCase("GROUP");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+15
-123
@@ -13,6 +13,7 @@ public class CommandWrapperBuilder {
|
||||
private Long groupId;
|
||||
private Long clientId;
|
||||
private Long loanId;
|
||||
private Long savingsId;
|
||||
private String actionName;
|
||||
private String entityName;
|
||||
private Long entityId;
|
||||
@@ -25,16 +26,11 @@ public class CommandWrapperBuilder {
|
||||
private Long supportedEntityId;
|
||||
|
||||
public CommandWrapper build() {
|
||||
return new CommandWrapper(this.officeId, this.groupId, this.clientId, this.loanId, this.actionName, this.entityName, this.entityId, this.subentityId,
|
||||
this.codeId, this.supportedEntityType, this.supportedEntityId, this.href, this.json,
|
||||
this.transactionId);
|
||||
return new CommandWrapper(this.officeId, this.groupId, this.clientId, this.loanId, this.savingsId, this.actionName,
|
||||
this.entityName, this.entityId, this.subentityId, this.codeId, this.supportedEntityType, this.supportedEntityId, this.href,
|
||||
this.json, this.transactionId);
|
||||
}
|
||||
|
||||
// public CommandWrapperBuilder withEntityId(final Long withId) {
|
||||
// this.entityId = withId;
|
||||
// return this;
|
||||
// }
|
||||
|
||||
public CommandWrapperBuilder withLoanId(final Long withLoanId) {
|
||||
this.loanId = withLoanId;
|
||||
return this;
|
||||
@@ -325,7 +321,7 @@ public class CommandWrapperBuilder {
|
||||
return this;
|
||||
}
|
||||
|
||||
public CommandWrapperBuilder createDatatable(final String datatable, final Long apptableId, final Long datatableId) {
|
||||
public CommandWrapperBuilder createDatatable(final String datatable, final Long apptableId, final Long datatableId) {
|
||||
this.actionName = "CREATE";
|
||||
commonDatatableSettings(datatable, apptableId, datatableId);
|
||||
return this;
|
||||
@@ -343,9 +339,8 @@ public class CommandWrapperBuilder {
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
private void commonDatatableSettings(final String datatable, final Long apptableId, final Long datatableId) {
|
||||
|
||||
|
||||
this.entityName = datatable;
|
||||
this.entityId = apptableId;
|
||||
this.subentityId = datatableId;
|
||||
@@ -355,8 +350,7 @@ public class CommandWrapperBuilder {
|
||||
this.href = "/datatables/" + datatable + "/" + apptableId + "/" + datatableId;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public CommandWrapperBuilder createLoanCharge(final Long loanId) {
|
||||
this.actionName = "CREATE";
|
||||
this.entityName = "LOANCHARGE";
|
||||
@@ -644,110 +638,6 @@ public class CommandWrapperBuilder {
|
||||
return this;
|
||||
}
|
||||
|
||||
public CommandWrapperBuilder createDepositProduct() {
|
||||
this.actionName = "CREATE";
|
||||
this.entityName = "DEPOSITPRODUCT";
|
||||
this.entityId = null;
|
||||
this.href = "/depositproducts/template";
|
||||
return this;
|
||||
}
|
||||
|
||||
public CommandWrapperBuilder updateDepositProduct(final Long productId) {
|
||||
this.actionName = "UPDATE";
|
||||
this.entityName = "DEPOSITPRODUCT";
|
||||
this.entityId = 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";
|
||||
this.entityName = "DEPOSITACCOUNT";
|
||||
this.entityId = null;
|
||||
this.href = "/depositaccounts/template";
|
||||
return this;
|
||||
}
|
||||
|
||||
public CommandWrapperBuilder updateDepositAccount(final Long accountId) {
|
||||
this.actionName = "UPDATE";
|
||||
this.entityName = "DEPOSITACCOUNT";
|
||||
this.entityId = accountId;
|
||||
this.href = "/depositaccounts/" + accountId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CommandWrapperBuilder deleteDepositAccount(final Long accountId) {
|
||||
this.actionName = "DELETE";
|
||||
this.entityName = "DEPOSITACCOUNT";
|
||||
this.entityId = accountId;
|
||||
this.href = "/depositaccounts/" + accountId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CommandWrapperBuilder approveDepositApplication(final Long accountId) {
|
||||
this.actionName = "APPROVE";
|
||||
this.entityName = "DEPOSITACCOUNT";
|
||||
this.entityId = accountId;
|
||||
this.href = "/depositaccounts/" + accountId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CommandWrapperBuilder withdrawDepositAmount(final Long accountId) {
|
||||
this.actionName = "WITHDRAWAL";
|
||||
this.entityName = "DEPOSITACCOUNT";
|
||||
this.entityId = accountId;
|
||||
this.href = "/depositaccounts/" + accountId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CommandWrapperBuilder withdrawInterestDepositAmount(final Long accountId) {
|
||||
this.actionName = "INTEREST";
|
||||
this.entityName = "DEPOSITACCOUNT";
|
||||
this.entityId = accountId;
|
||||
this.href = "/depositaccounts/" + accountId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CommandWrapperBuilder renewDepositAccount(final Long accountId) {
|
||||
this.actionName = "RENEW";
|
||||
this.entityName = "DEPOSITACCOUNT";
|
||||
this.entityId = accountId;
|
||||
this.href = "/depositaccounts/" + accountId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CommandWrapperBuilder rejectDepositAccount(final Long accountId) {
|
||||
this.actionName = "REJECT";
|
||||
this.entityName = "DEPOSITACCOUNT";
|
||||
this.entityId = accountId;
|
||||
this.href = "/depositaccounts/" + accountId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CommandWrapperBuilder withdrawDepositApplication(final Long accountId) {
|
||||
this.actionName = "WITHDRAW";
|
||||
this.entityName = "DEPOSITACCOUNT";
|
||||
this.entityId = accountId;
|
||||
this.href = "/depositaccounts/" + accountId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CommandWrapperBuilder undoDepositApplicationApproval(final Long accountId) {
|
||||
this.actionName = "APPROVALUNDO";
|
||||
this.entityName = "DEPOSITACCOUNT";
|
||||
this.entityId = accountId;
|
||||
this.href = "/depositaccounts/" + accountId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CommandWrapperBuilder createSavingProduct() {
|
||||
this.actionName = "CREATE";
|
||||
this.entityName = "SAVINGSPRODUCT";
|
||||
@@ -796,19 +686,21 @@ public class CommandWrapperBuilder {
|
||||
return this;
|
||||
}
|
||||
|
||||
public CommandWrapperBuilder depositOfSavingAmount(final Long accountId) {
|
||||
public CommandWrapperBuilder savingsAccountDeposit(final Long accountId) {
|
||||
this.actionName = "DEPOSIT";
|
||||
this.entityName = "SAVINGSACCOUNT";
|
||||
this.entityId = accountId;
|
||||
this.href = "/savingsaccounts/" + accountId;
|
||||
this.loanId = accountId;
|
||||
this.entityId = null;
|
||||
this.href = "/savingsaccounts/" + accountId + "/transactions";
|
||||
return this;
|
||||
}
|
||||
|
||||
public CommandWrapperBuilder withdrawSavingAmount(final Long accountId) {
|
||||
public CommandWrapperBuilder savingsAccountWithdrawal(final Long accountId) {
|
||||
this.actionName = "WITHDRAWAL";
|
||||
this.entityName = "SAVINGSACCOUNT";
|
||||
this.entityId = accountId;
|
||||
this.href = "/savingsaccounts/" + accountId;
|
||||
this.loanId = accountId;
|
||||
this.entityId = null;
|
||||
this.href = "/savingsaccounts/" + accountId + "/transactions";
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
+16
-7
@@ -40,15 +40,18 @@ public class PortfolioCommandSourceWritePlatformServiceImpl implements Portfolio
|
||||
|
||||
@Override
|
||||
public CommandProcessingResult logCommandSource(final CommandWrapper wrapper) {
|
||||
|
||||
|
||||
boolean isApprovedByChecker = false;
|
||||
// check if is update of own account details
|
||||
if (wrapper.isUpdateOfOwnUserDetails(context.authenticatedUser().getId())) {
|
||||
// then allow this operation to proceed.
|
||||
// maker checker doesnt mean anything here.
|
||||
isApprovedByChecker = true; // set to true in case permissions have been maker-checker enabled by accident.
|
||||
isApprovedByChecker = true; // set to true in case permissions have
|
||||
// been maker-checker enabled by
|
||||
// accident.
|
||||
} else {
|
||||
// if not user changing their own details - check user has permission to perform specific task.
|
||||
// if not user changing their own details - check user has
|
||||
// permission to perform specific task.
|
||||
context.authenticatedUser().validateHasPermissionTo(wrapper.getTaskPermissionName());
|
||||
}
|
||||
|
||||
@@ -57,7 +60,9 @@ public class PortfolioCommandSourceWritePlatformServiceImpl implements Portfolio
|
||||
try {
|
||||
final JsonElement parsedCommand = this.fromApiJsonHelper.parse(json);
|
||||
final JsonCommand command = JsonCommand.from(json, parsedCommand, this.fromApiJsonHelper, wrapper.getEntityName(),
|
||||
wrapper.getEntityId(), wrapper.getSubentityId(), wrapper.getGroupId(), wrapper.getClientId(), wrapper.getLoanId(), wrapper.getCodeId(), wrapper.getSupportedEntityType(), wrapper.getSupportedEntityId(), wrapper.getTransactionId());
|
||||
wrapper.getEntityId(), wrapper.getSubentityId(), wrapper.getGroupId(), wrapper.getClientId(), wrapper.getLoanId(),
|
||||
wrapper.getSavingsId(), wrapper.getCodeId(), wrapper.getSupportedEntityType(), wrapper.getSupportedEntityId(),
|
||||
wrapper.getTransactionId());
|
||||
|
||||
result = this.processAndLogCommandService.processAndLogCommand(wrapper, command, isApprovedByChecker);
|
||||
} catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) {
|
||||
@@ -67,7 +72,9 @@ public class PortfolioCommandSourceWritePlatformServiceImpl implements Portfolio
|
||||
final JsonElement parsedCommand = this.fromApiJsonHelper.parse(jsonToUse);
|
||||
|
||||
final JsonCommand command = JsonCommand.from(jsonToUse, parsedCommand, this.fromApiJsonHelper, wrapper.getEntityName(),
|
||||
wrapper.getEntityId(), wrapper.getSubentityId(), wrapper.getGroupId(), wrapper.getClientId(), wrapper.getLoanId(), wrapper.getCodeId(), wrapper.getSupportedEntityType(), wrapper.getSupportedEntityId(), wrapper.getTransactionId());
|
||||
wrapper.getEntityId(), wrapper.getSubentityId(), wrapper.getGroupId(), wrapper.getClientId(), wrapper.getLoanId(),
|
||||
wrapper.getSavingsId(), wrapper.getCodeId(), wrapper.getSupportedEntityType(), wrapper.getSupportedEntityId(),
|
||||
wrapper.getTransactionId());
|
||||
|
||||
result = this.processAndLogCommandService.logCommand(wrapper, command);
|
||||
}
|
||||
@@ -83,11 +90,13 @@ public class PortfolioCommandSourceWritePlatformServiceImpl implements Portfolio
|
||||
context.authenticatedUser().validateHasCheckerPermissionTo(commandSourceInput.getPermissionCode());
|
||||
|
||||
final CommandWrapper wrapper = CommandWrapper.fromExistingCommand(commandId, commandSourceInput.getActionName(),
|
||||
commandSourceInput.getEntityName(), commandSourceInput.resourceId(), commandSourceInput.subresourceId(), commandSourceInput.getResourceGetUrl());
|
||||
commandSourceInput.getEntityName(), commandSourceInput.resourceId(), commandSourceInput.subresourceId(),
|
||||
commandSourceInput.getResourceGetUrl());
|
||||
|
||||
final JsonElement parsedCommand = this.fromApiJsonHelper.parse(commandSourceInput.json());
|
||||
final JsonCommand command = JsonCommand.fromExistingCommand(commandId, commandSourceInput.json(), parsedCommand,
|
||||
this.fromApiJsonHelper, commandSourceInput.getEntityName(), commandSourceInput.resourceId(), commandSourceInput.subresourceId());
|
||||
this.fromApiJsonHelper, commandSourceInput.getEntityName(), commandSourceInput.resourceId(),
|
||||
commandSourceInput.subresourceId());
|
||||
|
||||
final boolean makerCheckerApproval = true;
|
||||
return this.processAndLogCommandService.processAndLogCommand(wrapper, command, makerCheckerApproval);
|
||||
|
||||
+9
-39
@@ -338,43 +338,9 @@ public class SynchronousCommandProcessingService implements CommandProcessingSer
|
||||
handler = applicationContext.getBean("reverseJournalEntryCommandHandler", NewCommandSourceHandler.class);
|
||||
} else {
|
||||
throw new UnsupportedCommandException(wrapper.commandName());
|
||||
}
|
||||
} else if (wrapper.isDepositProductResource()) {
|
||||
if (wrapper.isCreate()) {
|
||||
handler = applicationContext.getBean("createDepositProductCommandHandler", NewCommandSourceHandler.class);
|
||||
} else if (wrapper.isUpdate()) {
|
||||
handler = applicationContext.getBean("updateDepositProductCommandHandler", NewCommandSourceHandler.class);
|
||||
} else if (wrapper.isDelete()) {
|
||||
handler = applicationContext.getBean("deleteDepositProductCommandHandler", NewCommandSourceHandler.class);
|
||||
} else {
|
||||
throw new UnsupportedCommandException(wrapper.commandName());
|
||||
}
|
||||
} else if (wrapper.isDepositAccountResource()) {
|
||||
if (wrapper.isCreate()) {
|
||||
handler = applicationContext.getBean("createDepositAccountCommandHandler", NewCommandSourceHandler.class);
|
||||
} else if (wrapper.isUpdate()) {
|
||||
handler = applicationContext.getBean("updateDepositAccountCommandHandler", NewCommandSourceHandler.class);
|
||||
} else if (wrapper.isDelete()) {
|
||||
handler = applicationContext.getBean("deleteDepositAccountCommandHandler", NewCommandSourceHandler.class);
|
||||
} else if (wrapper.isApprovalOfDeposit()) {
|
||||
handler = applicationContext.getBean("approveDepositAccountCommandHandler", NewCommandSourceHandler.class);
|
||||
} else if (wrapper.isWithdrawDepositAmount()) {
|
||||
handler = applicationContext.getBean("withdrawDepositAccountAmountCommandHandler", NewCommandSourceHandler.class);
|
||||
} else if (wrapper.isWithdrawInterest()) {
|
||||
handler = applicationContext.getBean("withdrawInterestDepositAccountAmountCommandHandler", NewCommandSourceHandler.class);
|
||||
} else if (wrapper.isRenewOfDepositApplicaion()) {
|
||||
handler = applicationContext.getBean("renewDepositAccountCommandHandler", NewCommandSourceHandler.class);
|
||||
} else if (wrapper.isRejectionOfDepositApplicaion()) {
|
||||
handler = applicationContext.getBean("rejectDepositAccountCommandHandler", NewCommandSourceHandler.class);
|
||||
} else if (wrapper.isWithdrawByApplicant()) {
|
||||
handler = applicationContext.getBean("withDrawByApplicantDepositAccountCommandHandler", NewCommandSourceHandler.class);
|
||||
} else if (wrapper.isUndoApprovalOfDepositApplication()) {
|
||||
handler = applicationContext.getBean("undoApprovalDepositAccountCommandHandler", NewCommandSourceHandler.class);
|
||||
} else {
|
||||
throw new UnsupportedCommandException(wrapper.commandName());
|
||||
}
|
||||
} else if (wrapper.isSavingProductResource()) {
|
||||
if (wrapper.isCreate()) {
|
||||
} else if (wrapper.isSavingsProductResource()) {
|
||||
if (wrapper.isCreate()) {
|
||||
handler = applicationContext.getBean("createSavingsProductCommandHandler", NewCommandSourceHandler.class);
|
||||
} else if (wrapper.isUpdate()) {
|
||||
handler = applicationContext.getBean("updateSavingsProductCommandHandler", NewCommandSourceHandler.class);
|
||||
@@ -383,13 +349,17 @@ public class SynchronousCommandProcessingService implements CommandProcessingSer
|
||||
} else {
|
||||
throw new UnsupportedCommandException(wrapper.commandName());
|
||||
}
|
||||
} else if (wrapper.isSavingAccountResource()) {
|
||||
if (wrapper.isCreate()) {
|
||||
} else if (wrapper.isSavingsAccountResource()) {
|
||||
if (wrapper.isCreate()) {
|
||||
handler = applicationContext.getBean("createSavingsAccountCommandHandler", NewCommandSourceHandler.class);
|
||||
} else if (wrapper.isUpdate()) {
|
||||
handler = applicationContext.getBean("updateSavingsAccountCommandHandler", NewCommandSourceHandler.class);
|
||||
} else if (wrapper.isDelete()) {
|
||||
handler = applicationContext.getBean("deleteSavingsAccountCommandHandler", NewCommandSourceHandler.class);
|
||||
} else if (wrapper.isSavingsAccountDeposit()) {
|
||||
handler = applicationContext.getBean("depositSavingsAccountCommandHandler", NewCommandSourceHandler.class);
|
||||
} else if (wrapper.isSavingsAccountWithdrawal()) {
|
||||
handler = applicationContext.getBean("withdrawSavingsAccountCommandHandler", NewCommandSourceHandler.class);
|
||||
} else {
|
||||
throw new UnsupportedCommandException(wrapper.commandName());
|
||||
}
|
||||
@@ -415,7 +385,7 @@ public class SynchronousCommandProcessingService implements CommandProcessingSer
|
||||
} else {
|
||||
throw new UnsupportedCommandException(wrapper.commandName());
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
throw new UnsupportedCommandException(wrapper.commandName());
|
||||
}
|
||||
|
||||
+16
-10
@@ -37,6 +37,7 @@ public final class JsonCommand {
|
||||
private final Long groupId;
|
||||
private final Long clientId;
|
||||
private final Long loanId;
|
||||
private final Long savingsId;
|
||||
private final String entityName;
|
||||
private final Long codeId;
|
||||
private final String supportedEntityType;
|
||||
@@ -44,22 +45,22 @@ public final class JsonCommand {
|
||||
private final String transactionId;
|
||||
|
||||
public static JsonCommand from(final String jsonCommand, final JsonElement parsedCommand, final FromJsonHelper fromApiJsonHelper,
|
||||
final String entityName, final Long resourceId, final Long subresourceId, final Long groupId, final Long clientId, final Long loanId,
|
||||
final Long codeId, final String supportedEntityType,
|
||||
final Long supportedEntityId, final String transactionId) {
|
||||
return new JsonCommand(null, jsonCommand, parsedCommand, fromApiJsonHelper, entityName, resourceId, subresourceId, groupId, clientId, loanId,
|
||||
codeId, supportedEntityType, supportedEntityId, transactionId);
|
||||
final String entityName, final Long resourceId, final Long subresourceId, final Long groupId, final Long clientId,
|
||||
final Long loanId, final Long savingsId, final Long codeId, final String supportedEntityType, final Long supportedEntityId,
|
||||
final String transactionId) {
|
||||
return new JsonCommand(null, jsonCommand, parsedCommand, fromApiJsonHelper, entityName, resourceId, subresourceId, groupId,
|
||||
clientId, loanId, savingsId, codeId, supportedEntityType, supportedEntityId, transactionId);
|
||||
}
|
||||
|
||||
public static JsonCommand fromExistingCommand(final Long commandId, final String jsonCommand, final JsonElement parsedCommand,
|
||||
final FromJsonHelper fromApiJsonHelper, final String entityName, final Long resourceId, final Long subresourceId) {
|
||||
return new JsonCommand(commandId, jsonCommand, parsedCommand, fromApiJsonHelper, entityName, resourceId, subresourceId, null, null, null, null,
|
||||
null, null, null);
|
||||
return new JsonCommand(commandId, jsonCommand, parsedCommand, fromApiJsonHelper, entityName, resourceId, subresourceId, null, null,
|
||||
null, null, null, null, null, null);
|
||||
}
|
||||
|
||||
public JsonCommand(final Long commandId, final String jsonCommand, final JsonElement parsedCommand,
|
||||
final FromJsonHelper fromApiJsonHelper, final String entityName, final Long resourceId, final Long subresourceId, final Long groupId,
|
||||
final Long clientId, final Long loanId, final Long codeId,
|
||||
final FromJsonHelper fromApiJsonHelper, final String entityName, final Long resourceId, final Long subresourceId,
|
||||
final Long groupId, final Long clientId, final Long loanId, final Long savingsId, final Long codeId,
|
||||
final String supportedEntityType, final Long supportedEntityId, final String transactionId) {
|
||||
this.commandId = commandId;
|
||||
this.jsonCommand = jsonCommand;
|
||||
@@ -71,6 +72,7 @@ public final class JsonCommand {
|
||||
this.groupId = groupId;
|
||||
this.clientId = clientId;
|
||||
this.loanId = loanId;
|
||||
this.savingsId = savingsId;
|
||||
this.codeId = codeId;
|
||||
this.supportedEntityType = supportedEntityType;
|
||||
this.supportedEntityId = supportedEntityId;
|
||||
@@ -105,7 +107,7 @@ public final class JsonCommand {
|
||||
public Long entityId() {
|
||||
return this.resourceId;
|
||||
}
|
||||
|
||||
|
||||
public Long subentityId() {
|
||||
return this.subresourceId;
|
||||
}
|
||||
@@ -122,6 +124,10 @@ public final class JsonCommand {
|
||||
return this.loanId;
|
||||
}
|
||||
|
||||
public Long getSavingsId() {
|
||||
return this.savingsId;
|
||||
}
|
||||
|
||||
public Long getCodeId() {
|
||||
return this.codeId;
|
||||
}
|
||||
|
||||
+13
-4
@@ -19,6 +19,7 @@ public class CommandProcessingResult {
|
||||
private final Long groupId;
|
||||
private final Long clientId;
|
||||
private final Long loanId;
|
||||
private final Long savingsId;
|
||||
private final Long resourceId;
|
||||
private final String transactionId;
|
||||
private final Map<String, Object> changes;
|
||||
@@ -26,10 +27,10 @@ public class CommandProcessingResult {
|
||||
private final String resourceIdentifier;
|
||||
|
||||
public static CommandProcessingResult fromDetails(final Long commandId, final Long officeId, final Long groupId, final Long clientId,
|
||||
final Long loanId, final String resourceIdentifier, final Long entityId, final String transactionId,
|
||||
final Long loanId, final Long savingsId, final String resourceIdentifier, final Long entityId, final String transactionId,
|
||||
final Map<String, Object> changes) {
|
||||
return new CommandProcessingResult(commandId, officeId, groupId, clientId, loanId, resourceIdentifier, entityId, transactionId,
|
||||
changes);
|
||||
return new CommandProcessingResult(commandId, officeId, groupId, clientId, loanId, savingsId, resourceIdentifier, entityId,
|
||||
transactionId, changes);
|
||||
}
|
||||
|
||||
public static CommandProcessingResult commandOnlyResult(final Long commandId) {
|
||||
@@ -75,17 +76,20 @@ public class CommandProcessingResult {
|
||||
this.groupId = null;
|
||||
this.clientId = null;
|
||||
this.loanId = null;
|
||||
this.savingsId = null;
|
||||
this.transactionId = null;
|
||||
this.changes = new HashMap<String, Object>();
|
||||
}
|
||||
|
||||
private CommandProcessingResult(final Long commandId, final Long officeId, final Long groupId, final Long clientId, final Long loanId,
|
||||
final String resourceIdentifier, final Long resourceId, final String transactionId, final Map<String, Object> changesOnly) {
|
||||
final Long savingsId, final String resourceIdentifier, final Long resourceId, final String transactionId,
|
||||
final Map<String, Object> changesOnly) {
|
||||
this.commandId = commandId;
|
||||
this.officeId = officeId;
|
||||
this.groupId = groupId;
|
||||
this.clientId = clientId;
|
||||
this.loanId = loanId;
|
||||
this.savingsId = savingsId;
|
||||
this.resourceIdentifier = resourceIdentifier;
|
||||
this.resourceId = resourceId;
|
||||
this.changes = changesOnly;
|
||||
@@ -103,6 +107,7 @@ public class CommandProcessingResult {
|
||||
this.groupId = null;
|
||||
this.clientId = null;
|
||||
this.loanId = null;
|
||||
this.savingsId = null;
|
||||
this.transactionId = null;
|
||||
this.commandId = commandId;
|
||||
this.changes = changesOnly;
|
||||
@@ -136,6 +141,10 @@ public class CommandProcessingResult {
|
||||
return this.loanId;
|
||||
}
|
||||
|
||||
public Long getSavingsId() {
|
||||
return this.savingsId;
|
||||
}
|
||||
|
||||
public String getTransactionId() {
|
||||
return this.transactionId;
|
||||
}
|
||||
|
||||
+7
-1
@@ -18,13 +18,14 @@ public class CommandProcessingResultBuilder {
|
||||
private Long groupId;
|
||||
private Long clientId;
|
||||
private Long loanId;
|
||||
private Long savingsId;
|
||||
private String resourceIdentifier;
|
||||
private Long entityId;
|
||||
private String transactionId;
|
||||
private Map<String, Object> changes;
|
||||
|
||||
public CommandProcessingResult build() {
|
||||
return CommandProcessingResult.fromDetails(commandId, officeId, groupId, clientId, loanId, resourceIdentifier, entityId,
|
||||
return CommandProcessingResult.fromDetails(commandId, officeId, groupId, clientId, loanId, savingsId, resourceIdentifier, entityId,
|
||||
transactionId, changes);
|
||||
}
|
||||
|
||||
@@ -68,6 +69,11 @@ public class CommandProcessingResultBuilder {
|
||||
return this;
|
||||
}
|
||||
|
||||
public CommandProcessingResultBuilder withSavingsId(final Long withSavingsId) {
|
||||
this.savingsId = withSavingsId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CommandProcessingResultBuilder withTransactionId(final String withTransactionId) {
|
||||
this.transactionId = withTransactionId;
|
||||
return this;
|
||||
|
||||
+1
-1
@@ -67,7 +67,7 @@ public class JdbcSupport {
|
||||
|
||||
private static BigDecimal defaultToNullIfZero(final BigDecimal value) {
|
||||
BigDecimal result = value;
|
||||
if (BigDecimal.ZERO.compareTo(value) == 0) {
|
||||
if (value != null && BigDecimal.ZERO.compareTo(value) == 0) {
|
||||
result = null;
|
||||
}
|
||||
return result;
|
||||
|
||||
+1
-1
@@ -15,7 +15,7 @@ public abstract class AbstractPlatformDomainRuleException extends RuntimeExcepti
|
||||
private final String defaultUserMessage;
|
||||
private final Object[] defaultUserMessageArgs;
|
||||
|
||||
public AbstractPlatformDomainRuleException(String globalisationMessageCode, String defaultUserMessage, Object... defaultUserMessageArgs) {
|
||||
public AbstractPlatformDomainRuleException(final String globalisationMessageCode, final String defaultUserMessage, final Object... defaultUserMessageArgs) {
|
||||
this.globalisationMessageCode = globalisationMessageCode;
|
||||
this.defaultUserMessage = defaultUserMessage;
|
||||
this.defaultUserMessageArgs = defaultUserMessageArgs;
|
||||
|
||||
+1
-1
@@ -10,7 +10,7 @@ public class UnrecognizedQueryParamException extends RuntimeException {
|
||||
private final String queryParamKey;
|
||||
private final String queryParamValue;
|
||||
|
||||
public UnrecognizedQueryParamException(String queryParamKey, String queryParamValue) {
|
||||
public UnrecognizedQueryParamException(final String queryParamKey, final String queryParamValue) {
|
||||
this.queryParamKey = queryParamKey;
|
||||
this.queryParamValue = queryParamValue;
|
||||
}
|
||||
|
||||
+16
-4
@@ -93,8 +93,8 @@ public class Money implements Comparable<Money> {
|
||||
}
|
||||
|
||||
public Money plus(final BigDecimal amountToAdd) {
|
||||
if (amountToAdd.compareTo(BigDecimal.ZERO) == 0) { return this; }
|
||||
BigDecimal newAmount = this.amount.add(amountToAdd);
|
||||
if (amountToAdd == null || amountToAdd.compareTo(BigDecimal.ZERO) == 0) { return this; }
|
||||
final BigDecimal newAmount = this.amount.add(amountToAdd);
|
||||
return Money.of(monetaryCurrency(), newAmount);
|
||||
}
|
||||
|
||||
@@ -110,8 +110,8 @@ public class Money implements Comparable<Money> {
|
||||
}
|
||||
|
||||
public Money minus(final BigDecimal amountToSubtract) {
|
||||
if (amountToSubtract.compareTo(BigDecimal.ZERO) == 0) { return this; }
|
||||
BigDecimal newAmount = this.amount.subtract(amountToSubtract);
|
||||
if (amountToSubtract == null || amountToSubtract.compareTo(BigDecimal.ZERO) == 0) { return this; }
|
||||
final BigDecimal newAmount = this.amount.subtract(amountToSubtract);
|
||||
return Money.of(monetaryCurrency(), newAmount);
|
||||
}
|
||||
|
||||
@@ -223,6 +223,18 @@ public class Money implements Comparable<Money> {
|
||||
return this.amount;
|
||||
}
|
||||
|
||||
public BigDecimal getAmountDefaultedToNullIfZero() {
|
||||
return defaultToNullIfZero(this.amount);
|
||||
}
|
||||
|
||||
private static BigDecimal defaultToNullIfZero(final BigDecimal value) {
|
||||
BigDecimal result = value;
|
||||
if (value != null && BigDecimal.ZERO.compareTo(value) == 0) {
|
||||
result = null;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new StringBuilder().append(this.currencyCode).append(' ').append(this.amount.toPlainString()).toString();
|
||||
|
||||
-13
@@ -114,19 +114,6 @@ public class ClientAccountSummaryCollectionData {
|
||||
|
||||
this.anyLoanCount = countOf(this.pendingApprovalLoanCount, this.awaitingDisbursalLoanCount, this.activeLoanCount,
|
||||
this.closedLoanCount);
|
||||
//
|
||||
// , this.pendingApprovalDepositAccountsCount,
|
||||
// this.approvedDepositAccountsCount
|
||||
// , this.withdrawnByClientDepositAccountsCount,
|
||||
// this.closedDepositAccountsCount, this.rejectedDepositAccountsCount
|
||||
// , this.preclosedDepositAccountsCount,
|
||||
// this.maturedDepositAccountsCount,
|
||||
// this.pendingApprovalSavingAccountsCount
|
||||
// , this.approvedSavingAccountsCount,
|
||||
// this.withdrawnByClientSavingAccountsCount,
|
||||
// this.rejectedSavingAccountsCount
|
||||
// , this.closedSavingAccountsCount);
|
||||
|
||||
}
|
||||
|
||||
private Integer countOf(final Integer... objects) {
|
||||
|
||||
+39
-54
@@ -240,71 +240,24 @@ 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);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
List<ClientAccountSummaryData> pendingApprovalSavingAccounts = new ArrayList<ClientAccountSummaryData>();
|
||||
List<ClientAccountSummaryData> approvedSavingAccounts = new ArrayList<ClientAccountSummaryData>();
|
||||
List<ClientAccountSummaryData> withdrawnByClientSavingAccounts = new ArrayList<ClientAccountSummaryData>();
|
||||
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);
|
||||
// }
|
||||
// }
|
||||
final ClientSavingsAccountSummaryDataMapper savingsAccountSummaryDataMapper = new ClientSavingsAccountSummaryDataMapper();
|
||||
final String savingsSql = "select " + savingsAccountSummaryDataMapper.schema() + " where sa.client_id = ?";
|
||||
final List<ClientAccountSummaryData> savingsAccounts = this.jdbcTemplate.query(savingsSql, savingsAccountSummaryDataMapper,
|
||||
new Object[] { clientId });
|
||||
|
||||
approvedSavingAccounts.addAll(savingsAccounts);
|
||||
|
||||
return new ClientAccountSummaryCollectionData(pendingApprovalLoans, awaitingDisbursalLoans, openLoans, closedLoans,
|
||||
pendingApprovalDepositAccounts, approvedDepositAccounts, withdrawnByClientDespositAccounts, rejectedDepositAccounts,
|
||||
closedDepositAccounts, preclosedDepositAccounts, maturedDepositAccounts, pendingApprovalSavingAccounts,
|
||||
approvedSavingAccounts, withdrawnByClientSavingAccounts, rejectedSavingAccounts, closedSavingAccounts);
|
||||
|
||||
} catch (EmptyResultDataAccessException e) {
|
||||
throw new ClientNotFoundException(clientId);
|
||||
}
|
||||
@@ -327,6 +280,38 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
|
||||
return loanAccounts;
|
||||
}
|
||||
|
||||
private static final class ClientSavingsAccountSummaryDataMapper implements RowMapper<ClientAccountSummaryData> {
|
||||
|
||||
final String schemaSql;
|
||||
|
||||
public ClientSavingsAccountSummaryDataMapper() {
|
||||
StringBuilder accountsSummary = new StringBuilder();
|
||||
accountsSummary.append("sa.id as id, sa.account_no as accountNo, sa.external_id as externalId,");
|
||||
accountsSummary.append("sa.product_id as productId, p.name as productName ");
|
||||
accountsSummary.append("from m_savings_account sa ");
|
||||
accountsSummary.append("join m_savings_product as p on p.id = sa.product_id ");
|
||||
|
||||
this.schemaSql = accountsSummary.toString();
|
||||
}
|
||||
|
||||
public String schema() {
|
||||
return this.schemaSql;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClientAccountSummaryData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {
|
||||
|
||||
final Long id = JdbcSupport.getLong(rs, "id");
|
||||
final String accountNo = rs.getString("accountNo");
|
||||
final String externalId = rs.getString("externalId");
|
||||
final Long productId = JdbcSupport.getLong(rs, "productId");
|
||||
final String loanProductName = rs.getString("productName");
|
||||
final LoanStatusEnumData loanStatus = null;
|
||||
|
||||
return new ClientAccountSummaryData(id, accountNo, externalId, productId, loanProductName, loanStatus);
|
||||
}
|
||||
}
|
||||
|
||||
private static final class ClientLoanAccountSummaryDataMapper implements RowMapper<ClientAccountSummaryData> {
|
||||
|
||||
public String loanAccountSummarySchema() {
|
||||
|
||||
+103
@@ -0,0 +1,103 @@
|
||||
/**
|
||||
* 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 javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.POST;
|
||||
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.ApiRequestParameterHelper;
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||
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.security.service.PlatformSecurityContext;
|
||||
import org.mifosplatform.portfolio.savings.data.SavingsAccountTransactionData;
|
||||
import org.mifosplatform.portfolio.savings.service.SavingsAccountReadPlatformService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Path("/savingsaccounts/{savingsId}/transactions")
|
||||
@Component
|
||||
@Scope("singleton")
|
||||
public class SavingsAccountTransactionsApiResource {
|
||||
|
||||
private final PlatformSecurityContext context;
|
||||
private final DefaultToApiJsonSerializer<SavingsAccountTransactionData> toApiJsonSerializer;
|
||||
private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
|
||||
private final ApiRequestParameterHelper apiRequestParameterHelper;
|
||||
private final SavingsAccountReadPlatformService savingsAccountReadPlatformService;
|
||||
|
||||
@Autowired
|
||||
public SavingsAccountTransactionsApiResource(final PlatformSecurityContext context,
|
||||
final DefaultToApiJsonSerializer<SavingsAccountTransactionData> toApiJsonSerializer,
|
||||
final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService,
|
||||
final ApiRequestParameterHelper apiRequestParameterHelper,
|
||||
final SavingsAccountReadPlatformService savingsAccountReadPlatformService) {
|
||||
this.context = context;
|
||||
this.toApiJsonSerializer = toApiJsonSerializer;
|
||||
this.commandsSourceWritePlatformService = commandsSourceWritePlatformService;
|
||||
this.apiRequestParameterHelper = apiRequestParameterHelper;
|
||||
this.savingsAccountReadPlatformService = savingsAccountReadPlatformService;
|
||||
}
|
||||
|
||||
private boolean is(final String commandParam, final String commandValue) {
|
||||
return StringUtils.isNotBlank(commandParam) && commandParam.trim().equalsIgnoreCase(commandValue);
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("template")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String retrieveTemplate(@PathParam("savingsId") final Long savingsId, @QueryParam("command") final String commandParam,
|
||||
@Context final UriInfo uriInfo) {
|
||||
|
||||
context.authenticatedUser().validateHasReadPermission(SavingsApiConstants.SAVINGS_ACCOUNT_RESOURCE_NAME);
|
||||
|
||||
// FIXME - KW - for now just send back generic default information for
|
||||
// both deposit/withdrawal templates
|
||||
final SavingsAccountTransactionData savingsAccount = this.savingsAccountReadPlatformService
|
||||
.retrieveDepositTransactionTemplate(savingsId);
|
||||
|
||||
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
||||
return this.toApiJsonSerializer.serialize(settings, savingsAccount,
|
||||
SavingsApiConstants.SAVINGS_TRANSACTION_RESPONSE_DATA_PARAMETERS);
|
||||
}
|
||||
|
||||
@POST
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String transaction(@PathParam("savingsId") final Long savingsId, @QueryParam("command") final String commandParam,
|
||||
final String apiRequestBodyAsJson) {
|
||||
|
||||
final CommandWrapperBuilder builder = new CommandWrapperBuilder().withJson(apiRequestBodyAsJson);
|
||||
|
||||
CommandProcessingResult result = null;
|
||||
if (is(commandParam, "deposit")) {
|
||||
final CommandWrapper commandRequest = builder.savingsAccountDeposit(savingsId).build();
|
||||
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
||||
} else if (is(commandParam, "withdrawal")) {
|
||||
final CommandWrapper commandRequest = builder.savingsAccountWithdrawal(savingsId).build();
|
||||
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
||||
}
|
||||
|
||||
if (result == null) { throw new UnrecognizedQueryParamException("command", commandParam); }
|
||||
|
||||
return this.toApiJsonSerializer.serialize(result);
|
||||
}
|
||||
}
|
||||
+101
-71
@@ -5,7 +5,10 @@
|
||||
*/
|
||||
package org.mifosplatform.portfolio.savings.api;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.DELETE;
|
||||
@@ -23,6 +26,7 @@ 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.ApiParameterHelper;
|
||||
import org.mifosplatform.infrastructure.core.api.ApiRequestParameterHelper;
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
|
||||
@@ -30,6 +34,7 @@ import org.mifosplatform.infrastructure.core.serialization.ApiRequestJsonSeriali
|
||||
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.SavingsAccountTransactionData;
|
||||
import org.mifosplatform.portfolio.savings.data.SavingsProductData;
|
||||
import org.mifosplatform.portfolio.savings.service.SavingsAccountReadPlatformService;
|
||||
import org.mifosplatform.portfolio.savings.service.SavingsDropdownReadPlatformService;
|
||||
@@ -37,6 +42,7 @@ import org.mifosplatform.portfolio.savings.service.SavingsProductReadPlatformSer
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
@Path("/savingsaccounts")
|
||||
@Component
|
||||
@@ -67,77 +73,6 @@ public class SavingsAccountsApiResource {
|
||||
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 })
|
||||
@@ -153,6 +88,101 @@ public class SavingsAccountsApiResource {
|
||||
return this.toApiJsonSerializer.serialize(settings, savingsAccount, SavingsApiConstants.SAVINGS_ACCOUNT_RESPONSE_DATA_PARAMETERS);
|
||||
}
|
||||
|
||||
@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);
|
||||
}
|
||||
|
||||
@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);
|
||||
}
|
||||
|
||||
@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);
|
||||
|
||||
final SavingsAccountData savingsAccount = this.savingsAccountReadPlatformService.retrieveOne(accountId);
|
||||
|
||||
final Set<String> mandatoryResponseParameters = new HashSet<String>();
|
||||
SavingsAccountData savingsAccountTemplate = populateTemplateAndAssociations(accountId, savingsAccount, uriInfo,
|
||||
mandatoryResponseParameters);
|
||||
|
||||
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters(),
|
||||
mandatoryResponseParameters);
|
||||
return this.toApiJsonSerializer.serialize(settings, savingsAccountTemplate,
|
||||
SavingsApiConstants.SAVINGS_ACCOUNT_RESPONSE_DATA_PARAMETERS);
|
||||
}
|
||||
|
||||
private SavingsAccountData populateTemplateAndAssociations(final Long accountId, final SavingsAccountData savingsAccount,
|
||||
final UriInfo uriInfo, final Set<String> mandatoryResponseParameters) {
|
||||
|
||||
Collection<SavingsAccountTransactionData> transactions = null;
|
||||
Collection<SavingsProductData> productOptions = null;
|
||||
Collection<EnumOptionData> interestRatePeriodFrequencyTypeOptions = null;
|
||||
Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions = null;
|
||||
|
||||
final Set<String> associationParameters = ApiParameterHelper.extractAssociationsForResponseIfProvided(uriInfo.getQueryParameters());
|
||||
if (!associationParameters.isEmpty()) {
|
||||
|
||||
if (associationParameters.contains("all")) {
|
||||
associationParameters.addAll(Arrays.asList("transactions"));
|
||||
}
|
||||
|
||||
if (associationParameters.contains("transactions")) {
|
||||
mandatoryResponseParameters.add("transactions");
|
||||
final Collection<SavingsAccountTransactionData> currentTransactions = this.savingsAccountReadPlatformService
|
||||
.retrieveAllTransactions(accountId);
|
||||
if (!CollectionUtils.isEmpty(currentTransactions)) {
|
||||
transactions = currentTransactions;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
||||
if (settings.isTemplate()) {
|
||||
productOptions = this.savingsProductReadPlatformService.retrieveAllForLookup();
|
||||
interestRatePeriodFrequencyTypeOptions = this.dropdownReadPlatformService.retrieveInterestRatePeriodFrequencyTypeOptions();
|
||||
lockinPeriodFrequencyTypeOptions = this.dropdownReadPlatformService.retrieveLockinPeriodFrequencyTypeOptions();
|
||||
}
|
||||
|
||||
return SavingsAccountData.withTemplateOptions(savingsAccount, productOptions, interestRatePeriodFrequencyTypeOptions,
|
||||
lockinPeriodFrequencyTypeOptions, transactions);
|
||||
}
|
||||
|
||||
@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);
|
||||
}
|
||||
|
||||
@DELETE
|
||||
@Path("{accountId}")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
|
||||
+15
@@ -11,8 +11,13 @@ 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 SAVINGS_ACCOUNT_TRANSACTION_RESOURCE_NAME = "savingsaccount.transaction";
|
||||
|
||||
// general
|
||||
public static final String localeParamName = "locale";
|
||||
public static final String dateFormatParamName = "dateFormat";
|
||||
|
||||
// savings product and account parameters
|
||||
public static final String idParamName = "id";
|
||||
public static final String accountNoParamName = "accountNo";
|
||||
public static final String externalIdParamName = "externalId";
|
||||
@@ -29,6 +34,10 @@ public class SavingsApiConstants {
|
||||
public static final String lockinPeriodFrequencyParamName = "lockinPeriodFrequency";
|
||||
public static final String lockinPeriodFrequencyTypeParamName = "lockinPeriodFrequencyType";
|
||||
|
||||
// transaction parameters
|
||||
public static final String transactionDateParamName = "transactionDate";
|
||||
public static final String transactionAmountParamName = "transactionAmount";
|
||||
|
||||
public static final Set<String> SAVINGS_PRODUCT_REQUEST_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(localeParamName,
|
||||
nameParamName, descriptionParamName, currencyCodeParamName, digitsAfterDecimalParamName, interestRateParamName,
|
||||
interestRatePeriodFrequencyTypeParamName, minRequiredOpeningBalanceParamName, lockinPeriodFrequencyParamName,
|
||||
@@ -60,4 +69,10 @@ public class SavingsApiConstants {
|
||||
"savingsProductName", "currency", interestRateParamName, interestRatePeriodFrequencyTypeParamName, "annualInterestRate",
|
||||
minRequiredOpeningBalanceParamName, lockinPeriodFrequencyParamName, lockinPeriodFrequencyTypeParamName, "productOptions",
|
||||
"interestRatePeriodFrequencyTypeOptions", "lockinPeriodFrequencyTypeOptions"));
|
||||
|
||||
public static final Set<String> SAVINGS_ACCOUNT_TRANSACTION_REQUEST_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(
|
||||
localeParamName, dateFormatParamName, transactionDateParamName, transactionAmountParamName));
|
||||
|
||||
public static final Set<String> SAVINGS_TRANSACTION_RESPONSE_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(idParamName,
|
||||
"accountId", accountNoParamName, "currency", "amount"));
|
||||
}
|
||||
+20
-11
@@ -34,6 +34,10 @@ public class SavingsAccountData {
|
||||
private final Integer lockinPeriodFrequency;
|
||||
private final EnumOptionData lockinPeriodFrequencyType;
|
||||
|
||||
// associations
|
||||
private final SavingsAccountSummaryData summary;
|
||||
private final Collection<SavingsAccountTransactionData> transactions;
|
||||
|
||||
// template
|
||||
private final Collection<SavingsProductData> productOptions;
|
||||
private final Collection<EnumOptionData> interestRatePeriodFrequencyTypeOptions;
|
||||
@@ -43,27 +47,28 @@ public class SavingsAccountData {
|
||||
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 EnumOptionData lockinPeriodFrequencyType, final SavingsAccountSummaryData summary) {
|
||||
|
||||
final Collection<SavingsProductData> productOptions = null;
|
||||
final Collection<EnumOptionData> interestRatePeriodFrequencyTypeOptions = null;
|
||||
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions = null;
|
||||
final Collection<SavingsAccountTransactionData> transactions = null;
|
||||
|
||||
return new SavingsAccountData(id, accountNo, externalId, groupId, groupName, clientId, clientName, productId, productName,
|
||||
currency, interestRate, interestRatePeriodFrequencyType, annualInterestRate, minRequiredOpeningBalance,
|
||||
lockinPeriodFrequency, lockinPeriodFrequencyType, productOptions, interestRatePeriodFrequencyTypeOptions,
|
||||
lockinPeriodFrequencyTypeOptions);
|
||||
lockinPeriodFrequency, lockinPeriodFrequencyType, summary, productOptions, interestRatePeriodFrequencyTypeOptions,
|
||||
lockinPeriodFrequencyTypeOptions, transactions);
|
||||
}
|
||||
|
||||
public static SavingsAccountData withTemplateOptions(final SavingsAccountData account,
|
||||
final Collection<SavingsProductData> productOptions, final Collection<EnumOptionData> interestRatePeriodFrequencyTypeOptions,
|
||||
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions) {
|
||||
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions, final Collection<SavingsAccountTransactionData> transactions) {
|
||||
|
||||
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);
|
||||
account.minRequiredOpeningBalance, account.lockinPeriodFrequency, account.lockinPeriodFrequencyType, account.summary,
|
||||
productOptions, interestRatePeriodFrequencyTypeOptions, lockinPeriodFrequencyTypeOptions, transactions);
|
||||
}
|
||||
|
||||
public static SavingsAccountData withClientTemplate(final Long clientId, final String clientName, final Long groupId,
|
||||
@@ -81,24 +86,26 @@ public class SavingsAccountData {
|
||||
final BigDecimal minRequiredOpeningBalance = null;
|
||||
final Integer lockinPeriodFrequency = null;
|
||||
final EnumOptionData lockinPeriodFrequencyType = null;
|
||||
final SavingsAccountSummaryData summary = null;
|
||||
final Collection<SavingsProductData> productOptions = null;
|
||||
final Collection<CurrencyData> currencyOptions = null;
|
||||
final Collection<EnumOptionData> interestRatePeriodFrequencyTypeOptions = null;
|
||||
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions = null;
|
||||
final Collection<SavingsAccountTransactionData> transactions = null;
|
||||
|
||||
return new SavingsAccountData(id, accountNo, externalId, groupId, groupName, clientId, clientName, productId, productName,
|
||||
currency, interestRate, interestRatePeriodFrequencyType, annualInterestRate, minRequiredOpeningBalance,
|
||||
lockinPeriodFrequency, lockinPeriodFrequencyType, productOptions, interestRatePeriodFrequencyTypeOptions,
|
||||
lockinPeriodFrequencyTypeOptions);
|
||||
lockinPeriodFrequency, lockinPeriodFrequencyType, summary, productOptions, interestRatePeriodFrequencyTypeOptions,
|
||||
lockinPeriodFrequencyTypeOptions, transactions);
|
||||
}
|
||||
|
||||
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) {
|
||||
final EnumOptionData lockinPeriodFrequencyType, final SavingsAccountSummaryData summary,
|
||||
final Collection<SavingsProductData> productOptions, final Collection<EnumOptionData> interestRatePeriodFrequencyTypeOptions,
|
||||
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions, final Collection<SavingsAccountTransactionData> transactions) {
|
||||
this.id = id;
|
||||
this.accountNo = accountNo;
|
||||
this.externalId = externalId;
|
||||
@@ -115,9 +122,11 @@ public class SavingsAccountData {
|
||||
this.minRequiredOpeningBalance = minRequiredOpeningBalance;
|
||||
this.lockinPeriodFrequency = lockinPeriodFrequency;
|
||||
this.lockinPeriodFrequencyType = lockinPeriodFrequencyType;
|
||||
this.summary = summary;
|
||||
|
||||
this.productOptions = productOptions;
|
||||
this.interestRatePeriodFrequencyTypeOptions = interestRatePeriodFrequencyTypeOptions;
|
||||
this.lockinPeriodFrequencyTypeOptions = lockinPeriodFrequencyTypeOptions;
|
||||
this.transactions = transactions;
|
||||
}
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
/**
|
||||
* 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 org.mifosplatform.organisation.monetary.data.CurrencyData;
|
||||
|
||||
/**
|
||||
* Immutable data object representing loan summary information.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public class SavingsAccountSummaryData {
|
||||
|
||||
private final CurrencyData currency;
|
||||
private final BigDecimal totalDeposits;
|
||||
private final BigDecimal totalWithdrawals;
|
||||
private final BigDecimal totalInterestPosted;
|
||||
private final BigDecimal accountBalance;
|
||||
|
||||
public SavingsAccountSummaryData(final CurrencyData currency, final BigDecimal totalDeposits, final BigDecimal totalWithdrawals,
|
||||
final BigDecimal totalInterestPosted, final BigDecimal accountBalance) {
|
||||
this.currency = currency;
|
||||
this.totalDeposits = totalDeposits;
|
||||
this.totalWithdrawals = totalWithdrawals;
|
||||
this.totalInterestPosted = totalInterestPosted;
|
||||
this.accountBalance = accountBalance;
|
||||
}
|
||||
}
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
/**
|
||||
* 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 org.joda.time.LocalDate;
|
||||
import org.mifosplatform.organisation.monetary.data.CurrencyData;
|
||||
|
||||
/**
|
||||
* Immutable data object representing a savings account transaction.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public class SavingsAccountTransactionData {
|
||||
|
||||
private final Long id;
|
||||
private final SavingsAccountTransactionEnumData transactionType;
|
||||
private final Long accountId;
|
||||
private final String accountNo;
|
||||
private final LocalDate date;
|
||||
private final CurrencyData currency;
|
||||
private final BigDecimal amount;
|
||||
|
||||
public static SavingsAccountTransactionData create(final Long id, final SavingsAccountTransactionEnumData transactionType,
|
||||
final Long savingsId, final String savingsAccountNo, final LocalDate date, final CurrencyData currency, final BigDecimal amount) {
|
||||
return new SavingsAccountTransactionData(id, transactionType, savingsId, savingsAccountNo, date, currency, amount);
|
||||
}
|
||||
|
||||
public static SavingsAccountTransactionData template(final Long savingsId, final String savingsAccountNo,
|
||||
final LocalDate defaultLocalDate, final CurrencyData currency) {
|
||||
final Long id = null;
|
||||
final SavingsAccountTransactionEnumData transactionType = null;
|
||||
final BigDecimal amount = null;
|
||||
return new SavingsAccountTransactionData(id, transactionType, savingsId, savingsAccountNo, defaultLocalDate, currency, amount);
|
||||
}
|
||||
|
||||
private SavingsAccountTransactionData(final Long id, final SavingsAccountTransactionEnumData transactionType, final Long savingsId,
|
||||
final String savingsAccountNo, final LocalDate date, final CurrencyData currency, final BigDecimal amount) {
|
||||
this.id = id;
|
||||
this.transactionType = transactionType;
|
||||
this.accountId = savingsId;
|
||||
this.accountNo = savingsAccountNo;
|
||||
this.date = date;
|
||||
this.currency = currency;
|
||||
this.amount = amount;
|
||||
}
|
||||
}
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
package org.mifosplatform.portfolio.savings.data;
|
||||
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.transactionAmountParamName;
|
||||
import static org.mifosplatform.portfolio.savings.api.SavingsApiConstants.transactionDateParamName;
|
||||
|
||||
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.joda.time.LocalDate;
|
||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
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 SavingsAccountTransactionDataValidator {
|
||||
|
||||
private final FromJsonHelper fromApiJsonHelper;
|
||||
|
||||
@Autowired
|
||||
public SavingsAccountTransactionDataValidator(final FromJsonHelper fromApiJsonHelper) {
|
||||
this.fromApiJsonHelper = fromApiJsonHelper;
|
||||
}
|
||||
|
||||
public void validate(final JsonCommand command) {
|
||||
|
||||
final String json = command.json();
|
||||
|
||||
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
|
||||
|
||||
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
|
||||
fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json,
|
||||
SavingsApiConstants.SAVINGS_ACCOUNT_TRANSACTION_REQUEST_DATA_PARAMETERS);
|
||||
|
||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
|
||||
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
|
||||
.resource(SavingsApiConstants.SAVINGS_ACCOUNT_TRANSACTION_RESOURCE_NAME);
|
||||
|
||||
final JsonElement element = command.parsedJson();
|
||||
|
||||
final LocalDate transactionDate = fromApiJsonHelper.extractLocalDateNamed(transactionDateParamName, element);
|
||||
baseDataValidator.reset().parameter(transactionDateParamName).value(transactionDate).notNull();
|
||||
|
||||
final BigDecimal transactionAmount = fromApiJsonHelper.extractBigDecimalWithLocaleNamed(transactionAmountParamName, element);
|
||||
baseDataValidator.reset().parameter(transactionAmountParamName).value(transactionAmount).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); }
|
||||
}
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
/**
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Immutable data object represent savings account transaction type
|
||||
* enumerations.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public class SavingsAccountTransactionEnumData {
|
||||
|
||||
private final Long id;
|
||||
private final String code;
|
||||
private final String value;
|
||||
|
||||
public SavingsAccountTransactionEnumData(final Long id, final String code, final String value) {
|
||||
this.id = id;
|
||||
this.code = code;
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
+88
@@ -6,19 +6,28 @@
|
||||
package org.mifosplatform.portfolio.savings.domain;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
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.Transient;
|
||||
import javax.persistence.UniqueConstraint;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.hibernate.annotations.LazyCollection;
|
||||
import org.hibernate.annotations.LazyCollectionOption;
|
||||
import org.joda.time.LocalDate;
|
||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
import org.mifosplatform.infrastructure.core.service.DateUtils;
|
||||
import org.mifosplatform.infrastructure.security.service.RandomPasswordGenerator;
|
||||
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
|
||||
import org.mifosplatform.organisation.monetary.domain.Money;
|
||||
@@ -26,6 +35,8 @@ 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.mifosplatform.portfolio.savings.exception.InsufficientAccountBalanceException;
|
||||
import org.mifosplatform.portfolio.savings.exception.InvalidSavingsAccountTransactionException;
|
||||
import org.springframework.data.jpa.domain.AbstractPersistable;
|
||||
|
||||
@Entity
|
||||
@@ -73,8 +84,18 @@ public class SavingsAccount extends AbstractPersistable<Long> {
|
||||
@Column(name = "lockin_period_frequency_enum", nullable = false)
|
||||
private Integer lockinPeriodFrequencyType;
|
||||
|
||||
@Embedded
|
||||
private SavingsAccountSummary summary;
|
||||
|
||||
@OrderBy(value = "dateOf, id")
|
||||
@LazyCollection(LazyCollectionOption.FALSE)
|
||||
@OneToMany(cascade = CascadeType.ALL, mappedBy = "savingsAccount", orphanRemoval = true)
|
||||
private final List<SavingsAccountTransaction> transactions = new ArrayList<SavingsAccountTransaction>();
|
||||
|
||||
@Transient
|
||||
private boolean accountNumberRequiresAutoGeneration = false;
|
||||
@Transient
|
||||
private SavingsAccountTransactionSummaryWrapper savingsAccountTransactionSummaryWrapper;
|
||||
|
||||
protected SavingsAccount() {
|
||||
//
|
||||
@@ -113,6 +134,73 @@ public class SavingsAccount extends AbstractPersistable<Long> {
|
||||
if (lockinPeriodFrequencyType != null) {
|
||||
this.lockinPeriodFrequencyType = lockinPeriodFrequencyType.getValue();
|
||||
}
|
||||
this.summary = new SavingsAccountSummary();
|
||||
}
|
||||
|
||||
/**
|
||||
* Used after fetching/hydrating a {@link SavingsAccount} object to inject
|
||||
* helper services/components used for update summary details after
|
||||
* events/transactions on a loan.
|
||||
*/
|
||||
public void setHelpers(final SavingsAccountTransactionSummaryWrapper savingsAccountTransactionSummaryWrapper) {
|
||||
this.savingsAccountTransactionSummaryWrapper = savingsAccountTransactionSummaryWrapper;
|
||||
}
|
||||
|
||||
public SavingsAccountTransaction deposit(final LocalDate transactionDate, final BigDecimal transactionAmount) {
|
||||
|
||||
final Money amount = Money.of(this.currency, transactionAmount);
|
||||
|
||||
// FIXME - kw - check transactionDate is not before savings account
|
||||
// activation date.
|
||||
|
||||
if (isTransactionInTheFuture(transactionDate)) {
|
||||
final String defaultUserMessage = "Transaction date cannot be in the future.";
|
||||
throw new InvalidSavingsAccountTransactionException("in.the.future", defaultUserMessage, "transactionDate", transactionDate);
|
||||
}
|
||||
|
||||
final SavingsAccountTransaction transaction = SavingsAccountTransaction.deposit(this, transactionDate, amount);
|
||||
this.transactions.add(transaction);
|
||||
|
||||
this.summary.updateSummary(this.currency, this.savingsAccountTransactionSummaryWrapper, this.transactions);
|
||||
|
||||
return transaction;
|
||||
}
|
||||
|
||||
public SavingsAccountTransaction withdrawal(final LocalDate transactionDate, final BigDecimal transactionAmount) {
|
||||
|
||||
final Money amount = Money.of(this.currency, transactionAmount);
|
||||
|
||||
// FIXME - kw - check transactionDate is not before savings account
|
||||
// activation date.
|
||||
|
||||
if (isTransactionInTheFuture(transactionDate)) {
|
||||
final String defaultUserMessage = "Transaction date cannot be in the future.";
|
||||
throw new InvalidSavingsAccountTransactionException("in.the.future", defaultUserMessage, "transactionDate", transactionDate);
|
||||
}
|
||||
|
||||
if (isNotAllowedToWithdraw(amount)) {
|
||||
//
|
||||
throw new InsufficientAccountBalanceException("transactionAmount", getAccountBalance(), transactionAmount);
|
||||
}
|
||||
|
||||
final SavingsAccountTransaction transaction = SavingsAccountTransaction.withdrawal(this, transactionDate, amount);
|
||||
this.transactions.add(transaction);
|
||||
|
||||
this.summary.updateSummary(this.currency, this.savingsAccountTransactionSummaryWrapper, this.transactions);
|
||||
|
||||
return transaction;
|
||||
}
|
||||
|
||||
private boolean isTransactionInTheFuture(final LocalDate transactionDate) {
|
||||
return transactionDate.isAfter(DateUtils.getLocalDateOfTenant());
|
||||
}
|
||||
|
||||
private BigDecimal getAccountBalance() {
|
||||
return this.summary.getAccountBalance(this.currency).getAmount();
|
||||
}
|
||||
|
||||
private boolean isNotAllowedToWithdraw(final Money amount) {
|
||||
return this.summary.isLessThanOrEqualToAccountBalance(amount);
|
||||
}
|
||||
|
||||
public void update(final JsonCommand command, final Map<String, Object> actualChanges) {
|
||||
|
||||
+9
-3
@@ -32,6 +32,7 @@ import com.google.gson.JsonElement;
|
||||
@Service
|
||||
public class SavingsAccountAssembler {
|
||||
|
||||
private final SavingsAccountTransactionSummaryWrapper savingsAccountTransactionSummaryWrapper;
|
||||
private final ClientRepository clientRepository;
|
||||
private final GroupRepository groupRepository;
|
||||
private final SavingsProductRepository savingProductRepository;
|
||||
@@ -39,9 +40,11 @@ public class SavingsAccountAssembler {
|
||||
private final AprCalculator aprCalculator;
|
||||
|
||||
@Autowired
|
||||
public SavingsAccountAssembler(final ClientRepository clientRepository, final GroupRepository groupRepository,
|
||||
public SavingsAccountAssembler(final SavingsAccountTransactionSummaryWrapper savingsAccountTransactionSummaryWrapper,
|
||||
final ClientRepository clientRepository, final GroupRepository groupRepository,
|
||||
final SavingsProductRepository savingProductRepository, final AprCalculator aprCalculator,
|
||||
final FromJsonHelper fromApiJsonHelper) {
|
||||
this.savingsAccountTransactionSummaryWrapper = savingsAccountTransactionSummaryWrapper;
|
||||
this.clientRepository = clientRepository;
|
||||
this.groupRepository = groupRepository;
|
||||
this.savingProductRepository = savingProductRepository;
|
||||
@@ -106,7 +109,7 @@ public class SavingsAccountAssembler {
|
||||
} else {
|
||||
minRequiredOpeningBalance = product.minRequiredOpeningBalance();
|
||||
}
|
||||
|
||||
|
||||
Integer lockinPeriodFrequency = null;
|
||||
if (command.parameterExists(lockinPeriodFrequencyParamName)) {
|
||||
lockinPeriodFrequency = command.integerValueOfParameterNamed(lockinPeriodFrequencyParamName);
|
||||
@@ -125,8 +128,11 @@ public class SavingsAccountAssembler {
|
||||
lockinPeriodFrequencyType = product.lockinPeriodFrequencyType();
|
||||
}
|
||||
|
||||
return SavingsAccount.createNewAccount(client, group, product, accountNo, externalId, interestRate,
|
||||
final SavingsAccount account = SavingsAccount.createNewAccount(client, group, product, accountNo, externalId, interestRate,
|
||||
interestRatePeriodFrequencyType, annualInterestRate, minRequiredOpeningBalance, lockinPeriodFrequency,
|
||||
lockinPeriodFrequencyType);
|
||||
account.setHelpers(this.savingsAccountTransactionSummaryWrapper);
|
||||
|
||||
return account;
|
||||
}
|
||||
}
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
/**
|
||||
* 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 org.mifosplatform.portfolio.savings.exception.SavingsAccountNotFoundException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Wrapper for {@link SavingsAccountRepository} that is responsible for checking
|
||||
* if {@link SavingsAccount} is returned when using <code>findOne</code>
|
||||
* repository method and throwing an appropriate not found exception.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* This is to avoid need for checking and throwing in multiple areas of code
|
||||
* base where {@link SavingsAccountRepository} is required.
|
||||
* </p>
|
||||
*/
|
||||
@Service
|
||||
public class SavingsAccountRepositoryWrapper {
|
||||
|
||||
private final SavingsAccountRepository repository;
|
||||
private final SavingsAccountTransactionSummaryWrapper savingsAccountTransactionSummaryWrapper;
|
||||
|
||||
@Autowired
|
||||
public SavingsAccountRepositoryWrapper(final SavingsAccountRepository repository,
|
||||
final SavingsAccountTransactionSummaryWrapper savingsAccountTransactionSummaryWrapper) {
|
||||
this.repository = repository;
|
||||
this.savingsAccountTransactionSummaryWrapper = savingsAccountTransactionSummaryWrapper;
|
||||
}
|
||||
|
||||
public SavingsAccount findOneWithNotFoundDetection(final Long savingsId) {
|
||||
final SavingsAccount account = this.repository.findOne(savingsId);
|
||||
if (account == null) { throw new SavingsAccountNotFoundException(savingsId); }
|
||||
|
||||
account.setHelpers(this.savingsAccountTransactionSummaryWrapper);
|
||||
|
||||
return account;
|
||||
}
|
||||
|
||||
public void save(final SavingsAccount account) {
|
||||
this.repository.save(account);
|
||||
}
|
||||
|
||||
public void delete(final SavingsAccount account) {
|
||||
this.repository.delete(account);
|
||||
}
|
||||
|
||||
public void saveAndFlush(final SavingsAccount account) {
|
||||
this.repository.saveAndFlush(account);
|
||||
}
|
||||
}
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
package org.mifosplatform.portfolio.savings.domain;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Embeddable;
|
||||
|
||||
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
|
||||
import org.mifosplatform.organisation.monetary.domain.Money;
|
||||
|
||||
/**
|
||||
* {@link SavingsAccountSummary} encapsulates all the summary details of a
|
||||
* {@link SavingsAccount}.
|
||||
*/
|
||||
@Embeddable
|
||||
public final class SavingsAccountSummary {
|
||||
|
||||
@Column(name = "total_deposits_derived", scale = 6, precision = 19)
|
||||
private BigDecimal totalDeposits;
|
||||
|
||||
@Column(name = "total_withdrawals_derived", scale = 6, precision = 19)
|
||||
private BigDecimal totalWithdrawals;
|
||||
|
||||
@Column(name = "total_interest_posted_derived", scale = 6, precision = 19)
|
||||
private BigDecimal totalInterestPosted;
|
||||
|
||||
@Column(name = "account_balance_derived", scale = 6, precision = 19)
|
||||
private BigDecimal accountBalance = BigDecimal.ZERO;
|
||||
|
||||
protected SavingsAccountSummary() {
|
||||
//
|
||||
}
|
||||
|
||||
public void updateSummary(final MonetaryCurrency currency, final SavingsAccountTransactionSummaryWrapper wrapper,
|
||||
final List<SavingsAccountTransaction> transactions) {
|
||||
|
||||
this.totalDeposits = wrapper.calculateTotalDeposits(currency, transactions);
|
||||
this.totalWithdrawals = wrapper.calculateTotalWithdrawals(currency, transactions);
|
||||
this.totalInterestPosted = wrapper.calculateTotalInterestPosted(currency, transactions);
|
||||
|
||||
this.accountBalance = Money.of(currency, this.totalDeposits).plus(this.totalInterestPosted).minus(this.totalWithdrawals)
|
||||
.getAmount();
|
||||
}
|
||||
|
||||
public boolean isLessThanOrEqualToAccountBalance(final Money amount) {
|
||||
final Money accountBalance = getAccountBalance(amount.getCurrency());
|
||||
return accountBalance.isGreaterThanOrEqualTo(accountBalance);
|
||||
}
|
||||
|
||||
public Money getAccountBalance(final MonetaryCurrency currency) {
|
||||
return Money.of(currency, this.accountBalance);
|
||||
}
|
||||
}
|
||||
+102
@@ -0,0 +1,102 @@
|
||||
/**
|
||||
* 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.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.joda.time.LocalDate;
|
||||
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
|
||||
import org.mifosplatform.organisation.monetary.domain.Money;
|
||||
import org.springframework.data.jpa.domain.AbstractPersistable;
|
||||
|
||||
/**
|
||||
* All monetary transactions against a savings account are modelled through this
|
||||
* entity.
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "m_savings_account_transaction")
|
||||
public final class SavingsAccountTransaction extends AbstractPersistable<Long> {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@ManyToOne(optional = false)
|
||||
@JoinColumn(name = "savings_account_id", nullable = false)
|
||||
private SavingsAccount savingsAccount;
|
||||
|
||||
@Column(name = "transaction_type_enum", nullable = false)
|
||||
private final Integer typeOf;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Temporal(TemporalType.DATE)
|
||||
@Column(name = "transaction_date", nullable = false)
|
||||
private final Date dateOf;
|
||||
|
||||
@Column(name = "amount", scale = 6, precision = 19, nullable = false)
|
||||
private BigDecimal amount;
|
||||
|
||||
@Column(name = "is_reversed", nullable = false)
|
||||
private boolean reversed;
|
||||
|
||||
protected SavingsAccountTransaction() {
|
||||
this.dateOf = null;
|
||||
this.typeOf = null;
|
||||
}
|
||||
|
||||
public static SavingsAccountTransaction deposit(final SavingsAccount savingsAccount, final LocalDate date, final Money amount) {
|
||||
final boolean isReversed = false;
|
||||
return new SavingsAccountTransaction(savingsAccount, SavingsAccountTransactionType.DEPOSIT.getValue(), date, amount, isReversed);
|
||||
}
|
||||
|
||||
public static SavingsAccountTransaction withdrawal(final SavingsAccount savingsAccount, final LocalDate date, final Money amount) {
|
||||
final boolean isReversed = false;
|
||||
return new SavingsAccountTransaction(savingsAccount, SavingsAccountTransactionType.WITHDRAWAL.getValue(), date, amount, isReversed);
|
||||
}
|
||||
|
||||
private SavingsAccountTransaction(final SavingsAccount savingsAccount, final Integer typeOf, final LocalDate dateOf,
|
||||
final Money amount, final boolean isReversed) {
|
||||
this.savingsAccount = savingsAccount;
|
||||
this.typeOf = typeOf;
|
||||
this.dateOf = dateOf.toDate();
|
||||
this.amount = amount.getAmount();
|
||||
this.reversed = isReversed;
|
||||
}
|
||||
|
||||
public void reverse() {
|
||||
this.reversed = true;
|
||||
}
|
||||
|
||||
public Money getAmount(final MonetaryCurrency currency) {
|
||||
return Money.of(currency, this.amount);
|
||||
}
|
||||
|
||||
public boolean isDeposit() {
|
||||
return SavingsAccountTransactionType.fromInt(this.typeOf).isDeposit();
|
||||
}
|
||||
|
||||
public boolean isWithdrawal() {
|
||||
return SavingsAccountTransactionType.fromInt(this.typeOf).isWithdrawal();
|
||||
}
|
||||
|
||||
public boolean isInterestPosting() {
|
||||
return SavingsAccountTransactionType.fromInt(this.typeOf).isInterestPosting();
|
||||
}
|
||||
|
||||
public boolean isNotReversed() {
|
||||
return !isReversed();
|
||||
}
|
||||
|
||||
public boolean isReversed() {
|
||||
return this.reversed;
|
||||
}
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
/**
|
||||
* 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 org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||
|
||||
public interface SavingsAccountTransactionRepository extends JpaRepository<SavingsAccountTransaction, Long>,
|
||||
JpaSpecificationExecutor<SavingsAccountTransaction> {
|
||||
|
||||
}
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
package org.mifosplatform.portfolio.savings.domain;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
|
||||
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
|
||||
import org.mifosplatform.organisation.monetary.domain.Money;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* A wrapper for dealing with side-effect free functionality related to a
|
||||
* {@link SavingsAccount}'s {@link SavingsAccountTransaction}'s.
|
||||
*/
|
||||
@Component
|
||||
public final class SavingsAccountTransactionSummaryWrapper {
|
||||
|
||||
public BigDecimal calculateTotalDeposits(final MonetaryCurrency currency, final List<SavingsAccountTransaction> transactions) {
|
||||
Money total = Money.zero(currency);
|
||||
for (SavingsAccountTransaction transaction : transactions) {
|
||||
if (transaction.isDeposit() && transaction.isNotReversed()) {
|
||||
total = total.plus(transaction.getAmount(currency));
|
||||
}
|
||||
}
|
||||
return total.getAmountDefaultedToNullIfZero();
|
||||
}
|
||||
|
||||
public BigDecimal calculateTotalWithdrawals(final MonetaryCurrency currency, final List<SavingsAccountTransaction> transactions) {
|
||||
Money total = Money.zero(currency);
|
||||
for (SavingsAccountTransaction transaction : transactions) {
|
||||
if (transaction.isWithdrawal() && transaction.isNotReversed()) {
|
||||
total = total.plus(transaction.getAmount(currency));
|
||||
}
|
||||
}
|
||||
return total.getAmountDefaultedToNullIfZero();
|
||||
}
|
||||
|
||||
public BigDecimal calculateTotalInterestPosted(final MonetaryCurrency currency, final List<SavingsAccountTransaction> transactions) {
|
||||
Money total = Money.zero(currency);
|
||||
for (SavingsAccountTransaction transaction : transactions) {
|
||||
if (transaction.isInterestPosting() && transaction.isNotReversed()) {
|
||||
total = total.plus(transaction.getAmount(currency));
|
||||
}
|
||||
}
|
||||
return total.getAmountDefaultedToNullIfZero();
|
||||
}
|
||||
}
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
/**
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* An enumeration of different transactions that can occur on a
|
||||
* {@link SavingsAccount}.
|
||||
*/
|
||||
public enum SavingsAccountTransactionType {
|
||||
|
||||
INVALID(0, "savingsAccountTransactionType.invalid"), //
|
||||
DEPOSIT(1, "savingsAccountTransactionType.deposit"), //
|
||||
WITHDRAWAL(2, "savingsAccountTransactionType.withdrawal"), //
|
||||
INTEREST_POSTING(3, "savingsAccountTransactionType.interestPosting");
|
||||
|
||||
private final Integer value;
|
||||
private final String code;
|
||||
|
||||
private SavingsAccountTransactionType(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 SavingsAccountTransactionType fromInt(final Integer transactionType) {
|
||||
|
||||
if (transactionType == null) { return SavingsAccountTransactionType.INVALID; }
|
||||
|
||||
SavingsAccountTransactionType loanTransactionType = SavingsAccountTransactionType.INVALID;
|
||||
switch (transactionType) {
|
||||
case 1:
|
||||
loanTransactionType = SavingsAccountTransactionType.DEPOSIT;
|
||||
break;
|
||||
case 2:
|
||||
loanTransactionType = SavingsAccountTransactionType.WITHDRAWAL;
|
||||
break;
|
||||
case 3:
|
||||
loanTransactionType = SavingsAccountTransactionType.INTEREST_POSTING;
|
||||
break;
|
||||
}
|
||||
return loanTransactionType;
|
||||
}
|
||||
|
||||
public boolean isDeposit() {
|
||||
return this.value.equals(SavingsAccountTransactionType.DEPOSIT.getValue());
|
||||
}
|
||||
|
||||
public boolean isWithdrawal() {
|
||||
return this.value.equals(SavingsAccountTransactionType.WITHDRAWAL.getValue());
|
||||
}
|
||||
|
||||
public boolean isInterestPosting() {
|
||||
return this.value.equals(SavingsAccountTransactionType.INTEREST_POSTING.getValue());
|
||||
}
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
package org.mifosplatform.portfolio.savings.exception;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import org.mifosplatform.infrastructure.core.exception.AbstractPlatformDomainRuleException;
|
||||
|
||||
/**
|
||||
* Thrown when an attempt is made to withdraw money that is greater than the
|
||||
* account balance.
|
||||
*/
|
||||
public class InsufficientAccountBalanceException extends AbstractPlatformDomainRuleException {
|
||||
|
||||
public InsufficientAccountBalanceException(final String paramName, final BigDecimal accountBalance, final BigDecimal withdrawalRequested) {
|
||||
super("error.msg.savingsaccount.transaction.insufficient.account.balance", "Insufficient account balance.", paramName,
|
||||
accountBalance, withdrawalRequested);
|
||||
}
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
package org.mifosplatform.portfolio.savings.exception;
|
||||
|
||||
import org.mifosplatform.infrastructure.core.exception.AbstractPlatformDomainRuleException;
|
||||
|
||||
/**
|
||||
* Thrown when an attempt is made to withdraw money that is greater than the
|
||||
* account balance.
|
||||
*/
|
||||
public class InvalidSavingsAccountTransactionException extends AbstractPlatformDomainRuleException {
|
||||
|
||||
public InvalidSavingsAccountTransactionException(final String errorCode, final String defaultErrorMessage, final String paramName,
|
||||
final Object... defaultUserMessageArgs) {
|
||||
super("error.msg.savingsaccount.transaction." + errorCode, defaultErrorMessage, paramName, defaultUserMessageArgs);
|
||||
}
|
||||
}
|
||||
+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 DepositSavingsAccountCommandHandler implements NewCommandSourceHandler {
|
||||
|
||||
private final SavingsAccountWritePlatformService savingAccountWritePlatformService;
|
||||
|
||||
@Autowired
|
||||
public DepositSavingsAccountCommandHandler(final SavingsAccountWritePlatformService savingAccountWritePlatformService) {
|
||||
this.savingAccountWritePlatformService = savingAccountWritePlatformService;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult processCommand(final JsonCommand command) {
|
||||
return this.savingAccountWritePlatformService.deposit(command.getLoanId(), command);
|
||||
}
|
||||
}
|
||||
+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 WithdrawSavingsAccountCommandHandler implements NewCommandSourceHandler {
|
||||
|
||||
private final SavingsAccountWritePlatformService savingAccountWritePlatformService;
|
||||
|
||||
@Autowired
|
||||
public WithdrawSavingsAccountCommandHandler(final SavingsAccountWritePlatformService savingAccountWritePlatformService) {
|
||||
this.savingAccountWritePlatformService = savingAccountWritePlatformService;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult processCommand(final JsonCommand command) {
|
||||
return this.savingAccountWritePlatformService.withdrawal(command.getLoanId(), command);
|
||||
}
|
||||
}
|
||||
+6
-1
@@ -8,12 +8,17 @@ package org.mifosplatform.portfolio.savings.service;
|
||||
import java.util.Collection;
|
||||
|
||||
import org.mifosplatform.portfolio.savings.data.SavingsAccountData;
|
||||
import org.mifosplatform.portfolio.savings.data.SavingsAccountTransactionData;
|
||||
|
||||
public interface SavingsAccountReadPlatformService {
|
||||
|
||||
Collection<SavingsAccountData> retrieveAll();
|
||||
|
||||
SavingsAccountData retrieveOne(Long accountId);
|
||||
SavingsAccountData retrieveOne(Long savingsId);
|
||||
|
||||
SavingsAccountData retrieveTemplate(Long clientId, Long groupId, Long productId);
|
||||
|
||||
SavingsAccountTransactionData retrieveDepositTransactionTemplate(Long savingsId);
|
||||
|
||||
Collection<SavingsAccountTransactionData> retrieveAllTransactions(Long savingsId);
|
||||
}
|
||||
+146
-13
@@ -10,8 +10,10 @@ import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Collection;
|
||||
|
||||
import org.joda.time.LocalDate;
|
||||
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
|
||||
import org.mifosplatform.infrastructure.core.domain.JdbcSupport;
|
||||
import org.mifosplatform.infrastructure.core.service.DateUtils;
|
||||
import org.mifosplatform.infrastructure.core.service.TenantAwareRoutingDataSource;
|
||||
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
|
||||
import org.mifosplatform.organisation.monetary.data.CurrencyData;
|
||||
@@ -21,6 +23,9 @@ 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.SavingsAccountSummaryData;
|
||||
import org.mifosplatform.portfolio.savings.data.SavingsAccountTransactionData;
|
||||
import org.mifosplatform.portfolio.savings.data.SavingsAccountTransactionEnumData;
|
||||
import org.mifosplatform.portfolio.savings.data.SavingsProductData;
|
||||
import org.mifosplatform.portfolio.savings.exception.SavingsAccountNotFoundException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -38,6 +43,8 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
|
||||
private final GroupReadPlatformService groupReadPlatformService;
|
||||
private final SavingsProductReadPlatformService savingsProductReadPlatformService;
|
||||
private final SavingsDropdownReadPlatformService dropdownReadPlatformService;
|
||||
private final SavingsAccountTransactionTemplateMapper transactionTemplateMapper;
|
||||
private final SavingsAccountTransactionsMapper transactionsMapper;
|
||||
|
||||
@Autowired
|
||||
public SavingsAccountReadPlatformServiceImpl(final PlatformSecurityContext context, final TenantAwareRoutingDataSource dataSource,
|
||||
@@ -50,6 +57,8 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
|
||||
this.groupReadPlatformService = groupReadPlatformService;
|
||||
this.savingsProductReadPlatformService = savingProductReadPlatformService;
|
||||
this.dropdownReadPlatformService = dropdownReadPlatformService;
|
||||
transactionTemplateMapper = new SavingsAccountTransactionTemplateMapper();
|
||||
transactionsMapper = new SavingsAccountTransactionsMapper();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -59,7 +68,6 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
|
||||
final SavingAccountMapper mapper = new SavingAccountMapper();
|
||||
final String sql = "select " + mapper.schema();
|
||||
return this.jdbcTemplate.query(sql, mapper, new Object[] {});
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -88,14 +96,18 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
|
||||
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("curr.name as currencyName, curr.internationalized_name_code as currencyNameCode, ");
|
||||
sqlBuilder.append("curr.display_symbol as currencyDisplaySymbol, ");
|
||||
sqlBuilder.append("sa.nominal_interest_rate_per_period as interestRate, ");
|
||||
sqlBuilder.append("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("sa.lockin_period_frequency as lockinPeriodFrequency,");
|
||||
sqlBuilder.append("sa.lockin_period_frequency_enum as lockinPeriodFrequencyType, ");
|
||||
sqlBuilder.append("sa.total_deposits_derived as totalDeposits, ");
|
||||
sqlBuilder.append("sa.total_withdrawals_derived as totalWithdrawals, ");
|
||||
sqlBuilder.append("sa.total_interest_posted_derived as totalInterestPosted, ");
|
||||
sqlBuilder.append("sa.account_balance_derived as accountBalance ");
|
||||
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 ");
|
||||
@@ -137,7 +149,7 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
|
||||
.fromInt(JdbcSupport.getInteger(rs, "interestRatePeriodFrequencyType")));
|
||||
final BigDecimal annualInterestRate = rs.getBigDecimal("annualInterestRate");
|
||||
|
||||
final BigDecimal minRequiredOpeningBalance = rs.getBigDecimal("minRequiredOpeningBalance");
|
||||
final BigDecimal minRequiredOpeningBalance = JdbcSupport.getBigDecimalDefaultToNullIfZero(rs, "minRequiredOpeningBalance");
|
||||
|
||||
final Integer lockinPeriodFrequency = JdbcSupport.getInteger(rs, "lockinPeriodFrequency");
|
||||
EnumOptionData lockinPeriodFrequencyType = null;
|
||||
@@ -147,9 +159,17 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
|
||||
.fromInt(lockinPeriodFrequencyTypeValue));
|
||||
}
|
||||
|
||||
final BigDecimal totalDeposits = JdbcSupport.getBigDecimalDefaultToNullIfZero(rs, "totalDeposits");
|
||||
final BigDecimal totalWithdrawals = JdbcSupport.getBigDecimalDefaultToNullIfZero(rs, "totalWithdrawals");
|
||||
final BigDecimal totalInterestPosted = JdbcSupport.getBigDecimalDefaultToNullIfZero(rs, "totalInterestPosted");
|
||||
final BigDecimal accountBalance = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "accountBalance");
|
||||
|
||||
final SavingsAccountSummaryData summary = new SavingsAccountSummaryData(currency, totalDeposits, totalWithdrawals,
|
||||
totalInterestPosted, accountBalance);
|
||||
|
||||
return SavingsAccountData.instance(id, accountNo, externalId, groupId, groupName, clientId, clientName, productId, productName,
|
||||
currency, interestRate, interestRatePeriodFrequencyType, annualInterestRate, minRequiredOpeningBalance,
|
||||
lockinPeriodFrequency, lockinPeriodFrequencyType);
|
||||
lockinPeriodFrequency, lockinPeriodFrequencyType, summary);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -181,9 +201,10 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
|
||||
.retrieveInterestRatePeriodFrequencyTypeOptions();
|
||||
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions = this.dropdownReadPlatformService
|
||||
.retrieveLockinPeriodFrequencyTypeOptions();
|
||||
final Collection<SavingsAccountTransactionData> transactions = null;
|
||||
|
||||
template = SavingsAccountData.withTemplateOptions(template, productOptions, interestRatePeriodFrequencyTypeOptions,
|
||||
lockinPeriodFrequencyTypeOptions);
|
||||
lockinPeriodFrequencyTypeOptions, transactions);
|
||||
} else {
|
||||
|
||||
String clientName = null;
|
||||
@@ -200,13 +221,124 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
|
||||
|
||||
final Collection<EnumOptionData> interestRatePeriodFrequencyTypeOptions = null;
|
||||
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions = null;
|
||||
final Collection<SavingsAccountTransactionData> transactions = null;
|
||||
|
||||
template = SavingsAccountData.withTemplateOptions(template, productOptions, interestRatePeriodFrequencyTypeOptions,
|
||||
lockinPeriodFrequencyTypeOptions);
|
||||
lockinPeriodFrequencyTypeOptions, transactions);
|
||||
}
|
||||
|
||||
return template;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SavingsAccountTransactionData retrieveDepositTransactionTemplate(final Long savingsId) {
|
||||
|
||||
try {
|
||||
this.context.authenticatedUser();
|
||||
|
||||
final String sql = "select " + transactionTemplateMapper.schema() + " where sa.id = ?";
|
||||
|
||||
return this.jdbcTemplate.queryForObject(sql, transactionTemplateMapper, new Object[] { savingsId });
|
||||
} catch (EmptyResultDataAccessException e) {
|
||||
throw new SavingsAccountNotFoundException(savingsId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<SavingsAccountTransactionData> retrieveAllTransactions(final Long savingsId) {
|
||||
|
||||
final String sql = "select " + this.transactionsMapper.schema() + " where sa.id = ?";
|
||||
|
||||
return this.jdbcTemplate.query(sql, this.transactionsMapper, new Object[] { savingsId });
|
||||
}
|
||||
|
||||
private static final class SavingsAccountTransactionsMapper implements RowMapper<SavingsAccountTransactionData> {
|
||||
|
||||
private final String schemaSql;
|
||||
|
||||
public SavingsAccountTransactionsMapper() {
|
||||
|
||||
final StringBuilder sqlBuilder = new StringBuilder(400);
|
||||
sqlBuilder.append("tr.id as transactionId, tr.transaction_type_enum as transactionType, ");
|
||||
sqlBuilder.append("tr.transaction_date as transactionDate, tr.amount as transactionAmount,");
|
||||
sqlBuilder.append("sa.id as savingsId, sa.account_no as accountNo, ");
|
||||
sqlBuilder.append("sa.currency_code as currencyCode, sa.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("from m_savings_account sa ");
|
||||
sqlBuilder.append("join m_savings_account_transaction tr on tr.savings_account_id = sa.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 SavingsAccountTransactionData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {
|
||||
final Long id = rs.getLong("transactionId");
|
||||
final int transactionTypeInt = JdbcSupport.getInteger(rs, "transactionType");
|
||||
final SavingsAccountTransactionEnumData transactionType = SavingsEnumerations.transactionType(transactionTypeInt);
|
||||
|
||||
final LocalDate date = JdbcSupport.getLocalDate(rs, "transactionDate");
|
||||
final BigDecimal amount = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "transactionAmount");
|
||||
|
||||
final Long savingsId = rs.getLong("savingsId");
|
||||
final String accountNo = rs.getString("accountNo");
|
||||
|
||||
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);
|
||||
|
||||
return SavingsAccountTransactionData.create(id, transactionType, savingsId, accountNo, date, currency, amount);
|
||||
}
|
||||
}
|
||||
|
||||
private static final class SavingsAccountTransactionTemplateMapper implements RowMapper<SavingsAccountTransactionData> {
|
||||
|
||||
private final String schemaSql;
|
||||
|
||||
public SavingsAccountTransactionTemplateMapper() {
|
||||
final StringBuilder sqlBuilder = new StringBuilder(400);
|
||||
sqlBuilder.append("sa.id as id, sa.account_no as accountNo, ");
|
||||
sqlBuilder.append("sa.currency_code as currencyCode, sa.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("sa.min_required_opening_balance as minRequiredOpeningBalance ");
|
||||
sqlBuilder.append("from m_savings_account sa ");
|
||||
sqlBuilder.append("join m_currency curr on curr.code = sa.currency_code ");
|
||||
|
||||
this.schemaSql = sqlBuilder.toString();
|
||||
}
|
||||
|
||||
public String schema() {
|
||||
return this.schemaSql;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SavingsAccountTransactionData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {
|
||||
|
||||
final Long savingsId = rs.getLong("id");
|
||||
final String accountNo = rs.getString("accountNo");
|
||||
|
||||
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);
|
||||
|
||||
return SavingsAccountTransactionData.template(savingsId, accountNo, DateUtils.getLocalDateOfTenant(), currency);
|
||||
}
|
||||
}
|
||||
|
||||
private static final class SavingAccountTemplateMapper implements RowMapper<SavingsAccountData> {
|
||||
|
||||
private final ClientData client;
|
||||
@@ -257,7 +389,7 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
|
||||
.fromInt(JdbcSupport.getInteger(rs, "interestRatePeriodFrequencyType")));
|
||||
final BigDecimal annualInterestRate = null;
|
||||
|
||||
final BigDecimal minRequiredOpeningBalance = rs.getBigDecimal("minRequiredOpeningBalance");
|
||||
final BigDecimal minRequiredOpeningBalance = JdbcSupport.getBigDecimalDefaultToNullIfZero(rs, "minRequiredOpeningBalance");
|
||||
|
||||
final Integer lockinPeriodFrequency = JdbcSupport.getInteger(rs, "lockinPeriodFrequency");
|
||||
EnumOptionData lockinPeriodFrequencyType = null;
|
||||
@@ -281,9 +413,10 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
|
||||
groupName = group.getName();
|
||||
}
|
||||
|
||||
final SavingsAccountSummaryData summary = null;
|
||||
return SavingsAccountData.instance(null, null, null, groupId, groupName, clientId, clientName, productId, productName,
|
||||
currency, interestRate, interestRatePeriodFrequencyType, annualInterestRate, minRequiredOpeningBalance,
|
||||
lockinPeriodFrequency, lockinPeriodFrequencyType);
|
||||
lockinPeriodFrequency, lockinPeriodFrequencyType, summary);
|
||||
}
|
||||
}
|
||||
}
|
||||
+4
-4
@@ -14,9 +14,9 @@ public interface SavingsAccountWritePlatformService {
|
||||
|
||||
CommandProcessingResult updateSavingAccount(Long accountId, JsonCommand command);
|
||||
|
||||
CommandProcessingResult deposit(JsonCommand command);
|
||||
|
||||
CommandProcessingResult withdraw(JsonCommand command);
|
||||
|
||||
CommandProcessingResult deleteSavingAccount(Long accountId);
|
||||
|
||||
CommandProcessingResult deposit(Long savingsId, JsonCommand command);
|
||||
|
||||
CommandProcessingResult withdrawal(Long savingsId, JsonCommand command);
|
||||
}
|
||||
+73
-48
@@ -5,9 +5,11 @@
|
||||
*/
|
||||
package org.mifosplatform.portfolio.savings.service;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
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;
|
||||
@@ -23,12 +25,14 @@ 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.data.SavingsAccountTransactionDataValidator;
|
||||
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.SavingsAccountRepositoryWrapper;
|
||||
import org.mifosplatform.portfolio.savings.domain.SavingsAccountTransaction;
|
||||
import org.mifosplatform.portfolio.savings.domain.SavingsAccountTransactionRepository;
|
||||
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;
|
||||
@@ -43,9 +47,11 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
private final static Logger logger = LoggerFactory.getLogger(SavingsAccountWritePlatformServiceJpaRepositoryImpl.class);
|
||||
|
||||
private final PlatformSecurityContext context;
|
||||
private final SavingsAccountRepository savingAccountRepository;
|
||||
private final SavingsAccountRepositoryWrapper savingAccountRepository;
|
||||
private final SavingsAccountTransactionRepository savingsAccountTransactionRepository;
|
||||
private final SavingsAccountAssembler savingAccountAssembler;
|
||||
private final SavingsAccountDataValidator savingsAccountDataValidator;
|
||||
private final SavingsAccountTransactionDataValidator savingsAccountTransactionDataValidator;
|
||||
private final AccountNumberGeneratorFactory accountIdentifierGeneratorFactory;
|
||||
private final ClientRepository clientRepository;
|
||||
private final GroupRepository groupRepository;
|
||||
@@ -53,13 +59,18 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
|
||||
@Autowired
|
||||
public SavingsAccountWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context,
|
||||
final SavingsAccountRepository savingAccountRepository, final SavingsAccountAssembler savingAccountAssembler,
|
||||
final SavingsAccountRepositoryWrapper savingAccountRepository,
|
||||
final SavingsAccountTransactionRepository savingsAccountTransactionRepository,
|
||||
final SavingsAccountAssembler savingAccountAssembler,
|
||||
final SavingsAccountDataValidator savingsAccountDataValidator,
|
||||
final SavingsAccountTransactionDataValidator savingsAccountTransactionDataValidator,
|
||||
final AccountNumberGeneratorFactory accountIdentifierGeneratorFactory, final ClientRepository clientRepository,
|
||||
final GroupRepository groupRepository, final SavingsProductRepository savingsProductRepository) {
|
||||
this.context = context;
|
||||
this.savingAccountRepository = savingAccountRepository;
|
||||
this.savingsAccountTransactionRepository = savingsAccountTransactionRepository;
|
||||
this.savingAccountAssembler = savingAccountAssembler;
|
||||
this.savingsAccountTransactionDataValidator = savingsAccountTransactionDataValidator;
|
||||
this.accountIdentifierGeneratorFactory = accountIdentifierGeneratorFactory;
|
||||
this.savingsAccountDataValidator = savingsAccountDataValidator;
|
||||
this.clientRepository = clientRepository;
|
||||
@@ -136,8 +147,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
|
||||
final Map<String, Object> changes = new LinkedHashMap<String, Object>(20);
|
||||
|
||||
final SavingsAccount account = this.savingAccountRepository.findOne(accountId);
|
||||
if (account == null) { throw new SavingsAccountNotFoundException(accountId); }
|
||||
final SavingsAccount account = this.savingAccountRepository.findOneWithNotFoundDetection(accountId);
|
||||
|
||||
account.update(command, changes);
|
||||
|
||||
@@ -192,54 +202,13 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
}
|
||||
}
|
||||
|
||||
@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); }
|
||||
final SavingsAccount account = this.savingAccountRepository.findOneWithNotFoundDetection(accountId);
|
||||
|
||||
this.savingAccountRepository.delete(account);
|
||||
|
||||
@@ -250,4 +219,60 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
.withGroupId(account.groupId()) //
|
||||
.build();
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult deposit(final Long savingsId, final JsonCommand command) {
|
||||
|
||||
this.context.authenticatedUser();
|
||||
|
||||
this.savingsAccountTransactionDataValidator.validate(command);
|
||||
|
||||
final SavingsAccount account = this.savingAccountRepository.findOneWithNotFoundDetection(savingsId);
|
||||
|
||||
final LocalDate transactionDate = command.localDateValueOfParameterNamed("transactionDate");
|
||||
final BigDecimal transactionAmount = command.bigDecimalValueOfParameterNamed("transactionAmount");
|
||||
|
||||
final SavingsAccountTransaction deposit = account.deposit(transactionDate, transactionAmount);
|
||||
final Long transactionId = saveTransactionToGenerateTransactionId(deposit);
|
||||
|
||||
this.savingAccountRepository.save(account);
|
||||
|
||||
return new CommandProcessingResultBuilder() //
|
||||
.withEntityId(transactionId) //
|
||||
.withOfficeId(account.officeId()) //
|
||||
.withClientId(account.clientId()) //
|
||||
.withGroupId(account.groupId()) //
|
||||
.withSavingsId(savingsId) //
|
||||
.build();
|
||||
}
|
||||
|
||||
private Long saveTransactionToGenerateTransactionId(final SavingsAccountTransaction transaction) {
|
||||
this.savingsAccountTransactionRepository.save(transaction);
|
||||
return transaction.getId();
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult withdrawal(final Long savingsId, final JsonCommand command) {
|
||||
|
||||
this.context.authenticatedUser();
|
||||
|
||||
final SavingsAccount account = this.savingAccountRepository.findOneWithNotFoundDetection(savingsId);
|
||||
|
||||
final LocalDate transactionDate = command.localDateValueOfParameterNamed("transactionDate");
|
||||
final BigDecimal transactionAmount = command.bigDecimalValueOfParameterNamed("transactionAmount");
|
||||
|
||||
final SavingsAccountTransaction withdrawal = account.withdrawal(transactionDate, transactionAmount);
|
||||
final Long transactionId = saveTransactionToGenerateTransactionId(withdrawal);
|
||||
this.savingAccountRepository.save(account);
|
||||
|
||||
return new CommandProcessingResultBuilder() //
|
||||
.withEntityId(transactionId) //
|
||||
.withOfficeId(account.officeId()) //
|
||||
.withClientId(account.clientId()) //
|
||||
.withGroupId(account.groupId()) //
|
||||
.withSavingsId(savingsId) //
|
||||
.build();
|
||||
}
|
||||
}
|
||||
+32
@@ -7,6 +7,8 @@ package org.mifosplatform.portfolio.savings.service;
|
||||
|
||||
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
|
||||
import org.mifosplatform.portfolio.loanproduct.domain.PeriodFrequencyType;
|
||||
import org.mifosplatform.portfolio.savings.data.SavingsAccountTransactionEnumData;
|
||||
import org.mifosplatform.portfolio.savings.domain.SavingsAccountTransactionType;
|
||||
|
||||
public class SavingsEnumerations {
|
||||
|
||||
@@ -71,4 +73,34 @@ public class SavingsEnumerations {
|
||||
}
|
||||
return optionData;
|
||||
}
|
||||
|
||||
public static SavingsAccountTransactionEnumData transactionType(final int transactionType) {
|
||||
return transactionType(SavingsAccountTransactionType.fromInt(transactionType));
|
||||
}
|
||||
|
||||
public static SavingsAccountTransactionEnumData transactionType(final SavingsAccountTransactionType type) {
|
||||
|
||||
SavingsAccountTransactionEnumData optionData = new SavingsAccountTransactionEnumData(SavingsAccountTransactionType.INVALID
|
||||
.getValue().longValue(), SavingsAccountTransactionType.INVALID.getCode(), "Invalid");
|
||||
|
||||
switch (type) {
|
||||
case INVALID:
|
||||
optionData = new SavingsAccountTransactionEnumData(SavingsAccountTransactionType.INVALID.getValue().longValue(),
|
||||
SavingsAccountTransactionType.INVALID.getCode(), "Invalid");
|
||||
break;
|
||||
case DEPOSIT:
|
||||
optionData = new SavingsAccountTransactionEnumData(SavingsAccountTransactionType.DEPOSIT.getValue().longValue(),
|
||||
SavingsAccountTransactionType.DEPOSIT.getCode(), "Deposit");
|
||||
break;
|
||||
case WITHDRAWAL:
|
||||
optionData = new SavingsAccountTransactionEnumData(SavingsAccountTransactionType.WITHDRAWAL.getValue().longValue(),
|
||||
SavingsAccountTransactionType.WITHDRAWAL.getCode(), "Withdrawal");
|
||||
break;
|
||||
case INTEREST_POSTING:
|
||||
optionData = new SavingsAccountTransactionEnumData(SavingsAccountTransactionType.INTEREST_POSTING.getValue().longValue(),
|
||||
SavingsAccountTransactionType.INTEREST_POSTING.getCode(), "Interest posting");
|
||||
break;
|
||||
}
|
||||
return optionData;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user