This is an automated email from the ASF dual-hosted git repository. myrle pushed a commit to branch develop in repository https://gitbox.apache.org/repos/asf/fineract-cn-deposit-account-management.git
commit 11a939cecdce8cccc8656b1e37a5c8cad4e79df3 Author: mgeiss <mge...@mifos.org> AuthorDate: Sun Oct 22 09:00:35 2017 +0200 added opened on and last transaction date to product instance --- .../io/mifos/deposit/api/v1/EventConstants.java | 1 + .../api/v1/instance/domain/ProductInstance.java | 18 +++++++++ .../java/io/mifos/deposit/TestProductInstance.java | 47 +++++++++++++++++++++- .../command/TransactionProcessedCommand.java | 30 ++++++++++++++ .../command/handler/ProductInstanceAggregate.java | 22 ++++++++++ .../internal/mapper/ProductInstanceMapper.java | 17 ++++++++ .../internal/repository/ProductInstanceEntity.java | 24 +++++++++++ .../rest/ProductInstanceRestController.java | 4 ++ ..._add_opened_on_last_transaction_to_instance.sql | 20 +++++++++ 9 files changed, 182 insertions(+), 1 deletion(-) diff --git a/api/src/main/java/io/mifos/deposit/api/v1/EventConstants.java b/api/src/main/java/io/mifos/deposit/api/v1/EventConstants.java index 7e63d55..a10c48f 100644 --- a/api/src/main/java/io/mifos/deposit/api/v1/EventConstants.java +++ b/api/src/main/java/io/mifos/deposit/api/v1/EventConstants.java @@ -49,6 +49,7 @@ public interface EventConstants { String ACTIVATE_PRODUCT_INSTANCE_COMMAND = "ACTIVATE"; String CLOSE_PRODUCT_INSTANCE_COMMAND = "CLOSE"; + String PRODUCT_INSTANCE_TRANSACTION = "TRANSACTION"; String DIVIDEND_DISTRIBUTION = "dividend-distribution"; String SELECTOR_DIVIDEND_DISTRIBUTION = SELECTOR_NAME + " = '" + DIVIDEND_DISTRIBUTION + "'"; diff --git a/api/src/main/java/io/mifos/deposit/api/v1/instance/domain/ProductInstance.java b/api/src/main/java/io/mifos/deposit/api/v1/instance/domain/ProductInstance.java index 348543d..a37be73 100644 --- a/api/src/main/java/io/mifos/deposit/api/v1/instance/domain/ProductInstance.java +++ b/api/src/main/java/io/mifos/deposit/api/v1/instance/domain/ProductInstance.java @@ -28,6 +28,8 @@ public class ProductInstance { @ValidIdentifier(maxLength = 34, optional = true) private String accountIdentifier; private Set<String> beneficiaries; + private String openedOn; + private String lastTransactionDate; private String state; private Double balance; @@ -67,6 +69,22 @@ public class ProductInstance { this.beneficiaries = beneficiaries; } + public String getOpenedOn() { + return this.openedOn; + } + + public void setOpenedOn(final String openedOn) { + this.openedOn = openedOn; + } + + public String getLastTransactionDate() { + return this.lastTransactionDate; + } + + public void setLastTransactionDate(final String lastTransactionDate) { + this.lastTransactionDate = lastTransactionDate; + } + public String getState() { return this.state; } diff --git a/component-test/src/main/java/io/mifos/deposit/TestProductInstance.java b/component-test/src/main/java/io/mifos/deposit/TestProductInstance.java index cb875e5..6018d94 100644 --- a/component-test/src/main/java/io/mifos/deposit/TestProductInstance.java +++ b/component-test/src/main/java/io/mifos/deposit/TestProductInstance.java @@ -90,17 +90,21 @@ public class TestProductInstance extends AbstractDepositAccountManagementTest { Assert.assertTrue( super.eventRecorder.wait(EventConstants.ACTIVATE_PRODUCT_INSTANCE, foundProductInstance.getAccountIdentifier())); + + final ProductInstance activatedProductInstance = super.depositAccountManager.findProductInstance(foundProductInstance.getAccountIdentifier()); + Assert.assertNotNull(activatedProductInstance.getOpenedOn()); } @Test public void shouldCloseProductInstance() throws Exception { final ProductDefinition productDefinition = Fixture.productDefinition(); - super.depositAccountManager.create(productDefinition); super.eventRecorder.wait(EventConstants.POST_PRODUCT_DEFINITION, productDefinition.getIdentifier()); final ProductInstance productInstance = Fixture.productInstance(productDefinition.getIdentifier()); + final String openedOn = "2013-05-08Z"; + productInstance.setOpenedOn(openedOn); super.depositAccountManager.create(productInstance); @@ -110,6 +114,7 @@ public class TestProductInstance extends AbstractDepositAccountManagementTest { Assert.assertNotNull(productInstances); Assert.assertEquals(1, productInstances.size()); final ProductInstance foundProductInstance = productInstances.get(0); + Assert.assertEquals(openedOn, foundProductInstance.getOpenedOn()); super.depositAccountManager.postProductInstanceCommand( foundProductInstance.getAccountIdentifier(), EventConstants.CLOSE_PRODUCT_INSTANCE_COMMAND); @@ -330,4 +335,44 @@ public class TestProductInstance extends AbstractDepositAccountManagementTest { Assert.assertTrue(expectedTransactionTypes.isEmpty()); } + + @Test + public void shouldAddTransactionDateProductInstance() throws Exception { + final ProductDefinition productDefinition = Fixture.productDefinition(); + + super.depositAccountManager.create(productDefinition); + + super.eventRecorder.wait(EventConstants.POST_PRODUCT_DEFINITION, productDefinition.getIdentifier()); + + final ProductInstance productInstance = Fixture.productInstance(productDefinition.getIdentifier()); + + super.depositAccountManager.create(productInstance); + + super.eventRecorder.wait(EventConstants.POST_PRODUCT_INSTANCE, productInstance.getCustomerIdentifier()); + + final List<ProductInstance> productInstances = super.depositAccountManager.findProductInstances(productDefinition.getIdentifier()); + Assert.assertNotNull(productInstances); + Assert.assertEquals(1, productInstances.size()); + final ProductInstance foundProductInstance = productInstances.get(0); + + super.depositAccountManager.postProductInstanceCommand( + foundProductInstance.getAccountIdentifier(), EventConstants.ACTIVATE_PRODUCT_INSTANCE_COMMAND); + + Assert.assertTrue( + super.eventRecorder.wait(EventConstants.ACTIVATE_PRODUCT_INSTANCE, + foundProductInstance.getAccountIdentifier())); + + super.depositAccountManager.postProductInstanceCommand( + foundProductInstance.getAccountIdentifier(), EventConstants.PRODUCT_INSTANCE_TRANSACTION); + + Assert.assertTrue( + super.eventRecorder.wait(EventConstants.PUT_PRODUCT_INSTANCE, + foundProductInstance.getAccountIdentifier())); + + final List<ProductInstance> transactedProductInstances = super.depositAccountManager.findProductInstances(productDefinition.getIdentifier()); + Assert.assertNotNull(transactedProductInstances); + Assert.assertEquals(1, transactedProductInstances.size()); + final ProductInstance transactedProductInstance = transactedProductInstances.get(0); + Assert.assertNotNull(transactedProductInstance.getLastTransactionDate()); + } } diff --git a/service/src/main/java/io/mifos/deposit/service/internal/command/TransactionProcessedCommand.java b/service/src/main/java/io/mifos/deposit/service/internal/command/TransactionProcessedCommand.java new file mode 100644 index 0000000..79950c9 --- /dev/null +++ b/service/src/main/java/io/mifos/deposit/service/internal/command/TransactionProcessedCommand.java @@ -0,0 +1,30 @@ +/* + * Copyright 2017 The Mifos Initiative. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.mifos.deposit.service.internal.command; + +public class TransactionProcessedCommand { + + private final String accountIdentifier; + + public TransactionProcessedCommand(final String accountIdentifier) { + super(); + this.accountIdentifier = accountIdentifier; + } + + public String accountIdentifier() { + return this.accountIdentifier; + } +} diff --git a/service/src/main/java/io/mifos/deposit/service/internal/command/handler/ProductInstanceAggregate.java b/service/src/main/java/io/mifos/deposit/service/internal/command/handler/ProductInstanceAggregate.java index da6b8d7..29f188c 100644 --- a/service/src/main/java/io/mifos/deposit/service/internal/command/handler/ProductInstanceAggregate.java +++ b/service/src/main/java/io/mifos/deposit/service/internal/command/handler/ProductInstanceAggregate.java @@ -27,6 +27,7 @@ import io.mifos.deposit.service.ServiceConstants; import io.mifos.deposit.service.internal.command.ActivateProductInstanceCommand; import io.mifos.deposit.service.internal.command.CloseProductInstanceCommand; import io.mifos.deposit.service.internal.command.CreateProductInstanceCommand; +import io.mifos.deposit.service.internal.command.TransactionProcessedCommand; import io.mifos.deposit.service.internal.command.UpdateProductInstanceCommand; import io.mifos.deposit.service.internal.mapper.ProductInstanceMapper; import io.mifos.deposit.service.internal.repository.ProductDefinitionEntity; @@ -41,6 +42,7 @@ import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.transaction.annotation.Transactional; import java.time.Clock; +import java.time.LocalDate; import java.time.LocalDateTime; import java.util.Arrays; import java.util.HashSet; @@ -120,6 +122,9 @@ public class ProductInstanceAggregate { if (optionalProductInstance.isPresent()) { final ProductInstanceEntity productInstanceEntity = optionalProductInstance.get(); productInstanceEntity.setState("ACTIVE"); + if (productInstanceEntity.getOpenedOn() == null) { + productInstanceEntity.setOpenedOn(LocalDate.now(Clock.systemUTC())); + } productInstanceEntity.setLastModifiedBy(UserContextHolder.checkedGetUser()); productInstanceEntity.setLastModifiedOn(LocalDateTime.now(Clock.systemUTC())); this.productInstanceRepository.save(productInstanceEntity); @@ -186,6 +191,23 @@ public class ProductInstanceAggregate { } } + @Transactional + @CommandHandler + @EventEmitter(selectorName = EventConstants.SELECTOR_NAME, selectorValue = EventConstants.PUT_PRODUCT_INSTANCE) + public String process(final TransactionProcessedCommand transactionProcessedCommand) { + final Optional<ProductInstanceEntity> optionalProductInstance = + this.productInstanceRepository.findByAccountIdentifier(transactionProcessedCommand.accountIdentifier()); + + final ProductInstanceEntity productInstanceEntity = optionalProductInstance.orElseThrow(() -> + ServiceException.notFound("Product instance {0} not found.", transactionProcessedCommand.accountIdentifier())); + + productInstanceEntity.setLastTransactionDate(LocalDateTime.now(Clock.systemUTC())); + + this.productInstanceRepository.save(productInstanceEntity); + + return transactionProcessedCommand.accountIdentifier(); + } + private boolean hasChanged(final ProductInstance productInstance, final ProductInstanceEntity productInstanceEntity) { if (productInstance.getBeneficiaries() != null) { if (productInstanceEntity.getBeneficiaries() == null) { diff --git a/service/src/main/java/io/mifos/deposit/service/internal/mapper/ProductInstanceMapper.java b/service/src/main/java/io/mifos/deposit/service/internal/mapper/ProductInstanceMapper.java index 68a31c3..a841833 100644 --- a/service/src/main/java/io/mifos/deposit/service/internal/mapper/ProductInstanceMapper.java +++ b/service/src/main/java/io/mifos/deposit/service/internal/mapper/ProductInstanceMapper.java @@ -16,6 +16,7 @@ package io.mifos.deposit.service.internal.mapper; import io.mifos.accounting.api.v1.domain.Account; +import io.mifos.core.lang.DateConverter; import io.mifos.core.lang.ServiceException; import io.mifos.deposit.api.v1.instance.domain.ProductInstance; import io.mifos.deposit.service.internal.repository.ProductDefinitionEntity; @@ -49,6 +50,14 @@ public class ProductInstanceMapper { productInstance.getBeneficiaries().stream().collect(Collectors.joining(","))); } + if (productInstance.getOpenedOn() != null) { + productInstanceEntity.setOpenedOn(DateConverter.dateFromIsoString(productInstance.getOpenedOn())); + } + + if (productInstance.getLastTransactionDate() != null) { + productInstanceEntity.setLastTransactionDate(DateConverter.fromIsoString(productInstance.getLastTransactionDate())); + } + return productInstanceEntity; } else { throw ServiceException.notFound("Unable to assign product {0} to customer {1}, product not found.", @@ -69,6 +78,14 @@ public class ProductInstanceMapper { )); } + if (productInstanceEntity.getOpenedOn() != null) { + productInstance.setOpenedOn(DateConverter.toIsoString(productInstanceEntity.getOpenedOn())); + } + + if (productInstanceEntity.getLastTransactionDate() != null) { + productInstance.setLastTransactionDate(DateConverter.toIsoString(productInstanceEntity.getLastTransactionDate())); + } + if (account != null && account.getBalance() != null) { productInstance.setBalance(account.getBalance()); } else { diff --git a/service/src/main/java/io/mifos/deposit/service/internal/repository/ProductInstanceEntity.java b/service/src/main/java/io/mifos/deposit/service/internal/repository/ProductInstanceEntity.java index 53ad0bc..f95a8ea 100644 --- a/service/src/main/java/io/mifos/deposit/service/internal/repository/ProductInstanceEntity.java +++ b/service/src/main/java/io/mifos/deposit/service/internal/repository/ProductInstanceEntity.java @@ -15,6 +15,7 @@ */ package io.mifos.deposit.service.internal.repository; +import io.mifos.core.mariadb.util.LocalDateConverter; import io.mifos.core.mariadb.util.LocalDateTimeConverter; import javax.persistence.CascadeType; @@ -28,6 +29,7 @@ import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.Table; +import java.time.LocalDate; import java.time.LocalDateTime; @Entity @@ -47,6 +49,12 @@ public class ProductInstanceEntity { private String accountIdentifier; @Column(name = "beneficiaries", nullable = true, length = 256) private String beneficiaries; + @Convert(converter = LocalDateConverter.class) + @Column(name = "opened_on", nullable = false) + private LocalDate openedOn; + @Convert(converter = LocalDateTimeConverter.class) + @Column(name = "last_transaction_date", nullable = false) + private LocalDateTime lastTransactionDate; @Column(name = "a_state", nullable = false) private String state; @Column(name = "created_by", nullable = false, length = 32) @@ -104,6 +112,22 @@ public class ProductInstanceEntity { this.beneficiaries = beneficiaries; } + public LocalDate getOpenedOn() { + return this.openedOn; + } + + public void setOpenedOn(final LocalDate openedOn) { + this.openedOn = openedOn; + } + + public LocalDateTime getLastTransactionDate() { + return this.lastTransactionDate; + } + + public void setLastTransactionDate(final LocalDateTime lastTransactionDate) { + this.lastTransactionDate = lastTransactionDate; + } + public String getState() { return this.state; } diff --git a/service/src/main/java/io/mifos/deposit/service/rest/ProductInstanceRestController.java b/service/src/main/java/io/mifos/deposit/service/rest/ProductInstanceRestController.java index 0d0deb4..e56bda8 100644 --- a/service/src/main/java/io/mifos/deposit/service/rest/ProductInstanceRestController.java +++ b/service/src/main/java/io/mifos/deposit/service/rest/ProductInstanceRestController.java @@ -27,6 +27,7 @@ import io.mifos.deposit.service.ServiceConstants; import io.mifos.deposit.service.internal.command.ActivateProductInstanceCommand; import io.mifos.deposit.service.internal.command.CloseProductInstanceCommand; import io.mifos.deposit.service.internal.command.CreateProductInstanceCommand; +import io.mifos.deposit.service.internal.command.TransactionProcessedCommand; import io.mifos.deposit.service.internal.command.UpdateProductInstanceCommand; import io.mifos.deposit.service.internal.service.ProductInstanceService; import org.slf4j.Logger; @@ -150,6 +151,9 @@ public class ProductInstanceRestController { case EventConstants.CLOSE_PRODUCT_INSTANCE_COMMAND: this.commandGateway.process(new CloseProductInstanceCommand(identifier)); break; + case EventConstants.PRODUCT_INSTANCE_TRANSACTION: + this.commandGateway.process(new TransactionProcessedCommand(identifier)); + break; default: throw ServiceException.badRequest("Unsupported command {0}", command); } diff --git a/service/src/main/resources/db/migrations/mariadb/V6__add_opened_on_last_transaction_to_instance.sql b/service/src/main/resources/db/migrations/mariadb/V6__add_opened_on_last_transaction_to_instance.sql new file mode 100644 index 0000000..89e2bef --- /dev/null +++ b/service/src/main/resources/db/migrations/mariadb/V6__add_opened_on_last_transaction_to_instance.sql @@ -0,0 +1,20 @@ +-- +-- Copyright 2017 The Mifos Initiative. +-- +-- Licensed under the Apache License, Version 2.0 (the "License"); +-- you may not use this file except in compliance with the License. +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. +-- + +ALTER TABLE shed_product_instances ADD COLUMN opened_on DATE NULL; +ALTER TABLE shed_product_instances ADD COLUMN last_transaction_date TIMESTAMP(3) NULL; + +UPDATE shed_product_instances set opened_on = CURDATE() WHERE a_state <> 'PENDING'; \ No newline at end of file -- To stop receiving notification emails like this one, please contact my...@apache.org.