rbac-optimization #80

Merged
hsh-michaelhoennig merged 14 commits from rbac-optimization into master 2024-07-27 10:18:08 +02:00
33 changed files with 158 additions and 181 deletions
Showing only changes of commit b79a8ca22d - Show all commits

View File

@ -245,3 +245,17 @@ The HashJoin strategy could be great if the hash-map could be kept for multiple
### LAZY loading for Relation.anchorPerson/.holderPerson/
The slowest query now was fetching Relations joined with Contact, Anchor-Person and Holder-Person, for all tables using the restricted (RBAC) views (_rv).
We changed these mappings from `EAGER` (default) to `LAZY` to `@ManyToOne(fetch = FetchType.LAZY)` and got this result:
| query | calls | total (min) | mean (ms) |
|-------|-------|-------------|-----------|
| select hore1_0.uuid,hore1_0.anchoruuid,hore1_0.contactuuid,hore1_0.holderuuid,hore1_0.mark,hore1_0.type,hore1_0.version from hs_office_relation_rv hore1_0 where hore1_0.uuid=$1 | 517 | 5 | 565 |
| select hope1_0.uuid,hope1_0.familyname,hope1_0.givenname,hope1_0.persontype,hope1_0.salutation,hope1_0.title,hope1_0.tradename,hope1_0.version from hs_office_person_rv hope1_0 where hope1_0.uuid=$1 | 1015 | 4 | 240 |
| select hoce1_0.uuid,hoce1_0.caption,hoce1_0.emailaddresses,hoce1_0.phonenumbers,hoce1_0.postaladdress,hoce1_0.version from hs_office_contact_rv hoce1_0 where hoce1_0.uuid=$1 | 497 | 2 | 235
select * from isGranted(array[granteeId], grantedId) | 44613 | 1 | 1 |
Now, finally, the total runtime of the import was down to 12 minutes.

View File

