diff --git a/src/main/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerController.java b/src/main/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerController.java index 42b7afe9..9a71a622 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerController.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerController.java @@ -1,10 +1,15 @@ package net.hostsharing.hsadminng.hs.office.partner; import net.hostsharing.hsadminng.context.Context; +import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactEntity; import net.hostsharing.hsadminng.hs.office.generated.api.v1.api.HsOfficePartnersApi; import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficePartnerInsertResource; import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficePartnerPatchResource; import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficePartnerResource; +import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficePartnerRoleInsertResource; +import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity; +import net.hostsharing.hsadminng.hs.office.relationship.HsOfficeRelationshipEntity; +import net.hostsharing.hsadminng.hs.office.relationship.HsOfficeRelationshipType; import net.hostsharing.hsadminng.mapper.Mapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; @@ -56,7 +61,7 @@ public class HsOfficePartnerController implements HsOfficePartnersApi { context.define(currentUser, assumedRoles); - final var entityToSave = mapper.map(body, HsOfficePartnerEntity.class); + final var entityToSave = createPartnerEntity(body); final var saved = partnerRepo.save(entityToSave); @@ -119,4 +124,24 @@ public class HsOfficePartnerController implements HsOfficePartnersApi { final var mapped = mapper.map(saved, HsOfficePartnerResource.class); return ResponseEntity.ok(mapped); } + + private HsOfficePartnerEntity createPartnerEntity(final HsOfficePartnerInsertResource body) { + final var entityToSave = new HsOfficePartnerEntity(); + entityToSave.setPartnerNumber(body.getPartnerNumber()); + entityToSave.setPartnerRole(persistPartnerRole(body.getPartnerRole())); + entityToSave.setContact(em.find(HsOfficeContactEntity.class, body.getContactUuid())); + entityToSave.setPerson(em.find(HsOfficePersonEntity.class, body.getPersonUuid())); + entityToSave.setDetails(mapper.map(body.getDetails(), HsOfficePartnerDetailsEntity.class)); + return entityToSave; + } + + private HsOfficeRelationshipEntity persistPartnerRole(final HsOfficePartnerRoleInsertResource resource) { + final var entity = new HsOfficeRelationshipEntity(); + entity.setRelType(HsOfficeRelationshipType.PARTNER); + entity.setRelAnchor(em.find(HsOfficePersonEntity.class, resource.getRelAnchorUuid())); + entity.setRelHolder(em.find(HsOfficePersonEntity.class, resource.getRelHolderUuid())); + entity.setContact(em.find(HsOfficeContactEntity.class, resource.getContactUuid())); + em.persist(entity); + return entity; + } } diff --git a/src/main/resources/api-definition/hs-office/hs-office-partner-schemas.yaml b/src/main/resources/api-definition/hs-office/hs-office-partner-schemas.yaml index a6a94f67..a473bd49 100644 --- a/src/main/resources/api-definition/hs-office/hs-office-partner-schemas.yaml +++ b/src/main/resources/api-definition/hs-office/hs-office-partner-schemas.yaml @@ -96,6 +96,8 @@ components: format: int8 minimum: 10000 maximum: 99999 + partnerRole: + $ref: '#/components/schemas/HsOfficePartnerRoleInsert' personUuid: type: string format: uuid @@ -110,6 +112,24 @@ components: - contactUuid - details + HsOfficePartnerRoleInsert: + type: object + nullable: false + properties: + relAnchorUuid: + type: string + format: uuid + relHolderUuid: + type: string + format: uuid + contactUuid: + type: string + format: uuid + required: + - relAnchorUuid + - relHolderUuid + - relContactUuid + HsOfficePartnerDetailsInsert: type: object nullable: false diff --git a/src/main/resources/api-definition/hs-office/hs-office-relationship-schemas.yaml b/src/main/resources/api-definition/hs-office/hs-office-relationship-schemas.yaml index ae4e0453..af5e5f86 100644 --- a/src/main/resources/api-definition/hs-office/hs-office-relationship-schemas.yaml +++ b/src/main/resources/api-definition/hs-office/hs-office-relationship-schemas.yaml @@ -62,3 +62,4 @@ components: - relAnchorUuid - relHolderUuid - relType + - relContactUuid diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerControllerAcceptanceTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerControllerAcceptanceTest.java index c5f8558a..221c502f 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerControllerAcceptanceTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerControllerAcceptanceTest.java @@ -6,9 +6,10 @@ import net.hostsharing.hsadminng.HsadminNgApplication; import net.hostsharing.hsadminng.context.Context; import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRepository; import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRepository; +import net.hostsharing.hsadminng.hs.office.relationship.HsOfficeRelationshipEntity; +import net.hostsharing.hsadminng.hs.office.relationship.HsOfficeRelationshipType; import net.hostsharing.test.Accepts; import net.hostsharing.test.JpaAttempt; -import org.json.JSONException; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; @@ -24,8 +25,7 @@ import java.util.UUID; import static net.hostsharing.test.IsValidUuidMatcher.isUuidValid; import static net.hostsharing.test.JsonMatcher.lenientlyEquals; import static org.assertj.core.api.Assertions.assertThat; -import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.startsWith; +import static org.hamcrest.Matchers.*; @SpringBootTest( webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, @@ -33,6 +33,8 @@ import static org.hamcrest.Matchers.startsWith; ) class HsOfficePartnerControllerAcceptanceTest { + private static final UUID GIVEN_NON_EXISTING_PERSON_UUID = UUID.fromString("3fa85f64-5717-4562-b3fc-2c963f66afa6"); + @LocalServerPort private Integer port; @@ -63,7 +65,7 @@ class HsOfficePartnerControllerAcceptanceTest { class ListPartners { @Test - void globalAdmin_withoutAssumedRoles_canViewAllPartners_ifNoCriteriaGiven() throws JSONException { + void globalAdmin_withoutAssumedRoles_canViewAllPartners_ifNoCriteriaGiven() { RestAssured // @formatter:off .given() @@ -74,40 +76,7 @@ class HsOfficePartnerControllerAcceptanceTest { .then().log().all().assertThat() .statusCode(200) .contentType("application/json") - .body("", lenientlyEquals(""" - [ - { - "person": { "familyName": "Smith" }, - "partnerRole": { }, - "contact": { "label": "fifth contact" }, - "details": { "birthday": "1987-10-31" } - }, - { - "person": { "tradeName": "First GmbH" }, - "partnerRole": { }, - "contact": { "label": "first contact" }, - "details": { "registrationOffice": "Hamburg" } - }, - { - "person": { "tradeName": "Third OHG" }, - "partnerRole": { }, - "contact": { "label": "third contact" }, - "details": { "registrationOffice": "Hamburg" } - }, - { - "person": { "tradeName": "Second e.K." }, - "partnerRole": { }, - "contact": { "label": "second contact" }, - "details": { "registrationOffice": "Hamburg" } - }, - { - "person": { "personType": "INCORPORATED_FIRM" }, - "partnerRole": { }, - "contact": { "label": "fourth contact" }, - "details": { "registrationOffice": "Hamburg" } - } - ] - """)); + .body("", hasSize(5)); // @formatter:on } } @@ -121,6 +90,7 @@ class HsOfficePartnerControllerAcceptanceTest { void globalAdmin_withoutAssumedRole_canAddPartner() { context.define("superuser-alex@hostsharing.net"); + final var givenMandantPerson = personRepo.findPersonByOptionalNameLike("Hostsharing eG").get(0); final var givenPerson = personRepo.findPersonByOptionalNameLike("Third").get(0); final var givenContact = contactRepo.findContactByOptionalLabelLike("fourth").get(0); @@ -129,16 +99,26 @@ class HsOfficePartnerControllerAcceptanceTest { .header("current-user", "superuser-alex@hostsharing.net") .contentType(ContentType.JSON) .body(""" - { - "partnerNumber": "12345", - "contactUuid": "%s", - "personUuid": "%s", - "details": { - "registrationOffice": "Temp Registergericht Aurich", - "registrationNumber": "111111" - } - } - """.formatted(givenContact.getUuid(), givenPerson.getUuid())) + { + "partnerNumber": "12345", + "partnerRole": { + "relAnchorUuid": "%s", + "relHolderUuid": "%s", + "contactUuid": "%s" + }, + "personUuid": "%s", + "contactUuid": "%s", + "details": { + "registrationOffice": "Temp Registergericht Aurich", + "registrationNumber": "111111" + } + } + """.formatted( + givenMandantPerson.getUuid(), + givenPerson.getUuid(), + givenContact.getUuid(), + givenPerson.getUuid(), + givenContact.getUuid())) .port(port) .when() .post("http://localhost/api/hs/office/partners") @@ -163,6 +143,7 @@ class HsOfficePartnerControllerAcceptanceTest { void globalAdmin_canNotAddPartner_ifContactDoesNotExist() { context.define("superuser-alex@hostsharing.net"); + final var givenMandantPerson = personRepo.findPersonByOptionalNameLike("Hostsharing eG").get(0); final var givenPerson = personRepo.findPersonByOptionalNameLike("Third").get(0); final var givenContactUuid = UUID.fromString("3fa85f64-5717-4562-b3fc-2c963f66afa6"); @@ -171,13 +152,23 @@ class HsOfficePartnerControllerAcceptanceTest { .header("current-user", "superuser-alex@hostsharing.net") .contentType(ContentType.JSON) .body(""" - { - "partnerNumber": "12345", - "contactUuid": "%s", - "personUuid": "%s", - "details": {} - } - """.formatted(givenContactUuid, givenPerson.getUuid())) + { + "partnerNumber": "12345", + "partnerRole": { + "relAnchorUuid": "%s", + "relHolderUuid": "%s", + "contactUuid": "%s" + }, + "personUuid": "%s", + "contactUuid": "%s", + "details": {} + } + """.formatted( + givenMandantPerson, + givenPerson.getUuid(), + givenContactUuid, + givenPerson.getUuid(), + givenContactUuid)) .port(port) .when() .post("http://localhost/api/hs/office/partners") @@ -192,7 +183,6 @@ class HsOfficePartnerControllerAcceptanceTest { context.define("superuser-alex@hostsharing.net"); final var mandantPerson = personRepo.findPersonByOptionalNameLike("Hostsharing eG").get(0); - final var givenPersonUuid = UUID.fromString("3fa85f64-5717-4562-b3fc-2c963f66afa6"); final var givenContact = contactRepo.findContactByOptionalLabelLike("fourth").get(0); final var location = RestAssured // @formatter:off @@ -200,30 +190,29 @@ class HsOfficePartnerControllerAcceptanceTest { .header("current-user", "superuser-alex@hostsharing.net") .contentType(ContentType.JSON) .body(""" - { - "partnerNumber": "12345", - "partnerRole": { - "relAnchorUuid": "%s", - "relType": "PARTNER", - "relHolder": "%s", - "contact": "%s", - }, - "personUuid": "%s", - "contactUuid": "%s", - "details": {} - } + { + "partnerNumber": "12345", + "partnerRole": { + "relAnchorUuid": "%s", + "relHolderUuid": "%s", + "contact": "%s" + }, + "personUuid": "%s", + "contactUuid": "%s", + "details": {} + } """.formatted( mandantPerson.getUuid(), - givenPersonUuid, + GIVEN_NON_EXISTING_PERSON_UUID, givenContact.getUuid(), - givenPersonUuid, + GIVEN_NON_EXISTING_PERSON_UUID, givenContact.getUuid())) .port(port) .when() .post("http://localhost/api/hs/office/partners") .then().log().all().assertThat() .statusCode(400) - .body("message", is("Unable to find Person with uuid 3fa85f64-5717-4562-b3fc-2c963f66afa6")); + .body("message", is("Unable to find Person with uuid " + GIVEN_NON_EXISTING_PERSON_UUID)); // @formatter:on } } @@ -306,7 +295,7 @@ class HsOfficePartnerControllerAcceptanceTest { context.define("superuser-alex@hostsharing.net"); final var givenPartner = givenSomeTemporaryPartnerBessler(); final var givenPerson = personRepo.findPersonByOptionalNameLike("Third").get(0); - final var givenContact = contactRepo.findContactByOptionalLabelLike("forth").get(0); + final var givenContact = contactRepo.findContactByOptionalLabelLike("fourth").get(0); final var location = RestAssured // @formatter:off .given() @@ -314,7 +303,7 @@ class HsOfficePartnerControllerAcceptanceTest { .contentType(ContentType.JSON) .body(""" { - "debitorNumerPrefix": "12345", + "partnerNumber": "12345", "contactUuid": "%s", "personUuid": "%s", "details": { @@ -333,6 +322,7 @@ class HsOfficePartnerControllerAcceptanceTest { .statusCode(200) .contentType(ContentType.JSON) .body("uuid", isUuidValid()) + .body("partnerNumber", is(givenPartner.getPartnerNumber())) .body("details.registrationNumber", is("222222")) .body("contact.label", is(givenContact.getLabel())) .body("person.tradeName", is(givenPerson.getTradeName())); @@ -467,9 +457,20 @@ class HsOfficePartnerControllerAcceptanceTest { private HsOfficePartnerEntity givenSomeTemporaryPartnerBessler() { return jpaAttempt.transacted(() -> { context.define("superuser-alex@hostsharing.net"); + final var givenMandantPerson = personRepo.findPersonByOptionalNameLike("Hostsharing eG").get(0); + final var givenPerson = personRepo.findPersonByOptionalNameLike("Erben Bessler").get(0); final var givenContact = contactRepo.findContactByOptionalLabelLike("fourth contact").get(0); + + final var partnerRole = new HsOfficeRelationshipEntity(); + partnerRole.setRelType(HsOfficeRelationshipType.PARTNER); + partnerRole.setRelAnchor(givenMandantPerson); + partnerRole.setRelHolder(givenPerson); + partnerRole.setContact(givenContact); + em.persist(partnerRole); + final var newPartner = HsOfficePartnerEntity.builder() + .partnerRole(partnerRole) .person(givenPerson) .contact(givenContact) .details(HsOfficePartnerDetailsEntity.builder()