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-customer.git
commit 02cda5acd170614eaa3ddd37c4ec0c801ea050cd Author: mgeiss <[email protected]> AuthorDate: Wed Sep 27 11:34:33 2017 +0200 added delete and update for catalogs and fields --- .../catalog/api/v1/CatalogEventConstants.java | 7 +- .../catalog/api/v1/client/CatalogManager.java | 44 +++++++ .../CatalogNotFoundException.java} | 12 +- .../io/mifos/customer/catalog/TestCatalog.java | 144 +++++++++++++++++++++ .../catalog/listener/CatalogEventListener.java | 30 ++++- .../internal/command/ChangeFieldCommand.java | 22 +++- .../internal/command/DeleteCatalogCommand.java | 18 +-- .../internal/command/DeleteFieldCommand.java | 22 +++- .../internal/command/handler/CatalogAggregate.java | 82 +++++++++++- .../internal/repository/FieldValueRepository.java | 3 + .../internal/repository/OptionRepository.java | 12 +- .../service/internal/service/CatalogService.java | 40 +++++- .../rest/controller/CatalogRestController.java | 65 ++++++++++ 13 files changed, 458 insertions(+), 43 deletions(-) diff --git a/api/src/main/java/io/mifos/customer/catalog/api/v1/CatalogEventConstants.java b/api/src/main/java/io/mifos/customer/catalog/api/v1/CatalogEventConstants.java index 97b4955..7226fa0 100644 --- a/api/src/main/java/io/mifos/customer/catalog/api/v1/CatalogEventConstants.java +++ b/api/src/main/java/io/mifos/customer/catalog/api/v1/CatalogEventConstants.java @@ -22,6 +22,11 @@ public interface CatalogEventConstants { String SELECTOR_NAME = "action"; String POST_CATALOG = "post-catalog"; - String SELECTOR_POST_CATALOG = SELECTOR_NAME + " = '" + POST_CATALOG + "'"; + String DELETE_CATALOG = "delete-catalog"; + String SELECTOR_DELETE_CATALOG = SELECTOR_NAME + " = '" + DELETE_CATALOG + "'"; + String DELETE_FIELD = "delete-field"; + String SELECTOR_DELETE_FIELD = SELECTOR_NAME + " = '" + DELETE_FIELD + "'"; + String PUT_FIELD = "put-field"; + String SELECTOR_PUT_FIELD = SELECTOR_NAME + " = '" + PUT_FIELD + "'"; } diff --git a/api/src/main/java/io/mifos/customer/catalog/api/v1/client/CatalogManager.java b/api/src/main/java/io/mifos/customer/catalog/api/v1/client/CatalogManager.java index cc41531..edf7341 100644 --- a/api/src/main/java/io/mifos/customer/catalog/api/v1/client/CatalogManager.java +++ b/api/src/main/java/io/mifos/customer/catalog/api/v1/client/CatalogManager.java @@ -19,6 +19,7 @@ import io.mifos.core.api.annotation.ThrowsException; import io.mifos.core.api.annotation.ThrowsExceptions; import io.mifos.core.api.util.CustomFeignClientsConfiguration; import io.mifos.customer.catalog.api.v1.domain.Catalog; +import io.mifos.customer.catalog.api.v1.domain.Field; import org.springframework.cloud.netflix.feign.FeignClient; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; @@ -59,5 +60,48 @@ public interface CatalogManager { produces = MediaType.ALL_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE ) + @ThrowsExceptions({ + @ThrowsException(status = HttpStatus.NOT_FOUND, exception = CatalogNotFoundException.class) + }) Catalog findCatalog(@PathVariable("identifier") final String identifier); + + @RequestMapping( + path = "/catalogs/{identifier}", + method = RequestMethod.DELETE, + produces = MediaType.ALL_VALUE, + consumes = MediaType.APPLICATION_JSON_VALUE + ) + @ThrowsExceptions({ + @ThrowsException(status = HttpStatus.NOT_FOUND, exception = CatalogNotFoundException.class), + @ThrowsException(status = HttpStatus.BAD_REQUEST, exception = CatalogValidationException.class) + }) + void deleteCatalog(@PathVariable("identifier") final String identifier); + + @RequestMapping( + path = "/catalogs/{catalogIdentifier}/fields/{fieldIdentifier}", + method = RequestMethod.PUT, + produces = MediaType.APPLICATION_JSON_VALUE, + consumes = MediaType.APPLICATION_JSON_VALUE + ) + @ThrowsExceptions({ + @ThrowsException(status = HttpStatus.NOT_FOUND, exception = CatalogNotFoundException.class), + @ThrowsException(status = HttpStatus.BAD_REQUEST, exception = CatalogValidationException.class) + }) + void updateField(@PathVariable("catalogIdentifier") final String catalogIdentifier, + @PathVariable("fieldIdentifier") final String fieldIdentifier, + @RequestBody Field field); + + @RequestMapping( + path = "/catalogs/{catalogIdentifier}/fields/{fieldIdentifier}", + method = RequestMethod.DELETE, + produces = MediaType.ALL_VALUE, + consumes = MediaType.APPLICATION_JSON_VALUE + ) + @ThrowsExceptions({ + @ThrowsException(status = HttpStatus.NOT_FOUND, exception = CatalogNotFoundException.class), + @ThrowsException(status = HttpStatus.BAD_REQUEST, exception = CatalogValidationException.class) + }) + void deleteField(@PathVariable("catalogIdentifier") final String catalogIdentifier, + @PathVariable("fieldIdentifier") final String fieldIdentifier); + } diff --git a/api/src/main/java/io/mifos/customer/catalog/api/v1/CatalogEventConstants.java b/api/src/main/java/io/mifos/customer/catalog/api/v1/client/CatalogNotFoundException.java similarity index 69% copy from api/src/main/java/io/mifos/customer/catalog/api/v1/CatalogEventConstants.java copy to api/src/main/java/io/mifos/customer/catalog/api/v1/client/CatalogNotFoundException.java index 97b4955..ac58730 100644 --- a/api/src/main/java/io/mifos/customer/catalog/api/v1/CatalogEventConstants.java +++ b/api/src/main/java/io/mifos/customer/catalog/api/v1/client/CatalogNotFoundException.java @@ -13,15 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.mifos.customer.catalog.api.v1; +package io.mifos.customer.catalog.api.v1.client; -public interface CatalogEventConstants { - - String DESTINATION = "nun-v1"; - - String SELECTOR_NAME = "action"; - - String POST_CATALOG = "post-catalog"; - - String SELECTOR_POST_CATALOG = SELECTOR_NAME + " = '" + POST_CATALOG + "'"; +public class CatalogNotFoundException extends RuntimeException { } diff --git a/component-test/src/main/java/io/mifos/customer/catalog/TestCatalog.java b/component-test/src/main/java/io/mifos/customer/catalog/TestCatalog.java index 2fe10c6..4fd679d 100644 --- a/component-test/src/main/java/io/mifos/customer/catalog/TestCatalog.java +++ b/component-test/src/main/java/io/mifos/customer/catalog/TestCatalog.java @@ -15,6 +15,7 @@ */ package io.mifos.customer.catalog; +import com.google.common.collect.Lists; import io.mifos.anubis.test.v1.TenantApplicationSecurityEnvironmentTestRule; import io.mifos.core.api.context.AutoUserContext; import io.mifos.core.test.env.TestEnvironment; @@ -28,8 +29,10 @@ import io.mifos.customer.api.v1.client.CustomerManager; import io.mifos.customer.api.v1.domain.Customer; import io.mifos.customer.catalog.api.v1.CatalogEventConstants; import io.mifos.customer.catalog.api.v1.client.CatalogManager; +import io.mifos.customer.catalog.api.v1.client.CatalogValidationException; import io.mifos.customer.catalog.api.v1.domain.Catalog; import io.mifos.customer.catalog.api.v1.domain.Field; +import io.mifos.customer.catalog.api.v1.domain.Option; import io.mifos.customer.catalog.api.v1.domain.Value; import io.mifos.customer.catalog.util.CatalogGenerator; import io.mifos.customer.service.rest.config.CustomerRestConfiguration; @@ -54,6 +57,7 @@ import org.springframework.test.context.junit4.SpringRunner; import java.util.Arrays; import java.util.List; +import java.util.Optional; import java.util.stream.Collectors; @RunWith(SpringRunner.class) @@ -203,4 +207,144 @@ public class TestCatalog { final Customer savedCustomer = this.customerManager.findCustomer(randomCustomer.getIdentifier()); Assert.assertTrue(savedCustomer.getCustomValues().size() == 2); } + + @Test + public void shouldDeleteCatalog() throws Exception { + final Catalog catalog = CatalogGenerator.createRandomCatalog(); + + this.catalogManager.createCatalog(catalog); + this.eventRecorder.wait(CatalogEventConstants.POST_CATALOG, catalog.getIdentifier()); + + this.catalogManager.deleteCatalog(catalog.getIdentifier()); + Assert.assertTrue(this.eventRecorder.wait(CatalogEventConstants.DELETE_CATALOG, catalog.getIdentifier())); + } + + @Test(expected = CatalogValidationException.class) + public void shouldNotDeleteCatalogUsed() throws Exception { + final Catalog catalog = CatalogGenerator.createRandomCatalog(); + + this.catalogManager.createCatalog(catalog); + this.eventRecorder.wait(CatalogEventConstants.POST_CATALOG, catalog.getIdentifier()); + + final Customer randomCustomer = CustomerGenerator.createRandomCustomer(); + randomCustomer.setCustomValues(catalog.getFields() + .stream() + .map(field -> { + final Value value = new Value(); + value.setCatalogIdentifier(catalog.getIdentifier()); + value.setFieldIdentifier(field.getIdentifier()); + switch (Field.DataType.valueOf(field.getDataType())) { + case NUMBER: + value.setValue("25.00"); + break; + case SINGLE_SELECTION: + value.setValue("1"); + } + return value; + }) + .collect(Collectors.toList()) + ); + + this.customerManager.createCustomer(randomCustomer); + this.eventRecorder.wait(CustomerEventConstants.POST_CUSTOMER, randomCustomer.getIdentifier()); + + this.catalogManager.deleteCatalog(catalog.getIdentifier()); + } + + @Test + public void shouldDeleteField() throws Exception { + final Catalog catalog = CatalogGenerator.createRandomCatalog(); + + this.catalogManager.createCatalog(catalog); + this.eventRecorder.wait(CatalogEventConstants.POST_CATALOG, catalog.getIdentifier()); + + final Optional<Field> optionalField = catalog.getFields().stream().findFirst(); + optionalField.ifPresent(field -> { + this.catalogManager.deleteField(catalog.getIdentifier(), field.getIdentifier()); + try { + Assert.assertTrue(this.eventRecorder.wait(CatalogEventConstants.DELETE_FIELD, field.getIdentifier())); + } catch (final InterruptedException iex) { + Assert.fail(iex.getMessage()); + } + }); + + final Catalog savedCatalog = this.catalogManager.findCatalog(catalog.getIdentifier()); + Assert.assertEquals(1, savedCatalog.getFields().size()); + } + + @Test(expected = CatalogValidationException.class) + public void shouldNotDeleteField() throws Exception { + final Catalog catalog = CatalogGenerator.createRandomCatalog(); + + this.catalogManager.createCatalog(catalog); + this.eventRecorder.wait(CatalogEventConstants.POST_CATALOG, catalog.getIdentifier()); + + final Customer randomCustomer = CustomerGenerator.createRandomCustomer(); + randomCustomer.setCustomValues(catalog.getFields() + .stream() + .map(field -> { + final Value value = new Value(); + value.setCatalogIdentifier(catalog.getIdentifier()); + value.setFieldIdentifier(field.getIdentifier()); + switch (Field.DataType.valueOf(field.getDataType())) { + case NUMBER: + value.setValue("37.00"); + break; + case SINGLE_SELECTION: + value.setValue("1"); + } + return value; + }) + .collect(Collectors.toList()) + ); + + this.customerManager.createCustomer(randomCustomer); + this.eventRecorder.wait(CustomerEventConstants.POST_CUSTOMER, randomCustomer.getIdentifier()); + + final Optional<Field> optionalField = catalog.getFields().stream().findFirst(); + optionalField.ifPresent(field -> this.catalogManager.deleteField(catalog.getIdentifier(), field.getIdentifier())); + } + + @Test + public void shouldUpdateField() throws Exception { + final Catalog catalog = CatalogGenerator.createRandomCatalog(); + + this.catalogManager.createCatalog(catalog); + this.eventRecorder.wait(CatalogEventConstants.POST_CATALOG, catalog.getIdentifier()); + + final Optional<Field> optionalField = catalog.getFields() + .stream() + .filter(field -> field.getDataType().equals(Field.DataType.SINGLE_SELECTION.name())) + .findFirst(); + + optionalField.ifPresent(field -> { + final Option option = new Option(); + option.setLabel("new-option"); + option.setValue(2); + field.setOptions(Lists.newArrayList(option)); + this.catalogManager.updateField(catalog.getIdentifier(), field.getIdentifier(), field); + try { + Assert.assertTrue(this.eventRecorder.wait(CatalogEventConstants.PUT_FIELD, field.getIdentifier())); + } catch (final InterruptedException iex) { + Assert.fail(iex.getMessage()); + } + }); + + final Catalog savedCatalog = this.catalogManager.findCatalog(catalog.getIdentifier()); + final Optional<Field> optionalFetchedField = savedCatalog.getFields() + .stream() + .filter(field -> field.getDataType().equals(Field.DataType.SINGLE_SELECTION.name())) + .findFirst(); + + if (optionalFetchedField.isPresent()) { + final Field field = optionalFetchedField.get(); + Assert.assertEquals(1, field.getOptions().size()); + final Optional<Option> optionalOption = field.getOptions().stream().findFirst(); + Assert.assertTrue(optionalOption.isPresent()); + final Option option = optionalOption.get(); + Assert.assertEquals(Integer.valueOf(2), option.getValue()); + } else { + Assert.fail(); + } + } } diff --git a/component-test/src/main/java/io/mifos/customer/catalog/listener/CatalogEventListener.java b/component-test/src/main/java/io/mifos/customer/catalog/listener/CatalogEventListener.java index ad4575d..36d08ee 100644 --- a/component-test/src/main/java/io/mifos/customer/catalog/listener/CatalogEventListener.java +++ b/component-test/src/main/java/io/mifos/customer/catalog/listener/CatalogEventListener.java @@ -42,4 +42,32 @@ public class CatalogEventListener { public void customerCreatedEvent(@Header(TenantHeaderFilter.TENANT_HEADER) final String tenant, final String payload) { this.eventRecorder.event(tenant, CatalogEventConstants.POST_CATALOG, payload, String.class); - }} + } + + @JmsListener( + destination = CustomerEventConstants.DESTINATION, + selector = CatalogEventConstants.SELECTOR_DELETE_CATALOG + ) + public void onDeleteCatalog(@Header(TenantHeaderFilter.TENANT_HEADER) final String tenant, + final String payload) { + this.eventRecorder.event(tenant, CatalogEventConstants.DELETE_CATALOG, payload, String.class); + } + + @JmsListener( + destination = CustomerEventConstants.DESTINATION, + selector = CatalogEventConstants.SELECTOR_DELETE_FIELD + ) + public void onDeleteField(@Header(TenantHeaderFilter.TENANT_HEADER) final String tenant, + final String payload) { + this.eventRecorder.event(tenant, CatalogEventConstants.DELETE_FIELD, payload, String.class); + } + + @JmsListener( + destination = CustomerEventConstants.DESTINATION, + selector = CatalogEventConstants.SELECTOR_PUT_FIELD + ) + public void onChangeField(@Header(TenantHeaderFilter.TENANT_HEADER) final String tenant, + final String payload) { + this.eventRecorder.event(tenant, CatalogEventConstants.PUT_FIELD, payload, String.class); + } +} diff --git a/api/src/main/java/io/mifos/customer/catalog/api/v1/CatalogEventConstants.java b/service/src/main/java/io/mifos/customer/catalog/service/internal/command/ChangeFieldCommand.java similarity index 54% copy from api/src/main/java/io/mifos/customer/catalog/api/v1/CatalogEventConstants.java copy to service/src/main/java/io/mifos/customer/catalog/service/internal/command/ChangeFieldCommand.java index 97b4955..a0a100e 100644 --- a/api/src/main/java/io/mifos/customer/catalog/api/v1/CatalogEventConstants.java +++ b/service/src/main/java/io/mifos/customer/catalog/service/internal/command/ChangeFieldCommand.java @@ -13,15 +13,25 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.mifos.customer.catalog.api.v1; +package io.mifos.customer.catalog.service.internal.command; -public interface CatalogEventConstants { +import io.mifos.customer.catalog.api.v1.domain.Field; - String DESTINATION = "nun-v1"; +public class ChangeFieldCommand { + private final String catalogIdentifier; + private final Field field; - String SELECTOR_NAME = "action"; + public ChangeFieldCommand(final String catalogIdentifier, final Field field) { + super(); + this.catalogIdentifier = catalogIdentifier; + this.field = field; + } - String POST_CATALOG = "post-catalog"; + public String catalogIdentifier() { + return this.catalogIdentifier; + } - String SELECTOR_POST_CATALOG = SELECTOR_NAME + " = '" + POST_CATALOG + "'"; + public Field field() { + return this.field; + } } diff --git a/api/src/main/java/io/mifos/customer/catalog/api/v1/CatalogEventConstants.java b/service/src/main/java/io/mifos/customer/catalog/service/internal/command/DeleteCatalogCommand.java similarity index 66% copy from api/src/main/java/io/mifos/customer/catalog/api/v1/CatalogEventConstants.java copy to service/src/main/java/io/mifos/customer/catalog/service/internal/command/DeleteCatalogCommand.java index 97b4955..1545b09 100644 --- a/api/src/main/java/io/mifos/customer/catalog/api/v1/CatalogEventConstants.java +++ b/service/src/main/java/io/mifos/customer/catalog/service/internal/command/DeleteCatalogCommand.java @@ -13,15 +13,17 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.mifos.customer.catalog.api.v1; +package io.mifos.customer.catalog.service.internal.command; -public interface CatalogEventConstants { +public class DeleteCatalogCommand { + private final String identifier; - String DESTINATION = "nun-v1"; + public DeleteCatalogCommand(final String identifier) { + super(); + this.identifier = identifier; + } - String SELECTOR_NAME = "action"; - - String POST_CATALOG = "post-catalog"; - - String SELECTOR_POST_CATALOG = SELECTOR_NAME + " = '" + POST_CATALOG + "'"; + public String identifier() { + return this.identifier; + } } diff --git a/api/src/main/java/io/mifos/customer/catalog/api/v1/CatalogEventConstants.java b/service/src/main/java/io/mifos/customer/catalog/service/internal/command/DeleteFieldCommand.java similarity index 53% copy from api/src/main/java/io/mifos/customer/catalog/api/v1/CatalogEventConstants.java copy to service/src/main/java/io/mifos/customer/catalog/service/internal/command/DeleteFieldCommand.java index 97b4955..28c1cf5 100644 --- a/api/src/main/java/io/mifos/customer/catalog/api/v1/CatalogEventConstants.java +++ b/service/src/main/java/io/mifos/customer/catalog/service/internal/command/DeleteFieldCommand.java @@ -13,15 +13,23 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.mifos.customer.catalog.api.v1; +package io.mifos.customer.catalog.service.internal.command; -public interface CatalogEventConstants { +public class DeleteFieldCommand { + private final String catalogIdentifier; + private final String fieldIdentifier; - String DESTINATION = "nun-v1"; + public DeleteFieldCommand(final String catalogIdentifier, final String fieldIdentifier) { + super(); + this.catalogIdentifier = catalogIdentifier; + this.fieldIdentifier = fieldIdentifier; + } - String SELECTOR_NAME = "action"; + public String catalogIdentifier() { + return this.catalogIdentifier; + } - String POST_CATALOG = "post-catalog"; - - String SELECTOR_POST_CATALOG = SELECTOR_NAME + " = '" + POST_CATALOG + "'"; + public String fieldIdentifier() { + return this.fieldIdentifier; + } } diff --git a/service/src/main/java/io/mifos/customer/catalog/service/internal/command/handler/CatalogAggregate.java b/service/src/main/java/io/mifos/customer/catalog/service/internal/command/handler/CatalogAggregate.java index c464e3f..449f503 100644 --- a/service/src/main/java/io/mifos/customer/catalog/service/internal/command/handler/CatalogAggregate.java +++ b/service/src/main/java/io/mifos/customer/catalog/service/internal/command/handler/CatalogAggregate.java @@ -20,17 +20,26 @@ import io.mifos.core.command.annotation.CommandHandler; import io.mifos.core.command.annotation.EventEmitter; import io.mifos.customer.catalog.api.v1.CatalogEventConstants; import io.mifos.customer.catalog.api.v1.domain.Catalog; +import io.mifos.customer.catalog.api.v1.domain.Field; +import io.mifos.customer.catalog.service.internal.command.ChangeFieldCommand; import io.mifos.customer.catalog.service.internal.command.CreateCatalogCommand; +import io.mifos.customer.catalog.service.internal.command.DeleteCatalogCommand; +import io.mifos.customer.catalog.service.internal.command.DeleteFieldCommand; import io.mifos.customer.catalog.service.internal.mapper.CatalogMapper; import io.mifos.customer.catalog.service.internal.mapper.FieldMapper; +import io.mifos.customer.catalog.service.internal.mapper.OptionMapper; import io.mifos.customer.catalog.service.internal.repository.CatalogEntity; import io.mifos.customer.catalog.service.internal.repository.CatalogRepository; +import io.mifos.customer.catalog.service.internal.repository.FieldEntity; +import io.mifos.customer.catalog.service.internal.repository.FieldRepository; +import io.mifos.customer.catalog.service.internal.repository.OptionRepository; import io.mifos.customer.service.ServiceConstants; import org.slf4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.transaction.annotation.Transactional; +import java.util.Optional; import java.util.stream.Collectors; @Aggregate @@ -38,13 +47,19 @@ public class CatalogAggregate { private final Logger logger; private final CatalogRepository catalogRepository; + private final FieldRepository fieldRepository; + private final OptionRepository optionRepository; @Autowired public CatalogAggregate(@Qualifier(ServiceConstants.LOGGER_NAME) final Logger logger, - final CatalogRepository catalogRepository) { + final CatalogRepository catalogRepository, + final FieldRepository fieldRepository, + final OptionRepository optionRepository) { super(); this.logger = logger; this.catalogRepository = catalogRepository; + this.fieldRepository = fieldRepository; + this.optionRepository = optionRepository; } @Transactional @@ -61,4 +76,69 @@ public class CatalogAggregate { this.catalogRepository.save(catalogEntity); return catalog.getIdentifier(); } + + @Transactional + @CommandHandler + @EventEmitter(selectorName = CatalogEventConstants.SELECTOR_NAME, selectorValue = CatalogEventConstants.DELETE_CATALOG) + public String process(final DeleteCatalogCommand deleteCatalogCommand) { + final Optional<CatalogEntity> optionalCatalog = this.catalogRepository.findByIdentifier(deleteCatalogCommand.identifier()); + if (optionalCatalog.isPresent()) { + this.catalogRepository.delete(optionalCatalog.get()); + return deleteCatalogCommand.identifier(); + } + return null; + } + + @Transactional + @CommandHandler + @EventEmitter(selectorName = CatalogEventConstants.SELECTOR_NAME, selectorValue = CatalogEventConstants.DELETE_FIELD) + public String process(final DeleteFieldCommand deleteFieldCommand) { + final Optional<CatalogEntity> optionalCatalog = this.catalogRepository.findByIdentifier(deleteFieldCommand.catalogIdentifier()); + if (optionalCatalog.isPresent()) { + final Optional<FieldEntity> optionalField = + this.fieldRepository.findByCatalogAndIdentifier(optionalCatalog.get(), deleteFieldCommand.fieldIdentifier()); + if (optionalField.isPresent()) { + this.fieldRepository.delete(optionalField.get()); + return deleteFieldCommand.fieldIdentifier(); + } + } + return null; + } + + @Transactional + @CommandHandler + @EventEmitter(selectorName = CatalogEventConstants.SELECTOR_NAME, selectorValue = CatalogEventConstants.PUT_FIELD) + public String process(final ChangeFieldCommand changeFieldCommand) { + final Optional<CatalogEntity> optionalCatalog = this.catalogRepository.findByIdentifier(changeFieldCommand.catalogIdentifier()); + if (optionalCatalog.isPresent()) { + final Optional<FieldEntity> optionalField = + this.fieldRepository.findByCatalogAndIdentifier(optionalCatalog.get(), changeFieldCommand.field().getIdentifier()); + if (optionalField.isPresent()) { + final FieldEntity fieldEntity = optionalField.get(); + + fieldEntity.setOptions(null); + final FieldEntity temporarySavedField = this.fieldRepository.saveAndFlush(fieldEntity); + + this.optionRepository.deleteByField(temporarySavedField); + this.optionRepository.flush(); + + final Field field = changeFieldCommand.field(); + temporarySavedField.setLabel(field.getLabel()); + temporarySavedField.setHint(field.getHint()); + temporarySavedField.setDescription(field.getDescription()); + temporarySavedField.setMandatory(field.getMandatory()); + if (field.getOptions() != null) { + temporarySavedField.setOptions( + field.getOptions() + .stream() + .map(option -> OptionMapper.map(temporarySavedField, option)) + .collect(Collectors.toList()) + ); + } + this.fieldRepository.save(temporarySavedField); + return changeFieldCommand.field().getIdentifier(); + } + } + return null; + } } diff --git a/service/src/main/java/io/mifos/customer/catalog/service/internal/repository/FieldValueRepository.java b/service/src/main/java/io/mifos/customer/catalog/service/internal/repository/FieldValueRepository.java index af97cf6..01713b6 100644 --- a/service/src/main/java/io/mifos/customer/catalog/service/internal/repository/FieldValueRepository.java +++ b/service/src/main/java/io/mifos/customer/catalog/service/internal/repository/FieldValueRepository.java @@ -20,6 +20,7 @@ import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; import java.util.List; +import java.util.Optional; @Repository public interface FieldValueRepository extends JpaRepository<FieldValueEntity, Long> { @@ -27,4 +28,6 @@ public interface FieldValueRepository extends JpaRepository<FieldValueEntity, Lo List<FieldValueEntity> findByCustomer(final CustomerEntity customer); void deleteByCustomer(final CustomerEntity customer); + + Optional<FieldValueEntity> findByField(final FieldEntity fieldEntity); } diff --git a/api/src/main/java/io/mifos/customer/catalog/api/v1/CatalogEventConstants.java b/service/src/main/java/io/mifos/customer/catalog/service/internal/repository/OptionRepository.java similarity index 69% copy from api/src/main/java/io/mifos/customer/catalog/api/v1/CatalogEventConstants.java copy to service/src/main/java/io/mifos/customer/catalog/service/internal/repository/OptionRepository.java index 97b4955..d5d1bf3 100644 --- a/api/src/main/java/io/mifos/customer/catalog/api/v1/CatalogEventConstants.java +++ b/service/src/main/java/io/mifos/customer/catalog/service/internal/repository/OptionRepository.java @@ -13,15 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.mifos.customer.catalog.api.v1; +package io.mifos.customer.catalog.service.internal.repository; -public interface CatalogEventConstants { +import org.springframework.data.jpa.repository.JpaRepository; - String DESTINATION = "nun-v1"; +public interface OptionRepository extends JpaRepository<OptionEntity, Long> { - String SELECTOR_NAME = "action"; - - String POST_CATALOG = "post-catalog"; - - String SELECTOR_POST_CATALOG = SELECTOR_NAME + " = '" + POST_CATALOG + "'"; + void deleteByField(final FieldEntity fieldEntity); } diff --git a/service/src/main/java/io/mifos/customer/catalog/service/internal/service/CatalogService.java b/service/src/main/java/io/mifos/customer/catalog/service/internal/service/CatalogService.java index 78cc511..0b395dc 100644 --- a/service/src/main/java/io/mifos/customer/catalog/service/internal/service/CatalogService.java +++ b/service/src/main/java/io/mifos/customer/catalog/service/internal/service/CatalogService.java @@ -15,16 +15,22 @@ */ package io.mifos.customer.catalog.service.internal.service; +import io.mifos.core.lang.ServiceException; import io.mifos.customer.catalog.api.v1.domain.Catalog; import io.mifos.customer.catalog.service.internal.mapper.CatalogMapper; import io.mifos.customer.catalog.service.internal.mapper.FieldMapper; +import io.mifos.customer.catalog.service.internal.repository.CatalogEntity; import io.mifos.customer.catalog.service.internal.repository.CatalogRepository; +import io.mifos.customer.catalog.service.internal.repository.FieldEntity; +import io.mifos.customer.catalog.service.internal.repository.FieldRepository; +import io.mifos.customer.catalog.service.internal.repository.FieldValueRepository; import io.mifos.customer.service.ServiceConstants; 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.ArrayList; import java.util.List; import java.util.Optional; import java.util.stream.Collectors; @@ -34,13 +40,19 @@ public class CatalogService { private final Logger logger; private final CatalogRepository catalogRepository; + private final FieldRepository fieldRepository; + private final FieldValueRepository fieldValueRepository; @Autowired public CatalogService(@Qualifier(ServiceConstants.LOGGER_NAME) final Logger logger, - final CatalogRepository catalogRepository) { + final CatalogRepository catalogRepository, + final FieldRepository fieldRepository, + final FieldValueRepository fieldValueRepository) { super(); this.logger = logger; this.catalogRepository = catalogRepository; + this.fieldRepository = fieldRepository; + this.fieldValueRepository = fieldValueRepository; } public Boolean catalogExists(final String identifier) { @@ -76,4 +88,30 @@ public class CatalogService { return catalog; }); } + + public Boolean catalogInUse(final String identifier) { + final CatalogEntity catalogEntity = this.catalogRepository.findByIdentifier(identifier).orElseThrow( + () -> ServiceException.notFound("Catalog {0} not found.", identifier) + ); + + final ArrayList<Boolean> fieldUsageList = new ArrayList<>(); + catalogEntity.getFields().forEach(fieldEntity -> { + fieldUsageList.add(this.fieldInUse(catalogEntity, fieldEntity.getIdentifier())); + }); + + return fieldUsageList.stream().anyMatch(aBoolean -> aBoolean.equals(Boolean.TRUE)); + } + + public Boolean fieldInUse(final String catalogIdentifier, final String fieldIdentifier) { + final CatalogEntity catalogEntity = this.catalogRepository.findByIdentifier(catalogIdentifier).orElseThrow( + () -> ServiceException.notFound("Catalog {0} not found.", catalogIdentifier) + ); + return this.fieldInUse(catalogEntity, fieldIdentifier); + } + + private Boolean fieldInUse(final CatalogEntity catalogEntity, final String fieldIdentifier) { + final FieldEntity fieldEntity = this.fieldRepository.findByCatalogAndIdentifier(catalogEntity, fieldIdentifier).orElseThrow( + () -> ServiceException.notFound("Field {0} of catalog {1} not found.", catalogEntity.getIdentifier(), fieldIdentifier)); + return this.fieldValueRepository.findByField(fieldEntity).isPresent(); + } } diff --git a/service/src/main/java/io/mifos/customer/catalog/service/rest/controller/CatalogRestController.java b/service/src/main/java/io/mifos/customer/catalog/service/rest/controller/CatalogRestController.java index 96fe00e..6b0081e 100644 --- a/service/src/main/java/io/mifos/customer/catalog/service/rest/controller/CatalogRestController.java +++ b/service/src/main/java/io/mifos/customer/catalog/service/rest/controller/CatalogRestController.java @@ -21,7 +21,11 @@ import io.mifos.core.command.gateway.CommandGateway; import io.mifos.core.lang.ServiceException; import io.mifos.customer.PermittableGroupIds; import io.mifos.customer.catalog.api.v1.domain.Catalog; +import io.mifos.customer.catalog.api.v1.domain.Field; +import io.mifos.customer.catalog.service.internal.command.ChangeFieldCommand; import io.mifos.customer.catalog.service.internal.command.CreateCatalogCommand; +import io.mifos.customer.catalog.service.internal.command.DeleteCatalogCommand; +import io.mifos.customer.catalog.service.internal.command.DeleteFieldCommand; import io.mifos.customer.catalog.service.internal.service.CatalogService; import io.mifos.customer.service.ServiceConstants; import org.slf4j.Logger; @@ -36,6 +40,7 @@ import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; +import javax.validation.Valid; import java.util.List; @RestController @@ -101,4 +106,64 @@ public class CatalogRestController { .orElseThrow(() -> ServiceException.notFound("Catalog {0} not found.", identifier)) ); } + + @Permittable(value = AcceptedTokenType.TENANT, groupId = PermittableGroupIds.CATALOG) + @RequestMapping( + path = "/{identifier}", + method = RequestMethod.DELETE, + consumes = MediaType.ALL_VALUE, + produces = MediaType.APPLICATION_JSON_VALUE + ) + public + @ResponseBody + ResponseEntity<Void> deleteCatalog(@PathVariable("identifier") final String identifier) { + if (this.catalogService.catalogInUse(identifier)) { + throw ServiceException.badRequest("Catalog {0} in use.", identifier); + } + + this.commandGateway.process(new DeleteCatalogCommand(identifier)); + + return ResponseEntity.accepted().build(); + } + + @Permittable(value = AcceptedTokenType.TENANT, groupId = PermittableGroupIds.CATALOG) + @RequestMapping( + path = "/{catalogIdentifier}/fields/{fieldIdentifier}", + method = RequestMethod.PUT, + consumes = MediaType.APPLICATION_JSON_VALUE, + produces = MediaType.APPLICATION_JSON_VALUE + ) + public + @ResponseBody + ResponseEntity<Void> updateField(@PathVariable("catalogIdentifier") final String catalogIdentifier, + @PathVariable("fieldIdentifier") final String fieldIdentifier, + @RequestBody @Valid Field field) { + if (this.catalogService.fieldInUse(catalogIdentifier, fieldIdentifier)) { + throw ServiceException.badRequest("Catalog {0} in use.", catalogIdentifier); + } + + this.commandGateway.process(new ChangeFieldCommand(catalogIdentifier, field)); + + return ResponseEntity.accepted().build(); + } + + @Permittable(value = AcceptedTokenType.TENANT, groupId = PermittableGroupIds.CATALOG) + @RequestMapping( + path = "/{catalogIdentifier}/fields/{fieldIdentifier}", + method = RequestMethod.DELETE, + consumes = MediaType.ALL_VALUE, + produces = MediaType.APPLICATION_JSON_VALUE + ) + public + @ResponseBody + ResponseEntity<Void> deleteField(@PathVariable("catalogIdentifier") final String catalogIdentifier, + @PathVariable("fieldIdentifier") final String fieldIdentifier) { + if (this.catalogService.fieldInUse(catalogIdentifier, fieldIdentifier)) { + throw ServiceException.badRequest("Catalog {0} in use.", catalogIdentifier); + } + + this.commandGateway.process(new DeleteFieldCommand(catalogIdentifier, fieldIdentifier)); + + return ResponseEntity.accepted().build(); + } } -- To stop receiving notification emails like this one, please contact [email protected].