@ -70,7 +70,7 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
@Setter @Setter
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
public class HsBookingItemEntity implements Stringifyable, RbacObject, PropertiesProvider { public class HsBookingItemEntity implements Stringifyable, RbacObject<HsBookingItemEntity>, PropertiesProvider {
private static Stringify<HsBookingItemEntity> stringify = stringify(HsBookingItemEntity.class) private static Stringify<HsBookingItemEntity> stringify = stringify(HsBookingItemEntity.class)
.withProp(HsBookingItemEntity::getProject) .withProp(HsBookingItemEntity::getProject)

View File

@ -34,7 +34,7 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
@Setter @Setter
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
public class HsBookingProjectEntity implements Stringifyable, RbacObject { public class HsBookingProjectEntity implements Stringifyable, RbacObject<HsBookingProjectEntity> {
private static Stringify<HsBookingProjectEntity> stringify = stringify(HsBookingProjectEntity.class) private static Stringify<HsBookingProjectEntity> stringify = stringify(HsBookingProjectEntity.class)
.withProp(HsBookingProjectEntity::getDebitor) .withProp(HsBookingProjectEntity::getDebitor)

View File

@ -70,7 +70,7 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
@Setter @Setter
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
public class HsHostingAssetEntity implements Stringifyable, RbacObject, PropertiesProvider { public class HsHostingAssetEntity implements Stringifyable, RbacObject<HsHostingAssetEntity>, PropertiesProvider {
private static Stringify<HsHostingAssetEntity> stringify = stringify(HsHostingAssetEntity.class) private static Stringify<HsHostingAssetEntity> stringify = stringify(HsHostingAssetEntity.class)
.withProp(HsHostingAssetEntity::getType) .withProp(HsHostingAssetEntity::getType)

View File

@ -27,7 +27,7 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
@AllArgsConstructor @AllArgsConstructor
@FieldNameConstants @FieldNameConstants
@DisplayName("BankAccount") @DisplayName("BankAccount")
public class HsOfficeBankAccountEntity implements RbacObject, Stringifyable { public class HsOfficeBankAccountEntity implements RbacObject<HsOfficeBankAccountEntity>, Stringifyable {
private static Stringify<HsOfficeBankAccountEntity> toString = stringify(HsOfficeBankAccountEntity.class, "bankAccount") private static Stringify<HsOfficeBankAccountEntity> toString = stringify(HsOfficeBankAccountEntity.class, "bankAccount")
.withIdProp(HsOfficeBankAccountEntity::getIban) .withIdProp(HsOfficeBankAccountEntity::getIban)

View File

@ -35,7 +35,7 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
@AllArgsConstructor @AllArgsConstructor
@FieldNameConstants @FieldNameConstants
@DisplayName("Contact") @DisplayName("Contact")
public class HsOfficeContactEntity implements Stringifyable, RbacObject { public class HsOfficeContactEntity implements Stringifyable, RbacObject<HsOfficeContactEntity> {
private static Stringify<HsOfficeContactEntity> toString = stringify(HsOfficeContactEntity.class, "contact") private static Stringify<HsOfficeContactEntity> toString = stringify(HsOfficeContactEntity.class, "contact")
.withProp(Fields.caption, HsOfficeContactEntity::getCaption) .withProp(Fields.caption, HsOfficeContactEntity::getCaption)

View File

@ -41,7 +41,7 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
@DisplayName("CoopAssetsTransaction") @DisplayName("CoopAssetsTransaction")
public class HsOfficeCoopAssetsTransactionEntity implements Stringifyable, RbacObject { public class HsOfficeCoopAssetsTransactionEntity implements Stringifyable, RbacObject<HsOfficeCoopAssetsTransactionEntity> {
private static Stringify<HsOfficeCoopAssetsTransactionEntity> stringify = stringify(HsOfficeCoopAssetsTransactionEntity.class) private static Stringify<HsOfficeCoopAssetsTransactionEntity> stringify = stringify(HsOfficeCoopAssetsTransactionEntity.class)
.withIdProp(HsOfficeCoopAssetsTransactionEntity::getTaggedMemberNumber) .withIdProp(HsOfficeCoopAssetsTransactionEntity::getTaggedMemberNumber)

View File

@ -39,7 +39,7 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
@DisplayName("CoopShareTransaction") @DisplayName("CoopShareTransaction")
public class HsOfficeCoopSharesTransactionEntity implements Stringifyable, RbacObject { public class HsOfficeCoopSharesTransactionEntity implements Stringifyable, RbacObject<HsOfficeCoopSharesTransactionEntity> {
private static Stringify<HsOfficeCoopSharesTransactionEntity> stringify = stringify(HsOfficeCoopSharesTransactionEntity.class) private static Stringify<HsOfficeCoopSharesTransactionEntity> stringify = stringify(HsOfficeCoopSharesTransactionEntity.class)
.withIdProp(HsOfficeCoopSharesTransactionEntity::getMemberNumberTagged) .withIdProp(HsOfficeCoopSharesTransactionEntity::getMemberNumberTagged)

View File

@ -5,6 +5,7 @@ import net.hostsharing.hsadminng.hs.office.generated.api.v1.api.HsOfficeDebitors
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeDebitorInsertResource; import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeDebitorInsertResource;
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeDebitorPatchResource; import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeDebitorPatchResource;
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeDebitorResource; import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeDebitorResource;
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRepository;
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationEntity; import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationEntity;
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRepository; import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRepository;
import net.hostsharing.hsadminng.mapper.Mapper; import net.hostsharing.hsadminng.mapper.Mapper;
@ -37,6 +38,9 @@ public class HsOfficeDebitorController implements HsOfficeDebitorsApi {
@Autowired @Autowired
private HsOfficeDebitorRepository debitorRepo; private HsOfficeDebitorRepository debitorRepo;
@Autowired
private HsOfficePartnerRepository partnerRepo;
@Autowired @Autowired
private HsOfficeRelationRepository relRepo; private HsOfficeRelationRepository relRepo;
@ -91,6 +95,9 @@ public class HsOfficeDebitorController implements HsOfficeDebitorsApi {
() -> { throw new EntityNotFoundException("ERROR: [400] debitorRelUuid not found: " + body.getDebitorRelUuid());}); () -> { throw new EntityNotFoundException("ERROR: [400] debitorRelUuid not found: " + body.getDebitorRelUuid());});
} }
final var relatedPartner = partnerRepo.findPartnerByPartnerPersonUuid(entityToSave.getDebitorRel().getHolder().getUuid());
entityToSave.setPartnerNumber(relatedPartner.getPartnerNumber());
final var savedEntity = debitorRepo.save(entityToSave); final var savedEntity = debitorRepo.save(entityToSave);
em.flush(); em.flush();
em.refresh(savedEntity); em.refresh(savedEntity);

View File

@ -7,13 +7,13 @@ import lombok.NoArgsConstructor;
import lombok.Setter; import lombok.Setter;
import net.hostsharing.hsadminng.errors.DisplayName; import net.hostsharing.hsadminng.errors.DisplayName;
import net.hostsharing.hsadminng.hs.office.bankaccount.HsOfficeBankAccountEntity; import net.hostsharing.hsadminng.hs.office.bankaccount.HsOfficeBankAccountEntity;
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity;
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationEntity; import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationEntity;
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject; import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView; import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL; import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL;
import net.hostsharing.hsadminng.stringify.Stringify; import net.hostsharing.hsadminng.stringify.Stringify;
import net.hostsharing.hsadminng.stringify.Stringifyable; import net.hostsharing.hsadminng.stringify.Stringifyable;
import org.hibernate.Hibernate;
import org.hibernate.annotations.GenericGenerator; import org.hibernate.annotations.GenericGenerator;
import jakarta.persistence.Column; import jakarta.persistence.Column;
@ -54,7 +54,7 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
@DisplayName("Debitor") @DisplayName("Debitor")
public class HsOfficeDebitorEntity implements RbacObject, Stringifyable { public class HsOfficeDebitorEntity implements RbacObject<HsOfficeDebitorEntity>, Stringifyable {
public static final String DEBITOR_NUMBER_TAG = "D-"; public static final String DEBITOR_NUMBER_TAG = "D-";
public static final String TWO_DECIMAL_DIGITS = "^([0-9]{2})$"; public static final String TWO_DECIMAL_DIGITS = "^([0-9]{2})$";
@ -107,6 +107,16 @@ public class HsOfficeDebitorEntity implements RbacObject, Stringifyable {
@Column(name = "defaultprefix", columnDefinition = "char(3) not null") @Column(name = "defaultprefix", columnDefinition = "char(3) not null")
private String defaultPrefix; private String defaultPrefix;
@Override
public HsOfficeDebitorEntity load() {
RbacObject.super.load();
debitorRel.load();
if (refundBankAccount != null) {
refundBankAccount.load();
}
return this;
}
private String getDebitorNumberString() { private String getDebitorNumberString() {
return ofNullable(partnerNumber) return ofNullable(partnerNumber)
.filter(partner -> debitorNumberSuffix != null) .filter(partner -> debitorNumberSuffix != null)

View File

@ -61,7 +61,7 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
@DisplayName("Membership") @DisplayName("Membership")
public class HsOfficeMembershipEntity implements RbacObject, Stringifyable { public class HsOfficeMembershipEntity implements RbacObject<HsOfficeMembershipEntity>, Stringifyable {
public static final String MEMBER_NUMBER_TAG = "M-"; public static final String MEMBER_NUMBER_TAG = "M-";
public static final String TWO_DECIMAL_DIGITS = "^([0-9]{2})$"; public static final String TWO_DECIMAL_DIGITS = "^([0-9]{2})$";
@ -99,6 +99,13 @@ public class HsOfficeMembershipEntity implements RbacObject, Stringifyable {
@Enumerated(EnumType.STRING) @Enumerated(EnumType.STRING)
private HsOfficeMembershipStatus status; private HsOfficeMembershipStatus status;
@Override
public HsOfficeMembershipEntity load() {
RbacObject.super.load();
partner.load();
return this;
}
public void setValidFrom(final LocalDate validFrom) { public void setValidFrom(final LocalDate validFrom) {
setValidity(toPostgresDateRange(validFrom, getValidTo())); setValidity(toPostgresDateRange(validFrom, getValidTo()));
} }

View File

@ -26,7 +26,7 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
@DisplayName("PartnerDetails") @DisplayName("PartnerDetails")
public class HsOfficePartnerDetailsEntity implements RbacObject, Stringifyable { public class HsOfficePartnerDetailsEntity implements RbacObject<HsOfficePartnerDetailsEntity>, Stringifyable {
private static Stringify<HsOfficePartnerDetailsEntity> stringify = stringify( private static Stringify<HsOfficePartnerDetailsEntity> stringify = stringify(
HsOfficePartnerDetailsEntity.class, HsOfficePartnerDetailsEntity.class,

View File

@ -40,7 +40,7 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
@DisplayName("Partner") @DisplayName("Partner")
public class HsOfficePartnerEntity implements Stringifyable, RbacObject { public class HsOfficePartnerEntity implements Stringifyable, RbacObject<HsOfficePartnerEntity> {
public static final String PARTNER_NUMBER_TAG = "P-"; public static final String PARTNER_NUMBER_TAG = "P-";
@ -66,11 +66,11 @@ public class HsOfficePartnerEntity implements Stringifyable, RbacObject {
@Column(name = "partnernumber", columnDefinition = "numeric(5) not null") @Column(name = "partnernumber", columnDefinition = "numeric(5) not null")
private Integer partnerNumber; private Integer partnerNumber;
@ManyToOne(cascade = { PERSIST, MERGE, REFRESH, DETACH }, optional = false) @ManyToOne(cascade = { PERSIST, MERGE, REFRESH, DETACH }, optional = false, fetch = FetchType.EAGER)
@JoinColumn(name = "partnerreluuid", nullable = false) @JoinColumn(name = "partnerreluuid", nullable = false)
private HsOfficeRelationEntity partnerRel; private HsOfficeRelationEntity partnerRel;
@ManyToOne(cascade = { PERSIST, MERGE, REFRESH, DETACH }, optional = true) @ManyToOne(cascade = { PERSIST, MERGE, REFRESH, DETACH }, optional = true, fetch = FetchType.EAGER)
@JoinColumn(name = "detailsuuid") @JoinColumn(name = "detailsuuid")
@NotFound(action = NotFoundAction.IGNORE) @NotFound(action = NotFoundAction.IGNORE)
private HsOfficePartnerDetailsEntity details; private HsOfficePartnerDetailsEntity details;

View File

@ -31,13 +31,11 @@ public interface HsOfficePartnerRepository extends Repository<HsOfficePartnerEnt
@Query(""" @Query("""
SELECT DISTINCT partner SELECT DISTINCT partner
FROM HsOfficePartnerEntity partner FROM HsOfficePartnerEntity partner
JOIN HsOfficeRelationEntity dRel
ON dRel.uuid = :debitorUuid AND dRel.type = 'DEBITOR'
JOIN HsOfficeRelationEntity pRel JOIN HsOfficeRelationEntity pRel
ON pRel.uuid = partner.partnerRel.uuid AND pRel.type = 'PARTNER' ON pRel.uuid = partner.partnerRel.uuid AND pRel.type = 'PARTNER'
WHERE pRel.holder.uuid = dRel.anchor.uuid WHERE pRel.holder.uuid = :partnerPersonUuid
""") """)
HsOfficePartnerEntity findPartnerByDebitorUuid(UUID debitorUuid); HsOfficePartnerEntity findPartnerByPartnerPersonUuid(UUID partnerPersonUuid);
HsOfficePartnerEntity save(final HsOfficePartnerEntity entity); HsOfficePartnerEntity save(final HsOfficePartnerEntity entity);

View File

@ -30,7 +30,7 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
@AllArgsConstructor @AllArgsConstructor
@FieldNameConstants @FieldNameConstants
@DisplayName("Person") @DisplayName("Person")
public class HsOfficePersonEntity implements RbacObject, Stringifyable { public class HsOfficePersonEntity implements RbacObject<HsOfficePersonEntity>, Stringifyable {
private static Stringify<HsOfficePersonEntity> toString = stringify(HsOfficePersonEntity.class, "person") private static Stringify<HsOfficePersonEntity> toString = stringify(HsOfficePersonEntity.class, "person")
.withProp(Fields.personType, HsOfficePersonEntity::getPersonType) .withProp(Fields.personType, HsOfficePersonEntity::getPersonType)

View File

@ -75,6 +75,15 @@ public class HsOfficeRelationEntity implements RbacObject, Stringifyable {
@Column(name = "mark") @Column(name = "mark")
private String mark; private String mark;
@Override
public RbacObject<?> load() {
RbacObject.super.load();
anchor.load();
holder.load();
contact.load();
return this;
}
@Override @Override
public String toString() { public String toString() {
return toString.apply(this); return toString.apply(this);

View File

@ -40,7 +40,7 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
@DisplayName("SEPA-Mandate") @DisplayName("SEPA-Mandate")
public class HsOfficeSepaMandateEntity implements Stringifyable, RbacObject { public class HsOfficeSepaMandateEntity implements Stringifyable, RbacObject<HsOfficeSepaMandateEntity> {
private static Stringify<HsOfficeSepaMandateEntity> stringify = stringify(HsOfficeSepaMandateEntity.class) private static Stringify<HsOfficeSepaMandateEntity> stringify = stringify(HsOfficeSepaMandateEntity.class)
.withProp(e -> e.getBankAccount().getIban()) .withProp(e -> e.getBankAccount().getIban())

View File

@ -1,10 +1,18 @@
package net.hostsharing.hsadminng.rbac.rbacobject; package net.hostsharing.hsadminng.rbac.rbacobject;
import org.hibernate.Hibernate;
import java.util.UUID; import java.util.UUID;
public interface RbacObject { public interface RbacObject<T extends RbacObject<?>> {
UUID getUuid(); UUID getUuid();
int getVersion(); int getVersion();
default T load() {
Hibernate.initialize(this);
//noinspection unchecked
return (T) this;
};
} }

View File

@ -24,7 +24,7 @@ import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.rbacViewFor;
@Setter @Setter
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
public class TestCustomerEntity implements RbacObject { public class TestCustomerEntity implements RbacObject<TestCustomerEntity> {
@Id @Id
@GeneratedValue @GeneratedValue

View File

@ -27,7 +27,7 @@ import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.rbacViewFor;
@Setter @Setter
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
public class TestDomainEntity implements RbacObject { public class TestDomainEntity implements RbacObject<TestDomainEntity> {
@Id @Id
@GeneratedValue @GeneratedValue

View File

@ -27,7 +27,7 @@ import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.rbacViewFor;
@Setter @Setter
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
public class TestPackageEntity implements RbacObject { public class TestPackageEntity implements RbacObject<TestPackageEntity> {
@Id @Id
@GeneratedValue @GeneratedValue

View File

@ -287,7 +287,10 @@ class HsOfficeBankAccountControllerAcceptanceTest extends ContextBasedTestWithCl
.statusCode(204); // @formatter:on .statusCode(204); // @formatter:on
// then the given bankaccount is still there // then the given bankaccount is still there
assertThat(bankAccountRepo.findByUuid(givenBankAccount.getUuid())).isEmpty(); jpaAttempt.transacted(() -> {
context("superuser-alex@hostsharing.net", null);
assertThat(bankAccountRepo.findByUuid(givenBankAccount.getUuid())).isEmpty();
}).assertSuccessful();
} }
@Test @Test

View File

@ -309,7 +309,10 @@ class HsOfficeContactControllerAcceptanceTest extends ContextBasedTestWithCleanu
.statusCode(204); // @formatter:on .statusCode(204); // @formatter:on
// then the given contact is gone // then the given contact is gone
assertThat(contactRepo.findByUuid(givenContact.getUuid())).isEmpty(); jpaAttempt.transacted(() -> {
context("superuser-alex@hostsharing.net", null);
assertThat(contactRepo.findByUuid(givenContact.getUuid())).isEmpty();
}).assertSuccessful();
} }
@Test @Test
@ -326,7 +329,10 @@ class HsOfficeContactControllerAcceptanceTest extends ContextBasedTestWithCleanu
.statusCode(204); // @formatter:on .statusCode(204); // @formatter:on
// then the given contact is still there // then the given contact is still there
assertThat(contactRepo.findByUuid(givenContact.getUuid())).isEmpty(); jpaAttempt.transacted(() -> {
context("superuser-alex@hostsharing.net", null);
assertThat(contactRepo.findByUuid(givenContact.getUuid())).isEmpty();
}).assertSuccessful();
} }
@Test @Test

View File

@ -119,7 +119,7 @@ class HsOfficeCoopAssetsTransactionRepositoryIntegrationTest extends ContextBase
private void assertThatCoopAssetsTransactionIsPersisted(final HsOfficeCoopAssetsTransactionEntity saved) { private void assertThatCoopAssetsTransactionIsPersisted(final HsOfficeCoopAssetsTransactionEntity saved) {
final var found = coopAssetsTransactionRepo.findByUuid(saved.getUuid()); final var found = coopAssetsTransactionRepo.findByUuid(saved.getUuid());
assertThat(found).isNotEmpty().get().usingRecursiveComparison().isEqualTo(saved); assertThat(found).isNotEmpty().get().extracting(HsOfficeCoopAssetsTransactionEntity::toString).isEqualTo(saved.toString());
} }
} }

View File

@ -118,7 +118,7 @@ class HsOfficeCoopSharesTransactionRepositoryIntegrationTest extends ContextBase
private void assertThatCoopSharesTransactionIsPersisted(final HsOfficeCoopSharesTransactionEntity saved) { private void assertThatCoopSharesTransactionIsPersisted(final HsOfficeCoopSharesTransactionEntity saved) {
final var found = coopSharesTransactionRepo.findByUuid(saved.getUuid()); final var found = coopSharesTransactionRepo.findByUuid(saved.getUuid());
assertThat(found).isNotEmpty().get().usingRecursiveComparison().isEqualTo(saved); assertThat(found).isNotEmpty().get().extracting(HsOfficeCoopSharesTransactionEntity::toString).isEqualTo(saved.toString());
} }
} }

View File

@ -113,38 +113,6 @@ class HsOfficeDebitorControllerAcceptanceTest extends ContextBasedTestWithCleanu
}, },
"debitorNumber": 1000111, "debitorNumber": 1000111,
"debitorNumberSuffix": 11, "debitorNumberSuffix": 11,
"partner": {
"partnerNumber": 10001,
"partnerRel": {
"anchor": {
"personType": "LEGAL_PERSON",
"tradeName": "Hostsharing eG",
"givenName": null,
"familyName": null
},
"holder": {
"personType": "LEGAL_PERSON",
"tradeName": "First GmbH",
"givenName": null,
"familyName": null
},
"type": "PARTNER",
"mark": null,
"contact": {
"caption": "first contact",
"emailAddresses": { "main": "contact-admin@firstcontact.example.com" },
"phoneNumbers": { "phone_office": "+49 123 1234567" }
}
},
"details": {
"registrationOffice": "Hamburg",
"registrationNumber": "RegNo123456789",
"birthName": null,
"birthPlace": null,
"birthday": null,
"dateOfDeath": null
}
},
"billable": true, "billable": true,
"vatId": null, "vatId": null,
"vatCountryCode": null, "vatCountryCode": null,
@ -168,21 +136,6 @@ class HsOfficeDebitorControllerAcceptanceTest extends ContextBasedTestWithCleanu
}, },
"debitorNumber": 1000212, "debitorNumber": 1000212,
"debitorNumberSuffix": 12, "debitorNumberSuffix": 12,
"partner": {
"partnerNumber": 10002,
"partnerRel": {
"anchor": {"tradeName": "Hostsharing eG"},
"holder": {"tradeName": "Second e.K."},
"type": "PARTNER",
"contact": {
"emailAddresses": { "main": "contact-admin@secondcontact.example.com" }
}
},
"details": {
"registrationOffice": "Hamburg",
"registrationNumber": "RegNo123456789"
}
},
"billable": true, "billable": true,
"vatId": null, "vatId": null,
"vatCountryCode": null, "vatCountryCode": null,
@ -202,21 +155,6 @@ class HsOfficeDebitorControllerAcceptanceTest extends ContextBasedTestWithCleanu
}, },
"debitorNumber": 1000313, "debitorNumber": 1000313,
"debitorNumberSuffix": 13, "debitorNumberSuffix": 13,
"partner": {
"partnerNumber": 10003,
"partnerRel": {
"anchor": {"tradeName": "Hostsharing eG"},
"holder": {"tradeName": "Third OHG"},
"type": "PARTNER",
"contact": {
"emailAddresses": { "main": "contact-admin@thirdcontact.example.com" }
}
},
"details": {
"registrationOffice": "Hamburg",
"registrationNumber": "RegNo123456789"
}
},
"billable": true, "billable": true,
"vatId": null, "vatId": null,
"vatCountryCode": null, "vatCountryCode": null,
@ -357,7 +295,6 @@ class HsOfficeDebitorControllerAcceptanceTest extends ContextBasedTestWithCleanu
.contentType(ContentType.JSON) .contentType(ContentType.JSON)
.body("uuid", isUuidValid()) .body("uuid", isUuidValid())
.body("debitorRel.contact.caption", is(givenContact.getCaption())) .body("debitorRel.contact.caption", is(givenContact.getCaption()))
.body("partner.partnerRel.holder.tradeName", is(givenPartner.getPartnerRel().getHolder().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))
@ -471,25 +408,6 @@ class HsOfficeDebitorControllerAcceptanceTest extends ContextBasedTestWithCleanu
}, },
"debitorNumber": 1000111, "debitorNumber": 1000111,
"debitorNumberSuffix": 11, "debitorNumberSuffix": 11,
"partner": {
"partnerNumber": 10001,
"partnerRel": {
"anchor": { "personType": "LEGAL_PERSON", "tradeName": "Hostsharing eG"},
"holder": { "personType": "LEGAL_PERSON", "tradeName": "First GmbH"},
"type": "PARTNER",
"mark": null,
"contact": {
"caption": "first contact",
"postalAddress": "Vorname Nachname\\nStraße Hnr\\nPLZ Stadt",
"emailAddresses": { "main": "contact-admin@firstcontact.example.com" },
"phoneNumbers": { "phone_office": "+49 123 1234567" }
}
},
"details": {
"registrationOffice": "Hamburg",
"registrationNumber": "RegNo123456789"
}
},
"billable": true, "billable": true,
"vatBusiness": true, "vatBusiness": true,
"vatReverseCharge": false, "vatReverseCharge": false,
@ -583,24 +501,6 @@ class HsOfficeDebitorControllerAcceptanceTest extends ContextBasedTestWithCleanu
}, },
"debitorNumber": 10004${debitorNumberSuffix}, "debitorNumber": 10004${debitorNumberSuffix},
"debitorNumberSuffix": ${debitorNumberSuffix}, "debitorNumberSuffix": ${debitorNumberSuffix},
"partner": {
"partnerNumber": 10004,
"partnerRel": {
"anchor": { "tradeName": "Hostsharing eG" },
"holder": { "tradeName": "Fourth eG" },
"type": "PARTNER",
"mark": null,
"contact": { "caption": "fourth contact" }
},
"details": {
"registrationOffice": "Hamburg",
"registrationNumber": "RegNo123456789",
"birthName": null,
"birthPlace": null,
"birthday": null,
"dateOfDeath": null
}
},
"billable": true, "billable": true,
"vatId": "VAT222222", "vatId": "VAT222222",
"vatCountryCode": "AA", "vatCountryCode": "AA",
@ -609,22 +509,24 @@ class HsOfficeDebitorControllerAcceptanceTest extends ContextBasedTestWithCleanu
"defaultPrefix": "for" "defaultPrefix": "for"
} }
""" """
.replace("${debitorNumberSuffix}", givenDebitor.getDebitorNumberSuffix().toString())) .replace("${debitorNumberSuffix}", givenDebitor.getDebitorNumberSuffix()))
); );
// @formatter:on // @formatter:on
// finally, the debitor is actually updated // finally, the debitor is actually updated
context.define("superuser-alex@hostsharing.net"); jpaAttempt.transacted(() -> {
assertThat(debitorRepo.findByUuid(givenDebitor.getUuid())).isPresent().get() context.define("superuser-alex@hostsharing.net");
.matches(debitor -> { assertThat(debitorRepo.findByUuid(givenDebitor.getUuid())).isPresent().get()
assertThat(debitor.getDebitorRel().getHolder().getTradeName()) .matches(debitor -> {
.isEqualTo(givenDebitor.getDebitorRel().getHolder().getTradeName()); assertThat(debitor.getDebitorRel().getHolder().getTradeName())
assertThat(debitor.getDebitorRel().getContact().getCaption()).isEqualTo("fourth contact"); .isEqualTo(givenDebitor.getDebitorRel().getHolder().getTradeName());
assertThat(debitor.getVatId()).isEqualTo("VAT222222"); assertThat(debitor.getDebitorRel().getContact().getCaption()).isEqualTo("fourth contact");
assertThat(debitor.getVatCountryCode()).isEqualTo("AA"); assertThat(debitor.getVatId()).isEqualTo("VAT222222");
assertThat(debitor.isVatBusiness()).isEqualTo(true); assertThat(debitor.getVatCountryCode()).isEqualTo("AA");
return true; assertThat(debitor.isVatBusiness()).isEqualTo(true);
}); return true;
});
}).assertSuccessful();
} }
@Test @Test
@ -721,6 +623,7 @@ class HsOfficeDebitorControllerAcceptanceTest extends ContextBasedTestWithCleanu
final var givenPartner = partnerRepo.findPartnerByOptionalNameLike("Fourth").get(0); final var givenPartner = partnerRepo.findPartnerByOptionalNameLike("Fourth").get(0);
final var givenContact = contactRepo.findContactByOptionalCaptionLike("fourth contact").get(0); final var givenContact = contactRepo.findContactByOptionalCaptionLike("fourth contact").get(0);
final var newDebitor = HsOfficeDebitorEntity.builder() final var newDebitor = HsOfficeDebitorEntity.builder()
.partnerNumber(givenPartner.getPartnerNumber())
.debitorNumberSuffix(nextDebitorSuffix()) .debitorNumberSuffix(nextDebitorSuffix())
.billable(true) .billable(true)
.debitorRel( .debitorRel(

View File

@ -89,6 +89,7 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTestWithClean
// when // when
final var result = attempt(em, () -> { final var result = attempt(em, () -> {
final var newDebitor = HsOfficeDebitorEntity.builder() final var newDebitor = HsOfficeDebitorEntity.builder()
.partnerNumber(10001)
.debitorNumberSuffix("21") .debitorNumberSuffix("21")
.debitorRel(HsOfficeRelationEntity.builder() .debitorRel(HsOfficeRelationEntity.builder()
.type(HsOfficeRelationType.DEBITOR) .type(HsOfficeRelationType.DEBITOR)
@ -99,7 +100,8 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTestWithClean
.defaultPrefix("abc") .defaultPrefix("abc")
.billable(false) .billable(false)
.build(); .build();
return toCleanup(debitorRepo.save(newDebitor)); final HsOfficeDebitorEntity entity = debitorRepo.save(newDebitor);
return toCleanup(entity.load());
}); });
// then // then
@ -156,6 +158,7 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTestWithClean
final var givenDebitorPerson = one(personRepo.findPersonByOptionalNameLike("Fourth eG")); final var givenDebitorPerson = one(personRepo.findPersonByOptionalNameLike("Fourth eG"));
final var givenContact = one(contactRepo.findContactByOptionalCaptionLike("fourth contact")); final var givenContact = one(contactRepo.findContactByOptionalCaptionLike("fourth contact"));
final var newDebitor = HsOfficeDebitorEntity.builder() final var newDebitor = HsOfficeDebitorEntity.builder()
.partnerNumber(10001)
.debitorNumberSuffix("22") .debitorNumberSuffix("22")
.debitorRel(HsOfficeRelationEntity.builder() .debitorRel(HsOfficeRelationEntity.builder()
.type(HsOfficeRelationType.DEBITOR) .type(HsOfficeRelationType.DEBITOR)
@ -317,7 +320,7 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTestWithClean
assertThatDebitorIsVisibleForUserWithRole( assertThatDebitorIsVisibleForUserWithRole(
givenDebitor, givenDebitor,
"hs_office_relation#FourtheG-with-DEBITOR-FourtheG:ADMIN", true); "hs_office_relation#FourtheG-with-DEBITOR-FourtheG:ADMIN");
final var givenNewPartnerPerson = one(personRepo.findPersonByOptionalNameLike("First")); final var givenNewPartnerPerson = one(personRepo.findPersonByOptionalNameLike("First"));
final var givenNewBillingPerson = one(personRepo.findPersonByOptionalNameLike("Firby")); final var givenNewBillingPerson = one(personRepo.findPersonByOptionalNameLike("Firby"));
final var givenNewContact = one(contactRepo.findContactByOptionalCaptionLike("sixth contact")); final var givenNewContact = one(contactRepo.findContactByOptionalCaptionLike("sixth contact"));
@ -339,14 +342,15 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTestWithClean
givenDebitor.setVatId(givenNewVatId); givenDebitor.setVatId(givenNewVatId);
givenDebitor.setVatCountryCode(givenNewVatCountryCode); givenDebitor.setVatCountryCode(givenNewVatCountryCode);
givenDebitor.setVatBusiness(givenNewVatBusiness); givenDebitor.setVatBusiness(givenNewVatBusiness);
return toCleanup(debitorRepo.save(givenDebitor)); final HsOfficeDebitorEntity entity = debitorRepo.save(givenDebitor);
return toCleanup(entity.load());
}); });
// then // then
result.assertSuccessful(); result.assertSuccessful();
assertThatDebitorIsVisibleForUserWithRole( assertThatDebitorIsVisibleForUserWithRole(
result.returnedValue(), result.returnedValue(),
"global#global:ADMIN", true); "global#global:ADMIN");
// ... partner role was reassigned: // ... partner role was reassigned:
assertThatDebitorIsNotVisibleForUserWithRole( assertThatDebitorIsNotVisibleForUserWithRole(
@ -354,7 +358,7 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTestWithClean
"hs_office_relation#FourtheG-with-DEBITOR-FourtheG:ADMIN"); "hs_office_relation#FourtheG-with-DEBITOR-FourtheG:ADMIN");
assertThatDebitorIsVisibleForUserWithRole( assertThatDebitorIsVisibleForUserWithRole(
result.returnedValue(), result.returnedValue(),
"hs_office_relation#FirstGmbH-with-DEBITOR-FirbySusan:AGENT", true); "hs_office_relation#FirstGmbH-with-DEBITOR-FirbySusan:AGENT");
// ... contact role was reassigned: // ... contact role was reassigned:
assertThatDebitorIsNotVisibleForUserWithRole( assertThatDebitorIsNotVisibleForUserWithRole(
@ -362,7 +366,7 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTestWithClean
"hs_office_contact#fifthcontact:ADMIN"); "hs_office_contact#fifthcontact:ADMIN");
assertThatDebitorIsVisibleForUserWithRole( assertThatDebitorIsVisibleForUserWithRole(
result.returnedValue(), result.returnedValue(),
"hs_office_contact#sixthcontact:ADMIN", false); "hs_office_contact#sixthcontact:ADMIN");
// ... bank-account role was reassigned: // ... bank-account role was reassigned:
assertThatDebitorIsNotVisibleForUserWithRole( assertThatDebitorIsNotVisibleForUserWithRole(
@ -370,7 +374,7 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTestWithClean
"hs_office_bankaccount#DE02200505501015871393:ADMIN"); "hs_office_bankaccount#DE02200505501015871393:ADMIN");
assertThatDebitorIsVisibleForUserWithRole( assertThatDebitorIsVisibleForUserWithRole(
result.returnedValue(), result.returnedValue(),
"hs_office_bankaccount#DE02120300000000202051:ADMIN", true); "hs_office_bankaccount#DE02120300000000202051:ADMIN");
} }
@Test @Test
@ -380,27 +384,27 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTestWithClean
final var givenDebitor = givenSomeTemporaryDebitor("Fourth", "fifth contact", null, "fig"); final var givenDebitor = givenSomeTemporaryDebitor("Fourth", "fifth contact", null, "fig");
assertThatDebitorIsVisibleForUserWithRole( assertThatDebitorIsVisibleForUserWithRole(
givenDebitor, givenDebitor,
"hs_office_relation#FourtheG-with-DEBITOR-FourtheG:ADMIN", true); "hs_office_relation#FourtheG-with-DEBITOR-FourtheG:ADMIN");
assertThatDebitorActuallyInDatabase(givenDebitor, true); assertThatDebitorActuallyInDatabase(givenDebitor);
final var givenNewBankAccount = one(bankAccountRepo.findByOptionalHolderLike("first")); final var givenNewBankAccount = one(bankAccountRepo.findByOptionalHolderLike("first"));
// when // when
final var result = jpaAttempt.transacted(() -> { final var result = jpaAttempt.transacted(() -> {
context("superuser-alex@hostsharing.net"); context("superuser-alex@hostsharing.net");
givenDebitor.setRefundBankAccount(givenNewBankAccount); givenDebitor.setRefundBankAccount(givenNewBankAccount);
return toCleanup(debitorRepo.save(givenDebitor)); return toCleanup(debitorRepo.save(givenDebitor).load());
}); });
// then // then
result.assertSuccessful(); result.assertSuccessful();
assertThatDebitorIsVisibleForUserWithRole( assertThatDebitorIsVisibleForUserWithRole(
result.returnedValue(), result.returnedValue(),
"global#global:ADMIN", true); "global#global:ADMIN");
// ... bank-account role was assigned: // ... bank-account role was assigned:
assertThatDebitorIsVisibleForUserWithRole( assertThatDebitorIsVisibleForUserWithRole(
result.returnedValue(), result.returnedValue(),
"hs_office_bankaccount#DE02120300000000202051:ADMIN", true); "hs_office_bankaccount#DE02120300000000202051:ADMIN");
} }
@Test @Test
@ -410,21 +414,21 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTestWithClean
final var givenDebitor = givenSomeTemporaryDebitor("Fourth", "fifth contact", "Fourth", "fih"); final var givenDebitor = givenSomeTemporaryDebitor("Fourth", "fifth contact", "Fourth", "fih");
assertThatDebitorIsVisibleForUserWithRole( assertThatDebitorIsVisibleForUserWithRole(
givenDebitor, givenDebitor,
"hs_office_relation#HostsharingeG-with-PARTNER-FourtheG:AGENT", true); "hs_office_relation#HostsharingeG-with-PARTNER-FourtheG:AGENT");
assertThatDebitorActuallyInDatabase(givenDebitor, true); assertThatDebitorActuallyInDatabase(givenDebitor);
// when // when
final var result = jpaAttempt.transacted(() -> { final var result = jpaAttempt.transacted(() -> {
context("superuser-alex@hostsharing.net"); context("superuser-alex@hostsharing.net");
givenDebitor.setRefundBankAccount(null); givenDebitor.setRefundBankAccount(null);
return toCleanup(debitorRepo.save(givenDebitor)); return toCleanup(debitorRepo.save(givenDebitor).load());
}); });
// then // then
result.assertSuccessful(); result.assertSuccessful();
assertThatDebitorIsVisibleForUserWithRole( assertThatDebitorIsVisibleForUserWithRole(
result.returnedValue(), result.returnedValue(),
"global#global:ADMIN", true); "global#global:ADMIN");
// ... bank-account role was removed from previous bank-account admin: // ... bank-account role was removed from previous bank-account admin:
assertThatDebitorIsNotVisibleForUserWithRole( assertThatDebitorIsNotVisibleForUserWithRole(
@ -439,8 +443,8 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTestWithClean
final var givenDebitor = givenSomeTemporaryDebitor("Fourth", "eighth", "Fourth", "eig"); final var givenDebitor = givenSomeTemporaryDebitor("Fourth", "eighth", "Fourth", "eig");
assertThatDebitorIsVisibleForUserWithRole( assertThatDebitorIsVisibleForUserWithRole(
givenDebitor, givenDebitor,
"hs_office_relation#HostsharingeG-with-PARTNER-FourtheG:AGENT", true); "hs_office_relation#HostsharingeG-with-PARTNER-FourtheG:AGENT");
assertThatDebitorActuallyInDatabase(givenDebitor, true); assertThatDebitorActuallyInDatabase(givenDebitor);
// when // when
final var result = jpaAttempt.transacted(() -> { final var result = jpaAttempt.transacted(() -> {
@ -459,16 +463,17 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTestWithClean
// given // given
context("superuser-alex@hostsharing.net"); context("superuser-alex@hostsharing.net");
final var givenDebitor = givenSomeTemporaryDebitor("Fourth", "ninth", "Fourth", "nin"); final var givenDebitor = givenSomeTemporaryDebitor("Fourth", "ninth", "Fourth", "nin");
assertThatDebitorActuallyInDatabase(givenDebitor, true); assertThatDebitorActuallyInDatabase(givenDebitor);
assertThatDebitorIsVisibleForUserWithRole( assertThatDebitorIsVisibleForUserWithRole(
givenDebitor, givenDebitor,
"hs_office_contact#ninthcontact:ADMIN", false); "hs_office_contact#ninthcontact:ADMIN");
// when // when
final var result = jpaAttempt.transacted(() -> { final var result = jpaAttempt.transacted(() -> {
context("superuser-alex@hostsharing.net", "hs_office_contact#ninthcontact:ADMIN"); context("superuser-alex@hostsharing.net", "hs_office_contact#ninthcontact:ADMIN");
givenDebitor.setVatId("NEW-VAT-ID"); givenDebitor.setVatId("NEW-VAT-ID");
return toCleanup(debitorRepo.save(givenDebitor)); final HsOfficeDebitorEntity entity = debitorRepo.save(givenDebitor);
return toCleanup(entity.load());
}); });
// then // then
@ -478,7 +483,7 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTestWithClean
"Unable to find net.hostsharing.hsadminng.hs.office.bankaccount.HsOfficeBankAccountEntity with id "); "Unable to find net.hostsharing.hsadminng.hs.office.bankaccount.HsOfficeBankAccountEntity with id ");
} }
private void assertThatDebitorActuallyInDatabase(final HsOfficeDebitorEntity saved, final boolean withPartner) { private void assertThatDebitorActuallyInDatabase(final HsOfficeDebitorEntity saved) {
final var found = debitorRepo.findByUuid(saved.getUuid()); final var found = debitorRepo.findByUuid(saved.getUuid());
assertThat(found).isNotEmpty(); assertThat(found).isNotEmpty();
found.ifPresent(foundEntity -> { found.ifPresent(foundEntity -> {
@ -492,11 +497,10 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTestWithClean
private void assertThatDebitorIsVisibleForUserWithRole( private void assertThatDebitorIsVisibleForUserWithRole(
final HsOfficeDebitorEntity entity, final HsOfficeDebitorEntity entity,
final String assumedRoles, final String assumedRoles) {
final boolean withPartner) {
jpaAttempt.transacted(() -> { jpaAttempt.transacted(() -> {
context("superuser-alex@hostsharing.net", assumedRoles); context("superuser-alex@hostsharing.net", assumedRoles);
assertThatDebitorActuallyInDatabase(entity, withPartner); assertThatDebitorActuallyInDatabase(entity);
}).assertSuccessful(); }).assertSuccessful();
} }
@ -605,11 +609,13 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTestWithClean
final String defaultPrefix) { final String defaultPrefix) {
return jpaAttempt.transacted(() -> { return jpaAttempt.transacted(() -> {
context("superuser-alex@hostsharing.net"); context("superuser-alex@hostsharing.net");
final var givenPartnerPerson = one(personRepo.findPersonByOptionalNameLike(partnerName)); final var givenPartner = one(partnerRepo.findPartnerByOptionalNameLike(partnerName));
final var givenPartnerPerson = givenPartner.getPartnerRel().getHolder();
final var givenContact = one(contactRepo.findContactByOptionalCaptionLike(contactCaption)); final var givenContact = one(contactRepo.findContactByOptionalCaptionLike(contactCaption));
final var givenBankAccount = final var givenBankAccount =
bankAccountHolder != null ? one(bankAccountRepo.findByOptionalHolderLike(bankAccountHolder)) : null; bankAccountHolder != null ? one(bankAccountRepo.findByOptionalHolderLike(bankAccountHolder)) : null;
final var newDebitor = HsOfficeDebitorEntity.builder() final var newDebitor = HsOfficeDebitorEntity.builder()
.partnerNumber(givenPartner.getPartnerNumber())
.debitorNumberSuffix("20") .debitorNumberSuffix("20")
.debitorRel(HsOfficeRelationEntity.builder() .debitorRel(HsOfficeRelationEntity.builder()
.type(HsOfficeRelationType.DEBITOR) .type(HsOfficeRelationType.DEBITOR)
@ -622,7 +628,8 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTestWithClean
.billable(true) .billable(true)
.build(); .build();
return toCleanup(debitorRepo.save(newDebitor)); final HsOfficeDebitorEntity entity = debitorRepo.save(newDebitor);
return toCleanup(entity.load());
}).assertSuccessful().returnedValue(); }).assertSuccessful().returnedValue();
} }

View File

@ -4,6 +4,7 @@ import io.hypersistence.utils.hibernate.type.range.Range;
import net.hostsharing.hsadminng.context.Context; import net.hostsharing.hsadminng.context.Context;
import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorRepository; import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorRepository;
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRepository; import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRepository;
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject;
import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup; import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup;
import net.hostsharing.hsadminng.rbac.rbacgrant.RawRbacGrantRepository; import net.hostsharing.hsadminng.rbac.rbacgrant.RawRbacGrantRepository;
import net.hostsharing.hsadminng.rbac.rbacrole.RawRbacRoleRepository; import net.hostsharing.hsadminng.rbac.rbacrole.RawRbacRoleRepository;
@ -75,7 +76,7 @@ class HsOfficeMembershipRepositoryIntegrationTest extends ContextBasedTestWithCl
.validity(Range.closedInfinite(LocalDate.parse("2020-01-01"))) .validity(Range.closedInfinite(LocalDate.parse("2020-01-01")))
.membershipFeeBillable(true) .membershipFeeBillable(true)
.build(); .build();
return toCleanup(membershipRepo.save(newMembership)); return toCleanup(membershipRepo.save(newMembership).load());
}); });
// then // then
@ -202,9 +203,12 @@ class HsOfficeMembershipRepositoryIntegrationTest extends ContextBasedTestWithCl
@Test @Test
public void globalAdmin_canUpdateValidityOfArbitraryMembership() { public void globalAdmin_canUpdateValidityOfArbitraryMembership() {
// given // given
context("superuser-alex@hostsharing.net"); final var givenMembership = jpaAttempt.transacted(() -> {
final var givenMembership = givenSomeTemporaryMembership("First", "11"); context("superuser-alex@hostsharing.net");
assertThatMembershipExistsAndIsAccessibleToCurrentContext(givenMembership); final var tempMembership = givenSomeTemporaryMembership("First", "11");
assertThatMembershipExistsAndIsAccessibleToCurrentContext(tempMembership);
return tempMembership;
}).assertSuccessful().returnedValue();
final var newValidityEnd = LocalDate.now(); final var newValidityEnd = LocalDate.now();
// when // when
@ -214,13 +218,12 @@ class HsOfficeMembershipRepositoryIntegrationTest extends ContextBasedTestWithCl
givenMembership.setValidity(Range.closedOpen( givenMembership.setValidity(Range.closedOpen(
givenMembership.getValidity().lower(), newValidityEnd)); givenMembership.getValidity().lower(), newValidityEnd));
givenMembership.setStatus(HsOfficeMembershipStatus.CANCELLED); givenMembership.setStatus(HsOfficeMembershipStatus.CANCELLED);
return toCleanup(membershipRepo.save(givenMembership)); final HsOfficeMembershipEntity entity = membershipRepo.save(givenMembership);
return toCleanup(entity.load());
}); });
// then // then
result.assertSuccessful(); result.assertSuccessful();
membershipRepo.deleteByUuid(givenMembership.getUuid());
} }
@Test @Test
@ -363,7 +366,8 @@ class HsOfficeMembershipRepositoryIntegrationTest extends ContextBasedTestWithCl
.membershipFeeBillable(true) .membershipFeeBillable(true)
.build(); .build();
return toCleanup(membershipRepo.save(newMembership)); final HsOfficeMembershipEntity entity = membershipRepo.save(newMembership);
return toCleanup(entity.load());
}).assertSuccessful().returnedValue(); }).assertSuccessful().returnedValue();
} }

View File

@ -548,7 +548,7 @@ class HsOfficePartnerControllerAcceptanceTest extends ContextBasedTestWithCleanu
.build()) .build())
.build(); .build();
return partnerRepo.save(newPartner); return partnerRepo.save(newPartner).load();
}).assertSuccessful().returnedValue(); }).assertSuccessful().returnedValue();
} }

