rbac-optimization #80
@ -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.
|
||||||
|
@ -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)
|
||||||
|
@ -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)
|
||||||
|
@ -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)
|
||||||
|
@ -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)
|
||||||
|
@ -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)
|
||||||
|
@ -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)
|
||||||
|
@ -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)
|
||||||
|
@ -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);
|
||||||
|
@ -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)
|
||||||
|
@ -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()));
|
||||||
}
|
}
|
||||||
|
@ -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,
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
@ -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);
|
||||||
|
@ -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())
|
||||||
|
@ -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;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
jpaAttempt.transacted(() -> {
|
||||||
|
context("superuser-alex@hostsharing.net", null);
|
||||||
assertThat(bankAccountRepo.findByUuid(givenBankAccount.getUuid())).isEmpty();
|
assertThat(bankAccountRepo.findByUuid(givenBankAccount.getUuid())).isEmpty();
|
||||||
|
}).assertSuccessful();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -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
|
||||||
|
jpaAttempt.transacted(() -> {
|
||||||
|
context("superuser-alex@hostsharing.net", null);
|
||||||
assertThat(contactRepo.findByUuid(givenContact.getUuid())).isEmpty();
|
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
|
||||||
|
jpaAttempt.transacted(() -> {
|
||||||
|
context("superuser-alex@hostsharing.net", null);
|
||||||
assertThat(contactRepo.findByUuid(givenContact.getUuid())).isEmpty();
|
assertThat(contactRepo.findByUuid(givenContact.getUuid())).isEmpty();
|
||||||
|
}).assertSuccessful();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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,11 +509,12 @@ 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
|
||||||
|
jpaAttempt.transacted(() -> {
|
||||||
context.define("superuser-alex@hostsharing.net");
|
context.define("superuser-alex@hostsharing.net");
|
||||||
assertThat(debitorRepo.findByUuid(givenDebitor.getUuid())).isPresent().get()
|
assertThat(debitorRepo.findByUuid(givenDebitor.getUuid())).isPresent().get()
|
||||||
.matches(debitor -> {
|
.matches(debitor -> {
|
||||||
@ -625,6 +526,7 @@ class HsOfficeDebitorControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
|||||||
assertThat(debitor.isVatBusiness()).isEqualTo(true);
|
assertThat(debitor.isVatBusiness()).isEqualTo(true);
|
||||||
return 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(
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
final var givenMembership = jpaAttempt.transacted(() -> {
|
||||||
context("superuser-alex@hostsharing.net");
|
context("superuser-alex@hostsharing.net");
|
||||||
final var givenMembership = givenSomeTemporaryMembership("First", "11");
|
final var tempMembership = givenSomeTemporaryMembership("First", "11");
|
||||||
assertThatMembershipExistsAndIsAccessibleToCurrentContext(givenMembership);
|
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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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(
|
||||||
|
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user