introduce-partner-business-role #16
@ -1,10 +1,15 @@
|
|||||||
package net.hostsharing.hsadminng.hs.office.partner;
|
package net.hostsharing.hsadminng.hs.office.partner;
|
||||||
|
|
||||||
import net.hostsharing.hsadminng.context.Context;
|
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.api.HsOfficePartnersApi;
|
||||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficePartnerInsertResource;
|
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.HsOfficePartnerPatchResource;
|
||||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficePartnerResource;
|
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 net.hostsharing.hsadminng.mapper.Mapper;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
@ -56,7 +61,7 @@ public class HsOfficePartnerController implements HsOfficePartnersApi {
|
|||||||
|
|
||||||
context.define(currentUser, assumedRoles);
|
context.define(currentUser, assumedRoles);
|
||||||
|
|
||||||
final var entityToSave = mapper.map(body, HsOfficePartnerEntity.class);
|
final var entityToSave = createPartnerEntity(body);
|
||||||
|
|
||||||
final var saved = partnerRepo.save(entityToSave);
|
final var saved = partnerRepo.save(entityToSave);
|
||||||
|
|
||||||
@ -119,4 +124,24 @@ public class HsOfficePartnerController implements HsOfficePartnersApi {
|
|||||||
final var mapped = mapper.map(saved, HsOfficePartnerResource.class);
|
final var mapped = mapper.map(saved, HsOfficePartnerResource.class);
|
||||||
return ResponseEntity.ok(mapped);
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -96,6 +96,8 @@ components:
|
|||||||
format: int8
|
format: int8
|
||||||
minimum: 10000
|
minimum: 10000
|
||||||
maximum: 99999
|
maximum: 99999
|
||||||
|
partnerRole:
|
||||||
|
$ref: '#/components/schemas/HsOfficePartnerRoleInsert'
|
||||||
personUuid:
|
personUuid:
|
||||||
type: string
|
type: string
|
||||||
format: uuid
|
format: uuid
|
||||||
@ -110,6 +112,24 @@ components:
|
|||||||
- contactUuid
|
- contactUuid
|
||||||
- details
|
- 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:
|
HsOfficePartnerDetailsInsert:
|
||||||
type: object
|
type: object
|
||||||
nullable: false
|
nullable: false
|
||||||
|
@ -62,3 +62,4 @@ components:
|
|||||||
- relAnchorUuid
|
- relAnchorUuid
|
||||||
- relHolderUuid
|
- relHolderUuid
|
||||||
- relType
|
- relType
|
||||||
|
- relContactUuid
|
||||||
|
@ -6,9 +6,10 @@ import net.hostsharing.hsadminng.HsadminNgApplication;
|
|||||||
import net.hostsharing.hsadminng.context.Context;
|
import net.hostsharing.hsadminng.context.Context;
|
||||||
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRepository;
|
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRepository;
|
||||||
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRepository;
|
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.Accepts;
|
||||||
import net.hostsharing.test.JpaAttempt;
|
import net.hostsharing.test.JpaAttempt;
|
||||||
import org.json.JSONException;
|
|
||||||
import org.junit.jupiter.api.AfterEach;
|
import org.junit.jupiter.api.AfterEach;
|
||||||
import org.junit.jupiter.api.Nested;
|
import org.junit.jupiter.api.Nested;
|
||||||
import org.junit.jupiter.api.Test;
|
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.IsValidUuidMatcher.isUuidValid;
|
||||||
import static net.hostsharing.test.JsonMatcher.lenientlyEquals;
|
import static net.hostsharing.test.JsonMatcher.lenientlyEquals;
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.hamcrest.Matchers.is;
|
import static org.hamcrest.Matchers.*;
|
||||||
import static org.hamcrest.Matchers.startsWith;
|
|
||||||
|
|
||||||
@SpringBootTest(
|
@SpringBootTest(
|
||||||
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
|
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
|
||||||
@ -33,6 +33,8 @@ import static org.hamcrest.Matchers.startsWith;
|
|||||||
)
|
)
|
||||||
class HsOfficePartnerControllerAcceptanceTest {
|
class HsOfficePartnerControllerAcceptanceTest {
|
||||||
|
|
||||||
|
private static final UUID GIVEN_NON_EXISTING_PERSON_UUID = UUID.fromString("3fa85f64-5717-4562-b3fc-2c963f66afa6");
|
||||||
|
|
||||||
@LocalServerPort
|
@LocalServerPort
|
||||||
private Integer port;
|
private Integer port;
|
||||||
|
|
||||||
@ -63,7 +65,7 @@ class HsOfficePartnerControllerAcceptanceTest {
|
|||||||
class ListPartners {
|
class ListPartners {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void globalAdmin_withoutAssumedRoles_canViewAllPartners_ifNoCriteriaGiven() throws JSONException {
|
void globalAdmin_withoutAssumedRoles_canViewAllPartners_ifNoCriteriaGiven() {
|
||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
@ -74,40 +76,7 @@ class HsOfficePartnerControllerAcceptanceTest {
|
|||||||
.then().log().all().assertThat()
|
.then().log().all().assertThat()
|
||||||
.statusCode(200)
|
.statusCode(200)
|
||||||
.contentType("application/json")
|
.contentType("application/json")
|
||||||
.body("", lenientlyEquals("""
|
.body("", hasSize(5));
|
||||||
[
|
|
||||||
{
|
|
||||||
"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" }
|
|
||||||
}
|
|
||||||
]
|
|
||||||
"""));
|
|
||||||
// @formatter:on
|
// @formatter:on
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -121,6 +90,7 @@ class HsOfficePartnerControllerAcceptanceTest {
|
|||||||
void globalAdmin_withoutAssumedRole_canAddPartner() {
|
void globalAdmin_withoutAssumedRole_canAddPartner() {
|
||||||
|
|
||||||
context.define("superuser-alex@hostsharing.net");
|
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 givenPerson = personRepo.findPersonByOptionalNameLike("Third").get(0);
|
||||||
final var givenContact = contactRepo.findContactByOptionalLabelLike("fourth").get(0);
|
final var givenContact = contactRepo.findContactByOptionalLabelLike("fourth").get(0);
|
||||||
|
|
||||||
@ -129,16 +99,26 @@ class HsOfficePartnerControllerAcceptanceTest {
|
|||||||
.header("current-user", "superuser-alex@hostsharing.net")
|
.header("current-user", "superuser-alex@hostsharing.net")
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
"partnerNumber": "12345",
|
"partnerNumber": "12345",
|
||||||
"contactUuid": "%s",
|
"partnerRole": {
|
||||||
"personUuid": "%s",
|
"relAnchorUuid": "%s",
|
||||||
"details": {
|
"relHolderUuid": "%s",
|
||||||
"registrationOffice": "Temp Registergericht Aurich",
|
"contactUuid": "%s"
|
||||||
"registrationNumber": "111111"
|
},
|
||||||
}
|
"personUuid": "%s",
|
||||||
}
|
"contactUuid": "%s",
|
||||||
""".formatted(givenContact.getUuid(), givenPerson.getUuid()))
|
"details": {
|
||||||
|
"registrationOffice": "Temp Registergericht Aurich",
|
||||||
|
"registrationNumber": "111111"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
""".formatted(
|
||||||
|
givenMandantPerson.getUuid(),
|
||||||
|
givenPerson.getUuid(),
|
||||||
|
givenContact.getUuid(),
|
||||||
|
givenPerson.getUuid(),
|
||||||
|
givenContact.getUuid()))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.post("http://localhost/api/hs/office/partners")
|
.post("http://localhost/api/hs/office/partners")
|
||||||
@ -163,6 +143,7 @@ class HsOfficePartnerControllerAcceptanceTest {
|
|||||||
void globalAdmin_canNotAddPartner_ifContactDoesNotExist() {
|
void globalAdmin_canNotAddPartner_ifContactDoesNotExist() {
|
||||||
|
|
||||||
context.define("superuser-alex@hostsharing.net");
|
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 givenPerson = personRepo.findPersonByOptionalNameLike("Third").get(0);
|
||||||
final var givenContactUuid = UUID.fromString("3fa85f64-5717-4562-b3fc-2c963f66afa6");
|
final var givenContactUuid = UUID.fromString("3fa85f64-5717-4562-b3fc-2c963f66afa6");
|
||||||
|
|
||||||
@ -171,13 +152,23 @@ class HsOfficePartnerControllerAcceptanceTest {
|
|||||||
.header("current-user", "superuser-alex@hostsharing.net")
|
.header("current-user", "superuser-alex@hostsharing.net")
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
"partnerNumber": "12345",
|
"partnerNumber": "12345",
|
||||||
"contactUuid": "%s",
|
"partnerRole": {
|
||||||
"personUuid": "%s",
|
"relAnchorUuid": "%s",
|
||||||
"details": {}
|
"relHolderUuid": "%s",
|
||||||
}
|
"contactUuid": "%s"
|
||||||
""".formatted(givenContactUuid, givenPerson.getUuid()))
|
},
|
||||||
|
"personUuid": "%s",
|
||||||
|
"contactUuid": "%s",
|
||||||
|
"details": {}
|
||||||
|
}
|
||||||
|
""".formatted(
|
||||||
|
givenMandantPerson,
|
||||||
|
givenPerson.getUuid(),
|
||||||
|
givenContactUuid,
|
||||||
|
givenPerson.getUuid(),
|
||||||
|
givenContactUuid))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.post("http://localhost/api/hs/office/partners")
|
.post("http://localhost/api/hs/office/partners")
|
||||||
@ -192,7 +183,6 @@ class HsOfficePartnerControllerAcceptanceTest {
|
|||||||
|
|
||||||
context.define("superuser-alex@hostsharing.net");
|
context.define("superuser-alex@hostsharing.net");
|
||||||
final var mandantPerson = personRepo.findPersonByOptionalNameLike("Hostsharing eG").get(0);
|
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 givenContact = contactRepo.findContactByOptionalLabelLike("fourth").get(0);
|
||||||
|
|
||||||
final var location = RestAssured // @formatter:off
|
final var location = RestAssured // @formatter:off
|
||||||
@ -200,30 +190,29 @@ class HsOfficePartnerControllerAcceptanceTest {
|
|||||||
.header("current-user", "superuser-alex@hostsharing.net")
|
.header("current-user", "superuser-alex@hostsharing.net")
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
"partnerNumber": "12345",
|
"partnerNumber": "12345",
|
||||||
"partnerRole": {
|
"partnerRole": {
|
||||||
"relAnchorUuid": "%s",
|
"relAnchorUuid": "%s",
|
||||||
"relType": "PARTNER",
|
"relHolderUuid": "%s",
|
||||||
"relHolder": "%s",
|
"contact": "%s"
|
||||||
"contact": "%s",
|
},
|
||||||
},
|
"personUuid": "%s",
|
||||||
"personUuid": "%s",
|
"contactUuid": "%s",
|
||||||
"contactUuid": "%s",
|
"details": {}
|
||||||
"details": {}
|
}
|
||||||
}
|
|
||||||
""".formatted(
|
""".formatted(
|
||||||
mandantPerson.getUuid(),
|
mandantPerson.getUuid(),
|
||||||
givenPersonUuid,
|
GIVEN_NON_EXISTING_PERSON_UUID,
|
||||||
givenContact.getUuid(),
|
givenContact.getUuid(),
|
||||||
givenPersonUuid,
|
GIVEN_NON_EXISTING_PERSON_UUID,
|
||||||
givenContact.getUuid()))
|
givenContact.getUuid()))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.post("http://localhost/api/hs/office/partners")
|
.post("http://localhost/api/hs/office/partners")
|
||||||
.then().log().all().assertThat()
|
.then().log().all().assertThat()
|
||||||
.statusCode(400)
|
.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
|
// @formatter:on
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -306,7 +295,7 @@ class HsOfficePartnerControllerAcceptanceTest {
|
|||||||
context.define("superuser-alex@hostsharing.net");
|
context.define("superuser-alex@hostsharing.net");
|
||||||
final var givenPartner = givenSomeTemporaryPartnerBessler();
|
final var givenPartner = givenSomeTemporaryPartnerBessler();
|
||||||
final var givenPerson = personRepo.findPersonByOptionalNameLike("Third").get(0);
|
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
|
final var location = RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
@ -314,7 +303,7 @@ class HsOfficePartnerControllerAcceptanceTest {
|
|||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
"debitorNumerPrefix": "12345",
|
"partnerNumber": "12345",
|
||||||
"contactUuid": "%s",
|
"contactUuid": "%s",
|
||||||
"personUuid": "%s",
|
"personUuid": "%s",
|
||||||
"details": {
|
"details": {
|
||||||
@ -333,6 +322,7 @@ class HsOfficePartnerControllerAcceptanceTest {
|
|||||||
.statusCode(200)
|
.statusCode(200)
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("uuid", isUuidValid())
|
.body("uuid", isUuidValid())
|
||||||
|
.body("partnerNumber", is(givenPartner.getPartnerNumber()))
|
||||||
.body("details.registrationNumber", is("222222"))
|
.body("details.registrationNumber", is("222222"))
|
||||||
.body("contact.label", is(givenContact.getLabel()))
|
.body("contact.label", is(givenContact.getLabel()))
|
||||||
.body("person.tradeName", is(givenPerson.getTradeName()));
|
.body("person.tradeName", is(givenPerson.getTradeName()));
|
||||||
@ -467,9 +457,20 @@ class HsOfficePartnerControllerAcceptanceTest {
|
|||||||
private HsOfficePartnerEntity givenSomeTemporaryPartnerBessler() {
|
private HsOfficePartnerEntity givenSomeTemporaryPartnerBessler() {
|
||||||
return jpaAttempt.transacted(() -> {
|
return jpaAttempt.transacted(() -> {
|
||||||
context.define("superuser-alex@hostsharing.net");
|
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 givenPerson = personRepo.findPersonByOptionalNameLike("Erben Bessler").get(0);
|
||||||
final var givenContact = contactRepo.findContactByOptionalLabelLike("fourth contact").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()
|
final var newPartner = HsOfficePartnerEntity.builder()
|
||||||
|
.partnerRole(partnerRole)
|
||||||
.person(givenPerson)
|
.person(givenPerson)
|
||||||
.contact(givenContact)
|
.contact(givenContact)
|
||||||
.details(HsOfficePartnerDetailsEntity.builder()
|
.details(HsOfficePartnerDetailsEntity.builder()
|
||||||
|
Loading…
Reference in New Issue
Block a user