fineract-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From my...@apache.org
Subject [fineract-cn-deposit-account-management] 03/23: second iteration server side implementation
Date Mon, 22 Jan 2018 15:28:36 GMT
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 82018a224cdee216da2e1a5548f67f86bb93a9af
Author: mgeiss <mgeiss@mifos.org>
AuthorDate: Sun May 28 12:29:40 2017 +0700

    second iteration server side implementation
---
 .../api/v1/client/DepositAccountManager.java       |   9 +-
 .../domain/ProductDefinitionCommand.java           |  11 +-
 .../deposit/api/v1/instance/domain/State.java      |  70 -------------
 .../command/ActivateProductDefinitionCommand.java  |  38 +++++++
 .../DeactivateProductDefinitionCommand.java        |  38 +++++++
 .../handler/ProductDefinitionAggregate.java        |  61 ++++++++++-
 .../mapper/ProductDefinitionCommandMapper.java     |  46 +++++++++
 ...ty.java => ProductDefinitionCommandEntity.java} |  65 +++++++-----
 .../ProductDefinitionCommandRepository.java        |  25 +++++
 .../repository/ProductDefinitionEntity.java        |  46 +++++++++
 .../internal/repository/ProductInstanceEntity.java |  48 ++++++++-
 .../internal/service/ProductDefinitionService.java |  24 +++--
 .../internal/service/ProductInstanceService.java   |   3 -
 .../rest/ProductDefinitionRestController.java      |  39 ++++++-
 .../rest/ProductInstanceRestController.java        |   3 -
 .../db/migrations/mariadb/V1__initial_setup.sql    | 114 +++++++++++++++++++++
 16 files changed, 521 insertions(+), 119 deletions(-)

diff --git a/api/src/main/java/io/mifos/deposit/api/v1/client/DepositAccountManager.java b/api/src/main/java/io/mifos/deposit/api/v1/client/DepositAccountManager.java
index 80b69bc..516e4e2 100644
--- a/api/src/main/java/io/mifos/deposit/api/v1/client/DepositAccountManager.java
+++ b/api/src/main/java/io/mifos/deposit/api/v1/client/DepositAccountManager.java
@@ -20,7 +20,6 @@ import io.mifos.deposit.api.v1.definition.domain.Action;
 import io.mifos.deposit.api.v1.definition.domain.ProductDefinition;
 import io.mifos.deposit.api.v1.definition.domain.ProductDefinitionCommand;
 import io.mifos.deposit.api.v1.instance.domain.ProductInstance;
-import io.mifos.deposit.api.v1.instance.domain.StateChange;
 import org.springframework.cloud.netflix.feign.FeignClient;
 import org.springframework.http.MediaType;
 import org.springframework.web.bind.annotation.PathVariable;
