remove partner.person + partner.contact - WIP: compiles, but no more

This commit is contained in:
Michael Hoennig 2024-02-01 17:49:27 +01:00
parent 2c0101b46d
commit 38487e0579
15 changed files with 156 additions and 164 deletions

View File

@ -142,8 +142,6 @@ public class HsOfficePartnerController implements HsOfficePartnersApi {
final var entityToSave = new HsOfficePartnerEntity(); final var entityToSave = new HsOfficePartnerEntity();
entityToSave.setPartnerNumber(body.getPartnerNumber()); entityToSave.setPartnerNumber(body.getPartnerNumber());
entityToSave.setPartnerRole(persistPartnerRole(body.getPartnerRole())); entityToSave.setPartnerRole(persistPartnerRole(body.getPartnerRole()));
entityToSave.setContact(ref(HsOfficeContactEntity.class, body.getContactUuid()));
entityToSave.setPerson(ref(HsOfficePersonEntity.class, body.getPersonUuid()));
entityToSave.setDetails(mapper.map(body.getDetails(), HsOfficePartnerDetailsEntity.class)); entityToSave.setDetails(mapper.map(body.getDetails(), HsOfficePartnerDetailsEntity.class));
return entityToSave; return entityToSave;
} }

View File

@ -3,8 +3,8 @@ package net.hostsharing.hsadminng.hs.office.partner;
import lombok.*; import lombok.*;
import net.hostsharing.hsadminng.errors.DisplayName; import net.hostsharing.hsadminng.errors.DisplayName;
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactEntity; import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactEntity;
import net.hostsharing.hsadminng.persistence.HasUuid;
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity; import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity;
import net.hostsharing.hsadminng.persistence.HasUuid;
import net.hostsharing.hsadminng.hs.office.relationship.HsOfficeRelationshipEntity; import net.hostsharing.hsadminng.hs.office.relationship.HsOfficeRelationshipEntity;
import net.hostsharing.hsadminng.stringify.Stringify; import net.hostsharing.hsadminng.stringify.Stringify;
import net.hostsharing.hsadminng.stringify.Stringifyable; import net.hostsharing.hsadminng.stringify.Stringifyable;
@ -12,9 +12,9 @@ import org.hibernate.annotations.NotFound;
import org.hibernate.annotations.NotFoundAction; import org.hibernate.annotations.NotFoundAction;
import jakarta.persistence.*; import jakarta.persistence.*;
import java.util.Optional;
import java.util.UUID; import java.util.UUID;
import static java.util.Optional.ofNullable;
import static net.hostsharing.hsadminng.stringify.Stringify.stringify; import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
@Entity @Entity
@ -27,10 +27,17 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
@DisplayName("Partner") @DisplayName("Partner")
public class HsOfficePartnerEntity implements Stringifyable, HasUuid { public class HsOfficePartnerEntity implements Stringifyable, HasUuid {
public static final String PARTNER_NUMBER_TAG = "P-";
private static Stringify<HsOfficePartnerEntity> stringify = stringify(HsOfficePartnerEntity.class, "partner") private static Stringify<HsOfficePartnerEntity> stringify = stringify(HsOfficePartnerEntity.class, "partner")
.withProp(HsOfficePartnerEntity::getPerson) .withIdProp(HsOfficePartnerEntity::getPartnerNumber)
.withProp(HsOfficePartnerEntity::getContact) .withProp(p -> ofNullable(p.getPartnerRole())
.withSeparator(": ") .map(HsOfficeRelationshipEntity::getRelHolder)
.map(HsOfficePersonEntity::toShortString))
.withProp(p -> ofNullable(p.getPartnerRole())
.map(HsOfficeRelationshipEntity::getContact)
.map(HsOfficeContactEntity::toShortString))
.withSeparator(", ")
.quotedValues(false); .quotedValues(false);
@Id @Id
@ -44,21 +51,15 @@ public class HsOfficePartnerEntity implements Stringifyable, HasUuid {
@JoinColumn(name = "partnerroleuuid", nullable = false) @JoinColumn(name = "partnerroleuuid", nullable = false)
private HsOfficeRelationshipEntity partnerRole; private HsOfficeRelationshipEntity partnerRole;
// TODO: remove, is replaced by partnerRole
@ManyToOne
@JoinColumn(name = "personuuid", nullable = false)
private HsOfficePersonEntity person;
// TODO: remove, is replaced by partnerRole
@ManyToOne
@JoinColumn(name = "contactuuid", nullable = false)
private HsOfficeContactEntity contact;
@ManyToOne(cascade = { CascadeType.PERSIST, CascadeType.MERGE, CascadeType.DETACH }, optional = true) @ManyToOne(cascade = { CascadeType.PERSIST, CascadeType.MERGE, CascadeType.DETACH }, optional = true)
@JoinColumn(name = "detailsuuid") @JoinColumn(name = "detailsuuid")
@NotFound(action = NotFoundAction.IGNORE) @NotFound(action = NotFoundAction.IGNORE)
private HsOfficePartnerDetailsEntity details; private HsOfficePartnerDetailsEntity details;
public String getTaggedPartnerNumber() {
return PARTNER_NUMBER_TAG + partnerNumber;
}
@Override @Override
public String toString() { public String toString() {
return stringify.apply(this); return stringify.apply(this);
@ -66,6 +67,6 @@ public class HsOfficePartnerEntity implements Stringifyable, HasUuid {
@Override @Override
public String toShortString() { public String toShortString() {
return Optional.ofNullable(person).map(HsOfficePersonEntity::toShortString).orElse("<person=null>"); return getTaggedPartnerNumber();
} }
} }

View File

@ -1,13 +1,11 @@
package net.hostsharing.hsadminng.hs.office.partner; package net.hostsharing.hsadminng.hs.office.partner;
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactEntity;
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.person.HsOfficePersonEntity; import net.hostsharing.hsadminng.hs.office.relationship.HsOfficeRelationshipEntity;
import net.hostsharing.hsadminng.mapper.EntityPatcher; import net.hostsharing.hsadminng.mapper.EntityPatcher;
import net.hostsharing.hsadminng.mapper.OptionalFromJson; import net.hostsharing.hsadminng.mapper.OptionalFromJson;
import jakarta.persistence.EntityManager; import jakarta.persistence.EntityManager;
import java.util.UUID;
class HsOfficePartnerEntityPatcher implements EntityPatcher<HsOfficePartnerPatchResource> { class HsOfficePartnerEntityPatcher implements EntityPatcher<HsOfficePartnerPatchResource> {
private final EntityManager em; private final EntityManager em;
@ -21,19 +19,15 @@ class HsOfficePartnerEntityPatcher implements EntityPatcher<HsOfficePartnerPatch
@Override @Override
public void apply(final HsOfficePartnerPatchResource resource) { public void apply(final HsOfficePartnerPatchResource resource) {
OptionalFromJson.of(resource.getContactUuid()).ifPresent(newValue -> { OptionalFromJson.of(resource.getPartnerRoleUuid()).ifPresent(newValue -> {
verifyNotNull(newValue, "contact"); verifyNotNull(newValue, "contact");
entity.setContact(em.getReference(HsOfficeContactEntity.class, newValue)); entity.setPartnerRole(em.getReference(HsOfficeRelationshipEntity.class, newValue));
});
OptionalFromJson.of(resource.getPersonUuid()).ifPresent(newValue -> {
verifyNotNull(newValue, "person");
entity.setPerson(em.getReference(HsOfficePersonEntity.class, newValue));
}); });
new HsOfficePartnerDetailsEntityPatcher(em, entity.getDetails()).apply(resource.getDetails()); new HsOfficePartnerDetailsEntityPatcher(em, entity.getDetails()).apply(resource.getDetails());
} }
private void verifyNotNull(final UUID newValue, final String propertyName) { private void verifyNotNull(final Object newValue, final String propertyName) {
if (newValue == null) { if (newValue == null) {
throw new IllegalArgumentException("property '" + propertyName + "' must not be null"); throw new IllegalArgumentException("property '" + propertyName + "' must not be null");
} }

View File

@ -16,6 +16,7 @@ public final class Stringify<B> {
private final Class<B> clazz; private final Class<B> clazz;
private final String name; private final String name;
private Function<B, ?> idProp;
private final List<Property<B>> props = new ArrayList<>(); private final List<Property<B>> props = new ArrayList<>();
private String separator = ", "; private String separator = ", ";
private Boolean quotedValues = null; private Boolean quotedValues = null;
@ -42,6 +43,11 @@ public final class Stringify<B> {
} }
} }
public Stringify<B> withIdProp(final Function<B, ?> getter) {
idProp = getter;
return this;
}
public Stringify<B> withProp(final String propName, final Function<B, ?> getter) { public Stringify<B> withProp(final String propName, final Function<B, ?> getter) {
props.add(new Property<>(propName, getter)); props.add(new Property<>(propName, getter));
return this; return this;
@ -64,7 +70,9 @@ public final class Stringify<B> {
}) })
.map(propVal -> propName(propVal, "=") + optionallyQuoted(propVal)) .map(propVal -> propName(propVal, "=") + optionallyQuoted(propVal))
.collect(Collectors.joining(separator)); .collect(Collectors.joining(separator));
return name + "(" + propValues + ")"; return idProp == null
? name + "(" + idProp + ": " + propValues + ")"
: name + "(" + propValues + ")";
} }
public Stringify<B> withSeparator(final String separator) { public Stringify<B> withSeparator(final String separator) {

View File

@ -14,10 +14,8 @@ components:
format: int8 format: int8
minimum: 10000 minimum: 10000
maximum: 99999 maximum: 99999
person: partnerRole:
$ref: './hs-office-person-schemas.yaml#/components/schemas/HsOfficePerson' $ref: './hs-office-relationship-schemas.yaml#/components/schemas/HsOfficeRelationship'
contact:
$ref: './hs-office-contact-schemas.yaml#/components/schemas/HsOfficeContact'
details: details:
$ref: '#/components/schemas/HsOfficePartnerDetails' $ref: '#/components/schemas/HsOfficePartnerDetails'
@ -52,11 +50,7 @@ components:
HsOfficePartnerPatch: HsOfficePartnerPatch:
type: object type: object
properties: properties:
personUuid: partnerRoleUUid:
type: string
format: uuid
nullable: true
contactUuid:
type: string type: string
format: uuid format: uuid
nullable: true nullable: true
@ -98,18 +92,11 @@ components:
maximum: 99999 maximum: 99999
partnerRole: partnerRole:
$ref: '#/components/schemas/HsOfficePartnerRoleInsert' $ref: '#/components/schemas/HsOfficePartnerRoleInsert'
personUuid:
type: string
format: uuid
contactUuid:
type: string
format: uuid
details: details:
$ref: '#/components/schemas/HsOfficePartnerDetailsInsert' $ref: '#/components/schemas/HsOfficePartnerDetailsInsert'
required: required:
- partnerNumber - partnerNumber
- personUuid - partnerRole
- contactUuid
- details - details
HsOfficePartnerRoleInsert: HsOfficePartnerRoleInsert:

View File

@ -34,8 +34,6 @@ create table hs_office_partner
uuid uuid unique references RbacObject (uuid) initially deferred, uuid uuid unique references RbacObject (uuid) initially deferred,
partnerNumber numeric(5) unique not null, partnerNumber numeric(5) unique not null,
partnerRoleUuid uuid not null references hs_office_relationship(uuid), -- TODO: delete in after delete trigger partnerRoleUuid uuid not null references hs_office_relationship(uuid), -- TODO: delete in after delete trigger
personUuid uuid not null references hs_office_person(uuid), -- TODO: remove, replaced by partnerRoleUuid
contactUuid uuid not null references hs_office_contact(uuid), -- TODO: remove, replaced by partnerRoleUuid
detailsUuid uuid not null references hs_office_partner_details(uuid) -- deleted in after delete trigger detailsUuid uuid not null references hs_office_partner_details(uuid) -- deleted in after delete trigger
); );
--// --//

View File

@ -184,7 +184,7 @@ class HsOfficeDebitorControllerAcceptanceTest extends ContextBasedTestWithCleanu
.body("vatId", is("VAT123456")) .body("vatId", is("VAT123456"))
.body("defaultPrefix", is("for")) .body("defaultPrefix", is("for"))
.body("billingContact.label", is(givenContact.getLabel())) .body("billingContact.label", is(givenContact.getLabel()))
.body("partner.person.tradeName", is(givenPartner.getPerson().getTradeName())) .body("partner.partnerRole.relHolder.tradeName", is(givenPartner.getPartnerRole().getRelHolder().getTradeName()))
.body("refundBankAccount.holder", is(givenBankAccount.getHolder())) .body("refundBankAccount.holder", is(givenBankAccount.getHolder()))
.header("Location", startsWith("http://localhost")) .header("Location", startsWith("http://localhost"))
.extract().header("Location"); // @formatter:on .extract().header("Location"); // @formatter:on
@ -224,7 +224,7 @@ class HsOfficeDebitorControllerAcceptanceTest extends ContextBasedTestWithCleanu
.contentType(ContentType.JSON) .contentType(ContentType.JSON)
.body("uuid", isUuidValid()) .body("uuid", isUuidValid())
.body("billingContact.label", is(givenContact.getLabel())) .body("billingContact.label", is(givenContact.getLabel()))
.body("partner.person.tradeName", is(givenPartner.getPerson().getTradeName())) .body("partner.partnerRole.relHolder.tradeName", is(givenPartner.getPartnerRole().getRelHolder().getTradeName()))
.body("vatId", equalTo(null)) .body("vatId", equalTo(null))
.body("vatCountryCode", equalTo(null)) .body("vatCountryCode", equalTo(null))
.body("vatBusiness", equalTo(false)) .body("vatBusiness", equalTo(false))
@ -410,16 +410,15 @@ class HsOfficeDebitorControllerAcceptanceTest extends ContextBasedTestWithCleanu
.body("vatBusiness", is(true)) .body("vatBusiness", is(true))
.body("defaultPrefix", is("for")) .body("defaultPrefix", is("for"))
.body("billingContact.label", is(givenContact.getLabel())) .body("billingContact.label", is(givenContact.getLabel()))
.body("partner.person.tradeName", is(givenDebitor.getPartner().getPerson().getTradeName())); .body("partner.partnerRole.relHolder.tradeName", is(givenDebitor.getPartner().getPartnerRole().getRelHolder().getTradeName()));
// @formatter:on // @formatter:on
// finally, the debitor is actually updated // finally, the debitor is actually updated
context.define("superuser-alex@hostsharing.net"); context.define("superuser-alex@hostsharing.net");
assertThat(debitorRepo.findByUuid(givenDebitor.getUuid())).isPresent().get() assertThat(debitorRepo.findByUuid(givenDebitor.getUuid())).isPresent().get()
.matches(partner -> { .matches(partner -> {
assertThat(partner.getPartner().getPerson().getTradeName()).isEqualTo(givenDebitor.getPartner() assertThat(partner.getPartner().getPartnerRole().getRelHolder().getTradeName())
.getPerson() .isEqualTo(givenDebitor.getPartner().getPartnerRole().getRelHolder().getTradeName());
.getTradeName());
assertThat(partner.getBillingContact().getLabel()).isEqualTo("fourth contact"); assertThat(partner.getBillingContact().getLabel()).isEqualTo("fourth contact");
assertThat(partner.getVatId()).isEqualTo("VAT222222"); assertThat(partner.getVatId()).isEqualTo("VAT222222");
assertThat(partner.getVatCountryCode()).isEqualTo("AA"); assertThat(partner.getVatCountryCode()).isEqualTo("AA");
@ -461,9 +460,8 @@ class HsOfficeDebitorControllerAcceptanceTest extends ContextBasedTestWithCleanu
// finally, the debitor is actually updated // finally, the debitor is actually updated
assertThat(debitorRepo.findByUuid(givenDebitor.getUuid())).isPresent().get() assertThat(debitorRepo.findByUuid(givenDebitor.getUuid())).isPresent().get()
.matches(partner -> { .matches(partner -> {
assertThat(partner.getPartner().getPerson().getTradeName()).isEqualTo(givenDebitor.getPartner() assertThat(partner.getPartner().getPartnerRole().getRelHolder().getTradeName())
.getPerson() .isEqualTo(givenDebitor.getPartner().getPartnerRole().getRelHolder().getTradeName());
.getTradeName());
assertThat(partner.getBillingContact().getLabel()).isEqualTo("sixth contact"); assertThat(partner.getBillingContact().getLabel()).isEqualTo("sixth contact");
assertThat(partner.getVatId()).isEqualTo("VAT999999"); assertThat(partner.getVatId()).isEqualTo("VAT999999");
assertThat(partner.getVatCountryCode()).isEqualTo(givenDebitor.getVatCountryCode()); assertThat(partner.getVatCountryCode()).isEqualTo(givenDebitor.getVatCountryCode());

View File

@ -5,6 +5,7 @@ import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerDetailsEntity;
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity; import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity;
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity; import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity;
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonType; import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonType;
import net.hostsharing.hsadminng.hs.office.relationship.HsOfficeRelationshipEntity;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
@ -16,10 +17,12 @@ class HsOfficeDebitorEntityUnitTest {
final var given = HsOfficeDebitorEntity.builder() final var given = HsOfficeDebitorEntity.builder()
.debitorNumberSuffix((byte)67) .debitorNumberSuffix((byte)67)
.partner(HsOfficePartnerEntity.builder() .partner(HsOfficePartnerEntity.builder()
.person(HsOfficePersonEntity.builder() .partnerRole(HsOfficeRelationshipEntity.builder()
.relHolder(HsOfficePersonEntity.builder()
.personType(HsOfficePersonType.LEGAL_PERSON) .personType(HsOfficePersonType.LEGAL_PERSON)
.tradeName("some trade name") .tradeName("some trade name")
.build()) .build())
.build())
.details(HsOfficePartnerDetailsEntity.builder().birthName("some birth name").build()) .details(HsOfficePartnerDetailsEntity.builder().birthName("some birth name").build())
.partnerNumber(12345) .partnerNumber(12345)
.build()) .build())
@ -37,7 +40,7 @@ class HsOfficeDebitorEntityUnitTest {
final var given = HsOfficeDebitorEntity.builder() final var given = HsOfficeDebitorEntity.builder()
.debitorNumberSuffix((byte)67) .debitorNumberSuffix((byte)67)
.partner(HsOfficePartnerEntity.builder() .partner(HsOfficePartnerEntity.builder()
.person(null) .partnerRole(null)
.details(HsOfficePartnerDetailsEntity.builder().birthName("some birth name").build()) .details(HsOfficePartnerDetailsEntity.builder().birthName("some birth name").build())
.partnerNumber(12345) .partnerNumber(12345)
.build()) .build())

View File

@ -333,7 +333,7 @@ class HsOfficeMembershipControllerAcceptanceTest extends ContextBasedTestWithCle
.statusCode(200) .statusCode(200)
.contentType(ContentType.JSON) .contentType(ContentType.JSON)
.body("uuid", isUuidValid()) .body("uuid", isUuidValid())
.body("partner.person.tradeName", is(givenMembership.getPartner().getPerson().getTradeName())) .body("partner.person.tradeName", is(givenMembership.getPartner().getPartnerRole().getRelHolder().getTradeName()))
.body("mainDebitor.debitorNumber", is(givenMembership.getMainDebitor().getDebitorNumber())) .body("mainDebitor.debitorNumber", is(givenMembership.getMainDebitor().getDebitorNumber()))
.body("mainDebitor.debitorNumberSuffix", is((int) givenMembership.getMainDebitor().getDebitorNumberSuffix())) .body("mainDebitor.debitorNumberSuffix", is((int) givenMembership.getMainDebitor().getDebitorNumberSuffix()))
.body("mainDebitor.debitorNumberSuffix", is((int) givenMembership.getMainDebitor().getDebitorNumberSuffix())) .body("mainDebitor.debitorNumberSuffix", is((int) givenMembership.getMainDebitor().getDebitorNumberSuffix()))
@ -378,7 +378,7 @@ class HsOfficeMembershipControllerAcceptanceTest extends ContextBasedTestWithCle
.statusCode(200) .statusCode(200)
.contentType(ContentType.JSON) .contentType(ContentType.JSON)
.body("uuid", isUuidValid()) .body("uuid", isUuidValid())
.body("partner.person.tradeName", is(givenMembership.getPartner().getPerson().getTradeName())) .body("partner.person.tradeName", is(givenMembership.getPartner().getPartnerRole().getRelHolder().getTradeName()))
.body("mainDebitor.debitorNumber", is(1000313)) .body("mainDebitor.debitorNumber", is(1000313))
.body("memberNumberSuffix", is(givenMembership.getMemberNumberSuffix())) .body("memberNumberSuffix", is(givenMembership.getMemberNumberSuffix()))
.body("validFrom", is("2022-11-01")) .body("validFrom", is("2022-11-01"))

View File

@ -387,13 +387,15 @@ public class ImportOfficeData extends ContextBasedTest {
@Test @Test
@Order(2000) @Order(2000)
void verifyAllPartnersHavePersons() { void verifyAllPartnersHaveProperPartnerRoles() {
partners.forEach((id, p) -> { partners.forEach((id, p) -> {
final var partnerRole = p.getPartnerRole();
assertThat(partnerRole).describedAs("partner " + id + " without partnerRole").isNotNull();
if ( id != 99 ) { if ( id != 99 ) {
assertThat(p.getContact()).describedAs("partner " + id + " without contact").isNotNull(); assertThat(partnerRole.getContact()).describedAs("partner " + id + " without partnerRole.contact").isNotNull();
assertThat(p.getContact().getLabel()).describedAs("partner " + id + " without valid contact").isNotNull(); assertThat(partnerRole.getContact().getLabel()).describedAs("partner " + id + " without valid partnerRole.contact").isNotNull();
assertThat(p.getPerson()).describedAs("partner " + id + " without person").isNotNull(); assertThat(partnerRole.getRelHolder()).describedAs("partner " + id + " without partnerRole.relHolder").isNotNull();
assertThat(p.getPerson().getPersonType()).describedAs("partner " + id + " without valid person").isNotNull(); assertThat(partnerRole.getRelHolder().getPersonType()).describedAs("partner " + id + " without valid partnerRole.relHolder").isNotNull();
} }
}); });
} }
@ -424,9 +426,11 @@ public class ImportOfficeData extends ContextBasedTest {
// avoid a error when persisting the deliberetely invalid partner entry #99 // avoid a error when persisting the deliberetely invalid partner entry #99
final var idsToRemove = new HashSet<Integer>(); final var idsToRemove = new HashSet<Integer>();
partners.forEach( (id, r) -> { partners.forEach( (id, r) -> {
// such a record final var partnerRole = r.getPartnerRole();
if (r.getContact() == null || r.getContact().getLabel() == null ||
r.getPerson() == null | r.getPerson().getPersonType() == null ) { // such a record is in test data to test error messages
if (partnerRole.getContact() == null || partnerRole.getContact().getLabel() == null ||
partnerRole.getRelHolder() == null | partnerRole.getRelHolder().getPersonType() == null ) {
idsToRemove.add(id); idsToRemove.add(id);
} }
}); });
@ -441,10 +445,10 @@ public class ImportOfficeData extends ContextBasedTest {
// avoid a error when persisting the deliberetely invalid partner entry #99 // avoid a error when persisting the deliberetely invalid partner entry #99
final var idsToRemove = new HashSet<Integer>(); final var idsToRemove = new HashSet<Integer>();
debitors.forEach( (id, r) -> { debitors.forEach( (id, d) -> {
// such a record // such a record is in test data to test error messages
if (r.getBillingContact() == null || r.getBillingContact().getLabel() == null || if (d.getBillingContact() == null || d.getBillingContact().getLabel() == null ||
r.getPartner().getPerson() == null | r.getPartner().getPerson().getPersonType() == null ) { d.getPartner() == null || d.getPartner().getPartnerRole().getRelAnchor().getPersonType() == null ) {
idsToRemove.add(id); idsToRemove.add(id);
} }
}); });
@ -668,8 +672,6 @@ public class ImportOfficeData extends ContextBasedTest {
.partnerNumber(rec.getInteger("member_id")) .partnerNumber(rec.getInteger("member_id"))
.details(HsOfficePartnerDetailsEntity.builder().build()) .details(HsOfficePartnerDetailsEntity.builder().build())
.partnerRole(partnerRelationship) .partnerRole(partnerRelationship)
.contact(null) // is set during contacts import depending on assigned roles
.person(person)
.build(); .build();
partners.put(rec.getInteger("bp_id"), partner); partners.put(rec.getInteger("bp_id"), partner);
@ -824,9 +826,9 @@ public class ImportOfficeData extends ContextBasedTest {
final var partner = partners.get(bpId); final var partner = partners.get(bpId);
final var debitor = debitors.get(bpId); final var debitor = debitors.get(bpId);
final var partnerPerson = partner.getPerson(); final var partnerPerson = partner.getPartnerRole().getRelHolder();
if (containsPartnerRole(rec)) { if (containsPartnerRole(rec)) {
initPerson(partner.getPerson(), rec); initPerson(partnerPerson, rec);
} }
HsOfficePersonEntity contactPerson = partnerPerson; HsOfficePersonEntity contactPerson = partnerPerson;
@ -840,8 +842,7 @@ public class ImportOfficeData extends ContextBasedTest {
initContact(contact, rec); initContact(contact, rec);
if (containsPartnerRole(rec)) { if (containsPartnerRole(rec)) {
assertThat(partner.getContact()).isNull(); assertThat(partner.getPartnerRole().getContact()).isNull();
partner.setContact(contact);
partner.getPartnerRole().setContact(contact); partner.getPartnerRole().setContact(contact);
} }
if (containsRole(rec, "billing")) { if (containsRole(rec, "billing")) {
@ -876,11 +877,11 @@ public class ImportOfficeData extends ContextBasedTest {
private static void optionallyAddMissingContractualRelationships() { private static void optionallyAddMissingContractualRelationships() {
final var contractualMissing = new HashSet<Integer>(); final var contractualMissing = new HashSet<Integer>();
partners.forEach( (id, partner) -> { partners.forEach( (id, partner) -> {
final var partnerPerson = partner.getPerson(); final var partnerPerson = partner.getPartnerRole().getRelHolder();
if (relationships.values().stream() if (relationships.values().stream()
.filter(rel -> rel.getRelHolder() == partnerPerson && rel.getRelType() == HsOfficeRelationshipType.REPRESENTATIVE) .filter(rel -> rel.getRelHolder() == partnerPerson && rel.getRelType() == HsOfficeRelationshipType.REPRESENTATIVE)
.findFirst().isEmpty()) { .findFirst().isEmpty()) {
addRelationship(partnerPerson, partnerPerson, partner.getContact(), HsOfficeRelationshipType.REPRESENTATIVE); addRelationship(partnerPerson, partnerPerson, partner.getPartnerRole().getContact(), HsOfficeRelationshipType.REPRESENTATIVE);
contractualMissing.add(partner.getPartnerNumber()); contractualMissing.add(partner.getPartnerNumber());
} }
}); });

View File

@ -334,8 +334,9 @@ class HsOfficePartnerControllerAcceptanceTest extends ContextBasedTestWithCleanu
assertThat(partnerRepo.findByUuid(givenPartner.getUuid())).isPresent().get() assertThat(partnerRepo.findByUuid(givenPartner.getUuid())).isPresent().get()
.matches(partner -> { .matches(partner -> {
assertThat(partner.getPartnerNumber()).isEqualTo(givenPartner.getPartnerNumber()); assertThat(partner.getPartnerNumber()).isEqualTo(givenPartner.getPartnerNumber());
assertThat(partner.getPerson().getTradeName()).isEqualTo("Third OHG"); // TODO: assert partnerRole
assertThat(partner.getContact().getLabel()).isEqualTo("fourth contact"); // assertThat(partner.getPerson().getTradeName()).isEqualTo("Third OHG");
// assertThat(partner.getContact().getLabel()).isEqualTo("fourth contact");
assertThat(partner.getDetails().getRegistrationOffice()).isEqualTo("Temp Registergericht Aurich"); assertThat(partner.getDetails().getRegistrationOffice()).isEqualTo("Temp Registergericht Aurich");
assertThat(partner.getDetails().getRegistrationNumber()).isEqualTo("222222"); assertThat(partner.getDetails().getRegistrationNumber()).isEqualTo("222222");
assertThat(partner.getDetails().getBirthName()).isEqualTo("Maja Schmidt"); assertThat(partner.getDetails().getBirthName()).isEqualTo("Maja Schmidt");
@ -371,16 +372,18 @@ class HsOfficePartnerControllerAcceptanceTest extends ContextBasedTestWithCleanu
.statusCode(200) .statusCode(200)
.contentType(ContentType.JSON) .contentType(ContentType.JSON)
.body("uuid", isUuidValid()) .body("uuid", isUuidValid())
.body("details.birthName", is("Maja Schmidt")) .body("details.birthName", is("Maja Schmidt"));
.body("contact.label", is(givenPartner.getContact().getLabel())) // TODO: assert partnerRole
.body("person.tradeName", is(givenPartner.getPerson().getTradeName())); // .body("contact.label", is(givenPartner.getContact().getLabel()))
// .body("person.tradeName", is(givenPartner.getPerson().getTradeName()));
// @formatter:on // @formatter:on
// finally, the partner is actually updated // finally, the partner is actually updated
assertThat(partnerRepo.findByUuid(givenPartner.getUuid())).isPresent().get() assertThat(partnerRepo.findByUuid(givenPartner.getUuid())).isPresent().get()
.matches(person -> { .matches(person -> {
assertThat(person.getPerson().getTradeName()).isEqualTo(givenPartner.getPerson().getTradeName()); // TODO: assert partnerRole
assertThat(person.getContact().getLabel()).isEqualTo(givenPartner.getContact().getLabel()); // assertThat(person.getPerson().getTradeName()).isEqualTo(givenPartner.getPerson().getTradeName());
// assertThat(person.getContact().getLabel()).isEqualTo(givenPartner.getContact().getLabel());
assertThat(person.getDetails().getRegistrationOffice()).isEqualTo("Temp Registergericht Leer"); assertThat(person.getDetails().getRegistrationOffice()).isEqualTo("Temp Registergericht Leer");
assertThat(person.getDetails().getRegistrationNumber()).isEqualTo("333333"); assertThat(person.getDetails().getRegistrationNumber()).isEqualTo("333333");
assertThat(person.getDetails().getBirthName()).isEqualTo("Maja Schmidt"); assertThat(person.getDetails().getBirthName()).isEqualTo("Maja Schmidt");
@ -421,7 +424,7 @@ class HsOfficePartnerControllerAcceptanceTest extends ContextBasedTestWithCleanu
void contactAdminUser_canNotDeleteRelatedPartner() { void contactAdminUser_canNotDeleteRelatedPartner() {
context.define("superuser-alex@hostsharing.net"); context.define("superuser-alex@hostsharing.net");
final var givenPartner = givenSomeTemporaryPartnerBessler(20014); final var givenPartner = givenSomeTemporaryPartnerBessler(20014);
assertThat(givenPartner.getContact().getLabel()).isEqualTo("fourth contact"); assertThat(givenPartner.getPartnerRole().getContact().getLabel()).isEqualTo("fourth contact");
RestAssured // @formatter:off RestAssured // @formatter:off
.given() .given()
@ -441,7 +444,7 @@ class HsOfficePartnerControllerAcceptanceTest extends ContextBasedTestWithCleanu
void normalUser_canNotDeleteUnrelatedPartner() { void normalUser_canNotDeleteUnrelatedPartner() {
context.define("superuser-alex@hostsharing.net"); context.define("superuser-alex@hostsharing.net");
final var givenPartner = givenSomeTemporaryPartnerBessler(20015); final var givenPartner = givenSomeTemporaryPartnerBessler(20015);
assertThat(givenPartner.getContact().getLabel()).isEqualTo("fourth contact"); assertThat(givenPartner.getPartnerRole().getContact().getLabel()).isEqualTo("fourth contact");
RestAssured // @formatter:off RestAssured // @formatter:off
.given() .given()
@ -475,8 +478,6 @@ class HsOfficePartnerControllerAcceptanceTest extends ContextBasedTestWithCleanu
final var newPartner = HsOfficePartnerEntity.builder() final var newPartner = HsOfficePartnerEntity.builder()
.partnerRole(partnerRole) .partnerRole(partnerRole)
.partnerNumber(partnerNumber) .partnerNumber(partnerNumber)
.person(givenPerson)
.contact(givenContact)
.details(HsOfficePartnerDetailsEntity.builder() .details(HsOfficePartnerDetailsEntity.builder()
.registrationOffice("Temp Registergericht Leer") .registrationOffice("Temp Registergericht Leer")
.registrationNumber("333333") .registrationNumber("333333")

View File

@ -3,6 +3,7 @@ package net.hostsharing.hsadminng.hs.office.partner;
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactEntity; import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactEntity;
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.person.HsOfficePersonEntity; import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity;
import net.hostsharing.hsadminng.hs.office.relationship.HsOfficeRelationshipEntity;
import net.hostsharing.test.PatchUnitTestBase; import net.hostsharing.test.PatchUnitTestBase;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.TestInstance; import org.junit.jupiter.api.TestInstance;
@ -30,8 +31,7 @@ class HsOfficePartnerEntityPatcherUnitTest extends PatchUnitTestBase<
private static final UUID INITIAL_CONTACT_UUID = UUID.randomUUID(); private static final UUID INITIAL_CONTACT_UUID = UUID.randomUUID();
private static final UUID INITIAL_PERSON_UUID = UUID.randomUUID(); private static final UUID INITIAL_PERSON_UUID = UUID.randomUUID();
private static final UUID INITIAL_DETAILS_UUID = UUID.randomUUID(); private static final UUID INITIAL_DETAILS_UUID = UUID.randomUUID();
private static final UUID PATCHED_CONTACT_UUID = UUID.randomUUID(); private static final UUID PATCHED_PARTNER_ROLE_UUID = UUID.randomUUID();
private static final UUID PATCHED_PERSON_UUID = UUID.randomUUID();
private final HsOfficePersonEntity givenInitialPerson = HsOfficePersonEntity.builder() private final HsOfficePersonEntity givenInitialPerson = HsOfficePersonEntity.builder()
.uuid(INITIAL_PERSON_UUID) .uuid(INITIAL_PERSON_UUID)
@ -56,11 +56,15 @@ class HsOfficePartnerEntityPatcherUnitTest extends PatchUnitTestBase<
@Override @Override
protected HsOfficePartnerEntity newInitialEntity() { protected HsOfficePartnerEntity newInitialEntity() {
final var entity = new HsOfficePartnerEntity(); final var entity = HsOfficePartnerEntity.builder()
entity.setUuid(INITIAL_PARTNER_UUID); .uuid(INITIAL_PARTNER_UUID)
entity.setPerson(givenInitialPerson); .partnerNumber(12345)
entity.setContact(givenInitialContact); .partnerRole(HsOfficeRelationshipEntity.builder()
entity.setDetails(givenInitialDetails); .relHolder(givenInitialPerson)
.contact(givenInitialContact)
.build())
.details(givenInitialDetails)
.build();
return entity; return entity;
} }
@ -79,30 +83,18 @@ class HsOfficePartnerEntityPatcherUnitTest extends PatchUnitTestBase<
return Stream.of( return Stream.of(
new JsonNullableProperty<>( new JsonNullableProperty<>(
"contact", "contact",
HsOfficePartnerPatchResource::setContactUuid, HsOfficePartnerPatchResource::setPartnerRoleUuid,
PATCHED_CONTACT_UUID, PATCHED_PARTNER_ROLE_UUID,
HsOfficePartnerEntity::setContact, HsOfficePartnerEntity::setPartnerRole,
newContact(PATCHED_CONTACT_UUID)) newPartnerRole(PATCHED_PARTNER_ROLE_UUID))
.notNullable(),
new JsonNullableProperty<>(
"person",
HsOfficePartnerPatchResource::setPersonUuid,
PATCHED_PERSON_UUID,
HsOfficePartnerEntity::setPerson,
newPerson(PATCHED_PERSON_UUID))
.notNullable() .notNullable()
); );
} }
private static HsOfficeContactEntity newContact(final UUID uuid) { private static HsOfficeRelationshipEntity newPartnerRole(final UUID uuid) {
final var newContact = new HsOfficeContactEntity(); final var newPartnerRole = HsOfficeRelationshipEntity.builder()
newContact.setUuid(uuid); .uuid(uuid)
return newContact; .build();
} return newPartnerRole;
private HsOfficePersonEntity newPerson(final UUID uuid) {
final var newPerson = new HsOfficePersonEntity();
newPerson.setUuid(uuid);
return newPerson;
} }
} }

View File

@ -3,39 +3,39 @@ package net.hostsharing.hsadminng.hs.office.partner;
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactEntity; import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactEntity;
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity; import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity;
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonType; import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonType;
import net.hostsharing.hsadminng.hs.office.relationship.HsOfficeRelationshipEntity;
import net.hostsharing.hsadminng.hs.office.relationship.HsOfficeRelationshipType;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
class HsOfficePartnerEntityUnitTest { class HsOfficePartnerEntityUnitTest {
@Test private final HsOfficePartnerEntity givenPartner = HsOfficePartnerEntity.builder()
void toStringContainsPersonAndContact() { .partnerNumber(12345)
final var given = HsOfficePartnerEntity.builder() .partnerRole(HsOfficeRelationshipEntity.builder()
.person(HsOfficePersonEntity.builder() .relAnchor(HsOfficePersonEntity.builder()
.personType(HsOfficePersonType.LEGAL_PERSON)
.tradeName("Hostsharing eG")
.build())
.relType(HsOfficeRelationshipType.PARTNER)
.relHolder(HsOfficePersonEntity.builder()
.personType(HsOfficePersonType.LEGAL_PERSON) .personType(HsOfficePersonType.LEGAL_PERSON)
.tradeName("some trade name") .tradeName("some trade name")
.build()) .build())
.contact(HsOfficeContactEntity.builder().label("some label").build()) .contact(HsOfficeContactEntity.builder().label("some label").build())
.build())
.build(); .build();
final var result = given.toString(); @Test
void toStringContainsPartnerNumberPersonAndContact() {
assertThat(result).isEqualTo("partner(LP some trade name: some label)"); final var result = givenPartner.toString();
assertThat(result).isEqualTo("partner(P-12345: LP some trade name, some label)");
} }
@Test @Test
void toShortStringContainsPersonAndContact() { void toShortStringContainsPartnerNumber() {
final var given = HsOfficePartnerEntity.builder() final var result = givenPartner.toShortString();
.person(HsOfficePersonEntity.builder() assertThat(result).isEqualTo("P-12345");
.personType(HsOfficePersonType.LEGAL_PERSON)
.tradeName("some trade name")
.build())
.contact(HsOfficeContactEntity.builder().label("some label").build())
.build();
final var result = given.toShortString();
assertThat(result).isEqualTo("LP some trade name");
} }
} }

View File

@ -1,7 +1,9 @@
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.contact.HsOfficeContactRepository; import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRepository;
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity;
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.HsOfficeRelationshipEntity;
import net.hostsharing.hsadminng.hs.office.relationship.HsOfficeRelationshipRepository; import net.hostsharing.hsadminng.hs.office.relationship.HsOfficeRelationshipRepository;
@ -93,10 +95,7 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTestWithClean
final var newPartner = HsOfficePartnerEntity.builder() final var newPartner = HsOfficePartnerEntity.builder()
.partnerNumber(20031) .partnerNumber(20031)
.partnerRole(partnerRole) .partnerRole(partnerRole)
.person(givenPartnerPerson) .details(HsOfficePartnerDetailsEntity.builder().build())
.contact(givenContact)
.details(HsOfficePartnerDetailsEntity.builder()
.build())
.build(); .build();
return partnerRepo.save(newPartner); return partnerRepo.save(newPartner);
}); });
@ -136,8 +135,6 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTestWithClean
final var newPartner = HsOfficePartnerEntity.builder() final var newPartner = HsOfficePartnerEntity.builder()
.partnerNumber(20032) .partnerNumber(20032)
.partnerRole(newRelationship) .partnerRole(newRelationship)
.person(givenPartnerPerson)
.contact(givenContact)
.details(HsOfficePartnerDetailsEntity.builder().build()) .details(HsOfficePartnerDetailsEntity.builder().build())
.build(); .build();
return partnerRepo.save(newPartner); return partnerRepo.save(newPartner);
@ -297,12 +294,12 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTestWithClean
assertThatPartnerActuallyInDatabase(givenPartner); assertThatPartnerActuallyInDatabase(givenPartner);
final var givenNewPerson = personRepo.findPersonByOptionalNameLike("Third OHG").get(0); final var givenNewPerson = personRepo.findPersonByOptionalNameLike("Third OHG").get(0);
final var givenNewContact = contactRepo.findContactByOptionalLabelLike("sixth contact").get(0); final var givenNewContact = contactRepo.findContactByOptionalLabelLike("sixth contact").get(0);
final var givenNewPartnerRole = givenSomeTemporaryPartnerRole(givenNewPerson, givenNewContact);
// when // when
final var result = jpaAttempt.transacted(() -> { final var result = jpaAttempt.transacted(() -> {
context("superuser-alex@hostsharing.net"); context("superuser-alex@hostsharing.net");
givenPartner.setContact(givenNewContact); givenPartner.setPartnerRole(givenNewPartnerRole);
givenPartner.setPerson(givenNewPerson);
return partnerRepo.save(givenPartner); return partnerRepo.save(givenPartner);
}); });
@ -458,6 +455,12 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTestWithClean
"[creating partner test-data Seconde.K.-secondcontact, hs_office_partner, INSERT]"); "[creating partner test-data Seconde.K.-secondcontact, hs_office_partner, INSERT]");
} }
private HsOfficeRelationshipEntity givenSomeTemporaryPartnerRole(
final HsOfficePersonEntity givenNewPerson,
final HsOfficeContactEntity givenNewContact) {
return HsOfficeRelationshipEntity.builder().build();
}
private HsOfficePartnerEntity givenSomeTemporaryPartnerBessler( private HsOfficePartnerEntity givenSomeTemporaryPartnerBessler(
final Integer partnerNumber, final String person, final String contact) { final Integer partnerNumber, final String person, final String contact) {
return jpaAttempt.transacted(() -> { return jpaAttempt.transacted(() -> {
@ -478,8 +481,6 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTestWithClean
final var newPartner = HsOfficePartnerEntity.builder() final var newPartner = HsOfficePartnerEntity.builder()
.partnerNumber(partnerNumber) .partnerNumber(partnerNumber)
.partnerRole(partnerRole) .partnerRole(partnerRole)
.person(givenPartnerPerson)
.contact(givenContact)
.details(HsOfficePartnerDetailsEntity.builder().build()) .details(HsOfficePartnerDetailsEntity.builder().build())
.build(); .build();

View File

@ -2,7 +2,8 @@ package net.hostsharing.hsadminng.hs.office.partner;
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactEntity; import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactEntity;
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity; 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 static net.hostsharing.hsadminng.hs.office.person.HsOfficePersonType.LEGAL_PERSON; import static net.hostsharing.hsadminng.hs.office.person.HsOfficePersonType.LEGAL_PERSON;
@ -13,13 +14,22 @@ public class TestHsOfficePartner {
static public HsOfficePartnerEntity hsOfficePartnerWithLegalPerson(final String tradeName) { static public HsOfficePartnerEntity hsOfficePartnerWithLegalPerson(final String tradeName) {
return HsOfficePartnerEntity.builder() return HsOfficePartnerEntity.builder()
.partnerNumber(10001) .partnerNumber(10001)
.person(HsOfficePersonEntity.builder() .partnerRole(
HsOfficeRelationshipEntity.builder()
.relHolder(HsOfficePersonEntity.builder()
.personType(LEGAL_PERSON)
.tradeName("Hostsharing eG")
.build())
.relType(HsOfficeRelationshipType.PARTNER)
.relHolder(HsOfficePersonEntity.builder()
.personType(LEGAL_PERSON) .personType(LEGAL_PERSON)
.tradeName(tradeName) .tradeName(tradeName)
.build()) .build())
.contact(HsOfficeContactEntity.builder() .contact(HsOfficeContactEntity.builder()
.label(tradeName) .label(tradeName)
.build()) .build())
.build()
)
.build(); .build();
} }
} }