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-office.git
commit 70ad20231f76ca22a4e59f5c767747fda7cafacd Author: mgeiss <mge...@mifos.org> AuthorDate: Tue Sep 12 18:03:54 2017 +0200 added external references to office --- .../io/mifos/office/api/v1/EventConstants.java | 2 + .../office/api/v1/client/OrganizationManager.java | 12 ++++ .../office/api/v1/domain/ExternalReference.java | 53 +++++++++++++++ .../java/io/mifos/office/api/v1/domain/Office.java | 9 +++ .../main/java/io/mifos/office/TestEmployee.java | 9 ++- .../src/main/java/io/mifos/office/TestOffice.java | 71 ++++++++++++++++++-- .../mifos/office/listener/OfficeEventListener.java | 11 ++++ .../command/AddExternalReferenceCommand.java | 37 +++++++++++ .../command/handler/EmployeeAggregate.java | 2 +- .../internal/command/handler/OfficeAggregate.java | 51 ++++++++++++--- .../repository/ExternalReferenceEntity.java | 75 ++++++++++++++++++++++ .../repository/ExternalReferenceRepository.java | 32 +++++++++ .../office/internal/service/OfficeService.java | 24 ++++++- .../rest/controller/OfficeRestController.java | 47 ++++++++++++-- .../mariadb/V2__add_external_references.sql | 24 +++++++ .../resources/{logback.xml => logback-test.xml} | 4 +- 16 files changed, 438 insertions(+), 25 deletions(-) diff --git a/api/src/main/java/io/mifos/office/api/v1/EventConstants.java b/api/src/main/java/io/mifos/office/api/v1/EventConstants.java index dc5fa1c..c702f8e 100644 --- a/api/src/main/java/io/mifos/office/api/v1/EventConstants.java +++ b/api/src/main/java/io/mifos/office/api/v1/EventConstants.java @@ -28,6 +28,7 @@ public interface EventConstants { String OPERATION_DELETE_OFFICE = "delete-office"; String OPERATION_PUT_ADDRESS = "put-address"; String OPERATION_DELETE_ADDRESS = "delete-address"; + String OPERATION_PUT_REFERENCE = "put-reference"; String OPERATION_POST_EMPLOYEE = "post-employee"; String OPERATION_PUT_EMPLOYEE = "put-employee"; @@ -42,6 +43,7 @@ public interface EventConstants { String SELECTOR_DELETE_OFFICE = OPERATION_HEADER + " = '" + OPERATION_DELETE_OFFICE + "'"; String SELECTOR_PUT_ADDRESS = OPERATION_HEADER + " = '" + OPERATION_PUT_ADDRESS + "'"; String SELECTOR_DELETE_ADDRESS = OPERATION_HEADER + " = '" + OPERATION_DELETE_ADDRESS + "'"; + String SELECTOR_PUT_REFERENCE = OPERATION_HEADER + " = '" + OPERATION_PUT_REFERENCE + "'"; String SELECTOR_POST_EMPLOYEE = OPERATION_HEADER + " = '" + OPERATION_POST_EMPLOYEE + "'"; String SELECTOR_PUT_EMPLOYEE = OPERATION_HEADER + " = '" + OPERATION_PUT_EMPLOYEE + "'"; diff --git a/api/src/main/java/io/mifos/office/api/v1/client/OrganizationManager.java b/api/src/main/java/io/mifos/office/api/v1/client/OrganizationManager.java index 27831ac..29db698 100644 --- a/api/src/main/java/io/mifos/office/api/v1/client/OrganizationManager.java +++ b/api/src/main/java/io/mifos/office/api/v1/client/OrganizationManager.java @@ -22,6 +22,7 @@ import io.mifos.office.api.v1.domain.Address; import io.mifos.office.api.v1.domain.ContactDetail; import io.mifos.office.api.v1.domain.Employee; import io.mifos.office.api.v1.domain.EmployeePage; +import io.mifos.office.api.v1.domain.ExternalReference; import io.mifos.office.api.v1.domain.Office; import io.mifos.office.api.v1.domain.OfficePage; import org.springframework.cloud.netflix.feign.FeignClient; @@ -33,6 +34,7 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; +import javax.validation.Valid; import java.util.List; @SuppressWarnings("unused") @@ -223,4 +225,14 @@ public interface OrganizationManager { ) @ThrowsException(status = HttpStatus.NOT_FOUND, exception = NotFoundException.class) void deleteContactDetails(@PathVariable("useridentifier") final String identifier); + + @RequestMapping( + value = "/offices/{identifier}/references", + method = RequestMethod.PUT, + consumes = MediaType.APPLICATION_JSON_VALUE, + produces = MediaType.APPLICATION_JSON_VALUE + ) + @ThrowsException(status = HttpStatus.NOT_FOUND, exception = NotFoundException.class) + void addExternalReference(@PathVariable("identifier") final String officeIdentifier, + @RequestBody @Valid final ExternalReference externalReference); } diff --git a/api/src/main/java/io/mifos/office/api/v1/domain/ExternalReference.java b/api/src/main/java/io/mifos/office/api/v1/domain/ExternalReference.java new file mode 100644 index 0000000..bf2dabe --- /dev/null +++ b/api/src/main/java/io/mifos/office/api/v1/domain/ExternalReference.java @@ -0,0 +1,53 @@ +/* + * 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.office.api.v1.domain; + +import io.mifos.core.lang.validation.constraints.ValidIdentifier; + +import javax.validation.constraints.NotNull; + +public class ExternalReference { + + public enum State { + ACTIVE, + INACTIVE + } + + @ValidIdentifier + private String type; + @NotNull + private State state; + + public ExternalReference() { + super(); + } + + public String getType() { + return this.type; + } + + public void setType(final String type) { + this.type = type; + } + + public String getState() { + return this.state.name(); + } + + public void setState(final String state) { + this.state = State.valueOf(state); + } +} diff --git a/api/src/main/java/io/mifos/office/api/v1/domain/Office.java b/api/src/main/java/io/mifos/office/api/v1/domain/Office.java index 4fd3f22..05421e5 100644 --- a/api/src/main/java/io/mifos/office/api/v1/domain/Office.java +++ b/api/src/main/java/io/mifos/office/api/v1/domain/Office.java @@ -26,6 +26,7 @@ public class Office { private String name; private String description; private Address address; + private Boolean externalReferences; public Office() { super(); @@ -70,4 +71,12 @@ public class Office { public void setAddress(Address address) { this.address = address; } + + public Boolean getExternalReferences() { + return this.externalReferences; + } + + public void setExternalReferences(final Boolean externalReferences) { + this.externalReferences = externalReferences; + } } diff --git a/component-test/src/main/java/io/mifos/office/TestEmployee.java b/component-test/src/main/java/io/mifos/office/TestEmployee.java index a826e39..60c53cf 100644 --- a/component-test/src/main/java/io/mifos/office/TestEmployee.java +++ b/component-test/src/main/java/io/mifos/office/TestEmployee.java @@ -26,8 +26,8 @@ import io.mifos.core.test.listener.EventRecorder; import io.mifos.office.api.v1.EventConstants; import io.mifos.office.api.v1.client.AlreadyExistsException; import io.mifos.office.api.v1.client.BadRequestException; -import io.mifos.office.api.v1.client.OrganizationManager; import io.mifos.office.api.v1.client.NotFoundException; +import io.mifos.office.api.v1.client.OrganizationManager; import io.mifos.office.api.v1.domain.ContactDetail; import io.mifos.office.api.v1.domain.Employee; import io.mifos.office.api.v1.domain.EmployeePage; @@ -36,7 +36,12 @@ import io.mifos.office.rest.config.OfficeRestConfiguration; import io.mifos.office.util.EmployeeFactory; import io.mifos.office.util.OfficeFactory; import org.apache.commons.lang3.RandomStringUtils; -import org.junit.*; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Rule; +import org.junit.Test; import org.junit.rules.RuleChain; import org.junit.rules.TestRule; import org.junit.runner.RunWith; diff --git a/component-test/src/main/java/io/mifos/office/TestOffice.java b/component-test/src/main/java/io/mifos/office/TestOffice.java index 97f1b66..8e8ad1d 100644 --- a/component-test/src/main/java/io/mifos/office/TestOffice.java +++ b/component-test/src/main/java/io/mifos/office/TestOffice.java @@ -24,9 +24,14 @@ import io.mifos.core.test.fixture.mariadb.MariaDBInitializer; import io.mifos.core.test.listener.EnableEventRecording; import io.mifos.core.test.listener.EventRecorder; import io.mifos.office.api.v1.EventConstants; -import io.mifos.office.api.v1.client.*; +import io.mifos.office.api.v1.client.AlreadyExistsException; +import io.mifos.office.api.v1.client.BadRequestException; +import io.mifos.office.api.v1.client.ChildrenExistException; +import io.mifos.office.api.v1.client.NotFoundException; +import io.mifos.office.api.v1.client.OrganizationManager; import io.mifos.office.api.v1.domain.Address; import io.mifos.office.api.v1.domain.Employee; +import io.mifos.office.api.v1.domain.ExternalReference; import io.mifos.office.api.v1.domain.Office; import io.mifos.office.api.v1.domain.OfficePage; import io.mifos.office.rest.config.OfficeRestConfiguration; @@ -34,7 +39,12 @@ import io.mifos.office.util.AddressFactory; import io.mifos.office.util.EmployeeFactory; import io.mifos.office.util.OfficeFactory; import org.apache.commons.lang3.RandomStringUtils; -import org.junit.*; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Rule; +import org.junit.Test; import org.junit.rules.RuleChain; import org.junit.rules.TestRule; import org.junit.runner.RunWith; @@ -310,7 +320,7 @@ public class TestOffice { } @Test(expected = ChildrenExistException.class) - public void shouldNotDeleteOfficeWithBranches() throws Exception{ + public void shouldNotDeleteOfficeWithBranches() throws Exception { final Office parent = OfficeFactory.createRandomOffice(); this.organizationManager.createOffice(parent); this.eventRecorder.wait(EventConstants.OPERATION_POST_OFFICE, parent.getIdentifier()); @@ -323,7 +333,7 @@ public class TestOffice { } @Test(expected = ChildrenExistException.class) - public void shouldNotDeleteOfficeWithEmployees() throws Exception{ + public void shouldNotDeleteOfficeWithEmployees() throws Exception { final Office office = OfficeFactory.createRandomOffice(); this.organizationManager.createOffice(office); this.eventRecorder.wait(EventConstants.OPERATION_POST_OFFICE, office.getIdentifier()); @@ -336,6 +346,59 @@ public class TestOffice { this.organizationManager.deleteOffice(office.getIdentifier()); } + @Test(expected = ChildrenExistException.class) + public void shouldNotDeleteOfficeWithActiveExternalReference() throws Exception { + final Office randomOffice = OfficeFactory.createRandomOffice(); + this.organizationManager.createOffice(randomOffice); + Assert.assertTrue(this.eventRecorder.wait(EventConstants.OPERATION_POST_OFFICE, randomOffice.getIdentifier())); + + final ExternalReference externalReference = new ExternalReference(); + externalReference.setType("anytype"); + externalReference.setState(ExternalReference.State.ACTIVE.name()); + + this.organizationManager.addExternalReference(randomOffice.getIdentifier(), externalReference); + Assert.assertTrue(this.eventRecorder.wait(EventConstants.OPERATION_PUT_REFERENCE, randomOffice.getIdentifier())); + + this.organizationManager.deleteOffice(randomOffice.getIdentifier()); + } + + @Test + public void shouldDeleteOfficeWithInactiveExternalReference() throws Exception { + final Office randomOffice = OfficeFactory.createRandomOffice(); + this.organizationManager.createOffice(randomOffice); + Assert.assertTrue(this.eventRecorder.wait(EventConstants.OPERATION_POST_OFFICE, randomOffice.getIdentifier())); + + final ExternalReference externalReference = new ExternalReference(); + externalReference.setType("anytype"); + externalReference.setState(ExternalReference.State.INACTIVE.name()); + + this.organizationManager.addExternalReference(randomOffice.getIdentifier(), externalReference); + Assert.assertTrue(this.eventRecorder.wait(EventConstants.OPERATION_PUT_REFERENCE, randomOffice.getIdentifier())); + + final Office office = this.organizationManager.findOfficeByIdentifier(randomOffice.getIdentifier()); + Assert.assertFalse(office.getExternalReferences()); + + this.organizationManager.deleteOffice(randomOffice.getIdentifier()); + Assert.assertTrue(this.eventRecorder.wait(EventConstants.OPERATION_DELETE_OFFICE, randomOffice.getIdentifier())); + } + + @Test + public void shouldIndicateOfficeHasExternalReferences() throws Exception { + final Office randomOffice = OfficeFactory.createRandomOffice(); + this.organizationManager.createOffice(randomOffice); + Assert.assertTrue(this.eventRecorder.wait(EventConstants.OPERATION_POST_OFFICE, randomOffice.getIdentifier())); + + final ExternalReference externalReference = new ExternalReference(); + externalReference.setType("anytype"); + externalReference.setState(ExternalReference.State.ACTIVE.name()); + + this.organizationManager.addExternalReference(randomOffice.getIdentifier(), externalReference); + Assert.assertTrue(this.eventRecorder.wait(EventConstants.OPERATION_PUT_REFERENCE, randomOffice.getIdentifier())); + + final Office office = this.organizationManager.findOfficeByIdentifier(randomOffice.getIdentifier()); + Assert.assertTrue(office.getExternalReferences()); + } + @Configuration @ComponentScan( basePackages = "io.mifos.office.listener" diff --git a/component-test/src/main/java/io/mifos/office/listener/OfficeEventListener.java b/component-test/src/main/java/io/mifos/office/listener/OfficeEventListener.java index ff22b43..402c200 100644 --- a/component-test/src/main/java/io/mifos/office/listener/OfficeEventListener.java +++ b/component-test/src/main/java/io/mifos/office/listener/OfficeEventListener.java @@ -94,4 +94,15 @@ public class OfficeEventListener { throws Exception { this.eventRecorder.event(tenant, EventConstants.OPERATION_DELETE_ADDRESS, payload, String.class); } + + @JmsListener( + subscription = EventConstants.DESTINATION, + destination = EventConstants.DESTINATION, + selector = EventConstants.SELECTOR_PUT_REFERENCE + ) + public void onPutAReference(@Header(TenantHeaderFilter.TENANT_HEADER) final String tenant, + final String payload) + throws Exception { + this.eventRecorder.event(tenant, EventConstants.OPERATION_PUT_REFERENCE, payload, String.class); + } } diff --git a/service/src/main/java/io/mifos/office/internal/command/AddExternalReferenceCommand.java b/service/src/main/java/io/mifos/office/internal/command/AddExternalReferenceCommand.java new file mode 100644 index 0000000..5de9551 --- /dev/null +++ b/service/src/main/java/io/mifos/office/internal/command/AddExternalReferenceCommand.java @@ -0,0 +1,37 @@ +/* + * 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.office.internal.command; + +import io.mifos.office.api.v1.domain.ExternalReference; + +public class AddExternalReferenceCommand { + private final String officeIdentifier; + private final ExternalReference externalReference; + + public AddExternalReferenceCommand(final String officeIdentifier, final ExternalReference externalReference) { + super(); + this.officeIdentifier = officeIdentifier; + this.externalReference = externalReference; + } + + public String officeIdentifier() { + return this.officeIdentifier; + } + + public ExternalReference externalReference() { + return this.externalReference; + } +} diff --git a/service/src/main/java/io/mifos/office/internal/command/handler/EmployeeAggregate.java b/service/src/main/java/io/mifos/office/internal/command/handler/EmployeeAggregate.java index f2394f1..6840fb8 100644 --- a/service/src/main/java/io/mifos/office/internal/command/handler/EmployeeAggregate.java +++ b/service/src/main/java/io/mifos/office/internal/command/handler/EmployeeAggregate.java @@ -24,12 +24,12 @@ import io.mifos.office.api.v1.EventConstants; import io.mifos.office.api.v1.domain.ContactDetail; import io.mifos.office.api.v1.domain.Employee; import io.mifos.office.internal.command.CreateEmployeeCommand; +import io.mifos.office.internal.command.DeleteContactDetailCommand; import io.mifos.office.internal.command.DeleteEmployeeCommand; import io.mifos.office.internal.command.SetContactDetailsCommand; import io.mifos.office.internal.command.UpdateEmployeeCommand; import io.mifos.office.internal.mapper.ContactDetailMapper; import io.mifos.office.internal.mapper.EmployeeMapper; -import io.mifos.office.internal.command.DeleteContactDetailCommand; import io.mifos.office.internal.repository.ContactDetailEntity; import io.mifos.office.internal.repository.ContactDetailRepository; import io.mifos.office.internal.repository.EmployeeEntity; diff --git a/service/src/main/java/io/mifos/office/internal/command/handler/OfficeAggregate.java b/service/src/main/java/io/mifos/office/internal/command/handler/OfficeAggregate.java index 0930558..b2cfd14 100644 --- a/service/src/main/java/io/mifos/office/internal/command/handler/OfficeAggregate.java +++ b/service/src/main/java/io/mifos/office/internal/command/handler/OfficeAggregate.java @@ -22,19 +22,23 @@ import io.mifos.core.command.annotation.EventEmitter; import io.mifos.core.lang.ServiceException; import io.mifos.office.ServiceConstants; import io.mifos.office.api.v1.EventConstants; +import io.mifos.office.api.v1.domain.ExternalReference; import io.mifos.office.api.v1.domain.Office; +import io.mifos.office.internal.command.AddBranchCommand; +import io.mifos.office.internal.command.AddExternalReferenceCommand; +import io.mifos.office.internal.command.CreateOfficeCommand; import io.mifos.office.internal.command.DeleteAddressOfOfficeCommand; +import io.mifos.office.internal.command.DeleteOfficeCommand; +import io.mifos.office.internal.command.SetAddressForOfficeCommand; +import io.mifos.office.internal.command.UpdateOfficeCommand; import io.mifos.office.internal.mapper.AddressMapper; import io.mifos.office.internal.mapper.OfficeMapper; import io.mifos.office.internal.repository.AddressEntity; import io.mifos.office.internal.repository.AddressRepository; +import io.mifos.office.internal.repository.ExternalReferenceEntity; +import io.mifos.office.internal.repository.ExternalReferenceRepository; import io.mifos.office.internal.repository.OfficeEntity; import io.mifos.office.internal.repository.OfficeRepository; -import io.mifos.office.internal.command.AddBranchCommand; -import io.mifos.office.internal.command.CreateOfficeCommand; -import io.mifos.office.internal.command.DeleteOfficeCommand; -import io.mifos.office.internal.command.SetAddressForOfficeCommand; -import io.mifos.office.internal.command.UpdateOfficeCommand; import org.slf4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; @@ -52,15 +56,18 @@ public class OfficeAggregate { private final Logger logger; private final OfficeRepository officeRepository; private final AddressRepository addressRepository; + private final ExternalReferenceRepository externalReferenceRepository; @Autowired public OfficeAggregate(@Qualifier(ServiceConstants.SERVICE_LOGGER_NAME) final Logger logger, final OfficeRepository officeRepository, - final AddressRepository addressRepository) { + final AddressRepository addressRepository, + final ExternalReferenceRepository externalReferenceRepository) { super(); this.logger = logger; this.officeRepository = officeRepository; this.addressRepository = addressRepository; + this.externalReferenceRepository = externalReferenceRepository; } @Transactional @@ -126,11 +133,11 @@ public class OfficeAggregate { if (optionalOfficeEntity.isPresent()) { final OfficeEntity officeEntityToDelete = optionalOfficeEntity.get(); final Optional<AddressEntity> optionalAddressEntity = this.addressRepository.findByOffice(officeEntityToDelete); - if (optionalAddressEntity.isPresent()) { - this.addressRepository.delete(optionalAddressEntity.get()); - } + optionalAddressEntity.ifPresent(this.addressRepository::delete); this.officeRepository.delete(officeEntityToDelete); + + this.externalReferenceRepository.deleteByOfficeIdentifier(deleteOfficeCommand.identifier()); } return deleteOfficeCommand.identifier(); @@ -188,6 +195,32 @@ public class OfficeAggregate { return null; } + @Transactional + @CommandHandler + @EventEmitter(selectorName = EventConstants.OPERATION_HEADER, selectorValue = EventConstants.OPERATION_PUT_REFERENCE) + public String addExternalReference(final AddExternalReferenceCommand addExternalReferenceCommand) { + + final String officeIdentifier = addExternalReferenceCommand.officeIdentifier(); + final ExternalReference externalReference = addExternalReferenceCommand.externalReference(); + + final Optional<ExternalReferenceEntity> optionalExternalReference = + this.externalReferenceRepository.findByOfficeIdentifierAndType(officeIdentifier, externalReference.getType()); + + final ExternalReferenceEntity externalReferenceEntity; + if (optionalExternalReference.isPresent()) { + externalReferenceEntity = optionalExternalReference.get(); + } else { + externalReferenceEntity = new ExternalReferenceEntity(); + externalReferenceEntity.setOfficeIdentifier(officeIdentifier); + externalReferenceEntity.setType(externalReference.getType()); + } + externalReferenceEntity.setState(externalReference.getState()); + + this.externalReferenceRepository.save(externalReferenceEntity); + + return officeIdentifier; + } + private void createOffice(final Office office, final Office parentOffice) { if (this.officeRepository.existsByIdentifier(office.getIdentifier())) { this.logger.info("Office {} already exists.", office.getIdentifier()); diff --git a/service/src/main/java/io/mifos/office/internal/repository/ExternalReferenceEntity.java b/service/src/main/java/io/mifos/office/internal/repository/ExternalReferenceEntity.java new file mode 100644 index 0000000..9f126c2 --- /dev/null +++ b/service/src/main/java/io/mifos/office/internal/repository/ExternalReferenceEntity.java @@ -0,0 +1,75 @@ +/* + * 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.office.internal.repository; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "horus_external_references") +public class ExternalReferenceEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private Long id; + @Column(name = "office_identifier", nullable = false, length = 32) + private String officeIdentifier; + @Column(name = "a_type", nullable = false, length = 32) + private String type; + @Column(name = "a_state", nullable = false, length = 256) + private String state; + + public ExternalReferenceEntity() { + super(); + } + + public Long getId() { + return this.id; + } + + public void setId(final Long id) { + this.id = id; + } + + public String getOfficeIdentifier() { + return this.officeIdentifier; + } + + public void setOfficeIdentifier(final String officeIdentifier) { + this.officeIdentifier = officeIdentifier; + } + + public String getType() { + return this.type; + } + + public void setType(final String type) { + this.type = type; + } + + public String getState() { + return this.state; + } + + public void setState(final String state) { + this.state = state; + } +} diff --git a/service/src/main/java/io/mifos/office/internal/repository/ExternalReferenceRepository.java b/service/src/main/java/io/mifos/office/internal/repository/ExternalReferenceRepository.java new file mode 100644 index 0000000..86c7f7a --- /dev/null +++ b/service/src/main/java/io/mifos/office/internal/repository/ExternalReferenceRepository.java @@ -0,0 +1,32 @@ +/* + * 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.office.internal.repository; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import java.util.List; +import java.util.Optional; + +@Repository +public interface ExternalReferenceRepository extends JpaRepository<ExternalReferenceEntity, Long> { + + Optional<ExternalReferenceEntity> findByOfficeIdentifierAndType(final String officeIdentifier, final String type); + + List<ExternalReferenceEntity> findByOfficeIdentifier(final String officeIdentifier); + + void deleteByOfficeIdentifier(final String officeIdentifier); +} diff --git a/service/src/main/java/io/mifos/office/internal/service/OfficeService.java b/service/src/main/java/io/mifos/office/internal/service/OfficeService.java index e8b29c2..aa36d15 100644 --- a/service/src/main/java/io/mifos/office/internal/service/OfficeService.java +++ b/service/src/main/java/io/mifos/office/internal/service/OfficeService.java @@ -18,11 +18,17 @@ package io.mifos.office.internal.service; import io.mifos.core.lang.ServiceException; import io.mifos.office.ServiceConstants; import io.mifos.office.api.v1.domain.Address; +import io.mifos.office.api.v1.domain.ExternalReference; import io.mifos.office.api.v1.domain.Office; import io.mifos.office.api.v1.domain.OfficePage; import io.mifos.office.internal.mapper.AddressMapper; import io.mifos.office.internal.mapper.OfficeMapper; -import io.mifos.office.internal.repository.*; +import io.mifos.office.internal.repository.AddressEntity; +import io.mifos.office.internal.repository.AddressRepository; +import io.mifos.office.internal.repository.EmployeeRepository; +import io.mifos.office.internal.repository.ExternalReferenceRepository; +import io.mifos.office.internal.repository.OfficeEntity; +import io.mifos.office.internal.repository.OfficeRepository; import org.slf4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; @@ -42,17 +48,20 @@ public class OfficeService { private final OfficeRepository officeRepository; private final AddressRepository addressRepository; private final EmployeeRepository employeeRepository; + private final ExternalReferenceRepository externalReferenceRepository; @Autowired public OfficeService(@Qualifier(ServiceConstants.SERVICE_LOGGER_NAME) final Logger logger, final OfficeRepository officeRepository, final AddressRepository addressRepository, - final EmployeeRepository employeeRepository) { + final EmployeeRepository employeeRepository, + final ExternalReferenceRepository externalReferenceRepository) { super(); this.logger = logger; this.officeRepository = officeRepository; this.addressRepository = addressRepository; this.employeeRepository = employeeRepository; + this.externalReferenceRepository = externalReferenceRepository; } public boolean officeExists(final String identifier) { @@ -102,6 +111,8 @@ public class OfficeService { final Optional<AddressEntity> addressEntityOptional = this.addressRepository.findByOffice(officeEntityOptional.get()); addressEntityOptional.ifPresent(addressEntity -> office.setAddress(AddressMapper.map(addressEntity))); + + office.setExternalReferences(this.hasExternalReferences(office.getIdentifier())); }); return officeOptional; @@ -146,7 +157,16 @@ public class OfficeService { final Optional<AddressEntity> addressEntityOptional = this.addressRepository.findByOffice(officeEntity); addressEntityOptional.ifPresent(addressEntity -> office.setAddress(AddressMapper.map(addressEntity))); + + office.setExternalReferences(this.hasExternalReferences(office.getIdentifier())); }); return offices; } + + public boolean hasExternalReferences(final String officeIdentifier) { + return this.externalReferenceRepository.findByOfficeIdentifier(officeIdentifier) + .stream() + .anyMatch(externalReferenceEntity -> + externalReferenceEntity.getState().equals(ExternalReference.State.ACTIVE.name())); + } } diff --git a/service/src/main/java/io/mifos/office/rest/controller/OfficeRestController.java b/service/src/main/java/io/mifos/office/rest/controller/OfficeRestController.java index 70162fe..e90d3fd 100644 --- a/service/src/main/java/io/mifos/office/rest/controller/OfficeRestController.java +++ b/service/src/main/java/io/mifos/office/rest/controller/OfficeRestController.java @@ -20,13 +20,18 @@ import io.mifos.anubis.annotation.Permittable; import io.mifos.core.command.gateway.CommandGateway; import io.mifos.core.lang.ServiceException; import io.mifos.office.api.v1.PermittableGroupIds; -import io.mifos.office.api.v1.domain.*; -import io.mifos.office.internal.command.DeleteAddressOfOfficeCommand; -import io.mifos.office.internal.service.EmployeeService; -import io.mifos.office.internal.service.OfficeService; +import io.mifos.office.api.v1.domain.Address; +import io.mifos.office.api.v1.domain.ContactDetail; +import io.mifos.office.api.v1.domain.Employee; +import io.mifos.office.api.v1.domain.EmployeePage; +import io.mifos.office.api.v1.domain.ExternalReference; +import io.mifos.office.api.v1.domain.Office; +import io.mifos.office.api.v1.domain.OfficePage; import io.mifos.office.internal.command.AddBranchCommand; +import io.mifos.office.internal.command.AddExternalReferenceCommand; import io.mifos.office.internal.command.CreateEmployeeCommand; import io.mifos.office.internal.command.CreateOfficeCommand; +import io.mifos.office.internal.command.DeleteAddressOfOfficeCommand; import io.mifos.office.internal.command.DeleteContactDetailCommand; import io.mifos.office.internal.command.DeleteEmployeeCommand; import io.mifos.office.internal.command.DeleteOfficeCommand; @@ -35,13 +40,21 @@ import io.mifos.office.internal.command.SetAddressForOfficeCommand; import io.mifos.office.internal.command.SetContactDetailsCommand; import io.mifos.office.internal.command.UpdateEmployeeCommand; import io.mifos.office.internal.command.UpdateOfficeCommand; +import io.mifos.office.internal.service.EmployeeService; +import io.mifos.office.internal.service.OfficeService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.*; +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; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; import javax.validation.Valid; import java.util.List; @@ -228,6 +241,10 @@ public class OfficeRestController { throw ServiceException.conflict("Office {0} has employees.", identifier); } + if (this.officeService.hasExternalReferences(identifier)) { + throw ServiceException.conflict("Office {0} has external references.", identifier); + } + this.commandGateway.process(new DeleteOfficeCommand(identifier)); return ResponseEntity.accepted().build(); @@ -453,6 +470,26 @@ public class OfficeRestController { return ResponseEntity.accepted().build(); } + @Permittable(value = AcceptedTokenType.TENANT, groupId = PermittableGroupIds.OFFICE_MANAGEMENT) + @RequestMapping( + value = "/offices/{identifier}/references", + method = RequestMethod.PUT, + consumes = MediaType.APPLICATION_JSON_VALUE, + produces = MediaType.APPLICATION_JSON_VALUE + ) + public + @ResponseBody + ResponseEntity<Void> addExternalReference(@PathVariable("identifier") final String officeIdentifier, + @RequestBody @Valid final ExternalReference externalReference) { + if (!this.officeService.officeExists(officeIdentifier)) { + throw ServiceException.notFound("Office {0} not found.", officeIdentifier); + } + + this.commandGateway.process(new AddExternalReferenceCommand(officeIdentifier, externalReference)); + + return ResponseEntity.accepted().build(); + } + private Pageable createPageRequest(final Integer pageIndex, final Integer size, final String sortColumn, final String sortDirection) { final Integer pageIndexToUse = pageIndex != null ? pageIndex : 0; final Integer sizeToUse = size != null ? size : 20; diff --git a/service/src/main/resources/db/migrations/mariadb/V2__add_external_references.sql b/service/src/main/resources/db/migrations/mariadb/V2__add_external_references.sql new file mode 100644 index 0000000..7554b5c --- /dev/null +++ b/service/src/main/resources/db/migrations/mariadb/V2__add_external_references.sql @@ -0,0 +1,24 @@ +-- +-- 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. +-- + +CREATE TABLE horus_external_references ( + id BIGINT NOT NULL AUTO_INCREMENT, + office_identifier VARCHAR(32) NOT NULL, + a_type VARCHAR(32) NULL, + a_state VARCHAR(256) NULL, + CONSTRAINT external_references_pk PRIMARY KEY (id), + CONSTRAINT external_references_uq UNIQUE (office_identifier, a_type) +); \ No newline at end of file diff --git a/service/src/main/resources/logback.xml b/service/src/main/resources/logback-test.xml similarity index 94% rename from service/src/main/resources/logback.xml rename to service/src/main/resources/logback-test.xml index dd09a7a..361d67f 100644 --- a/service/src/main/resources/logback.xml +++ b/service/src/main/resources/logback-test.xml @@ -1,6 +1,6 @@ <!-- - Copyright 2017 The Mifos Initiative. + 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. @@ -41,7 +41,7 @@ <appender-ref ref="STDOUT" /> </logger> - <logger name="io" level="INFO"> + <logger name="io" level="DEBUG"> <appender-ref ref="STDOUT" /> </logger> -- To stop receiving notification emails like this one, please contact my...@apache.org.