@@ -94,6 +93,14 @@ public interface DepositAccountManager {
                @RequestBody @Valid final ProductDefinitionCommand command);
 
   @RequestMapping(
+      value = "/{identifier}/commands",
+      method = RequestMethod.GET,
+      consumes = MediaType.APPLICATION_JSON_VALUE,
+      produces = MediaType.ALL_VALUE
+  )
+  List<ProductDefinitionCommand> getProductDefinitionCommands(@PathVariable("identifier")
final String identifier);
+
+  @RequestMapping(
       value = "/instances",
       method = RequestMethod.POST,
       consumes = MediaType.APPLICATION_JSON_VALUE,
diff --git a/api/src/main/java/io/mifos/deposit/api/v1/definition/domain/ProductDefinitionCommand.java
b/api/src/main/java/io/mifos/deposit/api/v1/definition/domain/ProductDefinitionCommand.java
index 6014aa4..98171f2 100644
--- a/api/src/main/java/io/mifos/deposit/api/v1/definition/domain/ProductDefinitionCommand.java
+++ b/api/src/main/java/io/mifos/deposit/api/v1/definition/domain/ProductDefinitionCommand.java
@@ -20,8 +20,13 @@ import java.time.LocalDateTime;
 
 public class ProductDefinitionCommand {
 
+  public enum Action {
+    ACTIVATE,
+    DEACTIVATE
+  }
+
   @NotNull
-  private String action;
+  private Action action;
   private String note;
   private String createdBy;
   private LocalDateTime createdOn;
@@ -31,11 +36,11 @@ public class ProductDefinitionCommand {
   }
 
   public String getAction() {
-    return this.action;
+    return this.action.name();
   }
 
   public void setAction(final String action) {
-    this.action = action;
+    this.action = Action.valueOf(action);
   }
 
   public String getNote() {
diff --git a/api/src/main/java/io/mifos/deposit/api/v1/instance/domain/State.java b/api/src/main/java/io/mifos/deposit/api/v1/instance/domain/State.java
deleted file mode 100644
index deebfc6..0000000
--- a/api/src/main/java/io/mifos/deposit/api/v1/instance/domain/State.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * 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.api.v1.instance.domain;
-
-import javax.validation.constraints.NotNull;
-import java.time.LocalDateTime;
-
-public class State {
-
-  @NotNull
-  private Value value;
-  private String note;
-  private String createdBy;
-  private LocalDateTime createdOn;
-  public State() {
-    super();
-  }
-
-  public String getValue() {
-    return this.value.name();
-  }
-
-  public void setValue(final String value) {
-    this.value = Value.valueOf(value);
-  }
-
-  public String getNote() {
-    return this.note;
-  }
-
-  public void setNote(final String note) {
-    this.note = note;
-  }
-
-  public String getCreatedBy() {
-    return this.createdBy;
-  }
-
-  public void setCreatedBy(final String createdBy) {
-    this.createdBy = createdBy;
-  }
-
-  public LocalDateTime getCreatedOn() {
-    return this.createdOn;
-  }
-
-  public void setCreatedOn(final LocalDateTime createdOn) {
-    this.createdOn = createdOn;
-  }
-
-  public enum Value {
-    PENDING,
-    OPEN,
-    LOCKED,
-    CLOSED
-  }
-}
diff --git a/service/src/main/java/io/mifos/deposit/service/internal/command/ActivateProductDefinitionCommand.java
b/service/src/main/java/io/mifos/deposit/service/internal/command/ActivateProductDefinitionCommand.java
new file mode 100644
index 0000000..9acf6e8
--- /dev/null
+++ b/service/src/main/java/io/mifos/deposit/service/internal/command/ActivateProductDefinitionCommand.java
@@ -0,0 +1,38 @@
+/*
+ * 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;
+
+import io.mifos.deposit.api.v1.definition.domain.ProductDefinitionCommand;
+
+public class ActivateProductDefinitionCommand {
+
+  private final String identifier;
+  private final ProductDefinitionCommand command;
+
+  public ActivateProductDefinitionCommand(final String identifier, final ProductDefinitionCommand
command) {
+    super();
+    this.identifier = identifier;
+    this.command = command;
+  }
+
+  public String identifier() {
+    return this.identifier;
+  }
+
+  public ProductDefinitionCommand command() {
+    return this.command;
+  }
+}
diff --git a/service/src/main/java/io/mifos/deposit/service/internal/command/DeactivateProductDefinitionCommand.java
b/service/src/main/java/io/mifos/deposit/service/internal/command/DeactivateProductDefinitionCommand.java
new file mode 100644
index 0000000..a0c1da2
--- /dev/null
+++ b/service/src/main/java/io/mifos/deposit/service/internal/command/DeactivateProductDefinitionCommand.java
@@ -0,0 +1,38 @@
+/*
+ * 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;
+
+import io.mifos.deposit.api.v1.definition.domain.ProductDefinitionCommand;
+
+public class DeactivateProductDefinitionCommand {
+
+  private final String identifier;
+  private final ProductDefinitionCommand command;
+
+  public DeactivateProductDefinitionCommand(final String identifer, final ProductDefinitionCommand
command) {
+    super();
+    this.identifier = identifer;
+    this.command = command;
+  }
+
+  public String identifier() {
+    return this.identifier;
+  }
+
+  public ProductDefinitionCommand command() {
+    return this.command;
+  }
+}
diff --git a/service/src/main/java/io/mifos/deposit/service/internal/command/handler/ProductDefinitionAggregate.java
b/service/src/main/java/io/mifos/deposit/service/internal/command/handler/ProductDefinitionAggregate.java
index fcd4968..f37211a 100644
--- a/service/src/main/java/io/mifos/deposit/service/internal/command/handler/ProductDefinitionAggregate.java
+++ b/service/src/main/java/io/mifos/deposit/service/internal/command/handler/ProductDefinitionAggregate.java
@@ -15,36 +15,49 @@
  */
 package io.mifos.deposit.service.internal.command.handler;
 
+import io.mifos.core.api.util.UserContextHolder;
 import io.mifos.core.command.annotation.Aggregate;
 import io.mifos.core.command.annotation.CommandHandler;
 import io.mifos.core.command.annotation.EventEmitter;
 import io.mifos.deposit.api.v1.EventConstants;
 import io.mifos.deposit.api.v1.definition.domain.ProductDefinition;
+import io.mifos.deposit.api.v1.definition.domain.ProductDefinitionCommand;
 import io.mifos.deposit.service.ServiceConstants;
+import io.mifos.deposit.service.internal.command.ActivateProductDefinitionCommand;
 import io.mifos.deposit.service.internal.command.CreateProductDefinitionCommand;
+import io.mifos.deposit.service.internal.command.DeactivateProductDefinitionCommand;
+import io.mifos.deposit.service.internal.mapper.ProductDefinitionCommandMapper;
 import io.mifos.deposit.service.internal.mapper.ProductDefinitionMapper;
 import io.mifos.deposit.service.internal.repository.ActionRepository;
+import io.mifos.deposit.service.internal.repository.ProductDefinitionCommandRepository;
 import io.mifos.deposit.service.internal.repository.ProductDefinitionEntity;
 import io.mifos.deposit.service.internal.repository.ProductDefinitionRepository;
 import org.slf4j.Logger;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
 
+import java.time.Clock;
+import java.time.LocalDateTime;
+import java.util.Optional;
+
 @Aggregate
 public class ProductDefinitionAggregate {
 
   private final Logger logger;
   private final ProductDefinitionRepository productDefinitionRepository;
   private final ActionRepository actionRepository;
+  private final ProductDefinitionCommandRepository productDefinitionCommandRepository;
 
   @Autowired
   public ProductDefinitionAggregate(@Qualifier(ServiceConstants.LOGGER_NAME) final Logger
logger,
                                     final ProductDefinitionRepository productDefinitionRepository,
-                                    final ActionRepository actionRepository) {
+                                    final ActionRepository actionRepository,
+                                    final ProductDefinitionCommandRepository productDefinitionCommandRepository)
{
     super();
     this.logger = logger;
     this.productDefinitionRepository = productDefinitionRepository;
     this.actionRepository = actionRepository;
+    this.productDefinitionCommandRepository = productDefinitionCommandRepository;
   }
 
   @CommandHandler
@@ -56,8 +69,54 @@ public class ProductDefinitionAggregate {
     final ProductDefinitionEntity productDefinitionEntity =
         ProductDefinitionMapper.map(productDefinition, this.actionRepository);
 
+    productDefinitionEntity.setCreatedBy(UserContextHolder.checkedGetUser());
+    productDefinitionEntity.setCreatedOn(LocalDateTime.now(Clock.systemUTC()));
+
     this.productDefinitionRepository.save(productDefinitionEntity);
 
     return createProductDefinitionCommand.productDefinition().getIdentifier();
   }
+
+  @CommandHandler
+  @EventEmitter(selectorName = EventConstants.SELECTOR_NAME, selectorValue = EventConstants.POST_PRODUCT_DEFINITION_COMMAND)
+  public String activateProductdefintion(final ActivateProductDefinitionCommand activateProductDefinitionCommand)
{
+    final Optional<ProductDefinitionEntity> optionalProductDefinition = productDefinitionRepository.findByIdentifier(activateProductDefinitionCommand.identifier());
+
+    if (optionalProductDefinition.isPresent()) {
+      final ProductDefinitionCommand command = activateProductDefinitionCommand.command();
+
+      final ProductDefinitionEntity productDefinitionEntity = optionalProductDefinition.get();
+      productDefinitionEntity.setActive(Boolean.TRUE);
+      productDefinitionEntity.setLastModifiedBy(command.getCreatedBy());
+      productDefinitionEntity.setLastModifiedBy(command.getCreatedBy());
+      this.productDefinitionRepository.save(productDefinitionEntity);
+
+      this.productDefinitionCommandRepository.save(ProductDefinitionCommandMapper.map(command));
+      return activateProductDefinitionCommand.identifier();
+    } else {
+      this.logger.warn("Could not activate production definition {}, not found.", activateProductDefinitionCommand.identifier());
+      return null;
+    }
+  }
+
+  @CommandHandler
+  @EventEmitter(selectorName = EventConstants.SELECTOR_NAME, selectorValue = EventConstants.POST_PRODUCT_DEFINITION_COMMAND)
+  public String deactivateProductdefintion(final DeactivateProductDefinitionCommand activateProductDefinitionCommand)
{
+    final Optional<ProductDefinitionEntity> optionalProductDefinition = productDefinitionRepository.findByIdentifier(activateProductDefinitionCommand.identifier());
+
+    if (optionalProductDefinition.isPresent()) {
+      final ProductDefinitionCommand command = activateProductDefinitionCommand.command();
+
+      final ProductDefinitionEntity productDefinitionEntity = optionalProductDefinition.get();productDefinitionEntity.setActive(Boolean.FALSE);
+      productDefinitionEntity.setLastModifiedBy(command.getCreatedBy());
+      productDefinitionEntity.setLastModifiedBy(command.getCreatedBy());
+      this.productDefinitionRepository.save(productDefinitionEntity);
+
+      this.productDefinitionCommandRepository.save(ProductDefinitionCommandMapper.map(command));
+      return activateProductDefinitionCommand.identifier();
+    } else {
+      this.logger.warn("Could not activate production definition {}, not found.", activateProductDefinitionCommand.identifier());
+      return null;
+    }
+  }
 }
diff --git a/service/src/main/java/io/mifos/deposit/service/internal/mapper/ProductDefinitionCommandMapper.java
b/service/src/main/java/io/mifos/deposit/service/internal/mapper/ProductDefinitionCommandMapper.java
new file mode 100644
index 0000000..288ea70
--- /dev/null
+++ b/service/src/main/java/io/mifos/deposit/service/internal/mapper/ProductDefinitionCommandMapper.java
@@ -0,0 +1,46 @@
+/*
+ * 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.mapper;
+
+import io.mifos.deposit.api.v1.definition.domain.ProductDefinitionCommand;
+import io.mifos.deposit.service.internal.repository.ProductDefinitionCommandEntity;
+
+public class ProductDefinitionCommandMapper {
+
+  private ProductDefinitionCommandMapper() {
+    super();
+  }
+
+  public static ProductDefinitionCommandEntity map(final ProductDefinitionCommand command)
{
+    final ProductDefinitionCommandEntity entity = new ProductDefinitionCommandEntity();
+    entity.setAction(command.getAction());
+    entity.setNote(command.getNote());
+    entity.setCreatedBy(command.getCreatedBy());
+    entity.setCreatedOn(command.getCreatedOn());
+
+    return entity;
+  }
+
+  public static ProductDefinitionCommand map(final ProductDefinitionCommandEntity entity)
{
+    final ProductDefinitionCommand command = new ProductDefinitionCommand();
+    command.setAction(entity.getAction());
+    command.setNote(entity.getNote());
+    command.setCreatedBy(entity.getCreatedBy());
+    command.setCreatedOn(entity.getCreatedOn());
+
+    return command;
+  }
+}
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/ProductDefinitionCommandEntity.java
similarity index 60%
copy from service/src/main/java/io/mifos/deposit/service/internal/repository/ProductInstanceEntity.java
copy to service/src/main/java/io/mifos/deposit/service/internal/repository/ProductDefinitionCommandEntity.java
index c75edeb..a3c9dc2 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/ProductDefinitionCommandEntity.java
@@ -15,8 +15,6 @@
  */
 package io.mifos.deposit.service.internal.repository;
 
-import io.mifos.deposit.api.v1.definition.domain.ProductDefinition;
-
 import javax.persistence.CascadeType;
 import javax.persistence.Column;
 import javax.persistence.Entity;
@@ -27,26 +25,29 @@ import javax.persistence.Id;
 import javax.persistence.JoinColumn;
 import javax.persistence.ManyToOne;
 import javax.persistence.Table;
+import java.time.LocalDateTime;
 
 @Entity
-@Table(name = "shed_product_instance")
-public class ProductInstanceEntity {
+@Table(name = "shed_commands")
+public class ProductDefinitionCommandEntity {
 
   @Id
   @GeneratedValue(strategy = GenerationType.IDENTITY)
   @Column(name = "id", nullable = false)
   private Long id;
-  @Column(name = "customer_identifier", nullable = false)
-  private String customerIdentifier;
-  @ManyToOne(fetch = FetchType.EAGER, optional = false, cascade = CascadeType.ALL)
+  @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
   @JoinColumn(name = "product_definition_id", nullable = false)
   private ProductDefinitionEntity productDefinition;
-  @Column(name = "account_identifier", nullable = false)
-  private String accountIdentifier;
-  @Column(name = "a_state", nullable = false)
-  private String state;
+  @Column(name = "a_action", nullable = false)
+  private String action;
+  @Column(name = "note", nullable = false)
+  private String note;
+  @Column(name = "created_by", nullable = false, length = 32)
+  private String createdBy;
+  @Column(name = "created_on", nullable = false)
+  private LocalDateTime createdOn;
 
-  public ProductInstanceEntity() {
+  public ProductDefinitionCommandEntity() {
     super();
   }
 
@@ -58,14 +59,6 @@ public class ProductInstanceEntity {
     this.id = id;
   }
 
-  public String getCustomerIdentifier() {
-    return this.customerIdentifier;
-  }
-
-  public void setCustomerIdentifier(final String customerIdentifier) {
-    this.customerIdentifier = customerIdentifier;
-  }
-
   public ProductDefinitionEntity getProductDefinition() {
     return this.productDefinition;
   }
@@ -74,19 +67,35 @@ public class ProductInstanceEntity {
     this.productDefinition = productDefinition;
   }
 
-  public String getAccountIdentifier() {
-    return this.accountIdentifier;
+  public String getAction() {
+    return this.action;
+  }
+
+  public void setAction(final String action) {
+    this.action = action;
+  }
+
+  public String getNote() {
+    return this.note;
+  }
+
+  public void setNote(final String note) {
+    this.note = note;
+  }
+
+  public String getCreatedBy() {
+    return this.createdBy;
   }
 
-  public void setAccountIdentifier(final String accountIdentifier) {
-    this.accountIdentifier = accountIdentifier;
+  public void setCreatedBy(final String createdBy) {
+    this.createdBy = createdBy;
   }
 
-  public String getState() {
-    return this.state;
+  public LocalDateTime getCreatedOn() {
+    return this.createdOn;
   }
 
-  public void setState(final String state) {
-    this.state = state;
+  public void setCreatedOn(final LocalDateTime createdOn) {
+    this.createdOn = createdOn;
   }
 }
diff --git a/service/src/main/java/io/mifos/deposit/service/internal/repository/ProductDefinitionCommandRepository.java
b/service/src/main/java/io/mifos/deposit/service/internal/repository/ProductDefinitionCommandRepository.java
new file mode 100644
index 0000000..f9129c3
--- /dev/null
+++ b/service/src/main/java/io/mifos/deposit/service/internal/repository/ProductDefinitionCommandRepository.java
@@ -0,0 +1,25 @@
+/*
+ * 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.repository;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import java.util.List;
+
+public interface ProductDefinitionCommandRepository extends JpaRepository<ProductDefinitionCommandEntity,
Long> {
+
+  List<ProductDefinitionCommandEntity> findByProductDefinition(final ProductDefinitionEntity
productDefinitionEntity);
+}
diff --git a/service/src/main/java/io/mifos/deposit/service/internal/repository/ProductDefinitionEntity.java
b/service/src/main/java/io/mifos/deposit/service/internal/repository/ProductDefinitionEntity.java
index a916661..f5ec1d9 100644
--- a/service/src/main/java/io/mifos/deposit/service/internal/repository/ProductDefinitionEntity.java
+++ b/service/src/main/java/io/mifos/deposit/service/internal/repository/ProductDefinitionEntity.java
@@ -15,8 +15,11 @@
  */
 package io.mifos.deposit.service.internal.repository;
 
+import io.mifos.core.mariadb.util.LocalDateTimeConverter;
+
 import javax.persistence.CascadeType;
 import javax.persistence.Column;
+import javax.persistence.Convert;
 import javax.persistence.Entity;
 import javax.persistence.FetchType;
 import javax.persistence.GeneratedValue;
@@ -25,6 +28,7 @@ import javax.persistence.Id;
 import javax.persistence.OneToMany;
 import javax.persistence.OneToOne;
 import javax.persistence.Table;
+import java.time.LocalDateTime;
 import java.util.List;
 
 @Entity
@@ -61,6 +65,16 @@ public class ProductDefinitionEntity {
   private Boolean flexible;
   @Column(name = "is_active", nullable = false)
   private Boolean active;
+  @Column(name = "created_by", nullable = false, length = 32)
+  private String createdBy;
+  @Convert(converter = LocalDateTimeConverter.class)
+  @Column(name = "created_on", nullable = false)
+  private LocalDateTime createdOn;
+  @Column(name = "last_modified_by", nullable = false, length = 32)
+  private String lastModifiedBy;
+  @Convert(converter = LocalDateTimeConverter.class)
+  @Column(name = "last_modified_on", nullable = false)
+  private LocalDateTime lastModifiedOn;
 
   public ProductDefinitionEntity() {
     super();
@@ -180,4 +194,36 @@ public class ProductDefinitionEntity {
   public void setActive(final Boolean active) {
     this.active = active;
   }
+
+  public String getCreatedBy() {
+    return this.createdBy;
+  }
+
+  public void setCreatedBy(final String createdBy) {
+    this.createdBy = createdBy;
+  }
+
+  public LocalDateTime getCreatedOn() {
+    return this.createdOn;
+  }
+
+  public void setCreatedOn(final LocalDateTime createdOn) {
+    this.createdOn = createdOn;
+  }
+
+  public String getLastModifiedBy() {
+    return this.lastModifiedBy;
+  }
+
+  public void setLastModifiedBy(final String lastModifiedBy) {
+    this.lastModifiedBy = lastModifiedBy;
+  }
+
+  public LocalDateTime getLastModifiedOn() {
+    return this.lastModifiedOn;
+  }
+
+  public void setLastModifiedOn(final LocalDateTime lastModifiedOn) {
+    this.lastModifiedOn = lastModifiedOn;
+  }
 }
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 c75edeb..5171699 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,10 +15,11 @@
  */
 package io.mifos.deposit.service.internal.repository;
 
-import io.mifos.deposit.api.v1.definition.domain.ProductDefinition;
+import io.mifos.core.mariadb.util.LocalDateTimeConverter;
 
 import javax.persistence.CascadeType;
 import javax.persistence.Column;
+import javax.persistence.Convert;
 import javax.persistence.Entity;
 import javax.persistence.FetchType;
 import javax.persistence.GeneratedValue;
@@ -27,9 +28,10 @@ import javax.persistence.Id;
 import javax.persistence.JoinColumn;
 import javax.persistence.ManyToOne;
 import javax.persistence.Table;
+import java.time.LocalDateTime;
 
 @Entity
-@Table(name = "shed_product_instance")
+@Table(name = "shed_product_instances")
 public class ProductInstanceEntity {
 
   @Id
@@ -45,6 +47,16 @@ public class ProductInstanceEntity {
   private String accountIdentifier;
   @Column(name = "a_state", nullable = false)
   private String state;
+  @Column(name = "created_by", nullable = false, length = 32)
+  private String createdBy;
+  @Convert(converter = LocalDateTimeConverter.class)
+  @Column(name = "created_on", nullable = false)
+  private LocalDateTime createdOn;
+  @Column(name = "last_modified_by", nullable = false, length = 32)
+  private String lastModifiedBy;
+  @Convert(converter = LocalDateTimeConverter.class)
+  @Column(name = "last_modified_on", nullable = false)
+  private LocalDateTime lastModifiedOn;
 
   public ProductInstanceEntity() {
     super();
@@ -89,4 +101,36 @@ public class ProductInstanceEntity {
   public void setState(final String state) {
     this.state = state;
   }
+
+  public String getCreatedBy() {
+    return this.createdBy;
+  }
+
+  public void setCreatedBy(final String createdBy) {
+    this.createdBy = createdBy;
+  }
+
+  public LocalDateTime getCreatedOn() {
+    return this.createdOn;
+  }
+
+  public void setCreatedOn(final LocalDateTime createdOn) {
+    this.createdOn = createdOn;
+  }
+
+  public String getLastModifiedBy() {
+    return this.lastModifiedBy;
+  }
+
+  public void setLastModifiedBy(final String lastModifiedBy) {
+    this.lastModifiedBy = lastModifiedBy;
+  }
+
+  public LocalDateTime getLastModifiedOn() {
+    return this.lastModifiedOn;
+  }
+
+  public void setLastModifiedOn(final LocalDateTime lastModifiedOn) {
+    this.lastModifiedOn = lastModifiedOn;
+  }
 }
diff --git a/service/src/main/java/io/mifos/deposit/service/internal/service/ProductDefinitionService.java
b/service/src/main/java/io/mifos/deposit/service/internal/service/ProductDefinitionService.java
index 770387f..24baf6a 100644
--- a/service/src/main/java/io/mifos/deposit/service/internal/service/ProductDefinitionService.java
+++ b/service/src/main/java/io/mifos/deposit/service/internal/service/ProductDefinitionService.java
@@ -16,15 +16,18 @@
 package io.mifos.deposit.service.internal.service;
 
 import io.mifos.deposit.api.v1.definition.domain.ProductDefinition;
+import io.mifos.deposit.api.v1.definition.domain.ProductDefinitionCommand;
 import io.mifos.deposit.service.ServiceConstants;
+import io.mifos.deposit.service.internal.mapper.ProductDefinitionCommandMapper;
 import io.mifos.deposit.service.internal.mapper.ProductDefinitionMapper;
-import io.mifos.deposit.service.internal.repository.ActionRepository;
+import io.mifos.deposit.service.internal.repository.ProductDefinitionCommandRepository;
 import io.mifos.deposit.service.internal.repository.ProductDefinitionRepository;
 import org.slf4j.Logger;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.stereotype.Service;
 
+import java.util.Collections;
 import java.util.List;
 import java.util.Optional;
 import java.util.stream.Collectors;
@@ -34,16 +37,16 @@ public class ProductDefinitionService {
 
   private final Logger logger;
   private final ProductDefinitionRepository productDefinitionRepository;
-  private final ActionRepository actionRepository;
+  private final ProductDefinitionCommandRepository productDefinitionCommandRepository;
 
   @Autowired
   public ProductDefinitionService(@Qualifier(ServiceConstants.LOGGER_NAME) final Logger logger,
                                   final ProductDefinitionRepository productDefinitionRepository,
-                                  final ActionRepository actionRepository) {
+                                  final ProductDefinitionCommandRepository productDefinitionCommandRepository)
{
     super();
     this.logger = logger;
     this.productDefinitionRepository = productDefinitionRepository;
-    this.actionRepository = actionRepository;
+    this.productDefinitionCommandRepository = productDefinitionCommandRepository;
   }
 
   public List<ProductDefinition> fetchProductDefinitions() {
@@ -53,7 +56,16 @@ public class ProductDefinitionService {
         .collect(Collectors.toList());
   }
 
-  public Optional<ProductDefinition> findProductDefinition(final String identfier)
{
-    return this.productDefinitionRepository.findByIdentifier(identfier).map(ProductDefinitionMapper::map);
+  public Optional<ProductDefinition> findProductDefinition(final String identifier)
{
+    return this.productDefinitionRepository.findByIdentifier(identifier).map(ProductDefinitionMapper::map);
+  }
+
+  public List<ProductDefinitionCommand> findCommands(final String identifier) {
+    return this.productDefinitionRepository.findByIdentifier(identifier)
+        .map(productDefinitionEntity -> this.productDefinitionCommandRepository.findByProductDefinition(productDefinitionEntity)
+            .stream()
+            .map(ProductDefinitionCommandMapper::map)
+            .collect(Collectors.toList()))
+        .orElseGet(Collections::emptyList);
   }
 }
diff --git a/service/src/main/java/io/mifos/deposit/service/internal/service/ProductInstanceService.java
b/service/src/main/java/io/mifos/deposit/service/internal/service/ProductInstanceService.java
index 842b7e1..e16698a 100644
--- a/service/src/main/java/io/mifos/deposit/service/internal/service/ProductInstanceService.java
+++ b/service/src/main/java/io/mifos/deposit/service/internal/service/ProductInstanceService.java
@@ -15,12 +15,9 @@
  */
 package io.mifos.deposit.service.internal.service;
 
-import io.mifos.deposit.api.v1.definition.domain.ProductDefinition;
 import io.mifos.deposit.api.v1.instance.domain.ProductInstance;
 import io.mifos.deposit.service.ServiceConstants;
-import io.mifos.deposit.service.internal.mapper.ProductDefinitionMapper;
 import io.mifos.deposit.service.internal.mapper.ProductInstanceMapper;
-import io.mifos.deposit.service.internal.repository.ActionRepository;
 import io.mifos.deposit.service.internal.repository.ProductDefinitionEntity;
 import io.mifos.deposit.service.internal.repository.ProductDefinitionRepository;
 import io.mifos.deposit.service.internal.repository.ProductInstanceRepository;
diff --git a/service/src/main/java/io/mifos/deposit/service/rest/ProductDefinitionRestController.java
b/service/src/main/java/io/mifos/deposit/service/rest/ProductDefinitionRestController.java
index 62ec1f9..3a9583f 100644
--- a/service/src/main/java/io/mifos/deposit/service/rest/ProductDefinitionRestController.java
+++ b/service/src/main/java/io/mifos/deposit/service/rest/ProductDefinitionRestController.java
@@ -24,8 +24,9 @@ import io.mifos.deposit.api.v1.definition.domain.ProductDefinition;
 import io.mifos.deposit.api.v1.definition.domain.ProductDefinitionCommand;
 import io.mifos.deposit.api.v1.instance.domain.ProductInstance;
 import io.mifos.deposit.service.ServiceConstants;
+import io.mifos.deposit.service.internal.command.ActivateProductDefinitionCommand;
 import io.mifos.deposit.service.internal.command.CreateProductDefinitionCommand;
-import io.mifos.deposit.service.internal.repository.ProductInstanceRepository;
+import io.mifos.deposit.service.internal.command.DeactivateProductDefinitionCommand;
 import io.mifos.deposit.service.internal.service.ProductDefinitionService;
 import io.mifos.deposit.service.internal.service.ProductInstanceService;
 import org.slf4j.Logger;
@@ -132,6 +133,40 @@ public class ProductDefinitionRestController {
   @ResponseBody
   public ResponseEntity<Void> process(@PathVariable("identifier") final String identifier,
                                       @RequestBody @Valid final ProductDefinitionCommand
command) {
-    return ResponseEntity.accepted().build();
+
+    final Optional<ProductDefinition> optionalProductDefinition = this.productDefinitionService.findProductDefinition(identifier);
+    if (!optionalProductDefinition.isPresent()) {
+      throw ServiceException.notFound("Product definition {0} not found.", identifier);
+    } else {
+      switch (ProductDefinitionCommand.Action.valueOf(command.getAction())) {
+        case ACTIVATE:
+          this.commandGateway.process(new ActivateProductDefinitionCommand(identifier, command));
+          break;
+        case DEACTIVATE:
+          this.commandGateway.process(new DeactivateProductDefinitionCommand(identifier,
command));
+          break;
+        default:
+          throw ServiceException.badRequest("Unsupported product definition command {0}.",
command.getAction());
+      }
+      return ResponseEntity.accepted().build();
+    }
+  }
+
+  @Permittable(value = AcceptedTokenType.TENANT, groupId = PermittableGroupIds.DEFINITION_MANAGEMENT)
+  @RequestMapping(
+      value = "/{identifier}/commands",
+      method = RequestMethod.GET,
+      consumes = MediaType.ALL_VALUE,
+      produces = MediaType.APPLICATION_JSON_VALUE
+  )
+  @ResponseBody
+  public ResponseEntity<List<ProductDefinitionCommand>> getProductDefinitionCommands(@PathVariable("identifier")
final String identifier) {
+
+    final Optional<ProductDefinition> optionalProductDefinition = this.productDefinitionService.findProductDefinition(identifier);
+    if (!optionalProductDefinition.isPresent()) {
+      throw ServiceException.notFound("Product definition {0} not found.", identifier);
+    } else {
+      return ResponseEntity.ok(this.productDefinitionService.findCommands(identifier));
+    }
   }
 }
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 e833070..157890c 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
@@ -20,7 +20,6 @@ import io.mifos.anubis.annotation.Permittable;
 import io.mifos.core.command.gateway.CommandGateway;
 import io.mifos.deposit.api.v1.PermittableGroupIds;
 import io.mifos.deposit.api.v1.instance.domain.ProductInstance;
-import io.mifos.deposit.api.v1.instance.domain.StateChange;
 import io.mifos.deposit.service.ServiceConstants;
 import io.mifos.deposit.service.internal.service.ProductInstanceService;
 import org.slf4j.Logger;
@@ -28,7 +27,6 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.http.MediaType;
 import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestMethod;
@@ -37,7 +35,6 @@ import org.springframework.web.bind.annotation.ResponseBody;
 import org.springframework.web.bind.annotation.RestController;
 
 import javax.validation.Valid;
-import java.util.Collections;
 import java.util.List;
 
 @RestController
diff --git a/service/src/main/resources/db/migrations/mariadb/V1__initial_setup.sql b/service/src/main/resources/db/migrations/mariadb/V1__initial_setup.sql
index a25b381..9a2e18c 100644
--- a/service/src/main/resources/db/migrations/mariadb/V1__initial_setup.sql
+++ b/service/src/main/resources/db/migrations/mariadb/V1__initial_setup.sql
@@ -14,3 +14,117 @@
 -- limitations under the License.
 --
 
+CREATE TABLE shed_product_definitions (
+  id                         BIGINT         NOT NULL AUTO_INCREMENT,
+  a_type                     VARCHAR(32)    NOT NULL,
+  identifier                 VARCHAR(32)    NOT NULL,
+  a_name                     VARCHAR(256)   NOT NULL,
+  description                VARCHAR(2048)  NULL,
+  minimum_balance            NUMERIC(15, 5) NULL,
+  equity_ledger_identifier   VARCHAR(32)    NOT NULL,
+  expense_account_identifier VARCHAR(32)    NOT NULL,
+  interest                   NUMERIC(5, 2)  NULL,
+  is_flexible                BOOLEAN        NOT NULL,
+  is_active                  BOOLEAN        NOT NULL,
+  created_on                 TIMESTAMP(3)   NOT NULL,
+  created_by                 VARCHAR(32)    NOT NULL,
+  last_modified_on           TIMESTAMP(3)   NULL,
+  last_modified_by           VARCHAR(32)    NULL,
+  CONSTRAINT shed_product_definitions_pk PRIMARY KEY (id),
+  CONSTRAINT shed_prod_def_identifier_uq UNIQUE (identifier)
+);
+
+CREATE TABLE shed_currencies (
+  id                    BIGINT       NOT NULL AUTO_INCREMENT,
+  product_definition_id BIGINT       NOT NULL,
+  a_code                VARCHAR(4)   NOT NULL,
+  a_name                VARCHAR(256) NOT NULL,
+  sign                  VARCHAR(4)   NOT NULL,
+  scale                 INTEGER(5)   NOT NULL,
+  CONSTRAINT shed_currencies PRIMARY KEY (id),
+  CONSTRAINT shed_currencies_prod_def_fk FOREIGN KEY (product_definition_id) REFERENCES shed_product_definitions
(id)
+);
+
+CREATE TABLE shed_terms (
+  id                    BIGINT       NOT NULL AUTO_INCREMENT,
+  product_definition_id BIGINT       NOT NULL,
+  period                INTEGER(5)   NOT NULL,
+  time_unit             VARCHAR(32)  NOT NULL,
+  interest_payable      VARCHAR(32)  NOT NULL,
+  CONSTRAINT shed_terms PRIMARY KEY (id),
+  CONSTRAINT shed_terms_prod_def_fk FOREIGN KEY (product_definition_id) REFERENCES shed_product_definitions
(id)
+);
+
+CREATE TABLE shed_actions (
+  id               BIGINT        NOT NULL AUTO_INCREMENT,
+  identifier       VARCHAR(32)   NOT NULL,
+  a_name           VARCHAR(256)  NOT NULL,
+  description      VARCHAR(2048) NULL,
+  transaction_type VARCHAR(32)   NOT NULL,
+  CONSTRAINT shed_actions PRIMARY KEY (id)
+);
+
+INSERT INTO shed_actions
+  (identifier, a_name, transaction_type)
+VALUES
+  ('Open', 'Account Opening', 'ACCO');
+
+INSERT INTO shed_actions
+  (identifier, a_name, transaction_type)
+VALUES
+  ('Transfer', 'Account Transfer', 'ACCT');
+
+INSERT INTO shed_actions
+  (identifier, a_name, transaction_type)
+VALUES
+  ('Close', 'Account Closing', 'ACCC');
+
+INSERT INTO shed_actions
+  (identifier, a_name, transaction_type)
+VALUES
+  ('Deposit', 'Cash Deposit', 'CDPT');
+
+INSERT INTO shed_actions
+  (identifier, a_name, transaction_type)
+VALUES
+  ('Withdraw', 'Cash Withdrawal', 'CWDL');
+
+CREATE TABLE shed_charges (
+  id                        BIGINT        NOT NULL AUTO_INCREMENT,
+  identifier                VARCHAR(32)   NOT NULL,
+  action_id                 BIGINT        NOT NULL,
+  product_definition_id     BIGINT        NOT NULL,
+  income_account_identifier BIGINT        NOT NULL,
+  a_name                    VARCHAR(256)  NOT NULL,
+  description               VARCHAR(2048) NULL,
+  proportional              BOOLEAN   NOT NULL,
+  amount                    NUMERIC(5, 2)  NULL,
+  CONSTRAINT shed_charges PRIMARY KEY (id),
+  CONSTRAINT shed_charges_actions_fk FOREIGN KEY (action_id) REFERENCES shed_actions (id),
+  CONSTRAINT shed_charges_prod_def_fk FOREIGN KEY (product_definition_id) REFERENCES shed_product_definitions
(id)
+);
+
+CREATE TABLE shed_commands (
+  id                    BIGINT        NOT NULL AUTO_INCREMENT,
+  product_definition_id BIGINT        NOT NULL,
+  action                VARCHAR(256)  NOT NULL,
+  note                  VARCHAR(2048) NOT NULL,
+  created_on            TIMESTAMP(3)  NOT NULL,
+  created_by            VARCHAR(32)   NOT NULL,
+  CONSTRAINT shed_commands PRIMARY KEY (id),
+  CONSTRAINT shed_commands_prod_def_fk FOREIGN KEY (product_definition_id) REFERENCES shed_product_definitions
(id)
+);
+
+CREATE TABLE shed_product_instances (
+  id                    BIGINT       NOT NULL AUTO_INCREMENT,
+  customer_identifier   VARCHAR(32)  NOT NULL,
+  product_definition_id VARCHAR(32)  NOT NULL,
+  account_identifier    VARCHAR(32)  NOT NULL,
+  a_state               VARCHAR(32)  NOT NULL,
+  created_on            TIMESTAMP(3) NOT NULL,
+  created_by            VARCHAR(32)  NOT NULL,
+  last_modified_on      TIMESTAMP(3) NULL,
+  last_modified_by      VARCHAR(32)  NULL,
+  CONSTRAINT shed_product_instances_pk PRIMARY KEY (id),
+  CONSTRAINT shed_prod_inst_prod_def_fk FOREIGN KEY (product_definition_id) REFERENCES shed_product_definitions
(id)
+);

-- 
To stop receiving notification emails like this one, please contact
myrle@apache.org.

Mime
View raw message