From 45aab03d364c60a633a51007b583f5d49aed7f98 Mon Sep 17 00:00:00 2001 From: Michael Hoennig Date: Tue, 20 Feb 2024 13:03:17 +0100 Subject: [PATCH] remove partner from debitor and use debitorRel instead, WIP with working EntityUnitTest --- .../office/debitor/HsOfficeDebitorEntity.java | 31 +-- .../debitor/HsOfficeDebitorEntityPatcher.java | 8 +- .../office/person/HsOfficePersonEntity.java | 9 + .../hs-office/hs-office-debitor-schemas.yaml | 2 +- .../db/changelog/270-hs-office-debitor.sql | 5 +- .../changelog/273-hs-office-debitor-rbac.sql | 200 +++++++++--------- ...OfficeDebitorControllerAcceptanceTest.java | 31 +-- .../HsOfficeDebitorEntityPatcherUnitTest.java | 20 +- .../HsOfficeDebitorEntityUnitTest.java | 67 +++--- ...fficeDebitorRepositoryIntegrationTest.java | 112 ++++++---- .../office/debitor/TestHsOfficeDebitor.java | 12 +- .../hs/office/migration/ImportOfficeData.java | 16 +- ...OfficePartnerControllerAcceptanceTest.java | 1 - .../hsadminng/hs/office/test/EntityList.java | 15 ++ 14 files changed, 294 insertions(+), 235 deletions(-) create mode 100644 src/test/java/net/hostsharing/hsadminng/hs/office/test/EntityList.java diff --git a/src/main/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorEntity.java b/src/main/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorEntity.java index 75cf35b1..1c539828 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorEntity.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorEntity.java @@ -3,7 +3,8 @@ package net.hostsharing.hsadminng.hs.office.debitor; import lombok.*; import net.hostsharing.hsadminng.errors.DisplayName; import net.hostsharing.hsadminng.hs.office.bankaccount.HsOfficeBankAccountEntity; -import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactEntity; +import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity; +import net.hostsharing.hsadminng.hs.office.relationship.HsOfficeRelationshipEntity; import net.hostsharing.hsadminng.persistence.HasUuid; import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity; import net.hostsharing.hsadminng.stringify.Stringify; @@ -11,9 +12,9 @@ import net.hostsharing.hsadminng.stringify.Stringifyable; import org.hibernate.annotations.GenericGenerator; import jakarta.persistence.*; -import java.util.Optional; import java.util.UUID; +import static java.util.Optional.ofNullable; import static net.hostsharing.hsadminng.stringify.Stringify.stringify; @Entity @@ -31,7 +32,7 @@ public class HsOfficeDebitorEntity implements HasUuid, Stringifyable { private static Stringify stringify = stringify(HsOfficeDebitorEntity.class, "debitor") .withIdProp(HsOfficeDebitorEntity::toShortString) - .withProp(HsOfficeDebitorEntity::getPartner) + .withProp(e -> e.getDebitorRel().toShortString()) .withProp(HsOfficeDebitorEntity::getDefaultPrefix) .quotedValues(false); @@ -40,16 +41,12 @@ public class HsOfficeDebitorEntity implements HasUuid, Stringifyable { @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator") private UUID uuid; - @ManyToOne - @JoinColumn(name = "partneruuid") - private HsOfficePartnerEntity partner; - @Column(name = "debitornumbersuffix", columnDefinition = "numeric(2)") private Byte debitorNumberSuffix; // TODO maybe rather as a formatted String? - @ManyToOne - @JoinColumn(name = "billingcontactuuid") - private HsOfficeContactEntity billingContact; // TODO: migrate to billingPerson + @ManyToOne(cascade = CascadeType.ALL) + @JoinColumn(name = "debitorreluuid", nullable = false) + private HsOfficeRelationshipEntity debitorRel; @Column(name = "billable", nullable = false) private Boolean billable; // not a primitive because otherwise the default would be false @@ -74,14 +71,18 @@ public class HsOfficeDebitorEntity implements HasUuid, Stringifyable { private String defaultPrefix; private String getDebitorNumberString() { - if (partner == null || partner.getPartnerNumber() == null || debitorNumberSuffix == null ) { - return null; - } - return partner.getPartnerNumber() + String.format("%02d", debitorNumberSuffix); + return ofNullable(debitorRel) + .filter(partnerNumber -> debitorNumberSuffix != null) + .map(HsOfficeRelationshipEntity::getRelAnchor) + .map(HsOfficePersonEntity::getOptionalPartner) + .map(HsOfficePartnerEntity::getPartnerNumber) + .map(Object::toString) + .map(partnerNumber -> partnerNumber + String.format("%02d", debitorNumberSuffix)) + .orElse(null); } public Integer getDebitorNumber() { - return Optional.ofNullable(getDebitorNumberString()).map(Integer::parseInt).orElse(null); + return ofNullable(getDebitorNumberString()).map(Integer::parseInt).orElse(null); } @Override diff --git a/src/main/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorEntityPatcher.java b/src/main/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorEntityPatcher.java index 914c8230..f122de07 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorEntityPatcher.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorEntityPatcher.java @@ -1,8 +1,8 @@ package net.hostsharing.hsadminng.hs.office.debitor; import net.hostsharing.hsadminng.hs.office.bankaccount.HsOfficeBankAccountEntity; -import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactEntity; import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeDebitorPatchResource; +import net.hostsharing.hsadminng.hs.office.relationship.HsOfficeRelationshipEntity; import net.hostsharing.hsadminng.mapper.EntityPatcher; import net.hostsharing.hsadminng.mapper.OptionalFromJson; @@ -23,9 +23,9 @@ class HsOfficeDebitorEntityPatcher implements EntityPatcher { - verifyNotNull(newValue, "billingContact"); - entity.setBillingContact(em.getReference(HsOfficeContactEntity.class, newValue)); + OptionalFromJson.of(resource.getDebitorRelUuid()).ifPresent(newValue -> { + verifyNotNull(newValue, "partnerRel"); + entity.setDebitorRel(em.getReference(HsOfficeRelationshipEntity.class, newValue)); }); Optional.ofNullable(resource.getBillable()).ifPresent(entity::setBillable); OptionalFromJson.of(resource.getVatId()).ifPresent(entity::setVatId); diff --git a/src/main/java/net/hostsharing/hsadminng/hs/office/person/HsOfficePersonEntity.java b/src/main/java/net/hostsharing/hsadminng/hs/office/person/HsOfficePersonEntity.java index fde3972b..890deba6 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/office/person/HsOfficePersonEntity.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/office/person/HsOfficePersonEntity.java @@ -3,6 +3,7 @@ package net.hostsharing.hsadminng.hs.office.person; import lombok.*; import lombok.experimental.FieldNameConstants; import net.hostsharing.hsadminng.errors.DisplayName; +import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity; import net.hostsharing.hsadminng.persistence.HasUuid; import net.hostsharing.hsadminng.stringify.Stringify; import net.hostsharing.hsadminng.stringify.Stringifyable; @@ -46,6 +47,14 @@ public class HsOfficePersonEntity implements HasUuid, Stringifyable { @Column(name = "givenname") private String givenName; + @OneToOne(cascade = CascadeType.ALL) + @JoinTable(name = "hs_office_relationship", + joinColumns = + { @JoinColumn(name = "uuid", referencedColumnName = "relanchoruuid") }, + inverseJoinColumns = + { @JoinColumn(name = "relanchoruuid", referencedColumnName = "uuid") }) + private HsOfficePartnerEntity optionalPartner; + @Override public String toString() { return toString.apply(this); diff --git a/src/main/resources/api-definition/hs-office/hs-office-debitor-schemas.yaml b/src/main/resources/api-definition/hs-office/hs-office-debitor-schemas.yaml index 26736fac..6ce56416 100644 --- a/src/main/resources/api-definition/hs-office/hs-office-debitor-schemas.yaml +++ b/src/main/resources/api-definition/hs-office/hs-office-debitor-schemas.yaml @@ -43,7 +43,7 @@ components: HsOfficeDebitorPatch: type: object properties: - billingContactUuid: + debitorRelUuid: type: string format: uuid nullable: true diff --git a/src/main/resources/db/changelog/270-hs-office-debitor.sql b/src/main/resources/db/changelog/270-hs-office-debitor.sql index fae4e90c..a90dd196 100644 --- a/src/main/resources/db/changelog/270-hs-office-debitor.sql +++ b/src/main/resources/db/changelog/270-hs-office-debitor.sql @@ -7,10 +7,9 @@ create table hs_office_debitor ( uuid uuid unique references RbacObject (uuid) initially deferred, - partnerUuid uuid not null references hs_office_partner(uuid), - billable boolean not null default true, debitorNumberSuffix numeric(2) not null, - billingContactUuid uuid not null references hs_office_contact(uuid), + debitorRelUuid uuid not null references hs_office_relationship(uuid), + billable boolean not null default true, vatId varchar(24), -- TODO.spec: here or in person? vatCountryCode varchar(2), vatBusiness boolean not null, diff --git a/src/main/resources/db/changelog/273-hs-office-debitor-rbac.sql b/src/main/resources/db/changelog/273-hs-office-debitor-rbac.sql index 42769c59..f5bc485d 100644 --- a/src/main/resources/db/changelog/273-hs-office-debitor-rbac.sql +++ b/src/main/resources/db/changelog/273-hs-office-debitor-rbac.sql @@ -7,13 +7,6 @@ call generateRelatedRbacObject('hs_office_debitor'); --// --- ============================================================================ ---changeset hs-office-debitor-rbac-ROLE-DESCRIPTORS:1 endDelimiter:--// --- ---------------------------------------------------------------------------- -call generateRbacRoleDescriptors('hsOfficeDebitor', 'hs_office_debitor'); ---// - - -- ============================================================================ --changeset hs-office-debitor-rbac-ROLES-CREATION:1 endDelimiter:--// -- ---------------------------------------------------------------------------- @@ -27,121 +20,103 @@ create or replace function hsOfficeDebitorRbacRolesTrigger() language plpgsql strict as $$ declare - hsOfficeDebitorTenant RbacRoleDescriptor; - oldPartner hs_office_partner; - newPartner hs_office_partner; - oldPartnerRel hs_office_relationship; - newPartnerRel hs_office_relationship; - oldContact hs_office_contact; - newContact hs_office_contact; - newBankAccount hs_office_bankaccount; - oldBankAccount hs_office_bankaccount; + debitorUuid uuid; + + oldDebitorRel hs_office_relationship; + newDebitorRel hs_office_relationship; + + newPartnerRel hs_office_relationship; + + newBankAccount hs_office_bankaccount; + oldBankAccount hs_office_bankaccount; + begin call enterTriggerForObjectUuid(NEW.uuid); - hsOfficeDebitorTenant := hsOfficeDebitorTenant(NEW); + debitorUuid := NEW.uuid; - select * from hs_office_partner as p where p.uuid = NEW.partnerUuid into newPartner; - select * from hs_office_relationship as r where r.relType = 'PARTNER' and r.relHolderUuid = NEW.partnerUuid into newPartnerRel; - select * from hs_office_contact as c where c.uuid = NEW.billingContactUuid into newContact; - select * from hs_office_bankaccount as b where b.uuid = NEW.refundBankAccountUuid into newBankAccount; + select * into newDebitorRel + from hs_office_relationship as r where r.relType = 'DEBITOR' and r.relHolderUuid = NEW.debitorRelUuid; + + select * into newPartnerRel + from hs_office_relationship as r + join hs_office_partner as p on p.partnerRoleUuid = r.uuid + where r.relType = 'PARTNER' and r.relHolderUuid = newPartnerRel; + + select * from hs_office_bankaccount as b where b.uuid = NEW.refundBankAccountUuid + into newBankAccount; if TG_OP = 'INSERT' then - perform createRoleWithGrants( - hsOfficeDebitorOwner(NEW), - permissions => array['*'], - incomingSuperRoles => array[globalAdmin()], - userUuids => array[currentUserUuid()], - grantedByRole => globalAdmin() - ); + -- Permissions and Grants for Debitor - perform createRoleWithGrants( - hsOfficeDebitorAdmin(NEW), - permissions => array['edit'], - incomingSuperRoles => array[hsOfficeDebitorOwner(NEW)] - ); + call grantPermissionsToRole( + getRoleId(hsOfficeRelationshipOwner(newDebitorRel), 'fail'), + createPermissions(partnerUuid, array ['*']) + ); - perform createRoleWithGrants( - hsOfficeDebitorAgent(NEW), - incomingSuperRoles => array[ - hsOfficeDebitorAdmin(NEW), - hsOfficeRelationshipAdmin(newPartnerRel), - hsOfficeContactAdmin(newContact)], - outgoingSubRoles => array[ - hsOfficeBankAccountTenant(newBankaccount)] - ); + call grantPermissionsToRole( + getRoleId(hsOfficeRelationshipAdmin(newDebitorRel), 'fail'), + createPermissions(partnerUuid, array ['edit']) + ); - perform createRoleWithGrants( - hsOfficeDebitorTenant(NEW), - incomingSuperRoles => array[ - hsOfficeDebitorAgent(NEW), - hsOfficeRelationshipAgent(newPartnerRel), - hsOfficeBankAccountAdmin(newBankaccount)], - outgoingSubRoles => array[ - hsOfficeRelationshipTenant(newPartnerRel), - hsOfficeContactReferrer(newContact), - hsOfficeBankAccountGuest(newBankaccount)] - ); + call grantPermissionsToRole( + getRoleId(hsOfficeRelationshipTenant(newDebitorRel), 'fail'), + createPermissions(partnerUuid, array ['view']) + ); - perform createRoleWithGrants( - hsOfficeDebitorGuest(NEW), - permissions => array['view'], - incomingSuperRoles => array[ - hsOfficeDebitorTenant(NEW)] - ); + -- Grants to and from related Partner Relationship + + call grantRoleToRole(hsOfficeRelationshipAdmin(newDebitorRel), hsOfficeRelationshipAdmin(newPartnerRel), true); + call grantRoleToRole(hsOfficeRelationshipAgent(newPartnerRel), hsOfficeRelationshipAdmin(newDebitorRel), true); + + call grantRoleToRole(hsOfficeRelationshipAgent(newDebitorRel), hsOfficeRelationshipAgent(newPartnerRel), true); + call grantRoleToRole(hsOfficeRelationshipTenant(newPartnerRel), hsOfficeRelationshipAgent(newDebitorRel), true); + + -- Grants to and from refundBankAccount + + if newBankAccount is not null then + call grantRoleToRole(hsOfficeBankAccountReferrer(newBankAccount), hsOfficeRelationshipAgent(newDebitorRel), true); + call grantRoleToRole(hsOfficeRelationshipAgent(newDebitorRel), hsOfficeBankAccountAdmin(newBankAccount), true); + end if; elsif TG_OP = 'UPDATE' then - if OLD.partnerUuid <> NEW.partnerUuid then - select * from hs_office_partner as p where p.uuid = OLD.partnerUuid into oldPartner; - select * from hs_office_relationship as r where r.uuid = OLD.partnerUuid into oldPartnerRel; + if OLD.debitorRelUuid is distinct from NEW.debitorRelUuid then - call revokeRoleFromRole(hsOfficeDebitorAgent(OLD), hsOfficeRelationshipAdmin(oldPartnerRel)); - call grantRoleToRole(hsOfficeDebitorAgent(NEW), hsOfficeRelationshipAdmin(oldPartnerRel)); + select * into oldDebitorRel + from hs_office_relationship as r where r.relType = 'DEBITOR' and r.relHolderUuid = NEW.debitorRelUuid; - call revokeRoleFromRole(hsOfficeDebitorTenant(OLD), hsOfficeRelationshipAgent(oldPartnerRel)); - call grantRoleToRole(hsOfficeDebitorTenant(NEW), hsOfficeRelationshipAgent(newPartner)); + call grantPermissionsToRole( + getRoleId(hsOfficeRelationshipOwner(newDebitorRel), 'fail'), + createPermissions(partnerUuid, array ['*']) + ); + + call grantPermissionsToRole( + getRoleId(hsOfficeRelationshipAdmin(newDebitorRel), 'fail'), + createPermissions(partnerUuid, array ['edit']) + ); + + call grantPermissionsToRole( + getRoleId(hsOfficeRelationshipTenant(newDebitorRel), 'fail'), + createPermissions(partnerUuid, array ['view']) + ); - call revokeRoleFromRole(hsOfficeRelationshipTenant(oldPartnerRel), hsOfficeDebitorTenant(OLD)); - call grantRoleToRole(hsOfficeRelationshipTenant(newPartnerRel), hsOfficeDebitorTenant(NEW)); end if; - if OLD.billingContactUuid <> NEW.billingContactUuid then - select * from hs_office_contact as c where c.uuid = OLD.billingContactUuid into oldContact; + if OLD.refundBankAccountUuid is distinct from NEW.refundBankAccountUuid then - call revokeRoleFromRole(hsOfficeDebitorAgent(OLD), hsOfficeContactAdmin(oldContact)); - call grantRoleToRole(hsOfficeDebitorAgent(NEW), hsOfficeContactAdmin(newContact)); - - call revokeRoleFromRole(hsOfficeContactReferrer(oldContact), hsOfficeDebitorTenant(OLD)); - call grantRoleToRole(hsOfficeContactReferrer(newContact), hsOfficeDebitorTenant(NEW)); - end if; - - if (OLD.refundBankAccountUuid is not null or NEW.refundBankAccountUuid is not null) and - ( OLD.refundBankAccountUuid is null or NEW.refundBankAccountUuid is null or - OLD.refundBankAccountUuid <> NEW.refundBankAccountUuid ) then - - select * from hs_office_bankaccount as b where b.uuid = OLD.refundBankAccountUuid into oldBankAccount; + select * into oldBankAccount + from hs_office_bankaccount as b where b.uuid = OLD.refundBankAccountUuid; if oldBankAccount is not null then - call revokeRoleFromRole(hsOfficeBankAccountTenant(oldBankaccount), hsOfficeDebitorAgent(OLD)); - end if; - if newBankAccount is not null then - call grantRoleToRole(hsOfficeBankAccountTenant(newBankaccount), hsOfficeDebitorAgent(NEW)); + call revokeRoleFromRole(hsOfficeBankAccountReferrer(oldBankAccount), hsOfficeRelationshipAgent(oldDebitorRel), true); + call revokeRoleFromRole(hsOfficeRelationshipAgent(oldDebitorRel), hsOfficeBankAccountAdmin(oldBankAccount), true); end if; - if oldBankAccount is not null then - call revokeRoleFromRole(hsOfficeDebitorTenant(OLD), hsOfficeBankAccountAdmin(oldBankaccount)); - end if; if newBankAccount is not null then - call grantRoleToRole(hsOfficeDebitorTenant(NEW), hsOfficeBankAccountAdmin(newBankaccount)); - end if; - - if oldBankAccount is not null then - call revokeRoleFromRole(hsOfficeBankAccountGuest(oldBankaccount), hsOfficeDebitorTenant(OLD)); - end if; - if newBankAccount is not null then - call grantRoleToRole(hsOfficeBankAccountGuest(newBankaccount), hsOfficeDebitorTenant(NEW)); + call grantRoleToRole(hsOfficeBankAccountReferrer(newBankAccount), hsOfficeRelationshipAgent(newDebitorRel), true); + call grantRoleToRole(hsOfficeRelationshipAgent(newDebitorRel), hsOfficeBankAccountAdmin(newBankAccount), true); end if; end if; else @@ -172,6 +147,37 @@ execute procedure hsOfficeDebitorRbacRolesTrigger(); --// +/* + Creates and updates the roles and their assignments for debitor entities if partner rel changes. + */ + +create or replace function hsOfficeDebitorPartnerRelRbacRolesTrigger() + returns trigger + language plpgsql + strict as $$ +declare + +begin + call enterTriggerForObjectUuid(NEW.uuid); + + -- TODO + + call leaveTriggerForObjectUuid(NEW.uuid); + return NEW; +end; $$; +--// + +/* + An AFTER UPDATE TRIGGER which creates the role structure for debitors if partner relations change. + */ +create trigger updateRbacRolesForHsOfficeDebitor_Trigger + after update + on hs_office_partner + for each row +execute procedure hsOfficeDebitorPartnerRelRbacRolesTrigger(); +--// + + -- ============================================================================ --changeset hs-office-debitor-rbac-IDENTITY-VIEW:1 endDelimiter:--// -- ---------------------------------------------------------------------------- diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorControllerAcceptanceTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorControllerAcceptanceTest.java index 94d45e03..836b8b5b 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorControllerAcceptanceTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorControllerAcceptanceTest.java @@ -410,19 +410,20 @@ class HsOfficeDebitorControllerAcceptanceTest extends ContextBasedTestWithCleanu .body("vatBusiness", is(true)) .body("defaultPrefix", is("for")) .body("billingContact.label", is(givenContact.getLabel())) - .body("partner.partnerRole.relHolder.tradeName", is(givenDebitor.getPartner().getPartnerRole().getRelHolder().getTradeName())); + // TODO .body("partner.partnerRole.relHolder.tradeName", is(givenDebitor.getPartner().getPartnerRole().getRelHolder().getTradeName())) + ; // @formatter:on // finally, the debitor is actually updated context.define("superuser-alex@hostsharing.net"); assertThat(debitorRepo.findByUuid(givenDebitor.getUuid())).isPresent().get() - .matches(partner -> { - assertThat(partner.getPartner().getPartnerRole().getRelHolder().getTradeName()) - .isEqualTo(givenDebitor.getPartner().getPartnerRole().getRelHolder().getTradeName()); - assertThat(partner.getBillingContact().getLabel()).isEqualTo("fourth contact"); - assertThat(partner.getVatId()).isEqualTo("VAT222222"); - assertThat(partner.getVatCountryCode()).isEqualTo("AA"); - assertThat(partner.isVatBusiness()).isEqualTo(true); + .matches(debitor -> { + assertThat(debitor.getDebitorRel().getRelHolder().getTradeName()) + .isEqualTo(givenDebitor.getDebitorRel().getRelHolder().getTradeName()); + assertThat(debitor.getDebitorRel().getContact().getLabel()).isEqualTo("fourth contact"); + assertThat(debitor.getVatId()).isEqualTo("VAT222222"); + assertThat(debitor.getVatCountryCode()).isEqualTo("AA"); + assertThat(debitor.isVatBusiness()).isEqualTo(true); return true; }); } @@ -460,9 +461,9 @@ class HsOfficeDebitorControllerAcceptanceTest extends ContextBasedTestWithCleanu // finally, the debitor is actually updated assertThat(debitorRepo.findByUuid(givenDebitor.getUuid())).isPresent().get() .matches(partner -> { - assertThat(partner.getPartner().getPartnerRole().getRelHolder().getTradeName()) - .isEqualTo(givenDebitor.getPartner().getPartnerRole().getRelHolder().getTradeName()); - assertThat(partner.getBillingContact().getLabel()).isEqualTo("sixth contact"); + assertThat(partner.getDebitorRel().getRelHolder().getTradeName()) + .isEqualTo(givenDebitor.getDebitorRel().getRelHolder().getTradeName()); + assertThat(partner.getDebitorRel().getContact().getLabel()).isEqualTo("sixth contact"); assertThat(partner.getVatId()).isEqualTo("VAT999999"); assertThat(partner.getVatCountryCode()).isEqualTo(givenDebitor.getVatCountryCode()); assertThat(partner.isVatBusiness()).isEqualTo(givenDebitor.isVatBusiness()); @@ -499,7 +500,7 @@ class HsOfficeDebitorControllerAcceptanceTest extends ContextBasedTestWithCleanu void contactAdminUser_canNotDeleteRelatedDebitor() { context.define("superuser-alex@hostsharing.net"); final var givenDebitor = givenSomeTemporaryDebitor(); - assertThat(givenDebitor.getBillingContact().getLabel()).isEqualTo("fourth contact"); + assertThat(givenDebitor.getDebitorRel().getContact().getLabel()).isEqualTo("fourth contact"); RestAssured // @formatter:off .given() @@ -519,7 +520,7 @@ class HsOfficeDebitorControllerAcceptanceTest extends ContextBasedTestWithCleanu void normalUser_canNotDeleteUnrelatedDebitor() { context.define("superuser-alex@hostsharing.net"); final var givenDebitor = givenSomeTemporaryDebitor(); - assertThat(givenDebitor.getBillingContact().getLabel()).isEqualTo("fourth contact"); + assertThat(givenDebitor.getDebitorRel().getContact().getLabel()).isEqualTo("fourth contact"); RestAssured // @formatter:off .given() @@ -543,8 +544,8 @@ class HsOfficeDebitorControllerAcceptanceTest extends ContextBasedTestWithCleanu final var newDebitor = HsOfficeDebitorEntity.builder() .debitorNumberSuffix(++nextDebitorSuffix) .billable(true) - .partner(givenPartner) - .billingContact(givenContact) +// .partner(givenPartner) +// .billingContact(givenContact) .defaultPrefix("abc") .vatReverseCharge(false) .build(); diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorEntityPatcherUnitTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorEntityPatcherUnitTest.java index 01ea5777..e913999b 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorEntityPatcherUnitTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorEntityPatcherUnitTest.java @@ -72,8 +72,9 @@ class HsOfficeDebitorEntityPatcherUnitTest extends PatchUnitTestBase< protected HsOfficeDebitorEntity newInitialEntity() { final var entity = new HsOfficeDebitorEntity(); entity.setUuid(INITIAL_DEBITOR_UUID); - entity.setPartner(givenInitialPartner); - entity.setBillingContact(givenInitialContact); +// TODO +// entity.setPartner(givenInitialPartner); +// entity.setBillingContact(givenInitialContact); entity.setBillable(INITIAL_BILLABLE); entity.setVatId("initial VAT-ID"); entity.setVatCountryCode("AA"); @@ -97,13 +98,14 @@ class HsOfficeDebitorEntityPatcherUnitTest extends PatchUnitTestBase< @Override protected Stream propertyTestDescriptors() { return Stream.of( - new JsonNullableProperty<>( - "billingContact", - HsOfficeDebitorPatchResource::setBillingContactUuid, - PATCHED_CONTACT_UUID, - HsOfficeDebitorEntity::setBillingContact, - newBillingContact(PATCHED_CONTACT_UUID)) - .notNullable(), +// TODO +// new JsonNullableProperty<>( +// "billingContact", +// HsOfficeDebitorPatchResource::setBillingContactUuid, +// PATCHED_CONTACT_UUID, +// HsOfficeDebitorEntity::setBillingContact, +// newBillingContact(PATCHED_CONTACT_UUID)) +// .notNullable(), new SimpleProperty<>( "billable", HsOfficeDebitorPatchResource::setBillable, diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorEntityUnitTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorEntityUnitTest.java index 0c9b0e3d..d773b732 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorEntityUnitTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorEntityUnitTest.java @@ -1,7 +1,6 @@ package net.hostsharing.hsadminng.hs.office.debitor; import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactEntity; -import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerDetailsEntity; import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity; import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity; import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonType; @@ -12,52 +11,38 @@ import static org.assertj.core.api.Assertions.assertThat; class HsOfficeDebitorEntityUnitTest { + private HsOfficeRelationshipEntity givenDebitorRel = HsOfficeRelationshipEntity.builder() + .relAnchor(HsOfficePersonEntity.builder() + .personType(HsOfficePersonType.LEGAL_PERSON) + .tradeName("some partner trade name") + .optionalPartner(HsOfficePartnerEntity.builder() + .partnerNumber(12345) + .build()) + .build()) + .relHolder(HsOfficePersonEntity.builder() + .personType(HsOfficePersonType.LEGAL_PERSON) + .tradeName("some billing trade name") + .build()) + .contact(HsOfficeContactEntity.builder().label("some label").build()) + .build(); + @Test void toStringContainsPartnerAndContact() { final var given = HsOfficeDebitorEntity.builder() .debitorNumberSuffix((byte)67) - .partner(HsOfficePartnerEntity.builder() - .partnerRole(HsOfficeRelationshipEntity.builder() - .relHolder(HsOfficePersonEntity.builder() - .personType(HsOfficePersonType.LEGAL_PERSON) - .tradeName("some trade name") - .build()) - .build()) - .details(HsOfficePartnerDetailsEntity.builder().birthName("some birth name").build()) - .partnerNumber(12345) - .build()) - .billingContact(HsOfficeContactEntity.builder().label("some label").build()) + .debitorRel(givenDebitorRel) .defaultPrefix("som") .build(); final var result = given.toString(); - assertThat(result).isEqualTo("debitor(D-1234567: P-12345, som)"); - } - - @Test - void toStringWithoutPersonContainsDebitorNumber() { - final var given = HsOfficeDebitorEntity.builder() - .debitorNumberSuffix((byte)67) - .partner(HsOfficePartnerEntity.builder() - .partnerRole(null) - .details(HsOfficePartnerDetailsEntity.builder().birthName("some birth name").build()) - .partnerNumber(12345) - .build()) - .billingContact(HsOfficeContactEntity.builder().label("some label").build()) - .build(); - - final var result = given.toString(); - - assertThat(result).isEqualTo("debitor(D-1234567: P-12345)"); + assertThat(result).isEqualTo("debitor(D-1234567: rel(relAnchor='LP some partner trade name', relHolder='LP some billing trade name'), som)"); } @Test void toShortStringContainsDebitorNumber() { final var given = HsOfficeDebitorEntity.builder() - .partner(HsOfficePartnerEntity.builder() - .partnerNumber(12345) - .build()) + .debitorRel(givenDebitorRel) .debitorNumberSuffix((byte)67) .build(); @@ -69,9 +54,7 @@ class HsOfficeDebitorEntityUnitTest { @Test void getDebitorNumberWithPartnerNumberAndDebitorNumberSuffix() { final var given = HsOfficeDebitorEntity.builder() - .partner(HsOfficePartnerEntity.builder() - .partnerNumber(12345) - .build()) + .debitorRel(givenDebitorRel) .debitorNumberSuffix((byte)67) .build(); @@ -82,8 +65,9 @@ class HsOfficeDebitorEntityUnitTest { @Test void getDebitorNumberWithoutPartnerReturnsNull() { + givenDebitorRel.getRelAnchor().setOptionalPartner(null); final var given = HsOfficeDebitorEntity.builder() - .partner(null) + .debitorRel(givenDebitorRel) .debitorNumberSuffix((byte)67) .build(); @@ -94,10 +78,9 @@ class HsOfficeDebitorEntityUnitTest { @Test void getDebitorNumberWithoutPartnerNumberReturnsNull() { + givenDebitorRel.getRelAnchor().getOptionalPartner().setPartnerNumber(null); final var given = HsOfficeDebitorEntity.builder() - .partner(HsOfficePartnerEntity.builder() - .partnerNumber(null) - .build()) + .debitorRel(givenDebitorRel) .debitorNumberSuffix((byte)67) .build(); @@ -109,9 +92,7 @@ class HsOfficeDebitorEntityUnitTest { @Test void getDebitorNumberWithoutDebitorNumberSuffixReturnsNull() { final var given = HsOfficeDebitorEntity.builder() - .partner(HsOfficePartnerEntity.builder() - .partnerNumber(12345) - .build()) + .debitorRel(givenDebitorRel) .debitorNumberSuffix(null) .build(); diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorRepositoryIntegrationTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorRepositoryIntegrationTest.java index 659e6671..81014a1f 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorRepositoryIntegrationTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorRepositoryIntegrationTest.java @@ -4,8 +4,13 @@ import net.hostsharing.hsadminng.context.Context; import net.hostsharing.hsadminng.hs.office.bankaccount.HsOfficeBankAccountRepository; import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRepository; import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRepository; +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.hsadminng.hs.office.test.ContextBasedTestWithCleanup; import net.hostsharing.hsadminng.rbac.rbacgrant.RawRbacGrantRepository; +import net.hostsharing.hsadminng.rbac.rbacgrant.RbacGrantsMermaidService; +import net.hostsharing.hsadminng.rbac.rbacgrant.RbacGrantsMermaidService.Include; import net.hostsharing.hsadminng.rbac.rbacrole.RawRbacRoleRepository; import net.hostsharing.test.Array; import net.hostsharing.test.JpaAttempt; @@ -25,15 +30,17 @@ import jakarta.persistence.EntityManager; import jakarta.persistence.PersistenceContext; import jakarta.servlet.http.HttpServletRequest; import java.util.Arrays; +import java.util.EnumSet; import java.util.List; +import static net.hostsharing.hsadminng.hs.office.test.EntityList.one; import static net.hostsharing.hsadminng.rbac.rbacgrant.RawRbacGrantEntity.distinctGrantDisplaysOf; import static net.hostsharing.hsadminng.rbac.rbacrole.RawRbacRoleEntity.distinctRoleNamesOf; import static net.hostsharing.test.JpaAttempt.attempt; import static org.assertj.core.api.Assertions.assertThat; @DataJpaTest -@Import( { Context.class, JpaAttempt.class }) +@Import( { Context.class, JpaAttempt.class, RbacGrantsMermaidService.class }) class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTestWithCleanup { @Autowired @@ -45,6 +52,9 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTestWithClean @Autowired HsOfficeContactRepository contactRepo; + @Autowired + HsOfficePersonRepository personRepo; + @Autowired HsOfficeBankAccountRepository bankAccountRepo; @@ -60,9 +70,11 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTestWithClean @Autowired JpaAttempt jpaAttempt; + @Autowired + RbacGrantsMermaidService mermaidService; + @MockBean HttpServletRequest request; - @Nested class CreateDebitor { @@ -71,15 +83,19 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTestWithClean // given context("superuser-alex@hostsharing.net"); final var count = debitorRepo.count(); - final var givenPartner = partnerRepo.findPartnerByOptionalNameLike("First GmbH").get(0); - final var givenContact = contactRepo.findContactByOptionalLabelLike("first contact").get(0); + final var givenPartnerPerson = one(personRepo.findPersonByOptionalNameLike("First GmbH")); + final var givenContact = one(contactRepo.findContactByOptionalLabelLike("first contact")); // when final var result = attempt(em, () -> { final var newDebitor = HsOfficeDebitorEntity.builder() .debitorNumberSuffix((byte)21) - .partner(givenPartner) - .billingContact(givenContact) + .debitorRel(HsOfficeRelationshipEntity.builder() + .relType(HsOfficeRelationshipType.ACCOUNTING) + .relAnchor(givenPartnerPerson) + .relHolder(givenPartnerPerson) + .contact(givenContact) + .build()) .defaultPrefix("abc") .billable(false) .build(); @@ -99,16 +115,19 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTestWithClean public void canNotCreateNewDebitorWithInvalidDefaultPrefix(final String givenPrefix) { // given context("superuser-alex@hostsharing.net"); - final var count = debitorRepo.count(); - final var givenPartner = partnerRepo.findPartnerByOptionalNameLike("First GmbH").get(0); - final var givenContact = contactRepo.findContactByOptionalLabelLike("first contact").get(0); + final var givenPartnerPerson = one(personRepo.findPersonByOptionalNameLike("First GmbH")); + final var givenContact = one(contactRepo.findContactByOptionalLabelLike("first contact")); // when final var result = attempt(em, () -> { final var newDebitor = HsOfficeDebitorEntity.builder() .debitorNumberSuffix((byte)21) - .partner(givenPartner) - .billingContact(givenContact) + .debitorRel(HsOfficeRelationshipEntity.builder() + .relType(HsOfficeRelationshipType.ACCOUNTING) + .relAnchor(givenPartnerPerson) + .relHolder(givenPartnerPerson) + .contact(givenContact) + .build()) .billable(true) .vatReverseCharge(false) .vatBusiness(false) @@ -119,7 +138,7 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTestWithClean // then System.out.println("ok"); -// result.assertExceptionWithRootCauseMessage(org.hibernate.exception.ConstraintViolationException.class); +// TODO result.assertExceptionWithRootCauseMessage(org.hibernate.exception.ConstraintViolationException.class); } @Test @@ -138,12 +157,16 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTestWithClean // when attempt(em, () -> { - final var givenPartner = partnerRepo.findPartnerByOptionalNameLike("Fourth").get(0); - final var givenContact = contactRepo.findContactByOptionalLabelLike("fourth contact").get(0); + final var givenPartnerPerson = one(personRepo.findPersonByOptionalNameLike("First GmbH")); + final var givenContact = one(contactRepo.findContactByOptionalLabelLike("fourth contact")); final var newDebitor = HsOfficeDebitorEntity.builder() .debitorNumberSuffix((byte)22) - .partner(givenPartner) - .billingContact(givenContact) + .debitorRel(HsOfficeRelationshipEntity.builder() + .relType(HsOfficeRelationshipType.ACCOUNTING) + .relAnchor(givenPartnerPerson) + .relHolder(givenPartnerPerson) + .contact(givenContact) + .build()) .defaultPrefix("abc") .billable(false) .build(); @@ -178,13 +201,14 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTestWithClean // agent "{ grant role debitor#1000422:FeG.agent to role debitor#1000422:FeG.admin by system and assume }", "{ grant role debitor#1000422:FeG.agent to role contact#4th.admin by system and assume }", - "{ grant role debitor#1000422:FeG.agent to role partner#10004:FeG.admin by system and assume }", + // "{ grant role debitor#1000422:FeG.agent to role partner#10004:FeG.admin by system and assume }", // tenant - "{ grant role contact#4th.guest to role debitor#1000422:FeG.tenant by system and assume }", + //"{ grant role contact#4th.guest to role debitor#1000422:FeG.tenant by system and assume }", "{ grant role debitor#1000422:FeG.tenant to role debitor#1000422:FeG.agent by system and assume }", - "{ grant role debitor#1000422:FeG.tenant to role partner#10004:FeG.agent by system and assume }", - "{ grant role partner#10004:FeG.tenant to role debitor#1000422:FeG.tenant by system and assume }", + //"{ grant role debitor#1000422:FeG.tenant to role partner#10004:FeG.agent by system and assume }", + //"{ grant role partner#10004:FeG.tenant to role debitor#1000422:FeG.tenant by system and assume }", + "{ grant role contact#4th.referrer to role debitor#1000422:FeG.tenant by system and assume }", // guest "{ grant perm view on debitor#1000422:FeG to role debitor#1000422:FeG.guest by system and assume }", @@ -291,13 +315,17 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTestWithClean // given context("superuser-alex@hostsharing.net"); final var givenDebitor = givenSomeTemporaryDebitor("Fourth", "fifth contact", "Fourth", "fif"); + + RbacGrantsMermaidService.writeToFile("initial partner: Fourth eG + fourth contact", + mermaidService.allGrantsFrom(givenDebitor.getUuid(), "view", EnumSet.of(Include.USERS, Include.DETAILS)), + "doc/all-grants-before-globalAdmin_canUpdateArbitraryDebitor.md"); + assertThatDebitorIsVisibleForUserWithRole( givenDebitor, - "hs_office_partner#10004:FourtheG-fourthcontact.admin"); - assertThatDebitorActuallyInDatabase(givenDebitor); - final var givenNewPartner = partnerRepo.findPartnerByOptionalNameLike("First").get(0); - final var givenNewContact = contactRepo.findContactByOptionalLabelLike("sixth contact").get(0); - final var givenNewBankAccount = bankAccountRepo.findByOptionalHolderLike("first").get(0); + "hs_office_debitor#1000420:FourtheG-fourthcontact.agent"); + final var givenNewPartnerPerson = one(personRepo.findPersonByOptionalNameLike("First")); + final var givenNewContact = one(contactRepo.findContactByOptionalLabelLike("sixth contact")); + final var givenNewBankAccount = one(bankAccountRepo.findByOptionalHolderLike("first")); final String givenNewVatId = "NEW-VAT-ID"; final String givenNewVatCountryCode = "NC"; final boolean givenNewVatBusiness = !givenDebitor.isVatBusiness(); @@ -305,8 +333,12 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTestWithClean // when final var result = jpaAttempt.transacted(() -> { context("superuser-alex@hostsharing.net"); - givenDebitor.setPartner(givenNewPartner); - givenDebitor.setBillingContact(givenNewContact); + givenDebitor.setDebitorRel(HsOfficeRelationshipEntity.builder() + .relType(HsOfficeRelationshipType.ACCOUNTING) + .relAnchor(givenNewPartnerPerson) + .relHolder(givenNewPartnerPerson) + .contact(givenNewContact) + .build()); givenDebitor.setRefundBankAccount(givenNewBankAccount); givenDebitor.setVatId(givenNewVatId); givenDebitor.setVatCountryCode(givenNewVatCountryCode); @@ -354,7 +386,7 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTestWithClean givenDebitor, "hs_office_partner#10004:FourtheG-fourthcontact.admin"); assertThatDebitorActuallyInDatabase(givenDebitor); - final var givenNewBankAccount = bankAccountRepo.findByOptionalHolderLike("first").get(0); + final var givenNewBankAccount = one(bankAccountRepo.findByOptionalHolderLike("first")); // when final var result = jpaAttempt.transacted(() -> { @@ -498,14 +530,14 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTestWithClean } @Test - public void relatedPerson_canNotDeleteTheirRelatedDebitor() { + public void debitorAgent_canViewButNotDeleteTheirRelatedDebitor() { // given context("superuser-alex@hostsharing.net", null); final var givenDebitor = givenSomeTemporaryDebitor("Fourth", "eleventh", "Fourth", "ele"); // when final var result = jpaAttempt.transacted(() -> { - context("person-FourtheG@example.com"); + context("superuser-alex@hostsharing.net", "hs_office_debitor#1000420:FourtheG-fourthcontact.agent"); assertThat(debitorRepo.findByUuid(givenDebitor.getUuid())).isPresent(); debitorRepo.deleteByUuid(givenDebitor.getUuid()); @@ -562,20 +594,24 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTestWithClean } private HsOfficeDebitorEntity givenSomeTemporaryDebitor( - final String partner, - final String contact, - final String bankAccount, + final String partnerName, + final String contactLabel, + final String bankAccountHolder, final String defaultPrefix) { return jpaAttempt.transacted(() -> { context("superuser-alex@hostsharing.net"); - final var givenPartner = partnerRepo.findPartnerByOptionalNameLike(partner).get(0); - final var givenContact = contactRepo.findContactByOptionalLabelLike(contact).get(0); + final var givenPartnerPerson = one(personRepo.findPersonByOptionalNameLike(partnerName)); + final var givenContact = one(contactRepo.findContactByOptionalLabelLike(contactLabel)); final var givenBankAccount = - bankAccount != null ? bankAccountRepo.findByOptionalHolderLike(bankAccount).get(0) : null; + bankAccountHolder != null ? one(bankAccountRepo.findByOptionalHolderLike(bankAccountHolder)) : null; final var newDebitor = HsOfficeDebitorEntity.builder() .debitorNumberSuffix((byte)20) - .partner(givenPartner) - .billingContact(givenContact) + .debitorRel(HsOfficeRelationshipEntity.builder() + .relType(HsOfficeRelationshipType.ACCOUNTING) + .relAnchor(givenPartnerPerson) + .relHolder(givenPartnerPerson) + .contact(givenContact) + .build()) .refundBankAccount(givenBankAccount) .defaultPrefix(defaultPrefix) .billable(true) diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/debitor/TestHsOfficeDebitor.java b/src/test/java/net/hostsharing/hsadminng/hs/office/debitor/TestHsOfficeDebitor.java index 36b3d534..7a8bc46e 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/debitor/TestHsOfficeDebitor.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/debitor/TestHsOfficeDebitor.java @@ -1,7 +1,8 @@ package net.hostsharing.hsadminng.hs.office.debitor; import lombok.experimental.UtilityClass; - +import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity; +import net.hostsharing.hsadminng.hs.office.relationship.HsOfficeRelationshipEntity; import static net.hostsharing.hsadminng.hs.office.contact.TestHsOfficeContact.TEST_CONTACT; import static net.hostsharing.hsadminng.hs.office.partner.TestHsOfficePartner.TEST_PARTNER; @@ -13,7 +14,12 @@ public class TestHsOfficeDebitor { public static final HsOfficeDebitorEntity TEST_DEBITOR = HsOfficeDebitorEntity.builder() .debitorNumberSuffix(DEFAULT_DEBITOR_SUFFIX) - .partner(TEST_PARTNER) - .billingContact(TEST_CONTACT) + .debitorRel(HsOfficeRelationshipEntity.builder() + .relHolder(HsOfficePersonEntity.builder().build()) + .relAnchor(HsOfficePersonEntity.builder() + .optionalPartner(TEST_PARTNER) + .build()) + .contact(TEST_CONTACT) + .build()) .build(); } diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/migration/ImportOfficeData.java b/src/test/java/net/hostsharing/hsadminng/hs/office/migration/ImportOfficeData.java index 6bd27ded..0d7bff61 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/migration/ImportOfficeData.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/migration/ImportOfficeData.java @@ -445,8 +445,7 @@ public class ImportOfficeData extends ContextBasedTest { final var idsToRemove = new HashSet(); debitors.forEach( (id, d) -> { // such a record is in test data to test error messages - if (d.getBillingContact() == null || d.getBillingContact().getLabel() == null || - d.getPartner() == null || d.getPartner().getPartnerRole().getRelAnchor().getPersonType() == null ) { + if (false) { // TODO: how can I now empty debitors? idsToRemove.add(id); } }); @@ -676,10 +675,15 @@ public class ImportOfficeData extends ContextBasedTest { partners.put(rec.getInteger("bp_id"), partner); final var debitor = HsOfficeDebitorEntity.builder() - .partner(partner) .debitorNumberSuffix((byte) 0) + .debitorRel( + HsOfficeRelationshipEntity.builder() + .relType(HsOfficeRelationshipType.ACCOUNTING) + .relAnchor(partnerRelationship.getRelHolder()) + .relHolder(null) // gets set later + .build() + ) .defaultPrefix(rec.getString("member_code").replace("hsh00-", "")) - .partner(partner) .billable(rec.isEmpty("free") || rec.getString("free").equals("f")) .vatReverseCharge(rec.getBoolean("exempt_vat")) .vatBusiness("GROSS".equals(rec.getString("indicator_vat"))) // TODO: remove @@ -846,8 +850,8 @@ public class ImportOfficeData extends ContextBasedTest { partner.getPartnerRole().setContact(contact); } if (containsRole(rec, "billing")) { - assertThat(debitor.getBillingContact()).isNull(); - debitor.setBillingContact(contact); + assertThat(debitor.getDebitorRel().getContact()).isNull(); + debitor.getDebitorRel().setContact(contact); } if (containsRole(rec, "operation")) { addRelationship(partnerPerson, contactPerson, contact, HsOfficeRelationshipType.OPERATIONS); 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 8d4f1ff3..27e41ddb 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 @@ -19,7 +19,6 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.transaction.annotation.Transactional; -import java.util.EnumSet; import java.util.UUID; import static net.hostsharing.test.IsValidUuidMatcher.isUuidValid; diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/test/EntityList.java b/src/test/java/net/hostsharing/hsadminng/hs/office/test/EntityList.java new file mode 100644 index 00000000..1699a5d2 --- /dev/null +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/test/EntityList.java @@ -0,0 +1,15 @@ +package net.hostsharing.hsadminng.hs.office.test; + +import net.hostsharing.hsadminng.persistence.HasUuid; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +public class EntityList { + + public static E one(final List entities) { + assertThat(entities).hasSize(1); + return entities.stream().findFirst().orElseThrow(); + } +}