View File

@ -473,7 +473,7 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTestWithClean
.anchor(givenMandantorPerson) .anchor(givenMandantorPerson)
.contact(givenContact) .contact(givenContact)
.build(); .build();
relationRepo.save(partnerRel); relationRepo.save(partnerRel).load();
return partnerRel; return partnerRel;
} }

View File

@ -332,7 +332,7 @@ class HsOfficePersonControllerAcceptanceTest extends ContextBasedTestWithCleanup
.givenName("Temp Given Name " + RandomStringUtils.randomAlphabetic(10)) .givenName("Temp Given Name " + RandomStringUtils.randomAlphabetic(10))
.build(); .build();
return personRepo.save(newPerson); return personRepo.save(newPerson).load();
}).assertSuccessful().returnedValue(); }).assertSuccessful().returnedValue();
} }

View File

@ -295,7 +295,8 @@ class HsOfficeRelationRepositoryIntegrationTest extends ContextBasedTestWithClea
final var found = relationRepo.findByUuid(saved.getUuid()); final var found = relationRepo.findByUuid(saved.getUuid());
assertThat(found).isNotEmpty().get() assertThat(found).isNotEmpty().get()
.isNotSameAs(saved) .isNotSameAs(saved)
.usingRecursiveComparison().ignoringFields("version").isEqualTo(saved); .extracting(HsOfficeRelationEntity::toString)
.isEqualTo(saved.toString());
} }
private void assertThatRelationIsVisibleForUserWithRole( private void assertThatRelationIsVisibleForUserWithRole(

View File

@ -497,7 +497,7 @@ class HsOfficeSepaMandateControllerAcceptanceTest extends ContextBasedTestWithCl
return jpaAttempt.transacted(() -> { return jpaAttempt.transacted(() -> {
context.define("superuser-alex@hostsharing.net"); context.define("superuser-alex@hostsharing.net");
final var givenDebitor = debitorRepo.findDebitorByDebitorNumber(debitorNumber).get(0); final var givenDebitor = debitorRepo.findDebitorByDebitorNumber(debitorNumber).get(0);
final var givenPartner = partnerRepo.findPartnerByDebitorUuid(givenDebitor.getUuid()); final var givenPartner = partnerRepo.findPartnerByPartnerNumber(debitorNumber/100);
final var bankAccountHolder = ofNullable(givenPartner.getPartnerRel().getHolder().getTradeName()) final var bankAccountHolder = ofNullable(givenPartner.getPartnerRel().getHolder().getTradeName())
.orElse(givenPartner.getPartnerRel().getHolder().getFamilyName()); .orElse(givenPartner.getPartnerRel().getHolder().getFamilyName());
final var givenBankAccount = bankAccountRepo.findByOptionalHolderLike(bankAccountHolder).get(0); final var givenBankAccount = bankAccountRepo.findByOptionalHolderLike(bankAccountHolder).get(0);