diff --git a/mifosng-db/patches/06_hugo_specific_client_details.sql b/mifosng-db/patches/06_hugo_specific_client_details.sql new file mode 100644 index 000000000..ff57c362a --- /dev/null +++ b/mifosng-db/patches/06_hugo_specific_client_details.sql @@ -0,0 +1,17 @@ +CREATE TABLE `extra_client_details_hugo_specific` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT, + `client_id` bigint(20) NOT NULL, + `client_dob` date DEFAULT NULL, + `client_address` varchar(60) DEFAULT NULL, + `father_name` varchar(40) DEFAULT NULL, + `nominee` varchar(40) DEFAULT NULL, + `nominee_relationship` varchar(40) DEFAULT NULL, + `nominee_address` varchar(60) DEFAULT NULL, + `crime_no` varchar(40) DEFAULT NULL, + `police_station` varchar(40) DEFAULT NULL, + `other_notes` text, + PRIMARY KEY (`id`), + UNIQUE KEY `client_id` (`client_id`), + KEY `FK_extra_client_details_hugo_specific_1` (`client_id`), + CONSTRAINT `FK_extra_client_details_hugo_specific` FOREIGN KEY (`client_id`) REFERENCES `m_client` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/commands/domain/CommandWrapper.java b/mifosng-provider/src/main/java/org/mifosplatform/commands/domain/CommandWrapper.java index 316c62670..3f54f78e9 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/commands/domain/CommandWrapper.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/commands/domain/CommandWrapper.java @@ -360,4 +360,40 @@ public class CommandWrapper { public boolean isUpdateOfOwnUserDetails(final Long loggedInUserId) { return this.isUserResource() && isUpdate() && loggedInUserId.equals(this.entityId); } + + public boolean isDepositProductResource() { + return this.entityName.equalsIgnoreCase("DEPOSITPRODUCT"); + } + + public boolean isDepositAccountResource() { + return 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 isWithdrawInterest() { + return this.actionName.equalsIgnoreCase("INTEREST") && 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 isWithdrawByApplicant() { + return this.actionName.equalsIgnoreCase("WITHDRAW") && this.entityName.equalsIgnoreCase("DEPOSITACCOUNT"); + } + + public boolean isUndoApprovalOfDepositApplication() { + return this.actionName.equalsIgnoreCase("APPROVALUNDO") && this.entityName.equalsIgnoreCase("DEPOSITACCOUNT"); + } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/commands/service/CommandWrapperBuilder.java b/mifosng-provider/src/main/java/org/mifosplatform/commands/service/CommandWrapperBuilder.java index acc3f3369..923f9d4d0 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/commands/service/CommandWrapperBuilder.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/commands/service/CommandWrapperBuilder.java @@ -665,4 +665,109 @@ public class CommandWrapperBuilder { this.href = "/journalentries/"+transactionId; 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(Long accountId) { + this.actionName = "UPDATE"; + this.entityName = "DEPOSITACCOUNT"; + this.entityId = accountId; + this.href = "/depositaccounts/"+accountId; + return this; + } + + public CommandWrapperBuilder deleteDepositAccount(Long accountId) { + this.actionName = "DELETE"; + this.entityName = "DEPOSITACCOUNT"; + this.entityId = accountId; + this.href = "/depositaccounts/"+accountId; + return this; + } + + public CommandWrapperBuilder approveDepositApplication(Long accountId) { + this.actionName = "APPROVE"; + this.entityName = "DEPOSITACCOUNT"; + this.entityId = accountId; + this.href = "/depositaccounts/"+accountId; + return this; + } + + public CommandWrapperBuilder withdrawDepositAmount(Long accountId) { + this.actionName = "WITHDRAWAL"; + this.entityName = "DEPOSITACCOUNT"; + this.entityId = accountId; + this.href = "/depositaccounts/"+accountId; + return this; + } + + public CommandWrapperBuilder withdrawInterestDepositAmount(Long accountId) { + this.actionName = "INTEREST"; + this.entityName = "DEPOSITACCOUNT"; + this.entityId = accountId; + this.href = "/depositaccounts/"+accountId; + return this; + } + + public CommandWrapperBuilder renewDepositAccount(Long accountId) { + this.actionName = "RENEW"; + this.entityName = "DEPOSITACCOUNT"; + this.entityId = accountId; + this.href = "/depositaccounts/"+accountId; + return this; + } + + public CommandWrapperBuilder rejectDepositAccount(Long accountId) { + this.actionName = "REJECT"; + this.entityName = "DEPOSITACCOUNT"; + this.entityId = accountId; + this.href = "/depositaccounts/"+accountId; + return this; + } + + public CommandWrapperBuilder withdrawDepositApplication(Long accountId) { + this.actionName = "WITHDRAW"; + this.entityName = "DEPOSITACCOUNT"; + this.entityId = accountId; + this.href = "/depositaccounts/"+accountId; + return this; + } + + public CommandWrapperBuilder undoDepositApplicationApproval(Long accountId) { + this.actionName = "APPROVALUNDO"; + this.entityName = "DEPOSITACCOUNT"; + this.entityId = accountId; + this.href = "/depositaccounts/"+accountId; + return this; + } + } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/commands/service/SynchronousCommandProcessingService.java b/mifosng-provider/src/main/java/org/mifosplatform/commands/service/SynchronousCommandProcessingService.java index 3fa5f26cc..678a4eb34 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/commands/service/SynchronousCommandProcessingService.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/commands/service/SynchronousCommandProcessingService.java @@ -336,6 +336,40 @@ 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 { throw new UnsupportedCommandException(wrapper.commandName()); diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/api/SavingsAccountApiResource.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/api/SavingsAccountApiResource.java index b4a2d8408..3e11f7afe 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/api/SavingsAccountApiResource.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/api/SavingsAccountApiResource.java @@ -70,34 +70,16 @@ import org.springframework.stereotype.Component; @Scope("singleton") public class SavingsAccountApiResource { - @Autowired - private SavingAccountWritePlatformService savingAccountWritePlatformService; - - @Autowired - private SavingAccountReadPlatformService savingAccountReadPlatformService; - - @Autowired - private PortfolioApiDataConversionService apiDataConversionService; - - @Autowired - private PortfolioApiJsonSerializerService apiJsonSerializerService; - - @Autowired - private SavingProductReadPlatformService savingProductReadPlatformService; - - @Autowired - private CurrencyReadPlatformService currencyReadPlatformService; - + private final SavingAccountWritePlatformService savingAccountWritePlatformService; + private final SavingAccountReadPlatformService savingAccountReadPlatformService; + private final PortfolioApiDataConversionService apiDataConversionService; + private final PortfolioApiJsonSerializerService apiJsonSerializerService; + private final SavingProductReadPlatformService savingProductReadPlatformService; + private final CurrencyReadPlatformService currencyReadPlatformService; private final String entityType = "SAVINGSACCOUNT"; - - @Autowired - private PlatformSecurityContext context; - - @Autowired - private CalculateSavingSchedule calculateSavingSchedule; - - @Autowired - private ToApiJsonSerializer toApiJsonSerializer; + private final PlatformSecurityContext context; + private final CalculateSavingSchedule calculateSavingSchedule; + private final ToApiJsonSerializer toApiJsonSerializer; private static final Set typicalResponseParameters = new HashSet(Arrays.asList("id", "status", "externalId", "clientId", "clientName", "productId", "productName", "productType", "currencyData", "savingsDepostiAmountPerPeriod", @@ -107,6 +89,26 @@ public class SavingsAccountApiResource { "preClosureAllowed", "preClosureInterestRate", "withdrawnonDate", "rejectedonDate", "closedonDate", "isLockinPeriodAllowed", "lockinPeriod", "lockinPeriodType", "outstandingAmount", "savingScheduleData", "transactions", "interestPostEvery", "interestPostFrequency")); + + @Autowired + public SavingsAccountApiResource(final SavingAccountWritePlatformService savingAccountWritePlatformService, + final SavingAccountReadPlatformService savingAccountReadPlatformService, + final PortfolioApiDataConversionService apiDataConversionService, + final PortfolioApiJsonSerializerService apiJsonSerializerService, + final SavingProductReadPlatformService savingProductReadPlatformService, + final CurrencyReadPlatformService currencyReadPlatformService, + final PlatformSecurityContext context,final CalculateSavingSchedule calculateSavingSchedule, + final ToApiJsonSerializer toApiJsonSerializer) { + this.savingAccountWritePlatformService = savingAccountWritePlatformService; + this.savingAccountReadPlatformService = savingAccountReadPlatformService; + this.apiDataConversionService = apiDataConversionService; + this.apiJsonSerializerService =apiJsonSerializerService; + this.savingProductReadPlatformService = savingProductReadPlatformService; + this.currencyReadPlatformService = currencyReadPlatformService; + this.context = context; + this.calculateSavingSchedule = calculateSavingSchedule; + this.toApiJsonSerializer = toApiJsonSerializer; + } @POST @Consumes({ MediaType.APPLICATION_JSON }) @@ -139,13 +141,13 @@ public class SavingsAccountApiResource { @Path("{accountId}") @Consumes({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON }) - public Response updateSavingAccount(@PathParam("accountId") final Long accountId, final String jsonRequestBody) { + public String updateSavingAccount(@PathParam("accountId") final Long accountId, final String jsonRequestBody) { final SavingAccountCommand command = this.apiDataConversionService.convertJsonToSavingAccountCommand(accountId, jsonRequestBody); CommandProcessingResult entityIdentifier = this.savingAccountWritePlatformService.updateSavingAccount(command); - return Response.ok().entity(entityIdentifier).build(); + return this.toApiJsonSerializer.serialize(entityIdentifier); } @GET @@ -283,38 +285,38 @@ public class SavingsAccountApiResource { @Path("{accountId}") @Consumes({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON }) - public Response savingStateTransitions(@PathParam("accountId") final Long accountId, @QueryParam("command") final String commandParam, + public String savingStateTransitions(@PathParam("accountId") final Long accountId, @QueryParam("command") final String commandParam, final String jsonRequestBody) { - Response response = null; + String response = null; if (is(commandParam, "approve")) { SavingAccountApprovalCommand command = this.apiDataConversionService.convertJsonToSavingApprovalCommand(accountId, jsonRequestBody); CommandProcessingResult identifier = this.savingAccountWritePlatformService.approveSavingAccount(command); - response = Response.ok().entity(identifier).build(); + response = this.toApiJsonSerializer.serialize(identifier); } else if (is(commandParam, "depositmoney")) { SavingAccountDepositCommand command = this.apiDataConversionService.convertJsonToSavingAccountDepositCommand(accountId, jsonRequestBody); CommandProcessingResult identifier = this.savingAccountWritePlatformService.depositMoney(command); - response = Response.ok().entity(identifier).build(); + response = this.toApiJsonSerializer.serialize(identifier); } else if (is(commandParam, "withdraw")) { SavingAccountWithdrawalCommand command = this.apiDataConversionService.convertJsonToSavingAccountWithdrawalCommand(accountId, jsonRequestBody); CommandProcessingResult identifier = this.savingAccountWritePlatformService.withdrawSavingAmount(command); - response = Response.ok().entity(identifier).build(); + response = this.toApiJsonSerializer.serialize(identifier); } else { SavingStateTransitionsCommand command = this.apiDataConversionService.convertJsonToSavingStateTransitionCommand(accountId, jsonRequestBody); if (is(commandParam, "reject")) { CommandProcessingResult identifier = this.savingAccountWritePlatformService.rejectSavingApplication(command); - response = Response.ok().entity(identifier).build(); + response = this.toApiJsonSerializer.serialize(identifier); } else if (is(commandParam, "withdrewbyclient")) { CommandProcessingResult identifier = this.savingAccountWritePlatformService.withdrawSavingApplication(command); - response = Response.ok().entity(identifier).build(); + response =this.toApiJsonSerializer.serialize(identifier); } UndoStateTransitionCommand undoCommand = new UndoStateTransitionCommand(accountId, command.getNote()); if (is(commandParam, "undoapproval")) { CommandProcessingResult identifier = this.savingAccountWritePlatformService.undoSavingAccountApproval(undoCommand); - response = Response.ok().entity(identifier).build(); + response = this.toApiJsonSerializer.serialize(identifier); } } if (response == null) { throw new UnrecognizedQueryParamException("command", commandParam); } @@ -336,11 +338,11 @@ public class SavingsAccountApiResource { @Path("postinterest") @Consumes({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON }) - public Response postInterest() { + public String postInterest() { Collection savingAccounts = this.savingAccountReadPlatformService.retrieveSavingAccountsForLookUp(); CommandProcessingResult entityIdentifier = this.savingAccountWritePlatformService.postInterest(savingAccounts); - return Response.ok().entity(entityIdentifier).build(); + return this.toApiJsonSerializer.serialize(entityIdentifier); } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/service/SavingAccountWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/service/SavingAccountWritePlatformServiceJpaRepositoryImpl.java index 0b721ff81..d5ba8438d 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/service/SavingAccountWritePlatformServiceJpaRepositoryImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/service/SavingAccountWritePlatformServiceJpaRepositoryImpl.java @@ -6,6 +6,8 @@ package org.mifosplatform.portfolio.savingsaccount.service; import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; +import org.mifosplatform.infrastructure.core.data.CommandProcessingResultBuilder; + import java.util.Arrays; import java.util.Collection; import java.util.List; @@ -72,7 +74,9 @@ public class SavingAccountWritePlatformServiceJpaRepositoryImpl implements Savin SavingAccount account = this.savingAccountAssembler.assembleFrom(command); this.savingAccountRepository.save(account); - return new CommandProcessingResult(account.getId()); + return new CommandProcessingResultBuilder() // + .withEntityId(account.getId()) // + .build(); } catch (DataIntegrityViolationException dve) { handleDataIntegrityIssues(command, dve); return new CommandProcessingResult(Long.valueOf(-1)); @@ -93,7 +97,9 @@ public class SavingAccountWritePlatformServiceJpaRepositoryImpl implements Savin this.savingAccountAssembler.assembleFrom(command, account); this.savingAccountRepository.save(account); } - return new CommandProcessingResult(account.getId()); + return new CommandProcessingResultBuilder() // + .withEntityId(account.getId()) // + .build(); } catch (DataIntegrityViolationException dve) { handleDataIntegrityIssues(command, dve); return new CommandProcessingResult(Long.valueOf(-1)); @@ -138,7 +144,9 @@ public class SavingAccountWritePlatformServiceJpaRepositoryImpl implements Savin this.noteRepository.save(note); } - return new CommandProcessingResult(account.getId()); + return new CommandProcessingResultBuilder() // + .withEntityId(account.getId()) // + .build(); } private DepositLifecycleStateMachine defaultDepositLifecycleStateMachine() { @@ -167,7 +175,9 @@ public class SavingAccountWritePlatformServiceJpaRepositoryImpl implements Savin this.noteRepository.save(note); } - return new CommandProcessingResult(account.getId()); + return new CommandProcessingResultBuilder() // + .withEntityId(account.getId()) // + .build(); } @Override @@ -187,7 +197,9 @@ public class SavingAccountWritePlatformServiceJpaRepositoryImpl implements Savin this.noteRepository.save(note); } - return new CommandProcessingResult(account.getId()); + return new CommandProcessingResultBuilder() // + .withEntityId(account.getId()) // + .build(); } @Override @@ -213,7 +225,9 @@ public class SavingAccountWritePlatformServiceJpaRepositoryImpl implements Savin this.noteRepository.save(note); } - return new CommandProcessingResult(account.getId()); + return new CommandProcessingResultBuilder() // + .withEntityId(account.getId()) // + .build(); } @Override @@ -236,7 +250,9 @@ public class SavingAccountWritePlatformServiceJpaRepositoryImpl implements Savin Note note = Note.savingNote(account, noteText); this.noteRepository.save(note); } - return new CommandProcessingResult(account.getId()); + return new CommandProcessingResultBuilder() // + .withEntityId(account.getId()) // + .build(); } @Override @@ -255,7 +271,9 @@ public class SavingAccountWritePlatformServiceJpaRepositoryImpl implements Savin Note note = Note.savingNote(account, noteText); this.noteRepository.save(note); } - return new CommandProcessingResult(account.getId()); + return new CommandProcessingResultBuilder() // + .withEntityId(account.getId()) // + .build(); } @Override @@ -267,7 +285,9 @@ public class SavingAccountWritePlatformServiceJpaRepositoryImpl implements Savin } account.delete(); this.savingAccountRepository.save(account); - return new CommandProcessingResult(accountId); + return new CommandProcessingResultBuilder() // + .withEntityId(account.getId()) // + .build(); } @Override @@ -280,7 +300,9 @@ public class SavingAccountWritePlatformServiceJpaRepositoryImpl implements Savin this.savingAccountAssembler.postInterest(account); this.savingAccountRepository.save(account); } - return new CommandProcessingResult(new Long(savingAccounts.size())); + return new CommandProcessingResultBuilder() // + .withEntityId(Long.valueOf(savingAccounts.size())) // + .build(); } catch (Exception e) { return new CommandProcessingResult(Long.valueOf(-1)); } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/api/SavingProductsApiResource.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/api/SavingProductsApiResource.java index 903d66cb6..14e3e295b 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/api/SavingProductsApiResource.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/api/SavingProductsApiResource.java @@ -21,12 +21,12 @@ import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; import javax.ws.rs.core.UriInfo; import org.mifosplatform.infrastructure.core.api.ApiParameterHelper; import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; import org.mifosplatform.infrastructure.core.data.EnumOptionData; +import org.mifosplatform.infrastructure.core.serialization.DefaultToApiJsonSerializer; import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; import org.mifosplatform.organisation.monetary.data.CurrencyData; import org.mifosplatform.organisation.monetary.service.CurrencyReadPlatformService; @@ -52,46 +52,53 @@ import org.springframework.stereotype.Component; @Scope("singleton") public class SavingProductsApiResource { - @Autowired - private SavingProductReadPlatformService savingProductReadPlatformService; - - @Autowired - private SavingProductWritePlatformService savingProductWritePlatformService; - - @Autowired - private PortfolioApiDataConversionService apiDataConversionService; - - @Autowired - private PortfolioApiJsonSerializerService apiJsonSerializerService; - - @Autowired - private CurrencyReadPlatformService currencyReadPlatformService; - + private final SavingProductReadPlatformService savingProductReadPlatformService; + private final SavingProductWritePlatformService savingProductWritePlatformService; + private final PortfolioApiDataConversionService apiDataConversionService; + private final PortfolioApiJsonSerializerService apiJsonSerializerService; + private final CurrencyReadPlatformService currencyReadPlatformService; private final String entityType = "SAVINGSPRODUCT"; + private final PlatformSecurityContext context; + private final DefaultToApiJsonSerializer toApiJsonSerializer; + @Autowired - private PlatformSecurityContext context; + public SavingProductsApiResource(final SavingProductReadPlatformService savingProductReadPlatformService, + final SavingProductWritePlatformService savingProductWritePlatformService, + final PortfolioApiDataConversionService apiDataConversionService, + final PortfolioApiJsonSerializerService apiJsonSerializerService, + final CurrencyReadPlatformService currencyReadPlatformService, + final PlatformSecurityContext context, + final DefaultToApiJsonSerializer toApiJsonSerializer) { + this.savingProductReadPlatformService = savingProductReadPlatformService; + this.savingProductWritePlatformService = savingProductWritePlatformService; + this.apiDataConversionService = apiDataConversionService; + this.apiJsonSerializerService = apiJsonSerializerService; + this.currencyReadPlatformService = currencyReadPlatformService; + this.context = context; + this.toApiJsonSerializer = toApiJsonSerializer; + } @POST @Consumes({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON }) - public Response createSavingProduct(final String jsonRequestBody) { + public String createSavingProduct(final String jsonRequestBody) { final SavingProductCommand command = this.apiDataConversionService.convertJsonToSavingProductCommand(null, jsonRequestBody); CommandProcessingResult entityIdentifier = this.savingProductWritePlatformService.createSavingProduct(command); - return Response.ok().entity(entityIdentifier).build(); + return this.toApiJsonSerializer.serialize(entityIdentifier); } @PUT @Path("{productId}") @Consumes({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON }) - public Response updateSavingProduct(@PathParam("productId") final Long productId, final String jsonRequestBody) { + public String updateSavingProduct(@PathParam("productId") final Long productId, final String jsonRequestBody) { SavingProductCommand command = this.apiDataConversionService.convertJsonToSavingProductCommand(productId, jsonRequestBody); CommandProcessingResult entityIdentifier = this.savingProductWritePlatformService.updateSavingProduct(command); - return Response.ok().entity(entityIdentifier).build(); + return this.toApiJsonSerializer.serialize(entityIdentifier); } @GET @@ -210,10 +217,10 @@ public class SavingProductsApiResource { @Path("{productId}") @Consumes({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON }) - public Response deleteProduct(@PathParam("productId") final Long productId) { + public String deleteProduct(@PathParam("productId") final Long productId) { this.savingProductWritePlatformService.deleteSavingProduct(productId); - return Response.ok(new CommandProcessingResult(productId)).build(); + return this.toApiJsonSerializer.serialize(productId); } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/service/SavingProductWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/service/SavingProductWritePlatformServiceJpaRepositoryImpl.java index 7c7301631..43f5d684d 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/service/SavingProductWritePlatformServiceJpaRepositoryImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/service/SavingProductWritePlatformServiceJpaRepositoryImpl.java @@ -6,6 +6,7 @@ package org.mifosplatform.portfolio.savingsaccountproduct.service; import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; +import org.mifosplatform.infrastructure.core.data.CommandProcessingResultBuilder; import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency; import org.mifosplatform.portfolio.loanproduct.domain.PeriodFrequencyType; @@ -69,7 +70,9 @@ public class SavingProductWritePlatformServiceJpaRepositoryImpl implements Savin command.getLockinPeriod(), lockinPeriodType); this.savingProductRepository.save(product); - return new CommandProcessingResult(product.getId()); + return new CommandProcessingResultBuilder() // + .withEntityId(product.getId()) // + .build(); } @Transactional @@ -84,7 +87,9 @@ public class SavingProductWritePlatformServiceJpaRepositoryImpl implements Savin if (product == null) { throw new SavingProductNotFoundException(command.getId()); } product.update(command); this.savingProductRepository.save(product); - return new CommandProcessingResult(Long.valueOf(product.getId())); + return new CommandProcessingResultBuilder() // + .withEntityId(product.getId()) // + .build(); } @Transactional @@ -96,7 +101,9 @@ public class SavingProductWritePlatformServiceJpaRepositoryImpl implements Savin if (product == null || product.isDeleted()) { throw new SavingsProductNotFoundException(productId); } product.delete(); this.savingProductRepository.save(product); - return new CommandProcessingResult(Long.valueOf(product.getId())); + return new CommandProcessingResultBuilder() // + .withEntityId(product.getId()) // + .build(); } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/api/DepositAccountsApiResource.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/api/DepositAccountsApiResource.java index 7dd00a911..c803973b3 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/api/DepositAccountsApiResource.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/api/DepositAccountsApiResource.java @@ -28,21 +28,19 @@ import javax.ws.rs.core.Response.ResponseBuilder; import javax.ws.rs.core.UriInfo; import org.apache.commons.lang.StringUtils; +import org.mifosplatform.commands.domain.CommandWrapper; +import org.mifosplatform.commands.service.CommandWrapperBuilder; +import org.mifosplatform.commands.service.PortfolioCommandSourceWritePlatformService; import org.mifosplatform.infrastructure.core.api.ApiParameterHelper; +import org.mifosplatform.infrastructure.core.api.ApiRequestParameterHelper; import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; import org.mifosplatform.infrastructure.core.data.EnumOptionData; import org.mifosplatform.infrastructure.core.exception.UnrecognizedQueryParamException; +import org.mifosplatform.infrastructure.core.serialization.ApiRequestJsonSerializationSettings; +import org.mifosplatform.infrastructure.core.serialization.DefaultToApiJsonSerializer; import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; -import org.mifosplatform.portfolio.loanaccount.command.UndoStateTransitionCommand; import org.mifosplatform.portfolio.loanproduct.domain.PeriodFrequencyType; -import org.mifosplatform.portfolio.savingsaccount.PortfolioApiDataConversionService; -import org.mifosplatform.portfolio.savingsaccount.PortfolioApiJsonSerializerService; import org.mifosplatform.portfolio.savingsaccountproduct.service.SavingsDepositEnumerations; -import org.mifosplatform.portfolio.savingsdepositaccount.command.DepositAccountCommand; -import org.mifosplatform.portfolio.savingsdepositaccount.command.DepositAccountWithdrawInterestCommand; -import org.mifosplatform.portfolio.savingsdepositaccount.command.DepositAccountWithdrawalCommand; -import org.mifosplatform.portfolio.savingsdepositaccount.command.DepositStateTransitionApprovalCommand; -import org.mifosplatform.portfolio.savingsdepositaccount.command.DepositStateTransitionCommand; import org.mifosplatform.portfolio.savingsdepositaccount.data.DepositAccountData; import org.mifosplatform.portfolio.savingsdepositaccount.data.DepositAccountsForLookup; import org.mifosplatform.portfolio.savingsdepositaccount.data.DepositPermissionData; @@ -59,57 +57,72 @@ import org.springframework.stereotype.Component; @Component @Scope("singleton") public class DepositAccountsApiResource { - - @Autowired - private DepositAccountReadPlatformService depositAccountReadPlatformService; - - @Autowired - private DepositProductReadPlatformService depositProductReadPlatformService; - - @Autowired - private DepositAccountWritePlatformService depositAccountWritePlatformService; - - @Autowired - private PortfolioApiDataConversionService apiDataConversionService; - - @Autowired - private PortfolioApiJsonSerializerService apiJsonSerializerService; - - private final String entityType = "DEPOSITACCOUNT"; - @Autowired - private PlatformSecurityContext context; - - private static final Set typicalResponseParameters = new HashSet(Arrays.asList("id", "externalId", "clientId", - "clientName", "productId", "productName", "status", "currency", "deposit", "maturityInterestRate", "tenureInMonths", - "interestCompoundedEvery", "interestCompoundingAllowed", "interestCompoundedEveryPeriodType", "renewalAllowed", - "preClosureAllowed", "preClosureInterestRate", "withdrawnonDate", "rejectedonDate", "closedonDate", "transactions", - "interestPaid", "isInterestWithdrawable", "availableInterestForWithdrawal", "availableWithdrawalAmount", "todaysDate", + + private static final Set SAVINGS_DEPOSIT_ACCOUNT_DATA_PARAMETERS = new HashSet(Arrays.asList("productOptions", + "interestCompoundedEveryPeriodTypeOptions", "id", "externalId", "clientId", "clientName", "productId", "productName", "status", + "currency", "deposit", "maturityInterestRate", "tenureInMonths", "interestCompoundedEvery", + "interestCompoundedEveryPeriodType", "renewalAllowed", "preClosureAllowed", "preClosureInterestRate", "withdrawnonDate", + "rejectedonDate", "closedonDate", "transactions", "permissions", "isInterestWithdrawable", "interestPaid", + "interestCompoundingAllowed", "availableInterestForWithdrawal", "availableWithdrawalAmount", "todaysDate", "isLockinPeriodAllowed", "lockinPeriod", "lockinPeriodType", "printFDdetailsLocation", "availableInterest", "interestPostedAmount", "lastInterestPostedDate", "nextInterestPostedDate", "fatherName", "address", "imageKey")); + private final DepositAccountReadPlatformService depositAccountReadPlatformService; + + private final DepositProductReadPlatformService depositProductReadPlatformService; + + private final DepositAccountWritePlatformService depositAccountWritePlatformService; + + private final String entityType = "DEPOSITACCOUNT"; + + private final PlatformSecurityContext context; + + private final DefaultToApiJsonSerializer toApiJsonSerializer; + + private final ApiRequestParameterHelper apiRequestParameterHelper; + + private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService; + + @Autowired + public DepositAccountsApiResource(final DepositAccountReadPlatformService depositAccountReadPlatformService, + final DepositProductReadPlatformService depositProductReadPlatformService, + final DepositAccountWritePlatformService depositAccountWritePlatformService, + final PlatformSecurityContext context, + final DefaultToApiJsonSerializer toApiJsonSerializer, + final ApiRequestParameterHelper apiRequestParameterHelper, + final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService ) { + this.depositAccountReadPlatformService = depositAccountReadPlatformService; + this.depositProductReadPlatformService = depositProductReadPlatformService; + this.depositAccountWritePlatformService = depositAccountWritePlatformService; + this.context = context; + this.toApiJsonSerializer = toApiJsonSerializer; + this.apiRequestParameterHelper = apiRequestParameterHelper; + this.commandsSourceWritePlatformService = commandsSourceWritePlatformService; + } + @POST @Consumes({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON }) - public Response createDepositAccount(final String jsonRequestBody) { + public String createDepositAccount(final String apiRequestBodyAsJson) { - final DepositAccountCommand command = this.apiDataConversionService.convertJsonToDepositAccountCommand(null, jsonRequestBody); + final CommandWrapper commandRequest = new CommandWrapperBuilder().createDepositAccount().withJson(apiRequestBodyAsJson).build(); + + final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); - CommandProcessingResult entityIdentifier = this.depositAccountWritePlatformService.createDepositAccount(command); - - return Response.ok().entity(entityIdentifier).build(); + return this.toApiJsonSerializer.serialize(result); } @PUT @Path("{accountId}") @Consumes({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON }) - public Response updateDepositAccount(@PathParam("accountId") final Long accountId, final String jsonRequestBody) { + public String updateDepositAccount(@PathParam("accountId") final Long accountId, final String apiRequestBodyAsJson) { - final DepositAccountCommand command = this.apiDataConversionService.convertJsonToDepositAccountCommand(accountId, jsonRequestBody); + final CommandWrapper commandRequest = new CommandWrapperBuilder().updateDepositAccount(accountId).withJson(apiRequestBodyAsJson).build(); + + final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); - CommandProcessingResult entityIdentifier = this.depositAccountWritePlatformService.updateDepositAccount(command); - - return Response.ok().entity(entityIdentifier).build(); + return this.toApiJsonSerializer.serialize(result); } @GET @@ -119,15 +132,11 @@ public class DepositAccountsApiResource { context.authenticatedUser().validateHasReadPermission(entityType); - Set responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters()); - if (responseParameters.isEmpty()) { - responseParameters.addAll(typicalResponseParameters); - } - boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters()); - Collection accounts = this.depositAccountReadPlatformService.retrieveAllDepositAccounts(); - return this.apiJsonSerializerService.serializeDepositAccountDataToJson(prettyPrint, responseParameters, accounts); + final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters()); + + return this.toApiJsonSerializer.serialize(settings, accounts, SAVINGS_DEPOSIT_ACCOUNT_DATA_PARAMETERS); } @GET @@ -137,35 +146,26 @@ public class DepositAccountsApiResource { public String retrieveDepositAccount(@PathParam("accountId") final Long accountId, @Context final UriInfo uriInfo) { context.authenticatedUser().validateHasReadPermission(entityType); - - Set responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters()); - + DepositPermissionData permissions = null; - if (responseParameters.isEmpty()) { - responseParameters.addAll(typicalResponseParameters); - } - boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters()); - DepositAccountData account = this.depositAccountReadPlatformService.retrieveDepositAccount(accountId); + + final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters()); - boolean template = ApiParameterHelper.template(uriInfo.getQueryParameters()); - if (template) { - account = handleTemplateRelatedData(responseParameters, account); + if (settings.isTemplate()) { + account = handleTemplateRelatedData(account); } Set associationParameters = ApiParameterHelper.extractAssociationsForResponseIfProvided(uriInfo.getQueryParameters()); if (!associationParameters.isEmpty()) { if (associationParameters.contains("all")) { - responseParameters.addAll(Arrays.asList("permissions")); - } else { - responseParameters.addAll(associationParameters); + permissions = this.depositAccountReadPlatformService.retrieveDepositAccountsPermissions(account); + account = new DepositAccountData(account, permissions, account.getTransactions()); } - permissions = this.depositAccountReadPlatformService.retrieveDepositAccountsPermissions(account); - account = new DepositAccountData(account, permissions, account.getTransactions()); } - return this.apiJsonSerializerService.serializeDepositAccountDataToJson(prettyPrint, responseParameters, account); + return this.toApiJsonSerializer.serialize(settings, account, SAVINGS_DEPOSIT_ACCOUNT_DATA_PARAMETERS); } @GET @@ -177,33 +177,29 @@ public class DepositAccountsApiResource { context.authenticatedUser().validateHasReadPermission(entityType); - Set responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters()); - if (responseParameters.isEmpty()) { - responseParameters.addAll(typicalResponseParameters); - } - boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters()); - DepositAccountData account = this.depositAccountReadPlatformService.retrieveNewDepositAccountDetails(clientId, productId); - account = handleTemplateRelatedData(responseParameters, account); + account = handleTemplateRelatedData(account); - return this.apiJsonSerializerService.serializeDepositAccountDataToJson(prettyPrint, responseParameters, account); + final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters()); + + return this.toApiJsonSerializer.serialize(settings, account, SAVINGS_DEPOSIT_ACCOUNT_DATA_PARAMETERS); } @DELETE @Path("{accountId}") @Consumes({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON }) - public Response deleteProduct(@PathParam("accountId") final Long accountId) { + public String deleteProduct(@PathParam("accountId") final Long accountId) { - this.depositAccountWritePlatformService.deleteDepositAccount(accountId); + final CommandWrapper commandRequest = new CommandWrapperBuilder().deleteDepositAccount(accountId).build(); + + final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); - return Response.ok(new CommandProcessingResult(accountId)).build(); + return this.toApiJsonSerializer.serialize(result); } - private DepositAccountData handleTemplateRelatedData(final Set responseParameters, final DepositAccountData account) { - - responseParameters.addAll(Arrays.asList("interestCompoundedEveryPeriodTypeOptions", "productOptions")); + private DepositAccountData handleTemplateRelatedData(final DepositAccountData account) { Collection productOptions = depositProductReadPlatformService.retrieveAllDepositProductsForLookup(); @@ -217,52 +213,36 @@ public class DepositAccountsApiResource { @Path("{accountId}") @Consumes({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON }) - public Response SubmitDepositApplication(@PathParam("accountId") final Long accountId, - @QueryParam("command") final String commandParam, final String jsonRequestBody) { - - Response response = null; + public String SubmitDepositApplication(@PathParam("accountId") final Long accountId, + @QueryParam("command") final String commandParam, final String apiRequestBodyAsJson) { + + CommandWrapperBuilder builder = new CommandWrapperBuilder().withJson(apiRequestBodyAsJson); + CommandProcessingResult result = null; if (is(commandParam, "approve")) { - DepositStateTransitionApprovalCommand command = apiDataConversionService.convertJsonToDepositStateTransitionApprovalCommand( - accountId, jsonRequestBody); - CommandProcessingResult identifier = this.depositAccountWritePlatformService.approveDepositApplication(command); - response = Response.ok().entity(identifier).build(); + final CommandWrapper commandRequest = builder.approveDepositApplication(accountId).build(); + result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); } else if (is(commandParam, "withdrawal")) { - DepositAccountWithdrawalCommand command = apiDataConversionService.convertJsonToDepositWithdrawalCommand(accountId, - jsonRequestBody); - CommandProcessingResult identifier = this.depositAccountWritePlatformService.withdrawDepositAccountMoney(command); - response = Response.ok().entity(identifier).build(); + final CommandWrapper commandRequest = builder.withdrawDepositAmount(accountId).build(); + result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); } else if (is(commandParam, "interestwithdraw")) { - DepositAccountWithdrawInterestCommand command = apiDataConversionService.convertJsonToDepositAccountWithdrawInterestCommand( - accountId, jsonRequestBody); - CommandProcessingResult identifier = this.depositAccountWritePlatformService.withdrawDepositAccountInterestMoney(command); - response = Response.ok().entity(identifier).build(); + final CommandWrapper commandRequest = builder.withdrawInterestDepositAmount(accountId).build(); + result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); } else if (is(commandParam, "renew")) { - DepositAccountCommand command = apiDataConversionService.convertJsonToDepositAccountCommand(accountId, jsonRequestBody); - CommandProcessingResult entityIdentifier = this.depositAccountWritePlatformService.renewDepositAccount(command); - return Response.ok().entity(entityIdentifier).build(); - } else { - DepositStateTransitionCommand command = apiDataConversionService.convertJsonToDepositStateTransitionCommand(accountId, - jsonRequestBody); - if (is(commandParam, "reject")) { - CommandProcessingResult identifier = this.depositAccountWritePlatformService.rejectDepositApplication(command); - response = Response.ok().entity(identifier).build(); - } else if (is(commandParam, "withdrewbyclient")) { - CommandProcessingResult identifier = this.depositAccountWritePlatformService.withdrawDepositApplication(command); - response = Response.ok().entity(identifier).build(); - } + final CommandWrapper commandRequest = builder.renewDepositAccount(accountId).build(); + result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); + } else if (is(commandParam, "reject")) { + final CommandWrapper commandRequest = builder.rejectDepositAccount(accountId).build(); + result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); + } else if (is(commandParam, "withdrewbyclient")) { + final CommandWrapper commandRequest = builder.withdrawDepositApplication(accountId).build(); + result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); + } else if (is(commandParam, "undoapproval")) { + final CommandWrapper commandRequest = builder.undoDepositApplicationApproval(accountId).build(); + result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); + } else { throw new UnrecognizedQueryParamException("command", commandParam); } - UndoStateTransitionCommand undoCommand = new UndoStateTransitionCommand(accountId, command.getNote()); - - if (is(commandParam, "undoapproval")) { - CommandProcessingResult identifier = this.depositAccountWritePlatformService.undoDepositApproval(undoCommand); - response = Response.ok().entity(identifier).build(); - } - } - - if (response == null) { throw new UnrecognizedQueryParamException("command", commandParam); } - - return response; + return this.toApiJsonSerializer.serialize(result); } private boolean is(final String commandParam, final String commandValue) { @@ -273,14 +253,15 @@ public class DepositAccountsApiResource { @Path("postinterest") @Consumes({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON }) - public Response postInterest() { + public String postInterest() { Collection accounts = this.depositAccountReadPlatformService.retrieveDepositAccountForLookup(); CommandProcessingResult entityIdentifier = this.depositAccountWritePlatformService.postInterestToDepositAccount(accounts); - return Response.ok().entity(entityIdentifier).build(); + return this.toApiJsonSerializer.serialize(entityIdentifier); } - @GET + @SuppressWarnings("null") + @GET @Path("{accountId}/print") @Consumes({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON }) diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/domain/DepositAccount.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/domain/DepositAccount.java index b8d68ba41..e56509efb 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/domain/DepositAccount.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/domain/DepositAccount.java @@ -8,7 +8,9 @@ package org.mifosplatform.portfolio.savingsdepositaccount.domain; import java.math.BigDecimal; import java.util.ArrayList; import java.util.Date; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; import javax.persistence.CascadeType; import javax.persistence.Column; @@ -30,12 +32,12 @@ import org.hibernate.annotations.LazyCollectionOption; import org.joda.time.Days; import org.joda.time.LocalDate; import org.joda.time.Months; +import org.mifosplatform.infrastructure.core.api.JsonCommand; import org.mifosplatform.infrastructure.core.domain.AbstractAuditableCustom; import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency; import org.mifosplatform.organisation.monetary.domain.Money; import org.mifosplatform.portfolio.client.domain.Client; import org.mifosplatform.portfolio.loanproduct.domain.PeriodFrequencyType; -import org.mifosplatform.portfolio.savingsdepositaccount.command.DepositStateTransitionApprovalCommand; import org.mifosplatform.portfolio.savingsdepositaccount.exception.InvalidDepositStateTransitionException; import org.mifosplatform.portfolio.savingsdepositproduct.domain.DepositProduct; import org.mifosplatform.useradministration.domain.AppUser; @@ -276,31 +278,56 @@ public class DepositAccount extends AbstractAuditableCustom { this.externalId = this.getId() + "_" + this.externalId; } - public void approve(final LocalDate actualCommencementDate, final DepositLifecycleStateMachine depositLifecycleStateMachine, - final DepositStateTransitionApprovalCommand command, final FixedTermDepositInterestCalculator calculator) { + public Map approve(final LocalDate actualCommencementDate, final DepositLifecycleStateMachine depositLifecycleStateMachine, + final JsonCommand command, final FixedTermDepositInterestCalculator calculator) { + + final Map actualChanges = new LinkedHashMap(20); + final String localeAsInput = command.locale(); DepositAccountStatus statusEnum = depositLifecycleStateMachine.transition(DepositAccountEvent.DEPOSIT_APPROVED, DepositAccountStatus.fromInt(this.depositStatus)); this.depositStatus = statusEnum.getValue(); - if (command.getTenureInMonths() != null) { - this.tenureInMonths = command.getTenureInMonths(); + final String tenureInMonthsParamName = "tenureInMonths"; + if (command.isChangeInIntegerParameterNamed(tenureInMonthsParamName, this.tenureInMonths)) { + final Integer newValue = command.integerValueOfParameterNamed(tenureInMonthsParamName); + actualChanges.put(tenureInMonthsParamName, newValue); + actualChanges.put("locale", localeAsInput); + this.tenureInMonths = newValue; } - - if (command.getMaturityInterestRate() != null) { - this.interestRate = command.getMaturityInterestRate(); + + final String maturityInterestRateParamName = "maturityInterestRate"; + if (command.isChangeInBigDecimalParameterNamed(maturityInterestRateParamName, this.interestRate)) { + final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(maturityInterestRateParamName); + actualChanges.put(maturityInterestRateParamName, newValue); + actualChanges.put("locale", localeAsInput); + this.interestRate = newValue; } this.product.validateInterestRateInRange(this.interestRate); - if (command.getDepositAmount() != null) { - this.depositAmount = command.getDepositAmount(); + final String depositParamName = "deposit"; + if (command.isChangeInBigDecimalParameterNamed(depositParamName, this.depositAmount)) { + final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(depositParamName); + actualChanges.put(depositParamName, newValue); + actualChanges.put("locale", localeAsInput); + this.depositAmount = newValue; } this.product.validateDepositInRange(this.depositAmount); + + final String interestCompoundedEveryParamName = "interestCompoundedEvery"; + if (command.isChangeInIntegerParameterNamed(interestCompoundedEveryParamName, this.interestCompoundedEvery)) { + final Integer newValue = command.integerValueOfParameterNamed(interestCompoundedEveryParamName); + actualChanges.put(interestCompoundedEveryParamName, newValue); + actualChanges.put("locale", localeAsInput); + this.interestCompoundedEvery = newValue; + } - this.interestCompoundedEvery = command.getInterestCompoundedEvery(); - - if (command.getInterestCompoundedEveryPeriodType() != null) { - this.interestCompoundedFrequencyType = PeriodFrequencyType.fromInt(command.getInterestCompoundedEveryPeriodType()).getValue(); + final String interestCompoundedEveryPeriodTypeParamName = "interestCompoundedEveryPeriodType"; + if (command.isChangeInIntegerParameterNamed(interestCompoundedEveryPeriodTypeParamName, this.interestCompoundedFrequencyType)) { + final Integer newValue = command.integerValueOfParameterNamed(interestCompoundedEveryPeriodTypeParamName); + actualChanges.put(interestCompoundedEveryPeriodTypeParamName, newValue); + actualChanges.put("locale", localeAsInput); + this.interestCompoundedFrequencyType = PeriodFrequencyType.fromInt(newValue).getValue(); } this.actualCommencementDate = actualCommencementDate.toDate(); @@ -341,6 +368,7 @@ public class DepositAccount extends AbstractAuditableCustom { throw new InvalidDepositStateTransitionException("approval", "cannot.be.a.future.date", errorMessage, getActualCommencementDate()); } + return actualChanges; } public LocalDate getActualCommencementDate() { diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/handler/ApproveDepositAccountCommandHandler.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/handler/ApproveDepositAccountCommandHandler.java new file mode 100644 index 000000000..3a69f04da --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/handler/ApproveDepositAccountCommandHandler.java @@ -0,0 +1,24 @@ +package org.mifosplatform.portfolio.savingsdepositaccount.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.savingsdepositaccount.service.DepositAccountWritePlatformService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class ApproveDepositAccountCommandHandler implements NewCommandSourceHandler { + private final DepositAccountWritePlatformService depositAccountWritePlatformService; + + @Autowired + public ApproveDepositAccountCommandHandler(final DepositAccountWritePlatformService depositAccountWritePlatformService) { + this.depositAccountWritePlatformService = depositAccountWritePlatformService; + } + + @Override + public CommandProcessingResult processCommand(JsonCommand command) { + return this.depositAccountWritePlatformService.approveDepositApplication(command); + } + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/handler/CreateDepositAccountCommandHandler.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/handler/CreateDepositAccountCommandHandler.java new file mode 100644 index 000000000..1d6401e6d --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/handler/CreateDepositAccountCommandHandler.java @@ -0,0 +1,25 @@ +package org.mifosplatform.portfolio.savingsdepositaccount.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.savingsdepositaccount.service.DepositAccountWritePlatformService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class CreateDepositAccountCommandHandler implements NewCommandSourceHandler { + + private final DepositAccountWritePlatformService depositAccountWritePlatformService; + + @Autowired + public CreateDepositAccountCommandHandler(final DepositAccountWritePlatformService depositAccountWritePlatformService) { + this.depositAccountWritePlatformService = depositAccountWritePlatformService; + } + + @Override + public CommandProcessingResult processCommand(JsonCommand command) { + return this.depositAccountWritePlatformService.createDepositAccount(command); + } + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/handler/DeleteDepositAccountCommandHandler.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/handler/DeleteDepositAccountCommandHandler.java new file mode 100644 index 000000000..2205e9ebb --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/handler/DeleteDepositAccountCommandHandler.java @@ -0,0 +1,26 @@ +package org.mifosplatform.portfolio.savingsdepositaccount.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.savingsdepositaccount.service.DepositAccountWritePlatformService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class DeleteDepositAccountCommandHandler implements NewCommandSourceHandler { + + private final DepositAccountWritePlatformService depositAccountWritePlatformService; + + @Autowired + public DeleteDepositAccountCommandHandler(final DepositAccountWritePlatformService depositAccountWritePlatformService) { + this.depositAccountWritePlatformService = depositAccountWritePlatformService; + } + + @Override + public CommandProcessingResult processCommand(JsonCommand command) { + return this.depositAccountWritePlatformService.deleteDepositAccount(command.entityId()); + } + + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/handler/RejectDepositAccountCommandHandler.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/handler/RejectDepositAccountCommandHandler.java new file mode 100644 index 000000000..bebe4e1a9 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/handler/RejectDepositAccountCommandHandler.java @@ -0,0 +1,25 @@ +package org.mifosplatform.portfolio.savingsdepositaccount.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.savingsdepositaccount.service.DepositAccountWritePlatformService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class RejectDepositAccountCommandHandler implements NewCommandSourceHandler { + + private final DepositAccountWritePlatformService depositAccountWritePlatformService; + + @Autowired + public RejectDepositAccountCommandHandler(final DepositAccountWritePlatformService depositAccountWritePlatformService) { + this.depositAccountWritePlatformService = depositAccountWritePlatformService; + } + + @Override + public CommandProcessingResult processCommand(JsonCommand command) { + return this.depositAccountWritePlatformService.rejectDepositApplication(command); + } + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/handler/RenewDepositAccountCommandHandler.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/handler/RenewDepositAccountCommandHandler.java new file mode 100644 index 000000000..766385118 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/handler/RenewDepositAccountCommandHandler.java @@ -0,0 +1,26 @@ +package org.mifosplatform.portfolio.savingsdepositaccount.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.savingsdepositaccount.service.DepositAccountWritePlatformService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class RenewDepositAccountCommandHandler implements NewCommandSourceHandler { + + private final DepositAccountWritePlatformService depositAccountWritePlatformService; + + @Autowired + public RenewDepositAccountCommandHandler(final DepositAccountWritePlatformService depositAccountWritePlatformService) { + this.depositAccountWritePlatformService = depositAccountWritePlatformService; + } + + + @Override + public CommandProcessingResult processCommand(JsonCommand command) { + return this.depositAccountWritePlatformService.renewDepositAccount(command); + } + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/handler/UndoApprovalDepositAccountCommandHandler.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/handler/UndoApprovalDepositAccountCommandHandler.java new file mode 100644 index 000000000..8eb0cc2be --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/handler/UndoApprovalDepositAccountCommandHandler.java @@ -0,0 +1,25 @@ +package org.mifosplatform.portfolio.savingsdepositaccount.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.savingsdepositaccount.service.DepositAccountWritePlatformService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class UndoApprovalDepositAccountCommandHandler implements NewCommandSourceHandler { + + private final DepositAccountWritePlatformService depositAccountWritePlatformService; + + @Autowired + public UndoApprovalDepositAccountCommandHandler(final DepositAccountWritePlatformService depositAccountWritePlatformService) { + this.depositAccountWritePlatformService = depositAccountWritePlatformService; + } + + @Override + public CommandProcessingResult processCommand(JsonCommand command) { + return this.depositAccountWritePlatformService.undoDepositApproval(command); + } + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/handler/UpdateDepositAccountCommandHandler.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/handler/UpdateDepositAccountCommandHandler.java new file mode 100644 index 000000000..83f026786 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/handler/UpdateDepositAccountCommandHandler.java @@ -0,0 +1,26 @@ +package org.mifosplatform.portfolio.savingsdepositaccount.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.savingsdepositaccount.service.DepositAccountWritePlatformService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class UpdateDepositAccountCommandHandler implements NewCommandSourceHandler { + + private final DepositAccountWritePlatformService depositAccountWritePlatformService; + + @Autowired + public UpdateDepositAccountCommandHandler(final DepositAccountWritePlatformService depositAccountWritePlatformService) { + this.depositAccountWritePlatformService = depositAccountWritePlatformService; + } + + @Override + public CommandProcessingResult processCommand(JsonCommand command) { + return this.depositAccountWritePlatformService.updateDepositAccount(command.entityId(), command); + } + + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/handler/WithDrawByApplicantDepositAccountCommandHandler.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/handler/WithDrawByApplicantDepositAccountCommandHandler.java new file mode 100644 index 000000000..94f0e8a00 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/handler/WithDrawByApplicantDepositAccountCommandHandler.java @@ -0,0 +1,26 @@ +package org.mifosplatform.portfolio.savingsdepositaccount.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.savingsdepositaccount.service.DepositAccountWritePlatformService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class WithDrawByApplicantDepositAccountCommandHandler implements NewCommandSourceHandler { + + private final DepositAccountWritePlatformService depositAccountWritePlatformService; + + @Autowired + public WithDrawByApplicantDepositAccountCommandHandler(final DepositAccountWritePlatformService depositAccountWritePlatformService) { + this.depositAccountWritePlatformService = depositAccountWritePlatformService; + } + + + @Override + public CommandProcessingResult processCommand(JsonCommand command) { + return this.depositAccountWritePlatformService.withdrawDepositApplication(command); + } + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/handler/WithdrawDepositAccountAmountCommandHandler.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/handler/WithdrawDepositAccountAmountCommandHandler.java new file mode 100644 index 000000000..3fb272d96 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/handler/WithdrawDepositAccountAmountCommandHandler.java @@ -0,0 +1,27 @@ +package org.mifosplatform.portfolio.savingsdepositaccount.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.savingsdepositaccount.service.DepositAccountWritePlatformService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class WithdrawDepositAccountAmountCommandHandler implements NewCommandSourceHandler { + + private final DepositAccountWritePlatformService depositAccountWritePlatformService; + + @Autowired + public WithdrawDepositAccountAmountCommandHandler(final DepositAccountWritePlatformService depositAccountWritePlatformService) { + this.depositAccountWritePlatformService = depositAccountWritePlatformService; + } + + + @Override + public CommandProcessingResult processCommand(JsonCommand command) { + return this.depositAccountWritePlatformService.withdrawDepositAccountMoney(command); + } + + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/handler/WithdrawInterestDepositAccountAmountCommandHandler.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/handler/WithdrawInterestDepositAccountAmountCommandHandler.java new file mode 100644 index 000000000..bd84c0cb7 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/handler/WithdrawInterestDepositAccountAmountCommandHandler.java @@ -0,0 +1,26 @@ +package org.mifosplatform.portfolio.savingsdepositaccount.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.savingsdepositaccount.service.DepositAccountWritePlatformService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class WithdrawInterestDepositAccountAmountCommandHandler implements NewCommandSourceHandler { + + private final DepositAccountWritePlatformService depositAccountWritePlatformService; + + @Autowired + public WithdrawInterestDepositAccountAmountCommandHandler(final DepositAccountWritePlatformService depositAccountWritePlatformService) { + this.depositAccountWritePlatformService = depositAccountWritePlatformService; + } + + + @Override + public CommandProcessingResult processCommand(JsonCommand command) { + return this.depositAccountWritePlatformService.withdrawDepositAccountInterestMoney(command); + } + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/serialization/DepositAccountCommandFromApiJsonDeserializer.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/serialization/DepositAccountCommandFromApiJsonDeserializer.java new file mode 100644 index 000000000..97464643a --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/serialization/DepositAccountCommandFromApiJsonDeserializer.java @@ -0,0 +1,247 @@ +package org.mifosplatform.portfolio.savingsdepositaccount.serialization; + +import java.lang.reflect.Type; +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Set; + +import org.apache.commons.lang.StringUtils; +import org.joda.time.LocalDate; +import org.mifosplatform.infrastructure.core.data.ApiParameterError; +import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder; +import org.mifosplatform.infrastructure.core.exception.InvalidJsonException; +import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException; +import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.google.gson.JsonElement; +import com.google.gson.reflect.TypeToken; + +@Component +public class DepositAccountCommandFromApiJsonDeserializer { + + /** + * The parameters supported for this command. + */ + + private final Set supportedParams = new HashSet(Arrays.asList("clientId", "productId", "externalId", "deposit", + "maturityInterestRate", "preClosureInterestRate", "tenureInMonths", "interestCompoundedEvery", + "interestCompoundedEveryPeriodType", "commencementDate", "renewalAllowed", "preClosureAllowed", + "interestCompoundingAllowed", "locale", "dateFormat", "isInterestWithdrawable", "isLockinPeriodAllowed", "lockinPeriod", + "lockinPeriodType","note")); + + private final FromJsonHelper fromApiJsonHelper; + + @Autowired + public DepositAccountCommandFromApiJsonDeserializer(final FromJsonHelper fromApiJsonHelper) { + this.fromApiJsonHelper = fromApiJsonHelper; + } + + public void validateForCreate(final String json) { + + if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); } + + final Type typeOfMap = new TypeToken>() {}.getType(); + fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParams); + + List dataValidationErrors = new ArrayList(); + DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("deposit.account"); + final JsonElement element = fromApiJsonHelper.parse(json); + + final Long clientId = fromApiJsonHelper.extractLongNamed("clientId", element); + baseDataValidator.reset().parameter("clientId").value(clientId).notNull(); + + final Long productId = fromApiJsonHelper.extractLongNamed("productId", element); + baseDataValidator.reset().parameter("productId").value(productId).notNull(); + + final String externalId = fromApiJsonHelper.extractStringNamed("externalId", element); + baseDataValidator.reset().parameter("externalId").value(externalId).ignoreIfNull().notExceedingLengthOf(100); + + final BigDecimal deposit = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("deposit", element); + baseDataValidator.reset().parameter("deposit").value(deposit).notNull().zeroOrPositiveAmount(); + + final Integer tenureInMonths = fromApiJsonHelper.extractIntegerNamed("tenureInMonths", element, Locale.getDefault()); + baseDataValidator.reset().parameter("tenureInMonths").value(tenureInMonths).notNull().zeroOrPositiveAmount(); + + final BigDecimal maturityInterestRate = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("maturityInterestRate", element); + baseDataValidator.reset().parameter("maturityInterestRate").value(maturityInterestRate).notNull().zeroOrPositiveAmount(); + + final Integer interestCompoundedEvery = fromApiJsonHelper.extractIntegerNamed("interestCompoundedEvery", element, Locale.getDefault()); + baseDataValidator.reset().parameter("interestCompoundedEvery").value(interestCompoundedEvery).notNull().zeroOrPositiveAmount(); + + final Integer interestCompoundedEveryPeriodType = fromApiJsonHelper.extractIntegerNamed("interestCompoundedEveryPeriodType", element, Locale.getDefault()); + baseDataValidator.reset().parameter("interestCompoundedEveryPeriodType").value(interestCompoundedEveryPeriodType).notNull().inMinMaxRange(1, 3); + + final BigDecimal preClosureInterestRate = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("preClosureInterestRate", element); + baseDataValidator.reset().parameter("preClosureInterestRate").value(preClosureInterestRate).notNull().zeroOrPositiveAmount(); + + final LocalDate commencementDate = fromApiJsonHelper.extractLocalDateNamed("commencementDate", element); + baseDataValidator.reset().parameter("commencementDate").value(commencementDate).notNull(); + + final Boolean isInterestWithdrawable = fromApiJsonHelper.extractBooleanNamed("isInterestWithdrawable", element); + final Boolean isInterestWithdrawableChanged = isBooleanValueUpdated(isInterestWithdrawable); + baseDataValidator.reset().parameter("isInterestWithdrawable").trueOrFalseRequired(isInterestWithdrawableChanged); + + final Integer lockinPeriod = fromApiJsonHelper.extractIntegerNamed("lockinPeriod", element, Locale.getDefault()); + baseDataValidator.reset().parameter("lockinPeriod").value(lockinPeriod).ignoreIfNull().zeroOrPositiveAmount(); + + final Integer lockinPeriodType = fromApiJsonHelper.extractIntegerNamed("lockinPeriodType", element, Locale.getDefault()); + baseDataValidator.reset().parameter("lockinPeriodType").value(lockinPeriodType).ignoreIfNull().inMinMaxRange(1, 3); + + throwExceptionIfValidationWarningsExist(dataValidationErrors); + + } + + private void throwExceptionIfValidationWarningsExist(final List dataValidationErrors) { + if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", + "Validation errors exist.", dataValidationErrors); } + } + + private Boolean isBooleanValueUpdated(Boolean actualValue) { + Boolean isUpdated = false; + if(actualValue != null){ + isUpdated = true; + } + return isUpdated; + } + + public void validateForApprove(String json) { + + if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); } + + final Type typeOfMap = new TypeToken>() {}.getType(); + fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParams); + + List dataValidationErrors = new ArrayList(); + DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("deposit.account"); + final JsonElement element = fromApiJsonHelper.parse(json); + + final LocalDate commencementDate = fromApiJsonHelper.extractLocalDateNamed("commencementDate", element); + baseDataValidator.reset().parameter("commencementDate").value(commencementDate).notNull(); + + final BigDecimal deposit = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("deposit", element); + baseDataValidator.reset().parameter("deposit").value(deposit).ignoreIfNull().zeroOrPositiveAmount(); + + final BigDecimal maturityInterestRate = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("maturityInterestRate", element); + baseDataValidator.reset().parameter("maturityInterestRate").value(maturityInterestRate).ignoreIfNull().zeroOrPositiveAmount(); + + final Integer tenureInMonths = fromApiJsonHelper.extractIntegerNamed("tenureInMonths", element, Locale.getDefault()); + baseDataValidator.reset().parameter("tenureInMonths").value(tenureInMonths).ignoreIfNull().integerGreaterThanZero(); + + final Integer interestCompoundedEveryPeriodType = fromApiJsonHelper.extractIntegerNamed("interestCompoundedEveryPeriodType", element, Locale.getDefault()); + baseDataValidator.reset().parameter("interestCompoundedEveryPeriodType").value(interestCompoundedEveryPeriodType).ignoreIfNull().inMinMaxRange(2, 2); + + throwExceptionIfValidationWarningsExist(dataValidationErrors); + } + + public void validateForRenew(String json) { + + if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); } + + final Type typeOfMap = new TypeToken>() {}.getType(); + fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParams); + + List dataValidationErrors = new ArrayList(); + DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("deposit.account"); + final JsonElement element = fromApiJsonHelper.parse(json); + + final Long clientId = fromApiJsonHelper.extractLongNamed("clientId", element); + baseDataValidator.reset().parameter("clientId").value(clientId).ignoreIfNull(); + + final Long productId = fromApiJsonHelper.extractLongNamed("productId", element); + baseDataValidator.reset().parameter("productId").value(productId).ignoreIfNull(); + + final String externalId = fromApiJsonHelper.extractStringNamed("externalId", element); + baseDataValidator.reset().parameter("externalId").value(externalId).ignoreIfNull().notExceedingLengthOf(100); + + final BigDecimal deposit = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("deposit", element); + baseDataValidator.reset().parameter("deposit").value(deposit).ignoreIfNull().zeroOrPositiveAmount(); + + final BigDecimal maturityInterestRate = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("maturityInterestRate", element); + baseDataValidator.reset().parameter("maturityInterestRate").value(maturityInterestRate).ignoreIfNull() + .zeroOrPositiveAmount(); + + final BigDecimal preClosureInterestRate = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("preClosureInterestRate", element); + baseDataValidator.reset().parameter("preClosureInterestRate").value(preClosureInterestRate).ignoreIfNull() + .zeroOrPositiveAmount(); + + final Integer tenureInMonths = fromApiJsonHelper.extractIntegerNamed("tenureInMonths", element, Locale.getDefault()); + baseDataValidator.reset().parameter("tenureInMonths").value(tenureInMonths).ignoreIfNull().integerGreaterThanZero(); + + final Integer interestCompoundedEvery = fromApiJsonHelper.extractIntegerNamed("interestCompoundedEvery", element, Locale.getDefault()); + baseDataValidator.reset().parameter("interestCompoundedEvery").value(interestCompoundedEvery).ignoreIfNull() + .integerGreaterThanZero(); + + final Integer interestCompoundedEveryPeriodType = fromApiJsonHelper.extractIntegerNamed("interestCompoundedEveryPeriodType", element, Locale.getDefault()); + baseDataValidator.reset().parameter("interestCompoundedEveryPeriodType").value(interestCompoundedEveryPeriodType) + .ignoreIfNull().inMinMaxRange(2, 2); + + final LocalDate commencementDate = fromApiJsonHelper.extractLocalDateNamed("commencementDate", element); + baseDataValidator.reset().parameter("commencementDate").value(commencementDate).ignoreIfNull(); + + throwExceptionIfValidationWarningsExist(dataValidationErrors); + + } + + public void validateForUpdate(String json) { + + if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); } + + final Type typeOfMap = new TypeToken>() {}.getType(); + fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParams); + + List dataValidationErrors = new ArrayList(); + DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("deposit.account"); + final JsonElement element = fromApiJsonHelper.parse(json); + + final Long clientId = fromApiJsonHelper.extractLongNamed("clientId", element); + baseDataValidator.reset().parameter("clientId").value(clientId).ignoreIfNull(); + + final Long productId = fromApiJsonHelper.extractLongNamed("productId", element); + baseDataValidator.reset().parameter("productId").value(productId).ignoreIfNull(); + + final String externalId = fromApiJsonHelper.extractStringNamed("externalId", element); + baseDataValidator.reset().parameter("externalId").value(externalId).ignoreIfNull().notExceedingLengthOf(100); + + final BigDecimal deposit = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("deposit", element); + baseDataValidator.reset().parameter("deposit").value(deposit).ignoreIfNull().zeroOrPositiveAmount(); + + final Integer tenureInMonths = fromApiJsonHelper.extractIntegerNamed("tenureInMonths", element, Locale.getDefault()); + baseDataValidator.reset().parameter("tenureInMonths").value(tenureInMonths).ignoreIfNull().zeroOrPositiveAmount(); + + final BigDecimal maturityInterestRate = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("maturityInterestRate", element); + baseDataValidator.reset().parameter("maturityInterestRate").value(maturityInterestRate).ignoreIfNull().zeroOrPositiveAmount(); + + final Integer interestCompoundedEvery = fromApiJsonHelper.extractIntegerNamed("interestCompoundedEvery", element, Locale.getDefault()); + baseDataValidator.reset().parameter("interestCompoundedEvery").value(interestCompoundedEvery).ignoreIfNull().zeroOrPositiveAmount(); + + final Integer interestCompoundedEveryPeriodType = fromApiJsonHelper.extractIntegerNamed("interestCompoundedEveryPeriodType", element, Locale.getDefault()); + baseDataValidator.reset().parameter("interestCompoundedEveryPeriodType").value(interestCompoundedEveryPeriodType).ignoreIfNull().inMinMaxRange(1, 3); + + final BigDecimal preClosureInterestRate = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("preClosureInterestRate", element); + baseDataValidator.reset().parameter("preClosureInterestRate").value(preClosureInterestRate).ignoreIfNull().zeroOrPositiveAmount(); + + final LocalDate commencementDate = fromApiJsonHelper.extractLocalDateNamed("commencementDate", element); + baseDataValidator.reset().parameter("commencementDate").value(commencementDate).ignoreIfNull(); + + final Boolean isInterestWithdrawable = fromApiJsonHelper.extractBooleanNamed("isInterestWithdrawable", element); + final Boolean isInterestWithdrawableChanged = isBooleanValueUpdated(isInterestWithdrawable); + baseDataValidator.reset().parameter("isInterestWithdrawable").trueOrFalseRequired(isInterestWithdrawableChanged); + + final Integer lockinPeriod = fromApiJsonHelper.extractIntegerNamed("lockinPeriod", element, Locale.getDefault()); + baseDataValidator.reset().parameter("lockinPeriod").value(lockinPeriod).ignoreIfNull().zeroOrPositiveAmount(); + + final Integer lockinPeriodType = fromApiJsonHelper.extractIntegerNamed("lockinPeriodType", element, Locale.getDefault()); + baseDataValidator.reset().parameter("lockinPeriodType").value(lockinPeriodType).ignoreIfNull().inMinMaxRange(1, 3); + + throwExceptionIfValidationWarningsExist(dataValidationErrors); + + } + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/serialization/DepositAccountStateTransitionCommandFromApiJsonDeserializer.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/serialization/DepositAccountStateTransitionCommandFromApiJsonDeserializer.java new file mode 100644 index 000000000..74b130044 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/serialization/DepositAccountStateTransitionCommandFromApiJsonDeserializer.java @@ -0,0 +1,115 @@ +package org.mifosplatform.portfolio.savingsdepositaccount.serialization; + +import java.lang.reflect.Type; +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.apache.commons.lang.StringUtils; +import org.joda.time.LocalDate; +import org.mifosplatform.infrastructure.core.data.ApiParameterError; +import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder; +import org.mifosplatform.infrastructure.core.exception.InvalidJsonException; +import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException; +import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.google.gson.JsonElement; +import com.google.gson.reflect.TypeToken; + +@Component +public class DepositAccountStateTransitionCommandFromApiJsonDeserializer { + + /** + * The parameters supported for this command. + */ + + private final Set supportedParams = new HashSet(Arrays.asList("eventDate", "locale", "dateFormat", "note", "maturesOnDate", "amount" )); + + private final FromJsonHelper fromApiJsonHelper; + + @Autowired + public DepositAccountStateTransitionCommandFromApiJsonDeserializer(final FromJsonHelper fromApiJsonHelper) { + this.fromApiJsonHelper = fromApiJsonHelper; + } + + public void validateForReject(String json) { + + if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); } + + final Type typeOfMap = new TypeToken>() {}.getType(); + fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParams); + + List dataValidationErrors = new ArrayList(); + DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("deposit.account"); + final JsonElement element = fromApiJsonHelper.parse(json); + + final LocalDate eventDate = fromApiJsonHelper.extractLocalDateNamed("eventDate", element); + baseDataValidator.reset().parameter("eventDate").value(eventDate).notNull(); + + throwExceptionIfValidationWarningsExist(dataValidationErrors); + } + + private void throwExceptionIfValidationWarningsExist(final List dataValidationErrors) { + if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", + "Validation errors exist.", dataValidationErrors); } + } + + public void validateForWithdrawDepositApplication(String json) { + if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); } + + final Type typeOfMap = new TypeToken>() {}.getType(); + fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParams); + + List dataValidationErrors = new ArrayList(); + DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("deposit.account"); + final JsonElement element = fromApiJsonHelper.parse(json); + + final LocalDate eventDate = fromApiJsonHelper.extractLocalDateNamed("eventDate", element); + baseDataValidator.reset().parameter("eventDate").value(eventDate).notNull(); + + throwExceptionIfValidationWarningsExist(dataValidationErrors); + } + + public void validateForWithdrawDepositAmount(String json) { + + if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); } + + final Type typeOfMap = new TypeToken>() {}.getType(); + fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParams); + + List dataValidationErrors = new ArrayList(); + DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("deposit.account"); + final JsonElement element = fromApiJsonHelper.parse(json); + + final LocalDate maturesOnDate = fromApiJsonHelper.extractLocalDateNamed("maturesOnDate", element); + baseDataValidator.reset().parameter("maturesOnDate").value(maturesOnDate).notNull(); + + throwExceptionIfValidationWarningsExist(dataValidationErrors); + } + + public void validateForWithdrawInterestAmount(String json) { + + if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); } + + final Type typeOfMap = new TypeToken>() {}.getType(); + fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParams); + + List dataValidationErrors = new ArrayList(); + DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("deposit.account"); + final JsonElement element = fromApiJsonHelper.parse(json); + + final BigDecimal amount = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("amount", element); + baseDataValidator.reset().parameter("deposit").value(amount).notNull().zeroOrPositiveAmount(); + + throwExceptionIfValidationWarningsExist(dataValidationErrors); + } + + + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/service/DepositAccountAssembler.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/service/DepositAccountAssembler.java index 4043fa51d..592ef4cf6 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/service/DepositAccountAssembler.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/service/DepositAccountAssembler.java @@ -7,9 +7,14 @@ package org.mifosplatform.portfolio.savingsdepositaccount.service; import java.math.BigDecimal; import java.util.Arrays; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Locale; +import java.util.Map; import org.joda.time.LocalDate; +import org.mifosplatform.infrastructure.core.api.JsonCommand; +import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper; import org.mifosplatform.organisation.monetary.domain.Money; import org.mifosplatform.portfolio.client.domain.Client; import org.mifosplatform.portfolio.client.domain.ClientRepository; @@ -28,6 +33,8 @@ import org.mifosplatform.portfolio.savingsdepositproduct.exception.DepositProduc import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import com.google.gson.JsonElement; + /** * An assembler for turning {@link DepositAccountCommand} into * {@link DepositAccount}'s. @@ -38,91 +45,110 @@ public class DepositAccountAssembler { private final ClientRepository clientRepository; private final DepositProductRepository depositProductRepository; private final FixedTermDepositInterestCalculator fixedTermDepositInterestCalculator; + private final FromJsonHelper fromApiJsonHelper; @Autowired public DepositAccountAssembler(final ClientRepository clientRepository, final DepositProductRepository depositProductRepository, - final FixedTermDepositInterestCalculator fixedTermDepositInterestCalculator) { + final FixedTermDepositInterestCalculator fixedTermDepositInterestCalculator, final FromJsonHelper fromApiJsonHelper) { this.clientRepository = clientRepository; this.depositProductRepository = depositProductRepository; this.fixedTermDepositInterestCalculator = fixedTermDepositInterestCalculator; + this.fromApiJsonHelper = fromApiJsonHelper; } - public DepositAccount assembleFrom(final DepositAccountCommand command) { + public DepositAccount assembleFrom(final JsonCommand command) { + final JsonElement element = command.parsedJson(); + + final Long clientId = fromApiJsonHelper.extractLongNamed("clientId", element); + final Long productId = fromApiJsonHelper.extractLongNamed("productId", element); + final String externalId = fromApiJsonHelper.extractStringNamed("externalId", element); + final Boolean isInterestWithdrawable = fromApiJsonHelper.extractBooleanNamed("isInterestWithdrawable", element); + final BigDecimal depositValue = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("deposit", element); + final Integer tenureInMonthsCommandValue = fromApiJsonHelper.extractIntegerNamed("tenureInMonths", element, Locale.getDefault()); + final BigDecimal maturityInterestRateCommandValue = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("maturityInterestRate", element); + final BigDecimal preClosureInterestRateCommandValue = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("preClosureInterestRate", element); + final Integer interestCompoundedEveryCommandValue = fromApiJsonHelper.extractIntegerNamed("interestCompoundedEvery", element, Locale.getDefault()); + final Integer interestCompoundedEveryPeriodTypeCommandValue = fromApiJsonHelper.extractIntegerNamed("interestCompoundedEveryPeriodType", element, Locale.getDefault()); + final Boolean renewalAllowedCommandValue = fromApiJsonHelper.extractBooleanNamed("renewalAllowed", element); + final Boolean preClosureAllowedCommandValue = fromApiJsonHelper.extractBooleanNamed("preClosureAllowed", element); + final Boolean interestCompoundingAllowedCommandValue = fromApiJsonHelper.extractBooleanNamed("interestCompoundingAllowed", element); + final Boolean isLockinPeriodAllowedCommandValue = fromApiJsonHelper.extractBooleanNamed("isLockinPeriodAllowed", element); + final Integer lockinPeriodCommandValue = fromApiJsonHelper.extractIntegerNamed("lockinPeriod", element, Locale.getDefault()); + final Integer lockinPeriodTypeCommandValue = fromApiJsonHelper.extractIntegerNamed("lockinPeriodType", element, Locale.getDefault()); + final LocalDate commencementDate = fromApiJsonHelper.extractLocalDateNamed("commencementDate", element); + + Client client = this.clientRepository.findOne(clientId); + if (client == null || client.isDeleted()) { throw new ClientNotFoundException(clientId); } - Client client = this.clientRepository.findOne(command.getClientId()); - if (client == null || client.isDeleted()) { throw new ClientNotFoundException(command.getClientId()); } - - DepositProduct product = this.depositProductRepository.findOne(command.getProductId()); - if (product == null || product.isDeleted()) { throw new DepositProductNotFoundException(command.getProductId()); } - - boolean isInterestWithdrawable = command.isInterestWithdrawable(); + DepositProduct product = this.depositProductRepository.findOne(productId); + if (product == null || product.isDeleted()) { throw new DepositProductNotFoundException(productId); } // details inherited from product setting (unless allowed to be // overridden through account creation api - Money deposit = Money.of(product.getCurrency(), command.getDepositAmount()); + Money deposit = Money.of(product.getCurrency(), depositValue); Integer tenureInMonths = product.getTenureInMonths(); - if (command.getTenureInMonths() != null) { - tenureInMonths = command.getTenureInMonths(); + if (tenureInMonthsCommandValue != null) { + tenureInMonths = tenureInMonthsCommandValue; } BigDecimal maturityInterestRate = product.getMaturityDefaultInterestRate(); - if (command.getMaturityInterestRate() != null) { - maturityInterestRate = command.getMaturityInterestRate(); + if (maturityInterestRateCommandValue != null) { + maturityInterestRate = maturityInterestRateCommandValue; } BigDecimal preClosureInterestRate = product.getPreClosureInterestRate(); - if (command.getPreClosureInterestRate() != null) { - preClosureInterestRate = command.getPreClosureInterestRate(); + if (preClosureInterestRateCommandValue != null) { + preClosureInterestRate = preClosureInterestRateCommandValue; } if (product.getMaturityMinInterestRate().compareTo(preClosureInterestRate) == -1) { throw new DepositAccounDataValidationtException( preClosureInterestRate, product.getMaturityMinInterestRate()); } Integer compoundingInterestEvery = product.getInterestCompoundedEvery(); - if (command.getInterestCompoundedEvery() != null) { - compoundingInterestEvery = command.getInterestCompoundedEvery(); + if (interestCompoundedEveryCommandValue != null) { + compoundingInterestEvery = interestCompoundedEveryCommandValue; } PeriodFrequencyType compoundingInterestFrequency = product.getInterestCompoundedEveryPeriodType(); - if (command.getInterestCompoundedEveryPeriodType() != null) { - compoundingInterestFrequency = PeriodFrequencyType.fromInt(command.getInterestCompoundedEveryPeriodType()); + if (interestCompoundedEveryPeriodTypeCommandValue != null) { + compoundingInterestFrequency = PeriodFrequencyType.fromInt(interestCompoundedEveryPeriodTypeCommandValue); } boolean renewalAllowed = product.isRenewalAllowed(); - if (command.isRenewalAllowedChanged()) { - renewalAllowed = command.isRenewalAllowed(); + if (isBooleanValueUpdated(renewalAllowedCommandValue)) { + renewalAllowed = renewalAllowedCommandValue; } boolean preClosureAllowed = product.isPreClosureAllowed(); - if (command.isPreClosureAllowedChanged()) { - preClosureAllowed = command.isPreClosureAllowed(); + if (isBooleanValueUpdated(preClosureAllowedCommandValue)) { + preClosureAllowed = preClosureAllowedCommandValue; } boolean interestCompoundingAllowed = product.isInterestCompoundingAllowed(); - if (command.isInterestCompoundingAllowedChanged()) { - interestCompoundingAllowed = command.isInterestCompoundingAllowed(); + if (isBooleanValueUpdated(interestCompoundingAllowedCommandValue)) { + interestCompoundingAllowed = interestCompoundingAllowedCommandValue; } boolean isLockinPeriodAllowed = product.isLockinPeriodAllowed(); - if (command.isLockinPeriodChanged()) { - isLockinPeriodAllowed = command.isLockinPeriodAllowed(); + if (isBooleanValueUpdated(isLockinPeriodAllowedCommandValue)) { + isLockinPeriodAllowed = isLockinPeriodAllowedCommandValue; } Integer lockinPeriod = product.getLockinPeriod(); - if (command.getLockinPeriod() != null) { - lockinPeriod = command.getLockinPeriod(); + if (lockinPeriodCommandValue != null) { + lockinPeriod = lockinPeriodCommandValue; } PeriodFrequencyType lockinPeriodType = product.getLockinPeriodType(); - if (command.getLockinPeriodType() != null) { - lockinPeriodType = PeriodFrequencyType.fromInt(command.getLockinPeriodType()); + if (lockinPeriodTypeCommandValue != null) { + lockinPeriodType = PeriodFrequencyType.fromInt(lockinPeriodTypeCommandValue); } // end of details allowed to be overriden from product - DepositAccount account = new DepositAccount().openNew(client, product, command.getExternalId(), deposit, maturityInterestRate, + DepositAccount account = new DepositAccount().openNew(client, product, externalId, deposit, maturityInterestRate, preClosureInterestRate, tenureInMonths, compoundingInterestEvery, compoundingInterestFrequency, - command.getCommencementDate(), renewalAllowed, preClosureAllowed, this.fixedTermDepositInterestCalculator, + commencementDate, renewalAllowed, preClosureAllowed, this.fixedTermDepositInterestCalculator, defaultDepositLifecycleStateMachine(), isInterestWithdrawable, interestCompoundingAllowed, isLockinPeriodAllowed, lockinPeriod, lockinPeriodType); @@ -134,86 +160,147 @@ public class DepositAccountAssembler { return new DepositLifecycleStateMachineImpl(allowedDepositStatuses); } - public DepositAccount assembleFrom(DepositAccount account, DepositAccountCommand command) { + public DepositAccount assembleFrom(DepositAccount account, JsonCommand command) { + + final Map actualChanges = new LinkedHashMap(20); + final String localeAsInput = command.locale(); Client client = account.client(); DepositProduct product = account.product(); - if (command.getProductId() != null) { - product = this.depositProductRepository.findOne(command.getProductId()); - if (product == null || product.isDeleted()) { throw new DepositProductNotFoundException(command.getProductId()); } + final String productIdParamName = "productId"; + if (command.isChangeInLongParameterNamed(productIdParamName, account.product().getId())) { + final Long newValue = command.longValueOfParameterNamed(productIdParamName); + if (newValue != null) { + product = this.depositProductRepository.findOne(newValue); + if (product == null || product.isDeleted()) { throw new DepositProductNotFoundException(newValue); } + } + actualChanges.put(productIdParamName, newValue); + actualChanges.put("locale", localeAsInput); } - + Money deposit = account.getDeposit(); - if (command.getDepositAmount() != null) { - deposit = Money.of(account.getDeposit().getCurrency(), command.getDepositAmount()); + final String depositParamName = "deposit"; + if (command.isChangeInBigDecimalParameterNamed(depositParamName, deposit.getAmount())) { + final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(depositParamName); + actualChanges.put(depositParamName, newValue); + actualChanges.put("locale", localeAsInput); + deposit = Money.of(deposit.getCurrency(), newValue); } Integer tenureInMonths = account.getTenureInMonths(); - if (command.getTenureInMonths() != null) { - tenureInMonths = command.getTenureInMonths(); + final String tenureInMonthsParamName = "tenureInMonths"; + if (command.isChangeInIntegerParameterNamed(tenureInMonthsParamName, tenureInMonths)) { + final Integer newValue = command.integerValueOfParameterNamed(tenureInMonthsParamName); + actualChanges.put(tenureInMonthsParamName, newValue); + actualChanges.put("locale", localeAsInput); + tenureInMonths = newValue; } BigDecimal maturityInterestRate = account.getInterestRate(); - if (command.getMaturityInterestRate() != null) { - maturityInterestRate = command.getMaturityInterestRate(); + final String maturityInterestRateParamName = "maturityInterestRate"; + if (command.isChangeInBigDecimalParameterNamed(maturityInterestRateParamName, maturityInterestRate)) { + final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(maturityInterestRateParamName); + actualChanges.put(maturityInterestRateParamName, newValue); + actualChanges.put("locale", localeAsInput); + maturityInterestRate = newValue; } BigDecimal preClosureInterestRate = account.getPreClosureInterestRate(); - if (command.getPreClosureInterestRate() != null) { - preClosureInterestRate = command.getPreClosureInterestRate(); + final String preClosureInterestRateParamName = "preClosureInterestRate"; + if (command.isChangeInBigDecimalParameterNamed(preClosureInterestRateParamName, preClosureInterestRate)) { + final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(preClosureInterestRateParamName); + actualChanges.put(preClosureInterestRateParamName, newValue); + actualChanges.put("locale", localeAsInput); + preClosureInterestRate = newValue; } if (product.getMaturityMinInterestRate().compareTo(preClosureInterestRate) == -1) { throw new DepositAccounDataValidationtException( preClosureInterestRate, product.getMaturityMinInterestRate()); } - Integer compoundingInterestEvery = account.getInterestCompoundedEvery(); - if (command.getInterestCompoundedEvery() != null) { - compoundingInterestEvery = command.getInterestCompoundedEvery(); + Integer interestCompoundedEvery = account.getInterestCompoundedEvery(); + final String interestCompoundedEveryParamName = "interestCompoundedEvery"; + if (command.isChangeInIntegerParameterNamed(interestCompoundedEveryParamName, interestCompoundedEvery)) { + final Integer newValue = command.integerValueOfParameterNamed(interestCompoundedEveryParamName); + actualChanges.put(interestCompoundedEveryParamName, newValue); + actualChanges.put("locale", localeAsInput); + interestCompoundedEvery = newValue; } - PeriodFrequencyType compoundingInterestFrequency = account.getInterestCompoundedFrequencyType(); - if (command.getInterestCompoundedEveryPeriodType() != null) { - compoundingInterestFrequency = PeriodFrequencyType.fromInt(command.getInterestCompoundedEveryPeriodType()); + PeriodFrequencyType interestCompoundedEveryPeriodType = account.getInterestCompoundedFrequencyType(); + final String interestCompoundedEveryPeriodTypeParamName = "interestCompoundedEveryPeriodType"; + if (command.isChangeInIntegerParameterNamed(interestCompoundedEveryPeriodTypeParamName, interestCompoundedEveryPeriodType.getValue())) { + final Integer newValue = command.integerValueOfParameterNamed(interestCompoundedEveryPeriodTypeParamName); + actualChanges.put(interestCompoundedEveryPeriodTypeParamName, newValue); + actualChanges.put("locale", localeAsInput); + interestCompoundedEveryPeriodType = PeriodFrequencyType.fromInt(newValue); } - boolean renewalAllowed = account.isRenewalAllowed(); - if (command.isRenewalAllowedChanged()) { - renewalAllowed = command.isRenewalAllowed(); + Boolean renewalAllowed = account.isRenewalAllowed(); + final String renewalAllowedParamName = "renewalAllowed"; + if (command.isChangeInBooleanParameterNamed(renewalAllowedParamName, renewalAllowed)) { + final Boolean newValue = command.booleanObjectValueOfParameterNamed(renewalAllowedParamName); + actualChanges.put(renewalAllowedParamName, newValue); + actualChanges.put("locale", localeAsInput); + renewalAllowed = newValue; } - boolean preClosureAllowed = account.isPreClosureAllowed(); - if (command.isPreClosureAllowedChanged()) { - preClosureAllowed = command.isPreClosureAllowed(); + Boolean preClosureAllowed = account.isPreClosureAllowed(); + final String preClosureAllowedParamName = "preClosureAllowed"; + if (command.isChangeInBooleanParameterNamed(preClosureAllowedParamName, preClosureAllowed)) { + final Boolean newValue = command.booleanObjectValueOfParameterNamed(preClosureAllowedParamName); + actualChanges.put(preClosureAllowedParamName, newValue); + actualChanges.put("locale", localeAsInput); + preClosureAllowed = newValue; } - boolean isInterestWithdrawable = account.isInterestWithdrawable(); - if (command.isInterestWithdrawableChanged()) { - isInterestWithdrawable = command.isInterestWithdrawable(); + Boolean isInterestWithdrawable = account.isInterestWithdrawable(); + final String isInterestWithdrawableParamName = "isInterestWithdrawable"; + if (command.isChangeInBooleanParameterNamed(isInterestWithdrawableParamName, isInterestWithdrawable)) { + final Boolean newValue = command.booleanObjectValueOfParameterNamed(isInterestWithdrawableParamName); + actualChanges.put(isInterestWithdrawableParamName, newValue); + actualChanges.put("locale", localeAsInput); + isInterestWithdrawable = newValue; } - boolean isInterestCompoundingAllowed = account.isInterestCompoundingAllowed(); - if (command.isInterestCompoundingAllowedChanged()) { - isInterestCompoundingAllowed = command.isInterestCompoundingAllowed(); + Boolean isInterestCompoundingAllowed = account.isInterestCompoundingAllowed(); + final String isInterestCompoundingAllowedParamName = "interestCompoundingAllowed"; + if (command.isChangeInBooleanParameterNamed(isInterestCompoundingAllowedParamName, isInterestCompoundingAllowed)) { + final Boolean newValue = command.booleanObjectValueOfParameterNamed(isInterestCompoundingAllowedParamName); + actualChanges.put(isInterestCompoundingAllowedParamName, newValue); + actualChanges.put("locale", localeAsInput); + isInterestCompoundingAllowed = newValue; } - boolean isLockinPeriodAllowed = account.isLockinPeriodAllowed(); - if (command.isLockinPeriodChanged()) { - isLockinPeriodAllowed = command.isLockinPeriodAllowed(); + Boolean isLockinPeriodAllowed = account.isLockinPeriodAllowed(); + final String isLockinPeriodAllowedParamName = "isLockinPeriodAllowed"; + if (command.isChangeInBooleanParameterNamed(isLockinPeriodAllowedParamName, isLockinPeriodAllowed)) { + final Boolean newValue = command.booleanObjectValueOfParameterNamed(isLockinPeriodAllowedParamName); + actualChanges.put(isLockinPeriodAllowedParamName, newValue); + actualChanges.put("locale", localeAsInput); + isLockinPeriodAllowed = newValue; } Integer lockinPeriod = account.getLockinPeriod(); - if (command.getLockinPeriod() != null) { - lockinPeriod = command.getLockinPeriod(); + final String lockinPeriodParamName = "lockinPeriod"; + if (command.isChangeInIntegerParameterNamed(lockinPeriodParamName, lockinPeriod)) { + final Integer newValue = command.integerValueOfParameterNamed(lockinPeriodParamName); + actualChanges.put(lockinPeriodParamName, newValue); + actualChanges.put("locale", localeAsInput); + lockinPeriod = newValue; } PeriodFrequencyType lockinPeriodType = account.getLockinPeriodType(); - if (command.getLockinPeriodType() != null) { - lockinPeriodType = PeriodFrequencyType.fromInt(command.getLockinPeriodType()); + final String lockinPeriodTypeParamName = "lockinPeriodType"; + if (command.isChangeInIntegerParameterNamed(lockinPeriodTypeParamName, lockinPeriodType.getValue())) { + final Integer newValue = command.integerValueOfParameterNamed(lockinPeriodTypeParamName); + actualChanges.put(lockinPeriodTypeParamName, newValue); + actualChanges.put("locale", localeAsInput); + lockinPeriodType = PeriodFrequencyType.fromInt(newValue); } DepositAccount newAccount = new DepositAccount().openNew(client, product, null, deposit, maturityInterestRate, - preClosureInterestRate, tenureInMonths, compoundingInterestEvery, compoundingInterestFrequency, account.maturesOnDate() + preClosureInterestRate, tenureInMonths, interestCompoundedEvery, interestCompoundedEveryPeriodType, account.maturesOnDate() .plusDays(1), renewalAllowed, preClosureAllowed, this.fixedTermDepositInterestCalculator, defaultDepositLifecycleStateMachine(), isInterestWithdrawable, isInterestCompoundingAllowed, isLockinPeriodAllowed, lockinPeriod, lockinPeriodType); @@ -223,121 +310,206 @@ public class DepositAccountAssembler { return newAccount; } - /* - * public void adjustTotalAmountForPreclosureInterest(DepositAccount - * account,LocalDate eventDate) { - * account.adjustTotalAmountForPreclosureInterest - * (account,this.fixedTermDepositInterestCalculator,eventDate); } - */ - - public void assembleUpdatedDepositAccount(DepositAccount account, DepositAccountCommand command) { - - DepositProduct product = account.product(); - if (command.getProductId() != null) { - product = this.depositProductRepository.findOne(command.getProductId()); - if (product == null || product.isDeleted()) { throw new DepositProductNotFoundException(command.getProductId()); } + public Map assembleUpdatedDepositAccount(DepositAccount account, JsonCommand command) { + + final Map actualChanges = new LinkedHashMap(20); + final String localeAsInput = command.locale(); + + DepositProduct product = account.product(); + final String productIdParamName = "productId"; + if (command.isChangeInLongParameterNamed(productIdParamName, account.product().getId())) { + final Long newValue = command.longValueOfParameterNamed(productIdParamName); + if (newValue != null) { + product = this.depositProductRepository.findOne(newValue); + if (product == null || product.isDeleted()) { throw new DepositProductNotFoundException(newValue); } + } + actualChanges.put(productIdParamName, newValue); + actualChanges.put("locale", localeAsInput); } - + String externalId = account.getExternalId(); - if (command.isExternalIdChanged()) { - externalId = command.getExternalId(); + final String externalIdParamName = "externalId"; + if (command.isChangeInStringParameterNamed(externalIdParamName, externalId)) { + final String newValue = command.stringValueOfParameterNamed(externalIdParamName); + actualChanges.put(externalIdParamName, newValue); + externalId = newValue; } - + LocalDate commencementDate = account.getProjectedCommencementDate(); - if (command.isCommencementDateChanged()) { - commencementDate = new LocalDate(command.getCommencementDate()); - } - + final String commencementDateParamName = "commencementDate"; + if (command.isChangeInLocalDateParameterNamed("commencementDate", commencementDate)) { + final LocalDate newValue = command.localDateValueOfParameterNamed(commencementDateParamName); + actualChanges.put(commencementDateParamName, newValue); + commencementDate = newValue; + } + Money deposit = account.getDeposit(); - if (command.isDepositAmountChanged()) { - deposit = Money.of(product.getCurrency(), command.getDepositAmount()); + final String depositParamName = "deposit"; + if (command.isChangeInBigDecimalParameterNamed(depositParamName, deposit.getAmount())) { + final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(depositParamName); + actualChanges.put(depositParamName, newValue); + actualChanges.put("locale", localeAsInput); + deposit = Money.of(deposit.getCurrency(), newValue); } - + Integer tenureInMonths = account.getTenureInMonths(); - if (command.isTenureInMonthsChanged()) { - tenureInMonths = command.getTenureInMonths(); + final String tenureInMonthsParamName = "tenureInMonths"; + if (command.isChangeInIntegerParameterNamed(tenureInMonthsParamName, tenureInMonths)) { + final Integer newValue = command.integerValueOfParameterNamed(tenureInMonthsParamName); + actualChanges.put(tenureInMonthsParamName, newValue); + actualChanges.put("locale", localeAsInput); + tenureInMonths = newValue; } - + BigDecimal maturityInterestRate = account.getInterestRate(); - if (command.isMaturityActualInterestRateChanged()) { - maturityInterestRate = command.getMaturityInterestRate(); + final String maturityInterestRateParamName = "maturityInterestRate"; + if (command.isChangeInBigDecimalParameterNamed(maturityInterestRateParamName, maturityInterestRate)) { + final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(maturityInterestRateParamName); + actualChanges.put(maturityInterestRateParamName, newValue); + actualChanges.put("locale", localeAsInput); + maturityInterestRate = newValue; } - + BigDecimal preClosureInterestRate = account.getPreClosureInterestRate(); - if (command.isPreClosureInterestRateChanged()) { - preClosureInterestRate = command.getPreClosureInterestRate(); + final String preClosureInterestRateParamName = "preClosureInterestRate"; + if (command.isChangeInBigDecimalParameterNamed(preClosureInterestRateParamName, preClosureInterestRate)) { + final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(preClosureInterestRateParamName); + actualChanges.put(preClosureInterestRateParamName, newValue); + actualChanges.put("locale", localeAsInput); + preClosureInterestRate = newValue; } - + if (product.getMaturityMinInterestRate().compareTo(preClosureInterestRate) == -1) { throw new DepositAccounDataValidationtException( preClosureInterestRate, product.getMaturityMinInterestRate()); } - - Integer compoundingInterestEvery = account.getInterestCompoundedEvery(); - if (command.isCompoundingInterestEveryChanged()) { - compoundingInterestEvery = command.getInterestCompoundedEvery(); + + Integer interestCompoundedEvery = account.getInterestCompoundedEvery(); + final String interestCompoundedEveryParamName = "interestCompoundedEvery"; + if (command.isChangeInIntegerParameterNamed(interestCompoundedEveryParamName, interestCompoundedEvery)) { + final Integer newValue = command.integerValueOfParameterNamed(interestCompoundedEveryParamName); + actualChanges.put(interestCompoundedEveryParamName, newValue); + actualChanges.put("locale", localeAsInput); + interestCompoundedEvery = newValue; } - - PeriodFrequencyType compoundingInterestFrequency = account.getInterestCompoundedFrequencyType(); - if (command.getInterestCompoundedEveryPeriodType() != null) { - compoundingInterestFrequency = PeriodFrequencyType.fromInt(command.getInterestCompoundedEveryPeriodType()); + + PeriodFrequencyType interestCompoundedEveryPeriodType = account.getInterestCompoundedFrequencyType(); + final String interestCompoundedEveryPeriodTypeParamName = "interestCompoundedEveryPeriodType"; + if (command.isChangeInIntegerParameterNamed(interestCompoundedEveryPeriodTypeParamName, interestCompoundedEveryPeriodType.getValue())) { + final Integer newValue = command.integerValueOfParameterNamed(interestCompoundedEveryPeriodTypeParamName); + actualChanges.put(interestCompoundedEveryPeriodTypeParamName, newValue); + actualChanges.put("locale", localeAsInput); + interestCompoundedEveryPeriodType = PeriodFrequencyType.fromInt(newValue); } - - boolean renewalAllowed = account.isRenewalAllowed(); - if (command.isRenewalAllowedChanged()) { - renewalAllowed = command.isRenewalAllowed(); + + Boolean renewalAllowed = account.isRenewalAllowed(); + final String renewalAllowedParamName = "renewalAllowed"; + if (command.isChangeInBooleanParameterNamed(renewalAllowedParamName, renewalAllowed)) { + final Boolean newValue = command.booleanObjectValueOfParameterNamed(renewalAllowedParamName); + actualChanges.put(renewalAllowedParamName, newValue); + actualChanges.put("locale", localeAsInput); + renewalAllowed = newValue; } - - boolean preClosureAllowed = account.isPreClosureAllowed(); - if (command.isPreClosureAllowedChanged()) { - preClosureAllowed = command.isPreClosureAllowed(); + + Boolean preClosureAllowed = account.isPreClosureAllowed(); + final String preClosureAllowedParamName = "preClosureAllowed"; + if (command.isChangeInBooleanParameterNamed(preClosureAllowedParamName, preClosureAllowed)) { + final Boolean newValue = command.booleanObjectValueOfParameterNamed(preClosureAllowedParamName); + actualChanges.put(preClosureAllowedParamName, newValue); + actualChanges.put("locale", localeAsInput); + preClosureAllowed = newValue; } - - boolean isInterestWithdrawable = account.isInterestWithdrawable(); - if (command.isInterestWithdrawableChanged()) { - isInterestWithdrawable = command.isInterestWithdrawable(); + + Boolean isInterestWithdrawable = account.isInterestWithdrawable(); + final String isInterestWithdrawableParamName = "isInterestWithdrawable"; + if (command.isChangeInBooleanParameterNamed(isInterestWithdrawableParamName, isInterestWithdrawable)) { + final Boolean newValue = command.booleanObjectValueOfParameterNamed(isInterestWithdrawableParamName); + actualChanges.put(isInterestWithdrawableParamName, newValue); + actualChanges.put("locale", localeAsInput); + isInterestWithdrawable = newValue; } - - boolean isInterestCompoundingAllowed = account.isInterestCompoundingAllowed(); - if (command.isInterestCompoundingAllowedChanged()) { - isInterestCompoundingAllowed = command.isInterestCompoundingAllowed(); + + Boolean isInterestCompoundingAllowed = account.isInterestCompoundingAllowed(); + final String isInterestCompoundingAllowedParamName = "interestCompoundingAllowed"; + if (command.isChangeInBooleanParameterNamed(isInterestCompoundingAllowedParamName, isInterestCompoundingAllowed)) { + final Boolean newValue = command.booleanObjectValueOfParameterNamed(isInterestCompoundingAllowedParamName); + actualChanges.put(isInterestCompoundingAllowedParamName, newValue); + actualChanges.put("locale", localeAsInput); + isInterestCompoundingAllowed = newValue; } - - boolean isLockinPeriodAllowed = account.isLockinPeriodAllowed(); - if (command.isLockinPeriodChanged()) { - isLockinPeriodAllowed = command.isLockinPeriodAllowed(); + + Boolean isLockinPeriodAllowed = account.isLockinPeriodAllowed(); + final String isLockinPeriodAllowedParamName = "isLockinPeriodAllowed"; + if (command.isChangeInBooleanParameterNamed(isLockinPeriodAllowedParamName, isLockinPeriodAllowed)) { + final Boolean newValue = command.booleanObjectValueOfParameterNamed(isLockinPeriodAllowedParamName); + actualChanges.put(isLockinPeriodAllowedParamName, newValue); + actualChanges.put("locale", localeAsInput); + isLockinPeriodAllowed = newValue; } - + Integer lockinPeriod = account.getLockinPeriod(); - if (command.getLockinPeriod() != null) { - lockinPeriod = command.getLockinPeriod(); + final String lockinPeriodParamName = "lockinPeriod"; + if (command.isChangeInIntegerParameterNamed(lockinPeriodParamName, lockinPeriod)) { + final Integer newValue = command.integerValueOfParameterNamed(lockinPeriodParamName); + actualChanges.put(lockinPeriodParamName, newValue); + actualChanges.put("locale", localeAsInput); + lockinPeriod = newValue; } - + PeriodFrequencyType lockinPeriodType = account.getLockinPeriodType(); - if (command.getLockinPeriodType() != null) { - lockinPeriodType = PeriodFrequencyType.fromInt(command.getLockinPeriodType()); + final String lockinPeriodTypeParamName = "lockinPeriodType"; + if (command.isChangeInIntegerParameterNamed(lockinPeriodTypeParamName, lockinPeriodType.getValue())) { + final Integer newValue = command.integerValueOfParameterNamed(lockinPeriodTypeParamName); + actualChanges.put(lockinPeriodTypeParamName, newValue); + actualChanges.put("locale", localeAsInput); + lockinPeriodType = PeriodFrequencyType.fromInt(newValue); } + account.update(product, externalId, commencementDate, deposit, tenureInMonths, maturityInterestRate, preClosureInterestRate, - compoundingInterestEvery, compoundingInterestFrequency, renewalAllowed, preClosureAllowed, isInterestWithdrawable, + interestCompoundedEvery, interestCompoundedEveryPeriodType, renewalAllowed, preClosureAllowed, isInterestWithdrawable, isInterestCompoundingAllowed, this.fixedTermDepositInterestCalculator, isLockinPeriodAllowed, lockinPeriod, lockinPeriodType); + + return actualChanges; } - public void updateApprovedDepositAccount(DepositAccount account, DepositAccountCommand command) { - - boolean renewalAllowed = account.isRenewalAllowed(); - if (command.isRenewalAllowedChanged()) { - renewalAllowed = command.isRenewalAllowed(); + public Map updateApprovedDepositAccount(DepositAccount account, JsonCommand command) { + + final Map actualChanges = new LinkedHashMap(20); + final String localeAsInput = command.locale(); + + Boolean renewalAllowed = account.isRenewalAllowed(); + final String renewalAllowedParamName = "renewalAllowed"; + if (command.isChangeInBooleanParameterNamed(renewalAllowedParamName, renewalAllowed)) { + final Boolean newValue = command.booleanObjectValueOfParameterNamed(renewalAllowedParamName); + actualChanges.put(renewalAllowedParamName, newValue); + actualChanges.put("locale", localeAsInput); + renewalAllowed = newValue; } - boolean isInterestWithdrawable = account.isInterestWithdrawable(); - if (command.isInterestWithdrawableChanged()) { - isInterestWithdrawable = command.isInterestWithdrawable(); + Boolean isInterestWithdrawable = account.isInterestWithdrawable(); + final String isInterestWithdrawableParamName = "isInterestWithdrawable"; + if (command.isChangeInBooleanParameterNamed(isInterestWithdrawableParamName, isInterestWithdrawable)) { + final Boolean newValue = command.booleanObjectValueOfParameterNamed(isInterestWithdrawableParamName); + actualChanges.put(isInterestWithdrawableParamName, newValue); + actualChanges.put("locale", localeAsInput); + isInterestWithdrawable = newValue; } + account.update(renewalAllowed, isInterestWithdrawable); + + return actualChanges; } public void postInterest(DepositAccount account) { account.postInterestForDepositAccount(account, this.fixedTermDepositInterestCalculator); } + + private Boolean isBooleanValueUpdated(Boolean actualValue) { + Boolean isUpdated = false; + if(actualValue != null){ + isUpdated = true; + } + return isUpdated; + } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/service/DepositAccountReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/service/DepositAccountReadPlatformServiceImpl.java index 819c702da..9a2791af4 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/service/DepositAccountReadPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/service/DepositAccountReadPlatformServiceImpl.java @@ -155,7 +155,7 @@ public class DepositAccountReadPlatformServiceImpl implements DepositAccountRead + " ecd.father_name as fatherName, ecd.client_address as clientAddress " + " from m_deposit_account da " + " join m_currency curr on curr.code = da.currency_code " + " join m_client c on c.id = da.client_id " + " join m_product_deposit pd on pd.id = da.product_id" - + " left join extra_client_details ecd on da.client_id = ecd.client_id "; + + " left join extra_client_details_hugo_specific ecd on da.client_id = ecd.client_id "; } @Override diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/service/DepositAccountWritePlatformService.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/service/DepositAccountWritePlatformService.java index 17d22e60e..780d3c143 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/service/DepositAccountWritePlatformService.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/service/DepositAccountWritePlatformService.java @@ -7,56 +7,42 @@ package org.mifosplatform.portfolio.savingsdepositaccount.service; import java.util.Collection; +import org.mifosplatform.infrastructure.core.api.JsonCommand; import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; -import org.mifosplatform.portfolio.loanaccount.command.UndoStateTransitionCommand; -import org.mifosplatform.portfolio.savingsdepositaccount.command.DepositAccountCommand; -import org.mifosplatform.portfolio.savingsdepositaccount.command.DepositAccountWithdrawInterestCommand; -import org.mifosplatform.portfolio.savingsdepositaccount.command.DepositAccountWithdrawalCommand; -import org.mifosplatform.portfolio.savingsdepositaccount.command.DepositStateTransitionApprovalCommand; -import org.mifosplatform.portfolio.savingsdepositaccount.command.DepositStateTransitionCommand; import org.mifosplatform.portfolio.savingsdepositaccount.data.DepositAccountsForLookup; import org.springframework.security.access.prepost.PreAuthorize; public interface DepositAccountWritePlatformService { @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'CREATE_DEPOSITACCOUNT')") - CommandProcessingResult createDepositAccount(DepositAccountCommand command); + CommandProcessingResult createDepositAccount(JsonCommand command); @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'UPDATE_DEPOSITACCOUNT')") - CommandProcessingResult updateDepositAccount(DepositAccountCommand command); + CommandProcessingResult updateDepositAccount(Long accountId, JsonCommand command); @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'DELETE_DEPOSITACCOUNT')") - CommandProcessingResult deleteDepositAccount(Long productId); + CommandProcessingResult deleteDepositAccount(Long entityId); - // NOTE - took out permissions relating to doing things with deposit - // accounts in the past as doesn't appear to be code for it @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'APPROVE_DEPOSITACCOUNT')") - CommandProcessingResult approveDepositApplication(DepositStateTransitionApprovalCommand command); + CommandProcessingResult approveDepositApplication(JsonCommand command); @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'REJECT_DEPOSITACCOUNT')") - CommandProcessingResult rejectDepositApplication(DepositStateTransitionCommand command); + CommandProcessingResult rejectDepositApplication(JsonCommand command); @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'WITHDRAW_DEPOSITACCOUNT')") - CommandProcessingResult withdrawDepositApplication(DepositStateTransitionCommand command); + CommandProcessingResult withdrawDepositApplication(JsonCommand command); @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'APPROVALUNDO_DEPOSITACCOUNT')") - CommandProcessingResult undoDepositApproval(UndoStateTransitionCommand undoCommand); - - /* - * @PreAuthorize(value = - * "hasAnyRole('ALL_FUNCTIONS', '')" ) - * EntityIdentifier matureDepositApplication(DepositStateTransitionCommand - * command); - */ + CommandProcessingResult undoDepositApproval(JsonCommand undoCommand); @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'WITHDRAWAL_DEPOSITACCOUNT')") - CommandProcessingResult withdrawDepositAccountMoney(DepositAccountWithdrawalCommand command); + CommandProcessingResult withdrawDepositAccountMoney(JsonCommand command); @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'INTEREST_DEPOSITACCOUNT')") - CommandProcessingResult withdrawDepositAccountInterestMoney(DepositAccountWithdrawInterestCommand command); + CommandProcessingResult withdrawDepositAccountInterestMoney(JsonCommand command); @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'RENEW_DEPOSITACCOUNT')") - CommandProcessingResult renewDepositAccount(DepositAccountCommand command); + CommandProcessingResult renewDepositAccount(JsonCommand command); @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS')") CommandProcessingResult postInterestToDepositAccount(Collection accounts); diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/service/DepositAccountWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/service/DepositAccountWritePlatformServiceJpaRepositoryImpl.java index 2d5bd7233..78cd4d359 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/service/DepositAccountWritePlatformServiceJpaRepositoryImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/service/DepositAccountWritePlatformServiceJpaRepositoryImpl.java @@ -8,27 +8,22 @@ package org.mifosplatform.portfolio.savingsdepositaccount.service; import java.math.BigDecimal; import java.util.Arrays; import java.util.Collection; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; import org.apache.commons.lang.StringUtils; import org.joda.time.LocalDate; +import org.mifosplatform.infrastructure.core.api.JsonCommand; import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; +import org.mifosplatform.infrastructure.core.data.CommandProcessingResultBuilder; import org.mifosplatform.infrastructure.core.exception.PlatformDataIntegrityException; +import org.mifosplatform.infrastructure.security.exception.NoAuthorizationException; import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; import org.mifosplatform.organisation.monetary.domain.Money; import org.mifosplatform.portfolio.client.domain.Note; import org.mifosplatform.portfolio.client.domain.NoteRepository; -import org.mifosplatform.portfolio.loanaccount.command.UndoStateTransitionCommand; import org.mifosplatform.portfolio.savingsaccountproduct.exception.SavingsProductNotFoundException; -import org.mifosplatform.portfolio.savingsdepositaccount.command.DepositAccountCommand; -import org.mifosplatform.portfolio.savingsdepositaccount.command.DepositAccountCommandValidator; -import org.mifosplatform.portfolio.savingsdepositaccount.command.DepositAccountWithdrawInterestCommand; -import org.mifosplatform.portfolio.savingsdepositaccount.command.DepositAccountWithdrawalCommand; -import org.mifosplatform.portfolio.savingsdepositaccount.command.DepositAccountWithdrawalCommandValidator; -import org.mifosplatform.portfolio.savingsdepositaccount.command.DepositStateTransitionApprovalCommand; -import org.mifosplatform.portfolio.savingsdepositaccount.command.DepositStateTransitionApprovalCommandValidator; -import org.mifosplatform.portfolio.savingsdepositaccount.command.DepositStateTransitionCommand; -import org.mifosplatform.portfolio.savingsdepositaccount.command.WithDrawDepositAccountInterestCommandValidator; import org.mifosplatform.portfolio.savingsdepositaccount.data.DepositAccountsForLookup; import org.mifosplatform.portfolio.savingsdepositaccount.domain.DepositAccount; import org.mifosplatform.portfolio.savingsdepositaccount.domain.DepositAccountRepository; @@ -39,6 +34,8 @@ import org.mifosplatform.portfolio.savingsdepositaccount.domain.FixedTermDeposit import org.mifosplatform.portfolio.savingsdepositaccount.exception.DepositAccountNotFoundException; import org.mifosplatform.portfolio.savingsdepositaccount.exception.DepositAccountReopenException; import org.mifosplatform.portfolio.savingsdepositaccount.exception.DepositAccountTransactionsException; +import org.mifosplatform.portfolio.savingsdepositaccount.serialization.DepositAccountCommandFromApiJsonDeserializer; +import org.mifosplatform.portfolio.savingsdepositaccount.serialization.DepositAccountStateTransitionCommandFromApiJsonDeserializer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -56,28 +53,36 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo private final DepositAccountAssembler depositAccountAssembler; private final FixedTermDepositInterestCalculator fixedTermDepositInterestCalculator; private final NoteRepository noteRepository; + private final DepositAccountCommandFromApiJsonDeserializer fromApiJsonDeserializer; + private final DepositAccountStateTransitionCommandFromApiJsonDeserializer depositAccountStateTransitionCommandFromApiJsonDeserializer; @Autowired public DepositAccountWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, final DepositAccountRepository depositAccountRepository, final DepositAccountAssembler depositAccountAssembler, - final FixedTermDepositInterestCalculator fixedTermDepositInterestCalculator, final NoteRepository noteRepository) { + final FixedTermDepositInterestCalculator fixedTermDepositInterestCalculator, final NoteRepository noteRepository, + final DepositAccountCommandFromApiJsonDeserializer fromApiJsonDeserializer, + final DepositAccountStateTransitionCommandFromApiJsonDeserializer depositAccountStateTransitionCommandFromApiJsonDeserializer) { this.context = context; this.depositAccountRepository = depositAccountRepository; this.depositAccountAssembler = depositAccountAssembler; this.fixedTermDepositInterestCalculator = fixedTermDepositInterestCalculator; this.noteRepository = noteRepository; + this.fromApiJsonDeserializer = fromApiJsonDeserializer; + this.depositAccountStateTransitionCommandFromApiJsonDeserializer = depositAccountStateTransitionCommandFromApiJsonDeserializer; } /* * Guaranteed to throw an exception no matter what the data integrity issue * is. */ - private void handleDataIntegrityIssues(final DepositAccountCommand command, final DataIntegrityViolationException dve) { + private void handleDataIntegrityIssues(final JsonCommand command, final DataIntegrityViolationException dve) { Throwable realCause = dve.getMostSpecificCause(); - if (realCause.getMessage().contains("deposit_acc_external_id")) { throw new PlatformDataIntegrityException( - "error.msg.desposit.account.duplicate.externalId", "Deposit account with externalId " + command.getExternalId() - + " already exists", "externalId", command.getExternalId()); } + if (realCause.getMessage().contains("deposit_acc_external_id")) { + final String externalId = command.stringValueOfParameterNamed("externalId"); + throw new PlatformDataIntegrityException( + "error.msg.desposit.account.duplicate.externalId", "Deposit account with externalId " + externalId + + " already exists", "externalId", externalId); } logger.error(dve.getMessage(), dve); throw new PlatformDataIntegrityException("error.msg.deposit.account.unknown.data.integrity.issue", @@ -86,18 +91,18 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo @Transactional @Override - public CommandProcessingResult createDepositAccount(final DepositAccountCommand command) { + public CommandProcessingResult createDepositAccount(final JsonCommand command) { try { this.context.authenticatedUser(); - - DepositAccountCommandValidator validator = new DepositAccountCommandValidator(command); - validator.validateForCreate(); + this.fromApiJsonDeserializer.validateForCreate(command.json()); final DepositAccount account = this.depositAccountAssembler.assembleFrom(command); this.depositAccountRepository.save(account); - return new CommandProcessingResult(account.getId()); + return new CommandProcessingResultBuilder() // + .withEntityId(account.getId()) // + .build(); } catch (DataIntegrityViolationException dve) { handleDataIntegrityIssues(command, dve); return new CommandProcessingResult(Long.valueOf(-1)); @@ -116,49 +121,43 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo account.delete(); this.depositAccountRepository.save(account); - return new CommandProcessingResult(accountId); + return new CommandProcessingResultBuilder() // + .withEntityId(accountId) // + .build(); } @Transactional @Override - public CommandProcessingResult approveDepositApplication(final DepositStateTransitionApprovalCommand command) { + public CommandProcessingResult approveDepositApplication(final JsonCommand command) { - // AppUser currentUser = context.authenticatedUser(); + this.context.authenticatedUser(); + this.fromApiJsonDeserializer.validateForApprove(command.json()); - DepositStateTransitionApprovalCommandValidator validator = new DepositStateTransitionApprovalCommandValidator(command); - validator.validate(); + DepositAccount account = this.depositAccountRepository.findOne(command.entityId()); + if (account == null || account.isDeleted()) { throw new DepositAccountNotFoundException(command.entityId()); } - DepositAccount account = this.depositAccountRepository.findOne(command.getAccountId()); - if (account == null || account.isDeleted()) { throw new DepositAccountNotFoundException(command.getAccountId()); } + final LocalDate commencementDate = command.localDateValueOfParameterNamed("commencementDate"); - // FIXME - madhukar - you are checking for loan permission here instead - // of some specific deposit account permission. - // removing check for now until rules dealing with creating and - // maintaining deposit accounts in the past is clarified - LocalDate eventDate = command.getEventDate(); - // if (this.isBeforeToday(eventDate) && - // currentUser.canNotApproveLoanInPast()) { - // throw new - // NoAuthorizationException("User has no authority to approve deposit with a date in the past."); - // } - - account.approve(eventDate, defaultDepositLifecycleStateMachine(), command, this.fixedTermDepositInterestCalculator); + Map actualChanges = account.approve(commencementDate, defaultDepositLifecycleStateMachine(), command, this.fixedTermDepositInterestCalculator); this.depositAccountRepository.save(account); - - String noteText = command.getNote(); + + String noteText = command.stringValueOfParameterNamed("note"); if (StringUtils.isNotBlank(noteText)) { Note note = Note.depositNote(account, noteText); this.noteRepository.save(note); } - return new CommandProcessingResult(account.getId()); + return new CommandProcessingResultBuilder() // + .withEntityId(account.getId()) // + .with(actualChanges) + .build(); } - // private boolean isBeforeToday(final LocalDate date) { - // return date.isBefore(new LocalDate()); - // } + private boolean isBeforeToday(final LocalDate date) { + return date.isBefore(new LocalDate()); + } private DepositLifecycleStateMachine defaultDepositLifecycleStateMachine() { List allowedDepositStatuses = Arrays.asList(DepositAccountStatus.values()); return new DepositLifecycleStateMachineImpl(allowedDepositStatuses); @@ -166,141 +165,95 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo @Transactional @Override - public CommandProcessingResult rejectDepositApplication(DepositStateTransitionCommand command) { + public CommandProcessingResult rejectDepositApplication(JsonCommand command) { - // AppUser currentUser = context.authenticatedUser(); + this.context.authenticatedUser(); + this.depositAccountStateTransitionCommandFromApiJsonDeserializer.validateForReject(command.json()); - DepositStateTransitionCommandValidator validator = new DepositStateTransitionCommandValidator(command); - validator.validate(); + DepositAccount account = this.depositAccountRepository.findOne(command.entityId()); + if (account == null || account.isDeleted()) { throw new DepositAccountNotFoundException(command.entityId()); } - DepositAccount account = this.depositAccountRepository.findOne(command.getAccountId()); - if (account == null || account.isDeleted()) { throw new DepositAccountNotFoundException(command.getAccountId()); } - - // removing check for now until rules dealing with creating and - // maintaining deposit accounts in the past is clarified - LocalDate eventDate = command.getEventDate(); - // if (this.isBeforeToday(eventDate) && - // currentUser.canNotApproveLoanInPast()) { - // throw new - // NoAuthorizationException("User has no authority to approve deposit with a date in the past."); - // } + LocalDate eventDate = command.localDateValueOfParameterNamed("eventDate"); + if (this.isBeforeToday(eventDate)) { + throw new NoAuthorizationException("User has no authority to reject deposit with a date in the past."); + } account.reject(eventDate, defaultDepositLifecycleStateMachine()); this.depositAccountRepository.save(account); - String noteText = command.getNote(); + String noteText = command.stringValueOfParameterNamed("note"); if (StringUtils.isNotBlank(noteText)) { Note note = Note.depositNote(account, noteText); this.noteRepository.save(note); } - return new CommandProcessingResult(account.getId()); + return new CommandProcessingResultBuilder() // + .withEntityId(account.getId()) // + .build(); } @Transactional @Override - public CommandProcessingResult withdrawDepositApplication(DepositStateTransitionCommand command) { + public CommandProcessingResult withdrawDepositApplication(JsonCommand command) { - // AppUser currentUser = context.authenticatedUser(); + this.context.authenticatedUser(); + this.depositAccountStateTransitionCommandFromApiJsonDeserializer.validateForWithdrawDepositApplication(command.json()); - DepositStateTransitionCommandValidator validator = new DepositStateTransitionCommandValidator(command); - validator.validate(); + DepositAccount account = this.depositAccountRepository.findOne(command.entityId()); + if (account == null || account.isDeleted()) { throw new DepositAccountNotFoundException(command.entityId()); } - DepositAccount account = this.depositAccountRepository.findOne(command.getAccountId()); - if (account == null || account.isDeleted()) { throw new DepositAccountNotFoundException(command.getAccountId()); } - - // removing check for now until rules dealing with creating and - // maintaining deposit accounts in the past is clarified - LocalDate eventDate = command.getEventDate(); - // if (this.isBeforeToday(eventDate) && - // currentUser.canNotApproveLoanInPast()) { - // throw new - // NoAuthorizationException("User has no authority to approve deposit with a date in the past."); - // } + LocalDate eventDate = command.localDateValueOfParameterNamed("eventDate"); + if (this.isBeforeToday(eventDate)) { + throw new NoAuthorizationException("User has no authority to reject deposit with a date in the past."); + } account.withdrawnByApplicant(eventDate, defaultDepositLifecycleStateMachine()); this.depositAccountRepository.save(account); - String noteText = command.getNote(); + String noteText = command.stringValueOfParameterNamed("note"); if (StringUtils.isNotBlank(noteText)) { Note note = Note.depositNote(account, noteText); this.noteRepository.save(note); } - return new CommandProcessingResult(account.getId()); + return new CommandProcessingResultBuilder() // + .withEntityId(account.getId()) // + .build(); } @Transactional @Override - public CommandProcessingResult undoDepositApproval(UndoStateTransitionCommand command) { + public CommandProcessingResult undoDepositApproval(JsonCommand command) { context.authenticatedUser(); - DepositAccount account = this.depositAccountRepository.findOne(command.getLoanId()); - if (account == null || account.isDeleted()) { throw new DepositAccountNotFoundException(command.getLoanId()); } + DepositAccount account = this.depositAccountRepository.findOne(command.entityId()); + if (account == null || account.isDeleted()) { throw new DepositAccountNotFoundException(command.entityId()); } account.undoDepositApproval(defaultDepositLifecycleStateMachine()); this.depositAccountRepository.save(account); - String noteText = command.getNote(); + String noteText = command.stringValueOfParameterNamed("note"); if (StringUtils.isNotBlank(noteText)) { Note note = Note.depositNote(account, noteText); this.noteRepository.save(note); } - return new CommandProcessingResult(account.getId()); + return new CommandProcessingResultBuilder() // + .withEntityId(account.getId()) // + .build(); } - /* - * @Transactional - * - * @Override public EntityIdentifier - * matureDepositApplication(DepositStateTransitionCommand command) { - * - * AppUser currentUser = context.authenticatedUser(); - * - * DepositStateTransitionCommandValidator validator = new - * DepositStateTransitionCommandValidator(command); validator.validate(); - * - * DepositAccount account = - * this.depositAccountRepository.findOne(command.getAccountId()); if - * (account == null || account.isDeleted()) { throw new - * DepositAccountNotFoundException(command.getAccountId()); } - * - * LocalDate eventDate = command.getEventDate(); if - * (this.isBeforeToday(eventDate) && currentUser.canNotApproveLoanInPast()) - * { throw new NoAuthorizationException( - * "User has no authority to mature deposit with a date in the past."); } - * - * account.matureDepositApplication(eventDate, - * defaultDepositLifecycleStateMachine()); - * this.depositAccountRepository.save(account); - * - * if(account.isRenewalAllowed()){ final DepositAccount renewedAccount = - * this.depositAccountAssembler.assembleFrom(account); - * this.depositAccountRepository.save(renewedAccount); return new - * EntityIdentifier(renewedAccount.getId()); //returns the new deposit - * application id } - * - * String noteText = command.getNote(); if - * (StringUtils.isNotBlank(noteText)) { Note note = - * Note.depositNote(account, noteText); this.noteRepository.save(note); } - * - * return new EntityIdentifier(account.getId()); } - */ - @Transactional @Override - public CommandProcessingResult withdrawDepositAccountMoney(final DepositAccountWithdrawalCommand command) { + public CommandProcessingResult withdrawDepositAccountMoney(final JsonCommand command) { - context.authenticatedUser(); + this.context.authenticatedUser(); + this.depositAccountStateTransitionCommandFromApiJsonDeserializer.validateForWithdrawDepositAmount(command.json()); - DepositAccountWithdrawalCommandValidator validator = new DepositAccountWithdrawalCommandValidator(command); - validator.validate(); + DepositAccount account = this.depositAccountRepository.findOne(command.entityId()); + if (account == null || account.isDeleted()) { throw new DepositAccountNotFoundException(command.entityId()); } - DepositAccount account = this.depositAccountRepository.findOne(command.getAccountId()); - if (account == null || account.isDeleted()) { throw new DepositAccountNotFoundException(command.getAccountId()); } - - LocalDate eventDate = command.getMaturesOnDate(); + LocalDate eventDate = command.localDateValueOfParameterNamed("maturesOnDate"); Integer lockinPeriod = account.getLockinPeriod(); LocalDate lockinPeriodExpDate = account.getActualCommencementDate().plusMonths(Integer.valueOf(lockinPeriod)); @@ -315,26 +268,27 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo // } account.withdrawDepositAccountMoney(defaultDepositLifecycleStateMachine(), fixedTermDepositInterestCalculator, eventDate); this.depositAccountRepository.save(account); - String noteText = command.getNote(); + String noteText = command.stringValueOfParameterNamed("note"); if (StringUtils.isNotBlank(noteText)) { Note note = Note.depositNote(account, noteText); this.noteRepository.save(note); } - return new CommandProcessingResult(account.getId()); + return new CommandProcessingResultBuilder() // + .withEntityId(account.getId()) // + .build(); } @Transactional @Override - public CommandProcessingResult withdrawDepositAccountInterestMoney(DepositAccountWithdrawInterestCommand command) { + public CommandProcessingResult withdrawDepositAccountInterestMoney(JsonCommand command) { context.authenticatedUser(); + this.depositAccountStateTransitionCommandFromApiJsonDeserializer.validateForWithdrawInterestAmount(command.json()); - WithDrawDepositAccountInterestCommandValidator validator = new WithDrawDepositAccountInterestCommandValidator(command); - validator.validate(); - - DepositAccount account = this.depositAccountRepository.findOne(command.getAccountId()); - if (account == null || account.isDeleted()) { throw new DepositAccountNotFoundException(command.getAccountId()); } + BigDecimal interestAmount = command.bigDecimalValueOfParameterNamed("amount"); + DepositAccount account = this.depositAccountRepository.findOne(command.entityId()); + if (account == null || account.isDeleted()) { throw new DepositAccountNotFoundException(command.entityId()); } if (account.isInterestWithdrawable() && !account.isInterestCompoundingAllowed()) { // BigDecimal totalAvailableInterestForWithdrawal = getTotalWithdrawableInterestAvailable(account); @@ -342,9 +296,9 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo BigDecimal remainInterestForWithdrawal = account.getAvailableInterest(); //totalAvailableInterestForWithdrawal.subtract(interestPaid); if (remainInterestForWithdrawal.doubleValue() > 0) { - if (remainInterestForWithdrawal.doubleValue() >= command.getWithdrawInterest().doubleValue() - && command.getWithdrawInterest().doubleValue() > 0) { - account.withdrawInterest(Money.of(account.getDeposit().getCurrency(), command.getWithdrawInterest())); + if (remainInterestForWithdrawal.doubleValue() >= interestAmount.doubleValue() + && interestAmount.doubleValue() > 0) { + account.withdrawInterest(Money.of(account.getDeposit().getCurrency(), interestAmount)); this.depositAccountRepository.save(account); } else { throw new DepositAccountTransactionsException("deposit.transaction.interest.withdrawal.exceed", "You can Withdraw " @@ -358,28 +312,20 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo throw new DepositAccountTransactionsException("deposit.transaction.interest.withdrawal.cannot.withdraw", "You can not withdraw interst for this account"); } - return new CommandProcessingResult(account.getId()); + return new CommandProcessingResultBuilder() // + .withEntityId(account.getId()) // + .build(); } -/* private BigDecimal getTotalWithdrawableInterestAvailable(DepositAccount account) { - BigDecimal interstGettingForPeriod = BigDecimal.valueOf(account.getAccuredInterest().getAmount().doubleValue() - / new Double(account.getTenureInMonths())); - Integer noOfMonthsforInterestCal = Months.monthsBetween(account.getActualCommencementDate(), new LocalDate()).getMonths(); - Integer noOfPeriods = noOfMonthsforInterestCal / account.getInterestCompoundedEvery(); - return interstGettingForPeriod.multiply(new BigDecimal(noOfPeriods)); - }*/ - @Transactional @Override - public CommandProcessingResult renewDepositAccount(DepositAccountCommand command) { + public CommandProcessingResult renewDepositAccount(JsonCommand command) { this.context.authenticatedUser(); - - RenewDepositAccountCommandValidator validator = new RenewDepositAccountCommandValidator(command); - validator.validateForCreate(); - - DepositAccount account = this.depositAccountRepository.findOne(command.getId()); - if (account == null || account.isDeleted()) { throw new DepositAccountNotFoundException(command.getId()); } + this.fromApiJsonDeserializer.validateForRenew(command.json()); + + DepositAccount account = this.depositAccountRepository.findOne(command.entityId()); + if (account == null || account.isDeleted()) { throw new DepositAccountNotFoundException(command.entityId()); } // FIXME - KW - extract whats in this if into a method that naturally // describes what you are checking. @@ -391,7 +337,9 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo this.depositAccountRepository.save(renewedAccount); account.closeDepositAccount(defaultDepositLifecycleStateMachine()); this.depositAccountRepository.save(account); - return new CommandProcessingResult(renewedAccount.getId()); + return new CommandProcessingResultBuilder() // + .withEntityId(account.getId()) // + .build(); } throw new DepositAccountReopenException(account.getMaturityDate()); @@ -400,27 +348,33 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo throw new DepositAccountReopenException(account.getMaturityDate()); } + @Transactional @Override - public CommandProcessingResult updateDepositAccount(DepositAccountCommand command) { + public CommandProcessingResult updateDepositAccount(Long accountId, JsonCommand command) { try { - this.context.authenticatedUser(); - - DepositAccountCommandValidator validator = new DepositAccountCommandValidator(command); - validator.validateForUpdate(); - - final DepositAccount account = this.depositAccountRepository.findOne(command.getId()); - if (account == null || account.isDeleted()) { throw new DepositAccountNotFoundException(command.getId()); } - - if (account.isSubmittedAndPendingApproval()) { - this.depositAccountAssembler.assembleUpdatedDepositAccount(account, command); - } else if (account.isActive()) { - this.depositAccountAssembler.updateApprovedDepositAccount(account, command); - } - - this.depositAccountRepository.save(account); - - return new CommandProcessingResult(account.getId()); + + this.context.authenticatedUser(); + this.fromApiJsonDeserializer.validateForUpdate(command.json()); + + Map changes = new LinkedHashMap(20);; + + final DepositAccount account = this.depositAccountRepository.findOne(accountId); + if (account == null || account.isDeleted()) { throw new DepositAccountNotFoundException(accountId); } + + if (account.isSubmittedAndPendingApproval()) { + changes = this.depositAccountAssembler.assembleUpdatedDepositAccount(account, command); + } else if (account.isActive()) { + changes = this.depositAccountAssembler.updateApprovedDepositAccount(account, command); + } + + this.depositAccountRepository.save(account); + + return new CommandProcessingResultBuilder() // + .withEntityId(account.getId()) // + .with(changes) + .build(); + } catch (DataIntegrityViolationException dve) { handleDataIntegrityIssues(command, dve); return new CommandProcessingResult(Long.valueOf(-1)); @@ -439,7 +393,9 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo this.depositAccountAssembler.postInterest(account); this.depositAccountRepository.save(account); } - return new CommandProcessingResult(new Long(accounts.size())); + return new CommandProcessingResultBuilder() // + .withEntityId(Long.valueOf(accounts.size())) // + .build(); } catch (Exception e) { return new CommandProcessingResult(Long.valueOf(-1)); } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositproduct/api/DepositProductsApiResource.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositproduct/api/DepositProductsApiResource.java index d9f33e906..0a9a504bd 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositproduct/api/DepositProductsApiResource.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositproduct/api/DepositProductsApiResource.java @@ -23,22 +23,21 @@ import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.UriInfo; -import org.mifosplatform.infrastructure.core.api.ApiParameterHelper; +import org.mifosplatform.commands.domain.CommandWrapper; +import org.mifosplatform.commands.service.CommandWrapperBuilder; +import org.mifosplatform.commands.service.PortfolioCommandSourceWritePlatformService; +import org.mifosplatform.infrastructure.core.api.ApiRequestParameterHelper; import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; -import org.mifosplatform.infrastructure.core.data.CommandProcessingResultBuilder; import org.mifosplatform.infrastructure.core.data.EnumOptionData; +import org.mifosplatform.infrastructure.core.serialization.ApiRequestJsonSerializationSettings; import org.mifosplatform.infrastructure.core.serialization.DefaultToApiJsonSerializer; import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; import org.mifosplatform.organisation.monetary.data.CurrencyData; import org.mifosplatform.organisation.monetary.service.CurrencyReadPlatformService; import org.mifosplatform.portfolio.loanproduct.domain.PeriodFrequencyType; -import org.mifosplatform.portfolio.savingsaccount.PortfolioApiDataConversionService; -import org.mifosplatform.portfolio.savingsaccount.PortfolioApiJsonSerializerService; import org.mifosplatform.portfolio.savingsaccountproduct.service.SavingsDepositEnumerations; -import org.mifosplatform.portfolio.savingsdepositproduct.command.DepositProductCommand; import org.mifosplatform.portfolio.savingsdepositproduct.data.DepositProductData; import org.mifosplatform.portfolio.savingsdepositproduct.service.DepositProductReadPlatformService; -import org.mifosplatform.portfolio.savingsdepositproduct.service.DepositProductWritePlatformService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; @@ -47,42 +46,44 @@ import org.springframework.stereotype.Component; @Component @Scope("singleton") public class DepositProductsApiResource { + + private final Set DEPOSIT_PRODUCT_DATA_PARAMETERS = new HashSet(Arrays.asList("id", "externalId", "name", "description", "createdOn", "lastModifedOn", + "currencyCode", "digitsAfterDecimal", "minimumBalance", "maximumBalance", "tenureInMonths", "maturityDefaultInterestRate", "maturityMinInterestRate", + "maturityMaxInterestRate", "interestCompoundedEvery", "interestCompoundedEveryPeriodType", "renewalAllowed", "preClosureAllowed", "preClosureInterestRate", + "interestCompoundingAllowed", "isLockinPeriodAllowed", "lockinPeriod", "lockinPeriodType", "currency","currencyOptions", "interestCompoundedEveryPeriodTypeOptions")); private final String entityType = "DEPOSITPRODUCT"; private final PlatformSecurityContext context; private final DepositProductReadPlatformService depositProductReadPlatformService; private final CurrencyReadPlatformService currencyReadPlatformService; - private final DepositProductWritePlatformService depositProductWritePlatformService; - private final PortfolioApiDataConversionService apiDataConversionService; - private final PortfolioApiJsonSerializerService apiJsonSerializerService; private final DefaultToApiJsonSerializer toApiJsonSerializer; + private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService; + private final ApiRequestParameterHelper apiRequestParameterHelper; @Autowired public DepositProductsApiResource(final PlatformSecurityContext context, final DepositProductReadPlatformService depositProductReadPlatformService, final CurrencyReadPlatformService currencyReadPlatformService, - final DepositProductWritePlatformService depositProductWritePlatformService, - final PortfolioApiDataConversionService apiDataConversionService, - final PortfolioApiJsonSerializerService apiJsonSerializerService, - final DefaultToApiJsonSerializer toApiJsonSerializer) { + final DefaultToApiJsonSerializer toApiJsonSerializer, + final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService, + final ApiRequestParameterHelper apiRequestParameterHelper) { this.context = context; this.depositProductReadPlatformService = depositProductReadPlatformService; this.currencyReadPlatformService = currencyReadPlatformService; - this.depositProductWritePlatformService = depositProductWritePlatformService; - this.apiDataConversionService = apiDataConversionService; - this.apiJsonSerializerService = apiJsonSerializerService; this.toApiJsonSerializer = toApiJsonSerializer; + this.commandsSourceWritePlatformService = commandsSourceWritePlatformService; + this.apiRequestParameterHelper = apiRequestParameterHelper; } @POST @Consumes({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON }) - public String createDepositProduct(final String jsonRequestBody) { - - final DepositProductCommand command = this.apiDataConversionService.convertJsonToDepositProductCommand(null, jsonRequestBody); - - final CommandProcessingResult result = this.depositProductWritePlatformService.createDepositProduct(command); + public String createDepositProduct(final String apiRequestBodyAsJson) { + + final CommandWrapper commandRequest = new CommandWrapperBuilder().createDepositProduct().withJson(apiRequestBodyAsJson).build(); + + final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); return this.toApiJsonSerializer.serialize(result); } @@ -91,10 +92,11 @@ public class DepositProductsApiResource { @Path("{productId}") @Consumes({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON }) - public String updateDepositProduct(@PathParam("productId") final Long productId, final String jsonRequestBody) { - - final DepositProductCommand command = this.apiDataConversionService.convertJsonToDepositProductCommand(productId, jsonRequestBody); - final CommandProcessingResult result = this.depositProductWritePlatformService.updateDepositProduct(command); + public String updateDepositProduct(@PathParam("productId") final Long productId, final String apiRequestBodyAsJson) { + + final CommandWrapper commandRequest = new CommandWrapperBuilder().updateDepositProduct(productId).withJson(apiRequestBodyAsJson).build(); + + final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); return this.toApiJsonSerializer.serialize(result); } @@ -104,10 +106,10 @@ public class DepositProductsApiResource { @Consumes({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON }) public String deleteDepositProduct(@PathParam("productId") final Long productId) { - - this.depositProductWritePlatformService.deleteDepositProduct(productId); - - final CommandProcessingResult result = new CommandProcessingResultBuilder().withEntityId(productId).build(); + + final CommandWrapper commandRequest = new CommandWrapperBuilder().deleteDepositProduct(productId).build(); + + final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); return this.toApiJsonSerializer.serialize(result); } @@ -116,23 +118,10 @@ public class DepositProductsApiResource { @Consumes({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON }) public String retrieveAllDepositProducts(@Context final UriInfo uriInfo) { - context.authenticatedUser().validateHasReadPermission(entityType); - - Set typicalResponseParameters = new HashSet(Arrays.asList("id", "externalId", "name", "description", "createdOn", - "lastModifedOn", "currencyCode", "digitsAfterDecimal", "minimumBalance", "maximumBalance", "tenureInMonths", - "maturityDefaultInterestRate", "maturityMinInterestRate", "maturityMaxInterestRate", "interestCompoundedEvery", - "interestCompoundedEveryPeriodType", "renewalAllowed", "preClosureAllowed", "preClosureInterestRate", - "interestCompoundingAllowed", "isLockinPeriodAllowed", "lockinPeriod", "lockinPeriodType", "currency")); - - Set responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters()); - if (responseParameters.isEmpty()) { - responseParameters.addAll(typicalResponseParameters); - } - boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters()); - Collection products = this.depositProductReadPlatformService.retrieveAllDepositProducts(); - return this.apiJsonSerializerService.serializeDepositProductDataToJson(prettyPrint, responseParameters, products); + final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters()); + return this.toApiJsonSerializer.serialize(settings, products, DEPOSIT_PRODUCT_DATA_PARAMETERS); } @GET @@ -142,27 +131,14 @@ public class DepositProductsApiResource { public String retrieveDepositProductDetails(@PathParam("productId") final Long productId, @Context final UriInfo uriInfo) { context.authenticatedUser().validateHasReadPermission(entityType); - - Set typicalResponseParameters = new HashSet(Arrays.asList("id", "externalId", "name", "description", "createdOn", - "lastModifedOn", "currencyCode", "digitsAfterDecimal", "minimumBalance", "maximumBalance", "tenureInMonths", - "maturityDefaultInterestRate", "maturityMinInterestRate", "maturityMaxInterestRate", "interestCompoundedEvery", - "interestCompoundedEveryPeriodType", "renewalAllowed", "preClosureAllowed", "preClosureInterestRate", - "interestCompoundingAllowed", "isLockinPeriodAllowed", "lockinPeriod", "lockinPeriodType", "currency")); - - Set responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters()); - if (responseParameters.isEmpty()) { - responseParameters.addAll(typicalResponseParameters); - } - boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters()); - DepositProductData productData = this.depositProductReadPlatformService.retrieveDepositProductData(productId); - - boolean template = ApiParameterHelper.template(uriInfo.getQueryParameters()); - if (template) { - productData = handleTemplateRelatedData(responseParameters, productData); + final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters()); + + if (settings.isTemplate()) { + productData = handleTemplateRelatedData(productData); } - - return this.apiJsonSerializerService.serializeDepositProductDataToJson(prettyPrint, responseParameters, productData); + + return this.toApiJsonSerializer.serialize(settings, productData, DEPOSIT_PRODUCT_DATA_PARAMETERS); } @GET @@ -173,29 +149,16 @@ public class DepositProductsApiResource { context.authenticatedUser().validateHasReadPermission(entityType); - Set typicalResponseParameters = new HashSet(Arrays.asList("currencyOptions", - "interestCompoundedEveryPeriodTypeOptions", "id", "externalId", "name", "description", "createdOn", "lastModifedOn", - "currencyCode", "digitsAfterDecimal", "minimumBalance", "maximumBalance", "tenureInMonths", "maturityDefaultInterestRate", - "maturityMinInterestRate", "maturityMaxInterestRate", "interestCompoundedEvery", "interestCompoundedEveryPeriodType", - "renewalAllowed", "preClosureAllowed", "preClosureInterestRate", "isLockinPeriodAllowed", "lockinPeriod", - "lockinPeriodType", "currency")); - - Set responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters()); - if (responseParameters.isEmpty()) { - responseParameters.addAll(typicalResponseParameters); - } - boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters()); - DepositProductData depositProduct = this.depositProductReadPlatformService.retrieveNewDepositProductDetails(); - depositProduct = handleTemplateRelatedData(responseParameters, depositProduct); + depositProduct = handleTemplateRelatedData(depositProduct); - return this.apiJsonSerializerService.serializeDepositProductDataToJson(prettyPrint, responseParameters, depositProduct); + final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters()); + return this.toApiJsonSerializer.serialize(settings, depositProduct, DEPOSIT_PRODUCT_DATA_PARAMETERS); } - private DepositProductData handleTemplateRelatedData(final Set responseParameters, final DepositProductData productData) { + private DepositProductData handleTemplateRelatedData(final DepositProductData productData) { - responseParameters.addAll(Arrays.asList("currencyOptions", "interestCompoundedEveryPeriodTypeOptions")); Collection allowedCurrencies = this.currencyReadPlatformService.retrieveAllowedCurrencies(); EnumOptionData monthly = SavingsDepositEnumerations.interestCompoundingPeriodType(PeriodFrequencyType.MONTHS); diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositproduct/data/DepositProductData.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositproduct/data/DepositProductData.java index 8698edd71..0a385ee74 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositproduct/data/DepositProductData.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositproduct/data/DepositProductData.java @@ -85,8 +85,8 @@ public class DepositProductData { this.lockinPeriodType = lockinPeriodType; this.isLockinPeriodAllowed = isLockinPeriodAllowed; this.currency = currencyData; - this.currencyOptions = new ArrayList(); - this.interestCompoundedEveryPeriodTypeOptions = new ArrayList(); + this.currencyOptions = null; + this.interestCompoundedEveryPeriodTypeOptions = null; } public DepositProductData(final Collection currencyOptions, diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositproduct/domain/DepositProduct.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositproduct/domain/DepositProduct.java index 2abca306e..2ff6bf4a7 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositproduct/domain/DepositProduct.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositproduct/domain/DepositProduct.java @@ -6,6 +6,8 @@ package org.mifosplatform.portfolio.savingsdepositproduct.domain; import java.math.BigDecimal; +import java.util.LinkedHashMap; +import java.util.Map; import javax.persistence.Column; import javax.persistence.Embedded; @@ -14,10 +16,10 @@ import javax.persistence.Table; import javax.persistence.UniqueConstraint; import org.apache.commons.lang.StringUtils; +import org.mifosplatform.infrastructure.core.api.JsonCommand; import org.mifosplatform.infrastructure.core.domain.AbstractAuditableCustom; import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency; import org.mifosplatform.portfolio.loanproduct.domain.PeriodFrequencyType; -import org.mifosplatform.portfolio.savingsdepositproduct.command.DepositProductCommand; import org.mifosplatform.portfolio.savingsdepositproduct.exception.DepositProductValueOutsideRangeException; import org.mifosplatform.useradministration.domain.AppUser; @@ -206,93 +208,175 @@ public class DepositProduct extends AbstractAuditableCustom { this.externalId = this.getId() + "_DELETED_" + this.externalId; } - public void update(final DepositProductCommand command, final PeriodFrequencyType interestCompoundingFrequency, final PeriodFrequencyType lockinPeriodType){ + public Map update(final JsonCommand command){ - if (command.isExternalIdChanged()) { - this.externalId = command.getExternalId(); - } - - if (command.isNameChanged()) { - this.name = command.getName(); - } + final Map actualChanges = new LinkedHashMap(20); - if (command.isDescriptionChanged()) { - this.description = command.getDescription(); - } + final String localeAsInput = command.locale(); + + final String nameParamName = "name"; + if (command.isChangeInStringParameterNamed(nameParamName, this.name)) { + final String newValue = command.stringValueOfParameterNamed(nameParamName); + actualChanges.put(nameParamName, newValue); + this.name = newValue; + } + + final String descriptionParamName = "description"; + if (command.isChangeInStringParameterNamed(descriptionParamName, this.description)) { + final String newValue = command.stringValueOfParameterNamed(descriptionParamName); + actualChanges.put(descriptionParamName, newValue); + this.description = newValue; + } + + final String externalIdParamName = "externalId"; + if (command.isChangeInStringParameterNamed(externalIdParamName, this.externalId)) { + final String newValue = command.stringValueOfParameterNamed(externalIdParamName); + actualChanges.put(externalIdParamName, newValue); + this.externalId = newValue; + } + + String currencyCode = this.currency.getCode(); + Integer digitsAfterDecimal = this.currency.getDigitsAfterDecimal(); + + final String digitsAfterDecimalParamName = "digitsAfterDecimal"; + if (command.isChangeInIntegerParameterNamed(digitsAfterDecimalParamName, digitsAfterDecimal)) { + final Integer newValue = command.integerValueOfParameterNamed(digitsAfterDecimalParamName); + actualChanges.put(digitsAfterDecimalParamName, newValue); + actualChanges.put("locale", localeAsInput); + digitsAfterDecimal = newValue; + this.currency = new MonetaryCurrency(currencyCode, digitsAfterDecimal); + } + + final String currencyCodeParamName = "currencyCode"; + if (command.isChangeInStringParameterNamed(currencyCodeParamName, currencyCode)) { + final String newValue = command.stringValueOfParameterNamed(currencyCodeParamName); + actualChanges.put(currencyCodeParamName, newValue); + currencyCode = newValue; + this.currency = new MonetaryCurrency(currencyCode, digitsAfterDecimal); + } + + final String minimumBalanceParamName = "minimumBalance"; + if (command.isChangeInBigDecimalParameterNamed(minimumBalanceParamName, this.minimumBalance)) { + final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(minimumBalanceParamName); + actualChanges.put(minimumBalanceParamName, newValue); + actualChanges.put("locale", localeAsInput); + this.minimumBalance = newValue; + } + + final String maximumBalanceParamName = "maximumBalance"; + if (command.isChangeInBigDecimalParameterNamed(maximumBalanceParamName, this.maximumBalance)) { + final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(maximumBalanceParamName); + actualChanges.put(maximumBalanceParamName, newValue); + actualChanges.put("locale", localeAsInput); + this.maximumBalance = newValue; + } + + final String tenureInMonthsParamName = "tenureInMonths"; + if (command.isChangeInIntegerParameterNamed(tenureInMonthsParamName, this.tenureInMonths)) { + final Integer newValue = command.integerValueOfParameterNamed(tenureInMonthsParamName); + actualChanges.put(tenureInMonthsParamName, newValue); + actualChanges.put("locale", localeAsInput); + this.tenureInMonths = newValue; + } + + final String defaultInterestRateParamName = "maturityDefaultInterestRate"; + if (command.isChangeInBigDecimalParameterNamed(defaultInterestRateParamName, this.maturityDefaultInterestRate)) { + final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(defaultInterestRateParamName); + actualChanges.put(defaultInterestRateParamName, newValue); + actualChanges.put("locale", localeAsInput); + this.maturityDefaultInterestRate = newValue; + } + + final String minInterestRateParamName = "maturityMinInterestRate"; + if (command.isChangeInBigDecimalParameterNamed(minInterestRateParamName, this.maturityMinInterestRate)) { + final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(minInterestRateParamName); + actualChanges.put(minInterestRateParamName, newValue); + actualChanges.put("locale", localeAsInput); + this.maturityMinInterestRate = newValue; + } + + final String maxInterestRateParamName = "maturityMaxInterestRate"; + if (command.isChangeInBigDecimalParameterNamed(maxInterestRateParamName, this.maturityMaxInterestRate)) { + final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(maxInterestRateParamName); + actualChanges.put(maxInterestRateParamName, newValue); + actualChanges.put("locale", localeAsInput); + this.maturityMaxInterestRate = newValue; + } + + final String interestCompoundedEveryParamName = "interestCompoundedEvery"; + if (command.isChangeInIntegerParameterNamed(interestCompoundedEveryParamName, this.interestCompoundedEvery)) { + final Integer newValue = command.integerValueOfParameterNamed(interestCompoundedEveryParamName); + actualChanges.put(interestCompoundedEveryParamName, newValue); + actualChanges.put("locale", localeAsInput); + this.interestCompoundedEvery = newValue; + } + + final String interestCompoundedEveryPeriodTypeParamName = "interestCompoundedEveryPeriodType"; + if (command.isChangeInIntegerParameterNamed(interestCompoundedEveryPeriodTypeParamName, this.interestCompoundedEveryPeriodType.getValue())) { + final Integer newValue = command.integerValueOfParameterNamed(interestCompoundedEveryPeriodTypeParamName); + actualChanges.put(interestCompoundedEveryPeriodTypeParamName, newValue); + actualChanges.put("locale", localeAsInput); + this.interestCompoundedEveryPeriodType = PeriodFrequencyType.fromInt(newValue); + } - Integer digitsAfterDecimalChanged = this.currency.getDigitsAfterDecimal(); - if (command.isDigitsAfterDecimalChanged()) { - digitsAfterDecimalChanged = command.getDigitsAfterDecimal(); - } + final String renewalAllowedParamName = "renewalAllowed"; + if (command.isChangeInBooleanParameterNamed(renewalAllowedParamName, this.renewalAllowed)) { + final Boolean newValue = command.booleanObjectValueOfParameterNamed(renewalAllowedParamName); + actualChanges.put(renewalAllowedParamName, newValue); + actualChanges.put("locale", localeAsInput); + this.renewalAllowed = newValue; + } + + final String preClosureAllowedParamName = "preClosureAllowed"; + if (command.isChangeInBooleanParameterNamed(preClosureAllowedParamName, this.preClosureAllowed)) { + final Boolean newValue = command.booleanObjectValueOfParameterNamed(preClosureAllowedParamName); + actualChanges.put(preClosureAllowedParamName, newValue); + actualChanges.put("locale", localeAsInput); + this.preClosureAllowed = newValue; + } - String currencyCodeChanged = this.currency.getCode(); - if (command.isCurrencyCodeChanged()) { - currencyCodeChanged = command.getCurrencyCode(); - } + final String preClosureInterestRateParamName = "preClosureInterestRate"; + if (command.isChangeInBigDecimalParameterNamed(preClosureInterestRateParamName, this.preClosureInterestRate)) { + final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(preClosureInterestRateParamName); + actualChanges.put(preClosureInterestRateParamName, newValue); + actualChanges.put("locale", localeAsInput); + this.preClosureInterestRate = newValue; + } + + final String interestCompoundingAllowedParamName = "interestCompoundingAllowed"; + if (command.isChangeInBooleanParameterNamed(interestCompoundingAllowedParamName, this.interestCompoundingAllowed)) { + final Boolean newValue = command.booleanObjectValueOfParameterNamed(interestCompoundingAllowedParamName); + actualChanges.put(interestCompoundingAllowedParamName, newValue); + actualChanges.put("locale", localeAsInput); + this.interestCompoundingAllowed = newValue; + } - if (command.isDigitsAfterDecimalChanged() || command.isCurrencyCodeChanged()) { - this.currency = new MonetaryCurrency(currencyCodeChanged, digitsAfterDecimalChanged); - } - - if(command.isMinimumBalanceChanged()){ - this.minimumBalance=command.getMinimumBalance(); - } + final String isLockinPeriodAllowedParamName = "isLockinPeriodAllowed"; + if (command.isChangeInBooleanParameterNamed(isLockinPeriodAllowedParamName, this.isLockinPeriodAllowed)) { + final Boolean newValue = command.booleanObjectValueOfParameterNamed(isLockinPeriodAllowedParamName); + actualChanges.put(isLockinPeriodAllowedParamName, newValue); + actualChanges.put("locale", localeAsInput); + this.isLockinPeriodAllowed = newValue; + } - if(command.isMaximumBalanceChanged()){ - this.maximumBalance=command.getMaximumBalance(); - } + final String lockinPeriodParamName = "lockinPeriod"; + if (command.isChangeInIntegerParameterNamed(lockinPeriodParamName, this.lockinPeriod)) { + final Integer newValue = command.integerValueOfParameterNamed(lockinPeriodParamName); + actualChanges.put(lockinPeriodParamName, newValue); + actualChanges.put("locale", localeAsInput); + this.lockinPeriod = newValue; + } - if(command.isTenureMonthsChanged()){ - this.tenureInMonths=command.getTenureInMonths(); - } - if (command.isMaturityDefaultInterestRateChanged()) { - this.maturityDefaultInterestRate=command.getMaturityDefaultInterestRate(); - } - - if(command.isMaturityMaxInterestRateChanged()){ - this.maturityMaxInterestRate=command.getMaturityMaxInterestRate(); - } - - if (command.isMaturityMinInterestRateChanged()) { - this.maturityMinInterestRate=command.getMaturityMinInterestRate(); - } - - if (command.isInterestCompoundedEveryChanged()) { - this.interestCompoundedEvery = command.getInterestCompoundedEvery(); - } - - if (command.isInterestCompoundedEveryPeriodTypeChanged()) { - this.interestCompoundedEveryPeriodType = interestCompoundingFrequency; - } - - if (command.isRenewalAllowedChanged()) { - this.renewalAllowed=command.isRenewalAllowed(); - } - - if (command.isPreClosureAllowed()) { - this.preClosureAllowed=command.isPreClosureAllowed(); - } - - if (command.isPreClosureInterestRateChanged()) { - this.preClosureInterestRate=command.getPreClosureInterestRate(); - } - - if(command.interestCompoundingAllowedChanged()){ - this.interestCompoundingAllowed = command.isInterestCompoundingAllowed(); - } - - if(command.isLockinPeriodAllowedChanged()){ - this.isLockinPeriodAllowed = command.isLockinPeriodAllowed(); - } - - if(command.isLockinPeriodChanged()){ - this.lockinPeriod = command.getLockinPeriod(); - } - - if(command.isLockinPeriodTypeChanged()){ - this.lockinPeriodType = lockinPeriodType; - } + final String lockinPeriodTypeParamName = "lockinPeriodType"; + if (command.isChangeInIntegerParameterNamed(lockinPeriodTypeParamName, this.lockinPeriodType.getValue())) { + final Integer newValue = command.integerValueOfParameterNamed(lockinPeriodTypeParamName); + actualChanges.put(lockinPeriodTypeParamName, newValue); + actualChanges.put("locale", localeAsInput); + this.lockinPeriodType = PeriodFrequencyType.fromInt(newValue); + } + + return actualChanges; } public void validateInterestRateInRange(final BigDecimal interestRate) { @@ -330,4 +414,35 @@ public class DepositProduct extends AbstractAuditableCustom { throw new DepositProductValueOutsideRangeException(actualValue, minValue, maxValue, "deposit.account.deposit.amount"); } } + + public static DepositProduct assembleFromJson(JsonCommand command, PeriodFrequencyType interestCompoundingPeriodType, + PeriodFrequencyType lockinPeriodType) { + + final String name = command.stringValueOfParameterNamed("name"); + final String externalId = command.stringValueOfParameterNamed("externalId"); + final String description = command.stringValueOfParameterNamed("description"); + final String currencyCode = command.stringValueOfParameterNamed("currencyCode"); + final Integer digitsAfterDecimal = command.integerValueOfParameterNamed("digitsAfterDecimal"); + + final MonetaryCurrency currency = new MonetaryCurrency(currencyCode, digitsAfterDecimal); + final BigDecimal minimumBalance = command.bigDecimalValueOfParameterNamed("minimumBalance"); + final BigDecimal maximumBalance = command.bigDecimalValueOfParameterNamed("maximumBalance"); + + final Integer tenureMonths = command.integerValueOfParameterNamed("tenureInMonths"); + final BigDecimal maturityDefaultInterestRate = command.bigDecimalValueOfParameterNamed("maturityDefaultInterestRate"); + final BigDecimal maturityMinInterestRate = command.bigDecimalValueOfParameterNamed("maturityMinInterestRate"); + final BigDecimal maturityMaxInterestRate = command.bigDecimalValueOfParameterNamed("maturityMaxInterestRate"); + final Integer interestCompoundedEvery = command.integerValueOfParameterNamed("interestCompoundedEvery"); + + final boolean canRenew = command.booleanPrimitiveValueOfParameterNamed("canRenew"); + final boolean canPreClose = command.booleanPrimitiveValueOfParameterNamed("canPreClose"); + final BigDecimal preClosureInterestRate = command.bigDecimalValueOfParameterNamed("preClosureInterestRate"); + final boolean isInterestCompoundingAllowed = command.booleanPrimitiveValueOfParameterNamed("isInterestCompoundingAllowed"); + final boolean isLockinPeriodAllowed = command.booleanPrimitiveValueOfParameterNamed("isLockinPeriodAllowed"); + final Integer lockinPeriod = command.integerValueOfParameterNamed("lockinPeriod"); + + return new DepositProduct(name, externalId, description, currency, minimumBalance, maximumBalance, tenureMonths, maturityDefaultInterestRate, + maturityMinInterestRate, maturityMaxInterestRate, interestCompoundedEvery, interestCompoundingPeriodType, canRenew, canPreClose, + preClosureInterestRate, isInterestCompoundingAllowed, isLockinPeriodAllowed, lockinPeriod, lockinPeriodType); + } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositproduct/handler/CreateDepositProductCommandHandler.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositproduct/handler/CreateDepositProductCommandHandler.java new file mode 100644 index 000000000..da9afb813 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositproduct/handler/CreateDepositProductCommandHandler.java @@ -0,0 +1,25 @@ +package org.mifosplatform.portfolio.savingsdepositproduct.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.savingsdepositproduct.service.DepositProductWritePlatformService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class CreateDepositProductCommandHandler implements NewCommandSourceHandler { + + private final DepositProductWritePlatformService depositProductWritePlatformService; + + @Autowired + public CreateDepositProductCommandHandler(final DepositProductWritePlatformService depositProductWritePlatformService) { + this.depositProductWritePlatformService = depositProductWritePlatformService; + } + + @Override + public CommandProcessingResult processCommand(JsonCommand command) { + return this.depositProductWritePlatformService.createDepositProduct(command); + } + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositproduct/handler/DeleteDepositProductCommandHandler.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositproduct/handler/DeleteDepositProductCommandHandler.java new file mode 100644 index 000000000..daa3fd519 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositproduct/handler/DeleteDepositProductCommandHandler.java @@ -0,0 +1,25 @@ +package org.mifosplatform.portfolio.savingsdepositproduct.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.savingsdepositproduct.service.DepositProductWritePlatformService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class DeleteDepositProductCommandHandler implements NewCommandSourceHandler { + + private final DepositProductWritePlatformService depositProductWritePlatformService; + + @Autowired + public DeleteDepositProductCommandHandler(final DepositProductWritePlatformService depositProductWritePlatformService) { + this.depositProductWritePlatformService = depositProductWritePlatformService; + } + + @Override + public CommandProcessingResult processCommand(JsonCommand command) { + return this.depositProductWritePlatformService.deleteDepositProduct(command.entityId()); + } + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositproduct/handler/UpdateDepositProductCommandHandler.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositproduct/handler/UpdateDepositProductCommandHandler.java new file mode 100644 index 000000000..9a73225f5 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositproduct/handler/UpdateDepositProductCommandHandler.java @@ -0,0 +1,25 @@ +package org.mifosplatform.portfolio.savingsdepositproduct.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.savingsdepositproduct.service.DepositProductWritePlatformService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class UpdateDepositProductCommandHandler implements NewCommandSourceHandler { + +private final DepositProductWritePlatformService depositProductWritePlatformService; + + @Autowired + public UpdateDepositProductCommandHandler(final DepositProductWritePlatformService depositProductWritePlatformService) { + this.depositProductWritePlatformService = depositProductWritePlatformService; + } + + @Override + public CommandProcessingResult processCommand(JsonCommand command) { + return this.depositProductWritePlatformService.updateDepositProduct(command.entityId(),command); + } + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositproduct/serialization/DepositProductCommandFromApiJsonDeserializer.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositproduct/serialization/DepositProductCommandFromApiJsonDeserializer.java new file mode 100644 index 000000000..59df2da57 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositproduct/serialization/DepositProductCommandFromApiJsonDeserializer.java @@ -0,0 +1,221 @@ +package org.mifosplatform.portfolio.savingsdepositproduct.serialization; + +import java.lang.reflect.Type; +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Set; + +import org.apache.commons.lang.StringUtils; +import org.mifosplatform.infrastructure.core.data.ApiParameterError; +import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder; +import org.mifosplatform.infrastructure.core.exception.InvalidJsonException; +import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException; +import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.google.gson.JsonElement; +import com.google.gson.reflect.TypeToken; + +@Component +public final class DepositProductCommandFromApiJsonDeserializer { + + /** + * The parameters supported for this command. + */ + + Set supportedParams = new HashSet(Arrays.asList("locale", "name", "externalId", "description", "currencyCode", + "digitsAfterDecimal", "minimumBalance", "maximumBalance", "tenureInMonths", "maturityDefaultInterestRate", + "maturityMinInterestRate", "maturityMaxInterestRate", "interestCompoundedEvery", "interestCompoundedEveryPeriodType", + "renewalAllowed", "preClosureAllowed", "preClosureInterestRate", "interestCompoundingAllowed", "isLockinPeriodAllowed", + "lockinPeriod", "lockinPeriodType")); + + private final FromJsonHelper fromApiJsonHelper; + + @Autowired + public DepositProductCommandFromApiJsonDeserializer(final FromJsonHelper fromApiJsonHelper) { + this.fromApiJsonHelper = fromApiJsonHelper; + } + + public void validateForCreate(final String json) { + + if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); } + + final Type typeOfMap = new TypeToken>() {}.getType(); + fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParams); + + List dataValidationErrors = new ArrayList(); + DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("deposit.product"); + final JsonElement element = fromApiJsonHelper.parse(json); + + final String name = fromApiJsonHelper.extractStringNamed("name", element); + baseDataValidator.reset().parameter("name").value(name).notBlank().notExceedingLengthOf(100); + + final String externalId = fromApiJsonHelper.extractStringNamed("externalId", element); + baseDataValidator.reset().parameter("externalId").value(externalId).ignoreIfNull().notExceedingLengthOf(100); + + final String description = fromApiJsonHelper.extractStringNamed("description", element); + baseDataValidator.reset().parameter("description").value(description).notExceedingLengthOf(500); + + final String currencyCode = fromApiJsonHelper.extractStringNamed("currencyCode", element); + baseDataValidator.reset().parameter("currencyCode").value(currencyCode).notBlank(); + + final Integer digitsAfterDecimal = fromApiJsonHelper.extractIntegerNamed("digitsAfterDecimal", element, Locale.getDefault()); + baseDataValidator.reset().parameter("digitsAfterDecimal").value(digitsAfterDecimal).notNull().inMinMaxRange(0, 6); + + final BigDecimal minimumBalance = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("minimumBalance", element); + baseDataValidator.reset().parameter("minimumBalance").value(minimumBalance).notNull().zeroOrPositiveAmount(); + + final BigDecimal maximumBalance = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("maximumBalance", element); + baseDataValidator.reset().parameter("maximumBalance").value(maximumBalance).zeroOrPositiveAmount(); + baseDataValidator.reset().parameter("minimumBalance").comapareMinimumAndMaximumAmounts(minimumBalance, maximumBalance); + + final Integer tenureInMonths = fromApiJsonHelper.extractIntegerNamed("tenureInMonths", element, Locale.getDefault()); + baseDataValidator.reset().parameter("tenureInMonths").value(tenureInMonths).notNull().zeroOrPositiveAmount(); + + final BigDecimal maturityDefaultInterestRate = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("maturityDefaultInterestRate", element); + baseDataValidator.reset().parameter("maturityDefaultInterestRate").value(maturityDefaultInterestRate).notNull().zeroOrPositiveAmount(); + + final BigDecimal maturityMinInterestRate = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("maturityMinInterestRate", element); + baseDataValidator.reset().parameter("maturityMinInterestRate").value(maturityMinInterestRate).notNull().zeroOrPositiveAmount(); + + final BigDecimal maturityMaxInterestRate = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("maturityMaxInterestRate", element); + baseDataValidator.reset().parameter("maturityMaxInterestRate").value(maturityMaxInterestRate).notNull().zeroOrPositiveAmount(); + baseDataValidator.reset().parameter("maturityMinInterestRate").comapareMinAndMaxOfTwoBigDecmimalNos(maturityMinInterestRate, maturityMaxInterestRate); + baseDataValidator.reset().parameter("maturityDefaultInterestRate").comapareMinAndMaxOfTwoBigDecmimalNos(maturityDefaultInterestRate, maturityMaxInterestRate); + baseDataValidator.reset().parameter("maturityMinInterestRate").comapareMinAndMaxOfTwoBigDecmimalNos(maturityMinInterestRate, maturityDefaultInterestRate); + + final Integer interestCompoundedEvery = fromApiJsonHelper.extractIntegerNamed("interestCompoundedEvery", element, Locale.getDefault()); + baseDataValidator.reset().parameter("interestCompoundedEvery").value(interestCompoundedEvery).notNull().zeroOrPositiveAmount(); + + final Integer interestCompoundedEveryPeriodType = fromApiJsonHelper.extractIntegerNamed("interestCompoundedEveryPeriodType", element, Locale.getDefault()); + baseDataValidator.reset().parameter("interestCompoundedEveryPeriodType").value(interestCompoundedEveryPeriodType).notNull().inMinMaxRange(1, 3); + + final Boolean renewalAllowed = fromApiJsonHelper.extractBooleanNamed("renewalAllowed", element); + baseDataValidator.reset().parameter("renewalAllowed").trueOrFalseRequired(renewalAllowed); + + final Boolean preClosureAllowed = fromApiJsonHelper.extractBooleanNamed("preClosureAllowed", element); + baseDataValidator.reset().parameter("preClosureAllowed").trueOrFalseRequired(preClosureAllowed); + + final Boolean interestCompoundingAllowed = fromApiJsonHelper.extractBooleanNamed("interestCompoundingAllowed", element); + baseDataValidator.reset().parameter("interestCompoundingAllowed").trueOrFalseRequired(interestCompoundingAllowed); + + final BigDecimal preClosureInterestRate = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("preClosureInterestRate", element); + baseDataValidator.reset().parameter("preClosureInterestRate").value(preClosureInterestRate).notNull().zeroOrPositiveAmount(); + baseDataValidator.reset().parameter("preClosureInterestRate").comapareMinAndMaxOfTwoBigDecmimalNos(preClosureInterestRate,maturityMinInterestRate); + + final Boolean isLockinPeriodAllowed = fromApiJsonHelper.extractBooleanNamed("isLockinPeriodAllowed", element); + baseDataValidator.reset().parameter("isLockinPeriodAllowed").trueOrFalseRequired(isLockinPeriodAllowed); + + final Integer lockinPeriod = fromApiJsonHelper.extractIntegerNamed("lockinPeriod", element, Locale.getDefault()); + baseDataValidator.reset().parameter("lockinPeriod").value(lockinPeriod).notNull().zeroOrPositiveAmount(); + + final Integer lockinPeriodType = fromApiJsonHelper.extractIntegerNamed("lockinPeriodType", element, Locale.getDefault()); + baseDataValidator.reset().parameter("lockinPeriodType").value(lockinPeriodType).notNull().inMinMaxRange(1, 3); + + throwExceptionIfValidationWarningsExist(dataValidationErrors); + } + + public void validateForUpdate(String json) { + + if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); } + + final Type typeOfMap = new TypeToken>() {}.getType(); + fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParams); + + List dataValidationErrors = new ArrayList(); + DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("deposit.product"); + final JsonElement element = fromApiJsonHelper.parse(json); + + final String name = fromApiJsonHelper.extractStringNamed("name", element); + baseDataValidator.reset().parameter("name").value(name).notBlank().ignoreIfNull().notExceedingLengthOf(100); + + final String externalId = fromApiJsonHelper.extractStringNamed("externalId", element); + baseDataValidator.reset().parameter("externalId").value(externalId).ignoreIfNull().notExceedingLengthOf(100); + + final String description = fromApiJsonHelper.extractStringNamed("description", element); + baseDataValidator.reset().parameter("description").value(description).notExceedingLengthOf(500); + + final String currencyCode = fromApiJsonHelper.extractStringNamed("currencyCode", element); + baseDataValidator.reset().parameter("currencyCode").value(currencyCode).notBlank(); + + final Integer digitsAfterDecimal = fromApiJsonHelper.extractIntegerNamed("digitsAfterDecimal", element, Locale.getDefault()); + baseDataValidator.reset().parameter("digitsAfterDecimal").value(digitsAfterDecimal).ignoreIfNull().inMinMaxRange(0, 6); + + final BigDecimal minimumBalance = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("minimumBalance", element); + baseDataValidator.reset().parameter("minimumBalance").value(minimumBalance).ignoreIfNull().zeroOrPositiveAmount(); + + final BigDecimal maximumBalance = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("maximumBalance", element); + baseDataValidator.reset().parameter("maximumBalance").value(maximumBalance).zeroOrPositiveAmount(); + baseDataValidator.reset().parameter("minimumBalance").comapareMinimumAndMaximumAmounts(minimumBalance, maximumBalance); + + final Integer tenureInMonths = fromApiJsonHelper.extractIntegerNamed("tenureInMonths", element, Locale.getDefault()); + baseDataValidator.reset().parameter("tenureInMonths").value(tenureInMonths).ignoreIfNull().zeroOrPositiveAmount(); + + final BigDecimal maturityDefaultInterestRate = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("maturityDefaultInterestRate", element); + baseDataValidator.reset().parameter("maturityDefaultInterestRate").value(maturityDefaultInterestRate).ignoreIfNull().zeroOrPositiveAmount(); + + final BigDecimal maturityMinInterestRate = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("maturityMinInterestRate", element); + baseDataValidator.reset().parameter("maturityMinInterestRate").value(maturityMinInterestRate).ignoreIfNull().zeroOrPositiveAmount(); + + final BigDecimal maturityMaxInterestRate = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("maturityMaxInterestRate", element); + baseDataValidator.reset().parameter("maturityMaxInterestRate").value(maturityMaxInterestRate).ignoreIfNull().zeroOrPositiveAmount(); + baseDataValidator.reset().parameter("maturityMinInterestRate").comapareMinAndMaxOfTwoBigDecmimalNos(maturityMinInterestRate, maturityMaxInterestRate); + baseDataValidator.reset().parameter("maturityDefaultInterestRate").comapareMinAndMaxOfTwoBigDecmimalNos(maturityDefaultInterestRate, maturityMaxInterestRate); + baseDataValidator.reset().parameter("maturityMinInterestRate").comapareMinAndMaxOfTwoBigDecmimalNos(maturityMinInterestRate, maturityDefaultInterestRate); + + final Integer interestCompoundedEvery = fromApiJsonHelper.extractIntegerNamed("interestCompoundedEvery", element, Locale.getDefault()); + baseDataValidator.reset().parameter("interestCompoundedEvery").value(interestCompoundedEvery).ignoreIfNull().zeroOrPositiveAmount(); + + final Integer interestCompoundedEveryPeriodType = fromApiJsonHelper.extractIntegerNamed("interestCompoundedEveryPeriodType", element, Locale.getDefault()); + baseDataValidator.reset().parameter("interestCompoundedEveryPeriodType").value(interestCompoundedEveryPeriodType).ignoreIfNull().inMinMaxRange(1, 3); + + final Boolean renewalAllowed = fromApiJsonHelper.extractBooleanNamed("renewalAllowed", element); + final Boolean isrenewalAllowedChanged = isBooleanValueUpdated(renewalAllowed); + baseDataValidator.reset().parameter("renewalAllowed").trueOrFalseRequired(isrenewalAllowedChanged); + + final Boolean preClosureAllowed = fromApiJsonHelper.extractBooleanNamed("preClosureAllowed", element); + final Boolean isPreClosureAllowedChanged = isBooleanValueUpdated(preClosureAllowed); + baseDataValidator.reset().parameter("preClosureAllowed").trueOrFalseRequired(isPreClosureAllowedChanged); + + final Boolean interestCompoundingAllowed = fromApiJsonHelper.extractBooleanNamed("interestCompoundingAllowed", element); + final Boolean isInterestCompoundingAllowed = isBooleanValueUpdated(interestCompoundingAllowed); + baseDataValidator.reset().parameter("interestCompoundingAllowed").trueOrFalseRequired(isInterestCompoundingAllowed); + + final BigDecimal preClosureInterestRate = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("preClosureInterestRate", element); + baseDataValidator.reset().parameter("preClosureInterestRate").value(preClosureInterestRate).ignoreIfNull().zeroOrPositiveAmount(); + baseDataValidator.reset().parameter("preClosureInterestRate").comapareMinAndMaxOfTwoBigDecmimalNos(preClosureInterestRate,maturityMinInterestRate); + + final Boolean lockinPeriodAllowed = fromApiJsonHelper.extractBooleanNamed("isLockinPeriodAllowed", element); + final Boolean isLockinPeriodAllowed = isBooleanValueUpdated(lockinPeriodAllowed); + baseDataValidator.reset().parameter("isLockinPeriodAllowed").trueOrFalseRequired(isLockinPeriodAllowed); + + final Integer lockinPeriod = fromApiJsonHelper.extractIntegerNamed("lockinPeriod", element, Locale.getDefault()); + baseDataValidator.reset().parameter("lockinPeriod").value(lockinPeriod).ignoreIfNull().zeroOrPositiveAmount(); + + final Integer lockinPeriodType = fromApiJsonHelper.extractIntegerNamed("lockinPeriodType", element, Locale.getDefault()); + baseDataValidator.reset().parameter("lockinPeriodType").value(lockinPeriodType).ignoreIfNull().inMinMaxRange(1, 3); + + throwExceptionIfValidationWarningsExist(dataValidationErrors); + + } + + private Boolean isBooleanValueUpdated(Boolean actualValue) { + Boolean isUpdated = false; + if(actualValue != null){ + isUpdated = true; + } + return isUpdated; + } + + private void throwExceptionIfValidationWarningsExist(final List dataValidationErrors) { + if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", + "Validation errors exist.", dataValidationErrors); } + } + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositproduct/service/DepositProductReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositproduct/service/DepositProductReadPlatformServiceImpl.java index 959b34b0c..587236fbc 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositproduct/service/DepositProductReadPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositproduct/service/DepositProductReadPlatformServiceImpl.java @@ -26,6 +26,9 @@ import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; import org.springframework.stereotype.Service; + + + @Service public class DepositProductReadPlatformServiceImpl implements DepositProductReadPlatformService { @@ -50,7 +53,7 @@ public class DepositProductReadPlatformServiceImpl implements DepositProductRead public Collection retrieveAllDepositProductsForLookup() { this.context.authenticatedUser(); DepositProductLookupMapper depositProductLookupMapper = new DepositProductLookupMapper(); - String sql = "select " + depositProductLookupMapper.depositProductLookupSchema(); + String sql = "select " + depositProductLookupMapper.depositProductLookupSchema() + " where dp.is_deleted=0"; return this.jdbcTemplate.query(sql, depositProductLookupMapper, new Object[] {}); } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositproduct/service/DepositProductWritePlatformService.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositproduct/service/DepositProductWritePlatformService.java index 56a7efbd8..a389cd2b7 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositproduct/service/DepositProductWritePlatformService.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositproduct/service/DepositProductWritePlatformService.java @@ -5,18 +5,19 @@ */ package org.mifosplatform.portfolio.savingsdepositproduct.service; +import org.mifosplatform.infrastructure.core.api.JsonCommand; import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; -import org.mifosplatform.portfolio.savingsdepositproduct.command.DepositProductCommand; import org.springframework.security.access.prepost.PreAuthorize; public interface DepositProductWritePlatformService { @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'CREATE_DEPOSITPRODUCT')") - CommandProcessingResult createDepositProduct(DepositProductCommand command); + CommandProcessingResult createDepositProduct(JsonCommand command); @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'UPDATE_DEPOSITPRODUCT')") - CommandProcessingResult updateDepositProduct(DepositProductCommand command); + CommandProcessingResult updateDepositProduct(Long productId,JsonCommand command); @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'DELETE_DEPOSITPRODUCT')") CommandProcessingResult deleteDepositProduct(Long productId); + } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositproduct/service/DepositProductWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositproduct/service/DepositProductWritePlatformServiceJpaRepositoryImpl.java index 04d9716f5..fb1dfe753 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositproduct/service/DepositProductWritePlatformServiceJpaRepositoryImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositproduct/service/DepositProductWritePlatformServiceJpaRepositoryImpl.java @@ -5,16 +5,18 @@ */ package org.mifosplatform.portfolio.savingsdepositproduct.service; +import java.util.Map; + +import org.mifosplatform.infrastructure.core.api.JsonCommand; import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; import org.mifosplatform.infrastructure.core.data.CommandProcessingResultBuilder; import org.mifosplatform.infrastructure.core.exception.PlatformDataIntegrityException; import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; -import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency; import org.mifosplatform.portfolio.loanproduct.domain.PeriodFrequencyType; -import org.mifosplatform.portfolio.savingsdepositproduct.command.DepositProductCommand; import org.mifosplatform.portfolio.savingsdepositproduct.domain.DepositProduct; import org.mifosplatform.portfolio.savingsdepositproduct.domain.DepositProductRepository; import org.mifosplatform.portfolio.savingsdepositproduct.exception.DepositProductNotFoundException; +import org.mifosplatform.portfolio.savingsdepositproduct.serialization.DepositProductCommandFromApiJsonDeserializer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -29,95 +31,95 @@ public class DepositProductWritePlatformServiceJpaRepositoryImpl implements Depo private final PlatformSecurityContext context; private final DepositProductRepository depositProductRepository; + private final DepositProductCommandFromApiJsonDeserializer fromApiJsonDeserializer; @Autowired public DepositProductWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, - final DepositProductRepository depositProductRepository) { + final DepositProductRepository depositProductRepository, + final DepositProductCommandFromApiJsonDeserializer fromApiJsonDeserializer) { this.context = context; this.depositProductRepository = depositProductRepository; + this.fromApiJsonDeserializer = fromApiJsonDeserializer; } /* * Guaranteed to throw an exception no matter what the data integrity issue * is. */ - private void handleDataIntegrityIssues(final DepositProductCommand command, final DataIntegrityViolationException dve) { + private void handleDataIntegrityIssues(final JsonCommand command, final DataIntegrityViolationException dve) { Throwable realCause = dve.getMostSpecificCause(); - if (realCause.getMessage().contains("name_deposit_product")) { throw new PlatformDataIntegrityException( - "error.msg.desposit.product.duplicate.name", "Deposit product with name: " + command.getName() + " already exists", "name", - command.getName()); } - if (realCause.getMessage().contains("externalid_deposit_product")) { throw new PlatformDataIntegrityException( - "error.msg.desposit.product.duplicate.externalId", "Deposit product with externalId " + command.getExternalId() - + " already exists", "externalId", command.getExternalId()); } + if (realCause.getMessage().contains("name_deposit_product")) { + final String name = command.stringValueOfParameterNamed("name"); + throw new PlatformDataIntegrityException( + "error.msg.desposit.product.duplicate.name", "Deposit product with name: " + name + " already exists", "name", + name); } + if (realCause.getMessage().contains("externalid_deposit_product")) { + final String externalId = command.stringValueOfParameterNamed("externalId"); + throw new PlatformDataIntegrityException( + "error.msg.desposit.product.duplicate.externalId", "Deposit product with externalId " + externalId + + " already exists", "externalId", externalId); } logger.error(dve.getMessage(), dve); throw new PlatformDataIntegrityException("error.msg.deposit.product.unknown.data.integrity.issue", "Unknown data integrity issue with resource."); } - @Transactional + @Transactional @Override - public CommandProcessingResult createDepositProduct(final DepositProductCommand command) { + public CommandProcessingResult createDepositProduct(JsonCommand command) { + try { + this.context.authenticatedUser(); + this.fromApiJsonDeserializer.validateForCreate(command.json()); + + final Integer interestCompoundingPeriodTypeIntValue = command.integerValueOfParameterNamed("interestCompoundedEveryPeriodType"); + PeriodFrequencyType interestCompoundingPeriodType = PeriodFrequencyType.fromInt(interestCompoundingPeriodTypeIntValue); + + final Integer lockinPeriodTypeIntValue = command.integerValueOfParameterNamed("lockinPeriodType"); + PeriodFrequencyType lockinPeriodType = PeriodFrequencyType.fromInt(lockinPeriodTypeIntValue); + + DepositProduct product = DepositProduct.assembleFromJson(command,interestCompoundingPeriodType,lockinPeriodType); + + this.depositProductRepository.save(product); + + return new CommandProcessingResultBuilder() // + .withEntityId(product.getId()) // + .build(); + } catch (DataIntegrityViolationException dve) { + handleDataIntegrityIssues(command, dve); + return new CommandProcessingResult(Long.valueOf(-1)); + } + } - try { - this.context.authenticatedUser(); - DepositProductCommandValidator validator = new DepositProductCommandValidator(command); - validator.validateForCreate(); - - PeriodFrequencyType interestCompoundingPeriodType = PeriodFrequencyType.fromInt(command.getInterestCompoundedEveryPeriodType()); - PeriodFrequencyType lockinPeriodType = PeriodFrequencyType.fromInt(command.getLockinPeriodType()); - MonetaryCurrency currency = new MonetaryCurrency(command.getCurrencyCode(), command.getDigitsAfterDecimal()); - DepositProduct product = new DepositProduct(command.getName(), command.getExternalId(), command.getDescription(), currency, - command.getMinimumBalance(), command.getMaximumBalance(), command.getTenureInMonths(), - command.getMaturityDefaultInterestRate(), command.getMaturityMinInterestRate(), command.getMaturityMaxInterestRate(), - command.getInterestCompoundedEvery(), interestCompoundingPeriodType, command.isRenewalAllowed(), - command.isPreClosureAllowed(), command.getPreClosureInterestRate(), command.isInterestCompoundingAllowed(), - command.isLockinPeriodAllowed(), command.getLockinPeriod(), lockinPeriodType); - this.depositProductRepository.save(product); - - return new CommandProcessingResultBuilder() // - .withEntityId(product.getId()) // - .build(); - } catch (DataIntegrityViolationException dve) { - handleDataIntegrityIssues(command, dve); - return new CommandProcessingResult(Long.valueOf(-1)); - } - } - - @Transactional - @Override - public CommandProcessingResult updateDepositProduct(final DepositProductCommand command) { - - try { - this.context.authenticatedUser(); - DepositProductCommandValidator validator = new DepositProductCommandValidator(command); - validator.validateForUpdate(); - - DepositProduct product = this.depositProductRepository.findOne(command.getId()); - if (product == null) { throw new DepositProductNotFoundException(command.getId()); } - - PeriodFrequencyType interestCompoundingFrequency = null; - if (command.isInterestCompoundedEveryPeriodTypeChanged()) { - interestCompoundingFrequency = PeriodFrequencyType.fromInt(command.getInterestCompoundedEveryPeriodType()); + @Transactional + @Override + public CommandProcessingResult updateDepositProduct(final Long productId, final JsonCommand command) { + try { + + this.context.authenticatedUser(); + + this.fromApiJsonDeserializer.validateForUpdate(command.json()); + + DepositProduct product = this.depositProductRepository.findOne(productId); + if (product == null || product.isDeleted()) { throw new DepositProductNotFoundException(productId); } + + final Map changes = product.update(command); + + if (!changes.isEmpty()) { + this.depositProductRepository.saveAndFlush(product); } - - PeriodFrequencyType lockinPeriodType = null; - if (command.isLockinPeriodTypeChanged()) { - lockinPeriodType = PeriodFrequencyType.fromInt(command.getLockinPeriodType()); - } - - product.update(command, interestCompoundingFrequency, lockinPeriodType); - this.depositProductRepository.save(product); - - return new CommandProcessingResultBuilder() // - .withEntityId(product.getId()) // - .build(); - } catch (DataIntegrityViolationException dve) { - handleDataIntegrityIssues(command, dve); - return new CommandProcessingResult(Long.valueOf(-1)); - } - } + + return new CommandProcessingResultBuilder() // + .withCommandId(command.commandId()) // + .withEntityId(productId) // + .with(changes) // + .build(); + + } catch (DataIntegrityViolationException dve) { + handleDataIntegrityIssues(command, dve); + return new CommandProcessingResult(Long.valueOf(-1)); + } + } @Transactional @Override @@ -125,7 +127,7 @@ public class DepositProductWritePlatformServiceJpaRepositoryImpl implements Depo this.context.authenticatedUser(); DepositProduct product = this.depositProductRepository.findOne(productId); - if (product == null) { throw new DepositProductNotFoundException(productId); } + if (product == null || product.isDeleted()) { throw new DepositProductNotFoundException(productId); } product.delete(); this.depositProductRepository.save(product); @@ -134,4 +136,5 @@ public class DepositProductWritePlatformServiceJpaRepositoryImpl implements Depo .withEntityId(product.getId()) // .build(); } + } \ No newline at end of file