rename partnerRole -> partnerRel, relationship -> relation and remove rel-Prefix (relAnchor etc.) #23
@ -10,7 +10,7 @@ classDiagram
|
|||||||
|
|
||||||
namespace Partner {
|
namespace Partner {
|
||||||
class partner-MeierGmbH
|
class partner-MeierGmbH
|
||||||
class role-MeierGmbH
|
class rel-MeierGmbH
|
||||||
class personDetails-MeierGmbH
|
class personDetails-MeierGmbH
|
||||||
class contactData-MeierGmbH
|
class contactData-MeierGmbH
|
||||||
class person-MeierGmbH
|
class person-MeierGmbH
|
||||||
@ -19,28 +19,29 @@ classDiagram
|
|||||||
namespace Representatives {
|
namespace Representatives {
|
||||||
class person-FrankMeier
|
class person-FrankMeier
|
||||||
class contactData-FrankMeier
|
class contactData-FrankMeier
|
||||||
class role-MeierGmbH-FrankMeier
|
class rel-MeierGmbH-FrankMeier
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Debitors {
|
namespace Debitors {
|
||||||
class debitor-MeierGmbH
|
class debitor-MeierGmbH
|
||||||
class contactData-MeierGmbH-Buha
|
class contactData-MeierGmbH-Buha
|
||||||
class role-MeierGmbH-Buha
|
class rel-MeierGmbH-Buha
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Operations {
|
namespace Operations {
|
||||||
class person-SabineMeier
|
class person-SabineMeier
|
||||||
class contactData-SabineMeier
|
class contactData-SabineMeier
|
||||||
class role-MeierGmbH-SabineMeier
|
class rel-MeierGmbH-SabineMeier
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Enums {
|
namespace Enums {
|
||||||
|
|
||||||
class RoleType {
|
class RelationType {
|
||||||
<<enumeration>>
|
<<enumeration>>
|
||||||
UNKNOWN
|
UNKNOWN
|
||||||
|
PARTNER
|
||||||
|
DEBITOR
|
||||||
REPRESENTATIVE
|
REPRESENTATIVE
|
||||||
ACCOUNTING
|
|
||||||
OPERATIONS
|
OPERATIONS
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,9 +65,9 @@ classDiagram
|
|||||||
|
|
||||||
class partner-MeierGmbH {
|
class partner-MeierGmbH {
|
||||||
+Numeric partnerNumber: 12345
|
+Numeric partnerNumber: 12345
|
||||||
+Role partnerRole
|
+Relation partnerRel
|
||||||
}
|
}
|
||||||
partner-MeierGmbH *-- role-MeierGmbH
|
partner-MeierGmbH *-- rel-MeierGmbH
|
||||||
|
|
||||||
class person-MeierGmbH {
|
class person-MeierGmbH {
|
||||||
+personType: LEGAL
|
+personType: LEGAL
|
||||||
@ -90,22 +91,22 @@ classDiagram
|
|||||||
+emailAddresses: office@meier-gmbh.de
|
+emailAddresses: office@meier-gmbh.de
|
||||||
}
|
}
|
||||||
|
|
||||||
class role-MeierGmbH {
|
class rel-MeierGmbH {
|
||||||
+RoleType RoleType PARTNER
|
+RelationType type PARTNER
|
||||||
+Person anchor
|
+Person anchor
|
||||||
+Person holder
|
+Person holder
|
||||||
+Contact roleContact
|
+Contact contact
|
||||||
}
|
}
|
||||||
role-MeierGmbH o-- person-HostsharingEG : anchor
|
rel-MeierGmbH o-- person-HostsharingEG : anchor
|
||||||
role-MeierGmbH o-- person-MeierGmbH : holder
|
rel-MeierGmbH o-- person-MeierGmbH : holder
|
||||||
role-MeierGmbH o-- contactData-MeierGmbH
|
rel-MeierGmbH o-- contactData-MeierGmbH
|
||||||
|
|
||||||
%% --- Debitors ---
|
%% --- Debitors ---
|
||||||
|
|
||||||
class debitor-MeierGmbH {
|
class debitor-MeierGmbH {
|
||||||
+Partner partner
|
+Partner partner
|
||||||
+Numeric[2] debitorNumberSuffix: 00
|
+Numeric[2] debitorNumberSuffix: 00
|
||||||
+Role billingRole
|
+Relation debitorRel
|
||||||
+boolean billable: true
|
+boolean billable: true
|
||||||
+String vatId: ID123456789
|
+String vatId: ID123456789
|
||||||
+String vatCountryCode: DE
|
+String vatCountryCode: DE
|
||||||
@ -115,7 +116,7 @@ classDiagram
|
|||||||
+String defaultPrefix: mei
|
+String defaultPrefix: mei
|
||||||
}
|
}
|
||||||
debitor-MeierGmbH o-- partner-MeierGmbH
|
debitor-MeierGmbH o-- partner-MeierGmbH
|
||||||
debitor-MeierGmbH *-- role-MeierGmbH-Buha
|
debitor-MeierGmbH *-- rel-MeierGmbH-Buha
|
||||||
|
|
||||||
class contactData-MeierGmbH-Buha {
|
class contactData-MeierGmbH-Buha {
|
||||||
+postalAddress: Hauptstraße 5, 22345 Hamburg
|
+postalAddress: Hauptstraße 5, 22345 Hamburg
|
||||||
@ -123,15 +124,15 @@ classDiagram
|
|||||||
+emailAddresses: buha@meier-gmbh.de
|
+emailAddresses: buha@meier-gmbh.de
|
||||||
}
|
}
|
||||||
|
|
||||||
class role-MeierGmbH-Buha {
|
class rel-MeierGmbH-Buha {
|
||||||
+RoleType RoleType ACCOUNTING
|
+RelationType type DEBITOR
|
||||||
+Person anchor
|
+Person anchor
|
||||||
+Person holder
|
+Person holder
|
||||||
+Contact roleContact
|
+Contact contact
|
||||||
}
|
}
|
||||||
role-MeierGmbH-Buha o-- person-MeierGmbH : anchor
|
rel-MeierGmbH-Buha o-- person-MeierGmbH : anchor
|
||||||
role-MeierGmbH-Buha o-- person-MeierGmbH : holder
|
rel-MeierGmbH-Buha o-- person-MeierGmbH : holder
|
||||||
role-MeierGmbH-Buha o-- contactData-MeierGmbH-Buha
|
rel-MeierGmbH-Buha o-- contactData-MeierGmbH-Buha
|
||||||
|
|
||||||
%% --- Representatives ---
|
%% --- Representatives ---
|
||||||
|
|
||||||
@ -148,15 +149,15 @@ classDiagram
|
|||||||
+emailAddresses: frank.meier@meier-gmbh.de
|
+emailAddresses: frank.meier@meier-gmbh.de
|
||||||
}
|
}
|
||||||
|
|
||||||
class role-MeierGmbH-FrankMeier {
|
class rel-MeierGmbH-FrankMeier {
|
||||||
+RoleType RoleType REPRESENTATIVE
|
+RelationType type REPRESENTATIVE
|
||||||
+Person anchor
|
+Person anchor
|
||||||
+Person holder
|
+Person holder
|
||||||
+Contact roleContact
|
+Contact contact
|
||||||
}
|
}
|
||||||
role-MeierGmbH-FrankMeier o-- person-MeierGmbH : anchor
|
rel-MeierGmbH-FrankMeier o-- person-MeierGmbH : anchor
|
||||||
role-MeierGmbH-FrankMeier o-- person-FrankMeier : holder
|
rel-MeierGmbH-FrankMeier o-- person-FrankMeier : holder
|
||||||
role-MeierGmbH-FrankMeier o-- contactData-FrankMeier
|
rel-MeierGmbH-FrankMeier o-- contactData-FrankMeier
|
||||||
|
|
||||||
%% --- Operations ---
|
%% --- Operations ---
|
||||||
|
|
||||||
@ -173,14 +174,14 @@ classDiagram
|
|||||||
+emailAddresses: sabine.meier@meier-gmbh.de
|
+emailAddresses: sabine.meier@meier-gmbh.de
|
||||||
}
|
}
|
||||||
|
|
||||||
class role-MeierGmbH-SabineMeier {
|
class rel-MeierGmbH-SabineMeier {
|
||||||
+RoleType RoleType OPERATIONAL
|
+RelationType type OPERATIONAL
|
||||||
+Person anchor
|
+Person anchor
|
||||||
+Person holder
|
+Person holder
|
||||||
+Contact roleContact
|
+Contact contact
|
||||||
}
|
}
|
||||||
role-MeierGmbH-SabineMeier o-- person-MeierGmbH : anchor
|
rel-MeierGmbH-SabineMeier o-- person-MeierGmbH : anchor
|
||||||
role-MeierGmbH-SabineMeier o-- person-SabineMeier : holder
|
rel-MeierGmbH-SabineMeier o-- person-SabineMeier : holder
|
||||||
role-MeierGmbH-SabineMeier o-- contactData-SabineMeier
|
rel-MeierGmbH-SabineMeier o-- contactData-SabineMeier
|
||||||
|
|
||||||
```
|
```
|
||||||
|
@ -5,7 +5,7 @@ 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.contact.HsOfficeContactEntity;
|
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactEntity;
|
||||||
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity;
|
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity;
|
||||||
import net.hostsharing.hsadminng.hs.office.relationship.HsOfficeRelationshipEntity;
|
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationEntity;
|
||||||
import net.hostsharing.hsadminng.persistence.HasUuid;
|
import net.hostsharing.hsadminng.persistence.HasUuid;
|
||||||
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;
|
||||||
@ -113,10 +113,10 @@ public class HsOfficeDebitorEntity implements HasUuid, Stringifyable {
|
|||||||
SELECT debitor.uuid,
|
SELECT debitor.uuid,
|
||||||
'D-' || (SELECT partner.partnerNumber
|
'D-' || (SELECT partner.partnerNumber
|
||||||
FROM hs_office_partner partner
|
FROM hs_office_partner partner
|
||||||
JOIN hs_office_relationship partnerRel
|
JOIN hs_office_relation partnerRel
|
||||||
ON partnerRel.uuid = partner.partnerRoleUUid AND partnerRel.relType = 'PARTNER'
|
ON partnerRel.uuid = partner.partnerRelUUid AND partnerRel.type = 'PARTNER'
|
||||||
JOIN hs_office_relationship debitorRel
|
JOIN hs_office_relation debitorRel
|
||||||
ON debitorRel.relAnchorUuid = partnerRel.relHolderUuid AND partnerRel.relType = 'DEBITOR'
|
ON debitorRel.anchorUuid = partnerRel.holderUuid AND partnerRel.type = 'DEBITOR'
|
||||||
WHERE debitorRel.uuid = debitor.debitorRelUuid)
|
WHERE debitorRel.uuid = debitor.debitorRelUuid)
|
||||||
|| to_char(debitorNumberSuffix, 'fm00')
|
|| to_char(debitorNumberSuffix, 'fm00')
|
||||||
from hs_office_debitor as debitor
|
from hs_office_debitor as debitor
|
||||||
@ -133,11 +133,11 @@ public class HsOfficeDebitorEntity implements HasUuid, Stringifyable {
|
|||||||
"defaultPrefix" /* TODO: do we want that updatable? */)
|
"defaultPrefix" /* TODO: do we want that updatable? */)
|
||||||
.createPermission(custom("new-debitor")).grantedTo("global", ADMIN)
|
.createPermission(custom("new-debitor")).grantedTo("global", ADMIN)
|
||||||
|
|
||||||
.importRootEntityAliasProxy("debitorRel", HsOfficeRelationshipEntity.class,
|
.importRootEntityAliasProxy("debitorRel", HsOfficeRelationEntity.class,
|
||||||
fetchedBySql("""
|
fetchedBySql("""
|
||||||
SELECT *
|
SELECT *
|
||||||
FROM hs_office_relationship AS r
|
FROM hs_office_relation AS r
|
||||||
WHERE r.relType = 'DEBITOR' AND r.relHolderUuid = ${REF}.debitorRelUuid
|
WHERE r.type = 'DEBITOR' AND r.holderUuid = ${REF}.debitorRelUuid
|
||||||
"""),
|
"""),
|
||||||
dependsOnColumn("debitorRelUuid"))
|
dependsOnColumn("debitorRelUuid"))
|
||||||
.createPermission(DELETE).grantedTo("debitorRel", OWNER)
|
.createPermission(DELETE).grantedTo("debitorRel", OWNER)
|
||||||
@ -147,18 +147,18 @@ public class HsOfficeDebitorEntity implements HasUuid, Stringifyable {
|
|||||||
.importEntityAlias("refundBankAccount", HsOfficeBankAccountEntity.class,
|
.importEntityAlias("refundBankAccount", HsOfficeBankAccountEntity.class,
|
||||||
dependsOnColumn("refundBankAccountUuid"), fetchedBySql("""
|
dependsOnColumn("refundBankAccountUuid"), fetchedBySql("""
|
||||||
SELECT *
|
SELECT *
|
||||||
FROM hs_office_relationship AS r
|
FROM hs_office_relation AS r
|
||||||
WHERE r.relType = 'DEBITOR' AND r.relHolderUuid = ${REF}.debitorRelUuid
|
WHERE r.type = 'DEBITOR' AND r.holderUuid = ${REF}.debitorRelUuid
|
||||||
""")
|
""")
|
||||||
)
|
)
|
||||||
.toRole("refundBankAccount", ADMIN).grantRole("debitorRel", AGENT)
|
.toRole("refundBankAccount", ADMIN).grantRole("debitorRel", AGENT)
|
||||||
.toRole("debitorRel", AGENT).grantRole("refundBankAccount", REFERRER)
|
.toRole("debitorRel", AGENT).grantRole("refundBankAccount", REFERRER)
|
||||||
|
|
||||||
.importEntityAlias("partnerRel", HsOfficeRelationshipEntity.class,
|
.importEntityAlias("partnerRel", HsOfficeRelationEntity.class,
|
||||||
dependsOnColumn("partnerRelUuid"), fetchedBySql("""
|
dependsOnColumn("partnerRelUuid"), fetchedBySql("""
|
||||||
SELECT *
|
SELECT *
|
||||||
FROM hs_office_relationship AS partnerRel
|
FROM hs_office_relation AS partnerRel
|
||||||
WHERE ${debitorRel}.relAnchorUuid = partnerRel.relHolderUuid
|
WHERE ${debitorRel}.anchorUuid = partnerRel.holderUuid
|
||||||
""")
|
""")
|
||||||
)
|
)
|
||||||
.toRole("partnerRel", ADMIN).grantRole("debitorRel", ADMIN)
|
.toRole("partnerRel", ADMIN).grantRole("debitorRel", ADMIN)
|
||||||
|
@ -7,11 +7,11 @@ import net.hostsharing.hsadminng.hs.office.generated.api.v1.api.HsOfficePartners
|
|||||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficePartnerInsertResource;
|
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficePartnerInsertResource;
|
||||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficePartnerPatchResource;
|
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficePartnerPatchResource;
|
||||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficePartnerResource;
|
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficePartnerResource;
|
||||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficePartnerRoleInsertResource;
|
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficePartnerRelInsertResource;
|
||||||
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity;
|
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity;
|
||||||
import net.hostsharing.hsadminng.hs.office.relationship.HsOfficeRelationshipEntity;
|
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationEntity;
|
||||||
import net.hostsharing.hsadminng.hs.office.relationship.HsOfficeRelationshipRepository;
|
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRepository;
|
||||||
import net.hostsharing.hsadminng.hs.office.relationship.HsOfficeRelationshipType;
|
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationType;
|
||||||
import net.hostsharing.hsadminng.mapper.Mapper;
|
import net.hostsharing.hsadminng.mapper.Mapper;
|
||||||
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject;
|
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
@ -40,7 +40,7 @@ public class HsOfficePartnerController implements HsOfficePartnersApi {
|
|||||||
private HsOfficePartnerRepository partnerRepo;
|
private HsOfficePartnerRepository partnerRepo;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private HsOfficeRelationshipRepository relationshipRepo;
|
private HsOfficeRelationRepository relationRepo;
|
||||||
|
|
||||||
@PersistenceContext
|
@PersistenceContext
|
||||||
private EntityManager em;
|
private EntityManager em;
|
||||||
@ -112,7 +112,7 @@ public class HsOfficePartnerController implements HsOfficePartnersApi {
|
|||||||
|
|
||||||
if (partnerRepo.deleteByUuid(partnerUuid) != 1 ||
|
if (partnerRepo.deleteByUuid(partnerUuid) != 1 ||
|
||||||
// TODO: move to after delete trigger in partner
|
// TODO: move to after delete trigger in partner
|
||||||
relationshipRepo.deleteByUuid(partnerToDelete.get().getPartnerRole().getUuid()) != 1 ) {
|
relationRepo.deleteByUuid(partnerToDelete.get().getPartnerRel().getUuid()) != 1 ) {
|
||||||
return ResponseEntity.status(HttpStatus.FORBIDDEN).build();
|
return ResponseEntity.status(HttpStatus.FORBIDDEN).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -141,18 +141,18 @@ public class HsOfficePartnerController implements HsOfficePartnersApi {
|
|||||||
private HsOfficePartnerEntity createPartnerEntity(final HsOfficePartnerInsertResource body) {
|
private HsOfficePartnerEntity createPartnerEntity(final HsOfficePartnerInsertResource body) {
|
||||||
final var entityToSave = new HsOfficePartnerEntity();
|
final var entityToSave = new HsOfficePartnerEntity();
|
||||||
entityToSave.setPartnerNumber(body.getPartnerNumber());
|
entityToSave.setPartnerNumber(body.getPartnerNumber());
|
||||||
entityToSave.setPartnerRole(persistPartnerRole(body.getPartnerRole()));
|
entityToSave.setPartnerRel(persistPartnerRel(body.getPartnerRel()));
|
||||||
entityToSave.setContact(ref(HsOfficeContactEntity.class, body.getContactUuid()));
|
entityToSave.setContact(ref(HsOfficeContactEntity.class, body.getContactUuid()));
|
||||||
entityToSave.setPerson(ref(HsOfficePersonEntity.class, body.getPersonUuid()));
|
entityToSave.setPerson(ref(HsOfficePersonEntity.class, body.getPersonUuid()));
|
||||||
entityToSave.setDetails(mapper.map(body.getDetails(), HsOfficePartnerDetailsEntity.class));
|
entityToSave.setDetails(mapper.map(body.getDetails(), HsOfficePartnerDetailsEntity.class));
|
||||||
return entityToSave;
|
return entityToSave;
|
||||||
}
|
}
|
||||||
|
|
||||||
private HsOfficeRelationshipEntity persistPartnerRole(final HsOfficePartnerRoleInsertResource resource) {
|
private HsOfficeRelationEntity persistPartnerRel(final HsOfficePartnerRelInsertResource resource) {
|
||||||
final var entity = new HsOfficeRelationshipEntity();
|
final var entity = new HsOfficeRelationEntity();
|
||||||
entity.setRelType(HsOfficeRelationshipType.PARTNER);
|
entity.setType(HsOfficeRelationType.PARTNER);
|
||||||
entity.setRelAnchor(ref(HsOfficePersonEntity.class, resource.getRelAnchorUuid()));
|
entity.setAnchor(ref(HsOfficePersonEntity.class, resource.getAnchorUuid()));
|
||||||
entity.setRelHolder(ref(HsOfficePersonEntity.class, resource.getRelHolderUuid()));
|
entity.setHolder(ref(HsOfficePersonEntity.class, resource.getHolderUuid()));
|
||||||
entity.setContact(ref(HsOfficeContactEntity.class, resource.getContactUuid()));
|
entity.setContact(ref(HsOfficeContactEntity.class, resource.getContactUuid()));
|
||||||
em.persist(entity);
|
em.persist(entity);
|
||||||
return entity;
|
return entity;
|
||||||
|
@ -2,7 +2,7 @@ package net.hostsharing.hsadminng.hs.office.partner;
|
|||||||
|
|
||||||
import lombok.*;
|
import lombok.*;
|
||||||
import net.hostsharing.hsadminng.errors.DisplayName;
|
import net.hostsharing.hsadminng.errors.DisplayName;
|
||||||
import net.hostsharing.hsadminng.hs.office.relationship.HsOfficeRelationshipEntity;
|
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationEntity;
|
||||||
import net.hostsharing.hsadminng.persistence.HasUuid;
|
import net.hostsharing.hsadminng.persistence.HasUuid;
|
||||||
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;
|
||||||
@ -86,15 +86,15 @@ public class HsOfficePartnerDetailsEntity implements HasUuid, Stringifyable {
|
|||||||
"dateOfDeath")
|
"dateOfDeath")
|
||||||
.createPermission(custom("new-partner-details")).grantedTo("global", ADMIN)
|
.createPermission(custom("new-partner-details")).grantedTo("global", ADMIN)
|
||||||
|
|
||||||
.importRootEntityAliasProxy("partnerRel", HsOfficeRelationshipEntity.class,
|
.importRootEntityAliasProxy("partnerRel", HsOfficeRelationEntity.class,
|
||||||
fetchedBySql("""
|
fetchedBySql("""
|
||||||
SELECT partnerRel.*
|
SELECT partnerRel.*
|
||||||
FROM hs_office_relationship AS partnerRel
|
FROM hs_office_relation AS partnerRel
|
||||||
JOIN hs_office_partner AS partner
|
JOIN hs_office_partner AS partner
|
||||||
ON partner.detailsUuid = ${ref}.uuid
|
ON partner.detailsUuid = ${ref}.uuid
|
||||||
WHERE partnerRel.uuid = partner.partnerRoleUuid
|
WHERE partnerRel.uuid = partner.partnerRelUuid
|
||||||
"""),
|
"""),
|
||||||
dependsOnColumn("partnerRoleUuid"))
|
dependsOnColumn("partnerRelUuid"))
|
||||||
|
|
||||||
// The grants are defined in HsOfficePartnerEntity.rbac()
|
// The grants are defined in HsOfficePartnerEntity.rbac()
|
||||||
// because they have to be changed when its partnerRel changes,
|
// because they have to be changed when its partnerRel changes,
|
||||||
|
@ -5,7 +5,7 @@ import net.hostsharing.hsadminng.errors.DisplayName;
|
|||||||
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactEntity;
|
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactEntity;
|
||||||
import net.hostsharing.hsadminng.persistence.HasUuid;
|
import net.hostsharing.hsadminng.persistence.HasUuid;
|
||||||
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity;
|
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity;
|
||||||
import net.hostsharing.hsadminng.hs.office.relationship.HsOfficeRelationshipEntity;
|
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationEntity;
|
||||||
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;
|
||||||
@ -50,15 +50,15 @@ public class HsOfficePartnerEntity implements Stringifyable, HasUuid {
|
|||||||
private Integer partnerNumber;
|
private Integer partnerNumber;
|
||||||
|
|
||||||
@ManyToOne
|
@ManyToOne
|
||||||
@JoinColumn(name = "partnerroleuuid", nullable = false)
|
@JoinColumn(name = "partnerreluuid", nullable = false)
|
||||||
private HsOfficeRelationshipEntity partnerRole;
|
private HsOfficeRelationEntity partnerRel;
|
||||||
|
|
||||||
// TODO: remove, is replaced by partnerRole
|
// TODO: remove, is replaced by partnerRel
|
||||||
@ManyToOne
|
@ManyToOne
|
||||||
@JoinColumn(name = "personuuid", nullable = false)
|
@JoinColumn(name = "personuuid", nullable = false)
|
||||||
private HsOfficePersonEntity person;
|
private HsOfficePersonEntity person;
|
||||||
|
|
||||||
// TODO: remove, is replaced by partnerRole
|
// TODO: remove, is replaced by partnerRel
|
||||||
@ManyToOne
|
@ManyToOne
|
||||||
@JoinColumn(name = "contactuuid", nullable = false)
|
@JoinColumn(name = "contactuuid", nullable = false)
|
||||||
private HsOfficeContactEntity contact;
|
private HsOfficeContactEntity contact;
|
||||||
@ -87,13 +87,13 @@ public class HsOfficePartnerEntity implements Stringifyable, HasUuid {
|
|||||||
FROM hs_office_partner AS partner
|
FROM hs_office_partner AS partner
|
||||||
"""))
|
"""))
|
||||||
.withUpdatableColumns(
|
.withUpdatableColumns(
|
||||||
"partnerRoleUuid",
|
"partnerRelUuid",
|
||||||
"personUuid",
|
"personUuid",
|
||||||
"contactUuid")
|
"contactUuid")
|
||||||
.createPermission(custom("new-partner")).grantedTo("global", ADMIN)
|
.createPermission(custom("new-partner")).grantedTo("global", ADMIN)
|
||||||
|
|
||||||
.importRootEntityAliasProxy("partnerRel", HsOfficeRelationshipEntity.class,
|
.importRootEntityAliasProxy("partnerRel", HsOfficeRelationEntity.class,
|
||||||
fetchedBySql("SELECT * FROM hs_office_relationship AS r WHERE r.uuid = ${ref}.partnerRoleUuid"),
|
fetchedBySql("SELECT * FROM hs_office_relation AS r WHERE r.uuid = ${ref}.partnerRelUuid"),
|
||||||
dependsOnColumn("partnerRelUuid"))
|
dependsOnColumn("partnerRelUuid"))
|
||||||
.createPermission(DELETE).grantedTo("partnerRel", ADMIN)
|
.createPermission(DELETE).grantedTo("partnerRel", ADMIN)
|
||||||
.createPermission(UPDATE).grantedTo("partnerRel", AGENT)
|
.createPermission(UPDATE).grantedTo("partnerRel", AGENT)
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
package net.hostsharing.hsadminng.hs.office.relationship;
|
package net.hostsharing.hsadminng.hs.office.relation;
|
||||||
|
|
||||||
import net.hostsharing.hsadminng.context.Context;
|
import net.hostsharing.hsadminng.context.Context;
|
||||||
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRepository;
|
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRepository;
|
||||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.api.HsOfficeRelationshipsApi;
|
import net.hostsharing.hsadminng.hs.office.generated.api.v1.api.HsOfficeRelationsApi;
|
||||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.*;
|
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.*;
|
||||||
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRepository;
|
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRepository;
|
||||||
import net.hostsharing.hsadminng.mapper.Mapper;
|
import net.hostsharing.hsadminng.mapper.Mapper;
|
||||||
@ -22,7 +22,7 @@ import java.util.function.BiConsumer;
|
|||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
|
|
||||||
public class HsOfficeRelationshipController implements HsOfficeRelationshipsApi {
|
public class HsOfficeRelationController implements HsOfficeRelationsApi {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private Context context;
|
private Context context;
|
||||||
@ -31,10 +31,10 @@ public class HsOfficeRelationshipController implements HsOfficeRelationshipsApi
|
|||||||
private Mapper mapper;
|
private Mapper mapper;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private HsOfficeRelationshipRepository relationshipRepo;
|
private HsOfficeRelationRepository relationRepo;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private HsOfficePersonRepository relHolderRepo;
|
private HsOfficePersonRepository holderRepo;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private HsOfficeContactRepository contactRepo;
|
private HsOfficeContactRepository contactRepo;
|
||||||
@ -44,79 +44,79 @@ public class HsOfficeRelationshipController implements HsOfficeRelationshipsApi
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(readOnly = true)
|
@Transactional(readOnly = true)
|
||||||
public ResponseEntity<List<HsOfficeRelationshipResource>> listRelationships(
|
public ResponseEntity<List<HsOfficeRelationResource>> listRelations(
|
||||||
final String currentUser,
|
final String currentUser,
|
||||||
final String assumedRoles,
|
final String assumedRoles,
|
||||||
final UUID personUuid,
|
final UUID personUuid,
|
||||||
final HsOfficeRelationshipTypeResource relationshipType) {
|
final HsOfficeRelationTypeResource relationType) {
|
||||||
context.define(currentUser, assumedRoles);
|
context.define(currentUser, assumedRoles);
|
||||||
|
|
||||||
final var entities = relationshipRepo.findRelationshipRelatedToPersonUuidAndRelationshipType(personUuid,
|
final var entities = relationRepo.findRelationRelatedToPersonUuidAndRelationType(personUuid,
|
||||||
mapper.map(relationshipType, HsOfficeRelationshipType.class));
|
mapper.map(relationType, HsOfficeRelationType.class));
|
||||||
|
|
||||||
final var resources = mapper.mapList(entities, HsOfficeRelationshipResource.class,
|
final var resources = mapper.mapList(entities, HsOfficeRelationResource.class,
|
||||||
RELATIONSHIP_ENTITY_TO_RESOURCE_POSTMAPPER);
|
RELATION_ENTITY_TO_RESOURCE_POSTMAPPER);
|
||||||
return ResponseEntity.ok(resources);
|
return ResponseEntity.ok(resources);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional
|
@Transactional
|
||||||
public ResponseEntity<HsOfficeRelationshipResource> addRelationship(
|
public ResponseEntity<HsOfficeRelationResource> addRelation(
|
||||||
final String currentUser,
|
final String currentUser,
|
||||||
final String assumedRoles,
|
final String assumedRoles,
|
||||||
final HsOfficeRelationshipInsertResource body) {
|
final HsOfficeRelationInsertResource body) {
|
||||||
|
|
||||||
context.define(currentUser, assumedRoles);
|
context.define(currentUser, assumedRoles);
|
||||||
|
|
||||||
final var entityToSave = new HsOfficeRelationshipEntity();
|
final var entityToSave = new HsOfficeRelationEntity();
|
||||||
entityToSave.setRelType(HsOfficeRelationshipType.valueOf(body.getRelType()));
|
entityToSave.setType(HsOfficeRelationType.valueOf(body.getType()));
|
||||||
entityToSave.setRelAnchor(relHolderRepo.findByUuid(body.getRelAnchorUuid()).orElseThrow(
|
entityToSave.setAnchor(holderRepo.findByUuid(body.getAnchorUuid()).orElseThrow(
|
||||||
() -> new NoSuchElementException("cannot find relAnchorUuid " + body.getRelAnchorUuid())
|
() -> new NoSuchElementException("cannot find anchorUuid " + body.getAnchorUuid())
|
||||||
));
|
));
|
||||||
entityToSave.setRelHolder(relHolderRepo.findByUuid(body.getRelHolderUuid()).orElseThrow(
|
entityToSave.setHolder(holderRepo.findByUuid(body.getHolderUuid()).orElseThrow(
|
||||||
() -> new NoSuchElementException("cannot find relHolderUuid " + body.getRelHolderUuid())
|
() -> new NoSuchElementException("cannot find holderUuid " + body.getHolderUuid())
|
||||||
));
|
));
|
||||||
entityToSave.setContact(contactRepo.findByUuid(body.getContactUuid()).orElseThrow(
|
entityToSave.setContact(contactRepo.findByUuid(body.getContactUuid()).orElseThrow(
|
||||||
() -> new NoSuchElementException("cannot find contactUuid " + body.getContactUuid())
|
() -> new NoSuchElementException("cannot find contactUuid " + body.getContactUuid())
|
||||||
));
|
));
|
||||||
|
|
||||||
final var saved = relationshipRepo.save(entityToSave);
|
final var saved = relationRepo.save(entityToSave);
|
||||||
|
|
||||||
final var uri =
|
final var uri =
|
||||||
MvcUriComponentsBuilder.fromController(getClass())
|
MvcUriComponentsBuilder.fromController(getClass())
|
||||||
.path("/api/hs/office/relationships/{id}")
|
.path("/api/hs/office/relations/{id}")
|
||||||
.buildAndExpand(saved.getUuid())
|
.buildAndExpand(saved.getUuid())
|
||||||
.toUri();
|
.toUri();
|
||||||
final var mapped = mapper.map(saved, HsOfficeRelationshipResource.class,
|
final var mapped = mapper.map(saved, HsOfficeRelationResource.class,
|
||||||
RELATIONSHIP_ENTITY_TO_RESOURCE_POSTMAPPER);
|
RELATION_ENTITY_TO_RESOURCE_POSTMAPPER);
|
||||||
return ResponseEntity.created(uri).body(mapped);
|
return ResponseEntity.created(uri).body(mapped);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(readOnly = true)
|
@Transactional(readOnly = true)
|
||||||
public ResponseEntity<HsOfficeRelationshipResource> getRelationshipByUuid(
|
public ResponseEntity<HsOfficeRelationResource> getRelationByUuid(
|
||||||
final String currentUser,
|
final String currentUser,
|
||||||
final String assumedRoles,
|
final String assumedRoles,
|
||||||
final UUID relationshipUuid) {
|
final UUID relationUuid) {
|
||||||
|
|
||||||
context.define(currentUser, assumedRoles);
|
context.define(currentUser, assumedRoles);
|
||||||
|
|
||||||
final var result = relationshipRepo.findByUuid(relationshipUuid);
|
final var result = relationRepo.findByUuid(relationUuid);
|
||||||
if (result.isEmpty()) {
|
if (result.isEmpty()) {
|
||||||
return ResponseEntity.notFound().build();
|
return ResponseEntity.notFound().build();
|
||||||
}
|
}
|
||||||
return ResponseEntity.ok(mapper.map(result.get(), HsOfficeRelationshipResource.class, RELATIONSHIP_ENTITY_TO_RESOURCE_POSTMAPPER));
|
return ResponseEntity.ok(mapper.map(result.get(), HsOfficeRelationResource.class, RELATION_ENTITY_TO_RESOURCE_POSTMAPPER));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional
|
@Transactional
|
||||||
public ResponseEntity<Void> deleteRelationshipByUuid(
|
public ResponseEntity<Void> deleteRelationByUuid(
|
||||||
final String currentUser,
|
final String currentUser,
|
||||||
final String assumedRoles,
|
final String assumedRoles,
|
||||||
final UUID relationshipUuid) {
|
final UUID relationUuid) {
|
||||||
context.define(currentUser, assumedRoles);
|
context.define(currentUser, assumedRoles);
|
||||||
|
|
||||||
final var result = relationshipRepo.deleteByUuid(relationshipUuid);
|
final var result = relationRepo.deleteByUuid(relationUuid);
|
||||||
if (result == 0) {
|
if (result == 0) {
|
||||||
return ResponseEntity.notFound().build();
|
return ResponseEntity.notFound().build();
|
||||||
}
|
}
|
||||||
@ -126,27 +126,27 @@ public class HsOfficeRelationshipController implements HsOfficeRelationshipsApi
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional
|
@Transactional
|
||||||
public ResponseEntity<HsOfficeRelationshipResource> patchRelationship(
|
public ResponseEntity<HsOfficeRelationResource> patchRelation(
|
||||||
final String currentUser,
|
final String currentUser,
|
||||||
final String assumedRoles,
|
final String assumedRoles,
|
||||||
final UUID relationshipUuid,
|
final UUID relationUuid,
|
||||||
final HsOfficeRelationshipPatchResource body) {
|
final HsOfficeRelationPatchResource body) {
|
||||||
|
|
||||||
context.define(currentUser, assumedRoles);
|
context.define(currentUser, assumedRoles);
|
||||||
|
|
||||||
final var current = relationshipRepo.findByUuid(relationshipUuid).orElseThrow();
|
final var current = relationRepo.findByUuid(relationUuid).orElseThrow();
|
||||||
|
|
||||||
new HsOfficeRelationshipEntityPatcher(em, current).apply(body);
|
new HsOfficeRelationEntityPatcher(em, current).apply(body);
|
||||||
|
|
||||||
final var saved = relationshipRepo.save(current);
|
final var saved = relationRepo.save(current);
|
||||||
final var mapped = mapper.map(saved, HsOfficeRelationshipResource.class);
|
final var mapped = mapper.map(saved, HsOfficeRelationResource.class);
|
||||||
return ResponseEntity.ok(mapped);
|
return ResponseEntity.ok(mapped);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
final BiConsumer<HsOfficeRelationshipEntity, HsOfficeRelationshipResource> RELATIONSHIP_ENTITY_TO_RESOURCE_POSTMAPPER = (entity, resource) -> {
|
final BiConsumer<HsOfficeRelationEntity, HsOfficeRelationResource> RELATION_ENTITY_TO_RESOURCE_POSTMAPPER = (entity, resource) -> {
|
||||||
resource.setRelAnchor(mapper.map(entity.getRelAnchor(), HsOfficePersonResource.class));
|
resource.setAnchor(mapper.map(entity.getAnchor(), HsOfficePersonResource.class));
|
||||||
resource.setRelHolder(mapper.map(entity.getRelHolder(), HsOfficePersonResource.class));
|
resource.setHolder(mapper.map(entity.getHolder(), HsOfficePersonResource.class));
|
||||||
resource.setContact(mapper.map(entity.getContact(), HsOfficeContactResource.class));
|
resource.setContact(mapper.map(entity.getContact(), HsOfficeContactResource.class));
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package net.hostsharing.hsadminng.hs.office.relationship;
|
package net.hostsharing.hsadminng.hs.office.relation;
|
||||||
|
|
||||||
import lombok.*;
|
import lombok.*;
|
||||||
import lombok.experimental.FieldNameConstants;
|
import lombok.experimental.FieldNameConstants;
|
||||||
@ -24,49 +24,49 @@ import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.rbacViewFor;
|
|||||||
import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "hs_office_relationship_rv")
|
@Table(name = "hs_office_relation_rv")
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
@Builder
|
@Builder
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@FieldNameConstants
|
@FieldNameConstants
|
||||||
public class HsOfficeRelationshipEntity implements HasUuid, Stringifyable {
|
public class HsOfficeRelationEntity implements HasUuid, Stringifyable {
|
||||||
|
|
||||||
private static Stringify<HsOfficeRelationshipEntity> toString = stringify(HsOfficeRelationshipEntity.class, "rel")
|
private static Stringify<HsOfficeRelationEntity> toString = stringify(HsOfficeRelationEntity.class, "rel")
|
||||||
.withProp(Fields.relAnchor, HsOfficeRelationshipEntity::getRelAnchor)
|
.withProp(Fields.anchor, HsOfficeRelationEntity::getAnchor)
|
||||||
.withProp(Fields.relType, HsOfficeRelationshipEntity::getRelType)
|
.withProp(Fields.type, HsOfficeRelationEntity::getType)
|
||||||
.withProp(Fields.relMark, HsOfficeRelationshipEntity::getRelMark)
|
.withProp(Fields.mark, HsOfficeRelationEntity::getMark)
|
||||||
.withProp(Fields.relHolder, HsOfficeRelationshipEntity::getRelHolder)
|
.withProp(Fields.holder, HsOfficeRelationEntity::getHolder)
|
||||||
.withProp(Fields.contact, HsOfficeRelationshipEntity::getContact);
|
.withProp(Fields.contact, HsOfficeRelationEntity::getContact);
|
||||||
|
|
||||||
private static Stringify<HsOfficeRelationshipEntity> toShortString = stringify(HsOfficeRelationshipEntity.class, "rel")
|
private static Stringify<HsOfficeRelationEntity> toShortString = stringify(HsOfficeRelationEntity.class, "rel")
|
||||||
.withProp(Fields.relAnchor, HsOfficeRelationshipEntity::getRelAnchor)
|
.withProp(Fields.anchor, HsOfficeRelationEntity::getAnchor)
|
||||||
.withProp(Fields.relType, HsOfficeRelationshipEntity::getRelType)
|
.withProp(Fields.type, HsOfficeRelationEntity::getType)
|
||||||
.withProp(Fields.relHolder, HsOfficeRelationshipEntity::getRelHolder);
|
.withProp(Fields.holder, HsOfficeRelationEntity::getHolder);
|
||||||
|
|
||||||
@Id
|
@Id
|
||||||
@GeneratedValue
|
@GeneratedValue
|
||||||
private UUID uuid;
|
private UUID uuid;
|
||||||
|
|
||||||
@ManyToOne
|
@ManyToOne
|
||||||
@JoinColumn(name = "relanchoruuid")
|
@JoinColumn(name = "anchoruuid")
|
||||||
private HsOfficePersonEntity relAnchor;
|
private HsOfficePersonEntity anchor;
|
||||||
|
|
||||||
@ManyToOne
|
@ManyToOne
|
||||||
@JoinColumn(name = "relholderuuid")
|
@JoinColumn(name = "holderuuid")
|
||||||
private HsOfficePersonEntity relHolder;
|
private HsOfficePersonEntity holder;
|
||||||
|
|
||||||
@ManyToOne
|
@ManyToOne
|
||||||
@JoinColumn(name = "contactuuid")
|
@JoinColumn(name = "contactuuid")
|
||||||
private HsOfficeContactEntity contact;
|
private HsOfficeContactEntity contact;
|
||||||
|
|
||||||
@Column(name = "reltype")
|
@Column(name = "type")
|
||||||
@Enumerated(EnumType.STRING)
|
@Enumerated(EnumType.STRING)
|
||||||
private HsOfficeRelationshipType relType;
|
private HsOfficeRelationType type;
|
||||||
|
|
||||||
@Column(name = "relmark")
|
@Column(name = "mark")
|
||||||
private String relMark;
|
private String mark;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
@ -79,22 +79,22 @@ public class HsOfficeRelationshipEntity implements HasUuid, Stringifyable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static RbacView rbac() {
|
public static RbacView rbac() {
|
||||||
return rbacViewFor("relationship", HsOfficeRelationshipEntity.class)
|
return rbacViewFor("relation", HsOfficeRelationEntity.class)
|
||||||
.withIdentityView(SQL.projection("""
|
.withIdentityView(SQL.projection("""
|
||||||
(select idName from hs_office_person_iv p where p.uuid = relAnchorUuid)
|
(select idName from hs_office_person_iv p where p.uuid = anchorUuid)
|
||||||
|| '-with-' || target.relType || '-'
|
|| '-with-' || target.type || '-'
|
||||||
|| (select idName from hs_office_person_iv p where p.uuid = relHolderUuid)
|
|| (select idName from hs_office_person_iv p where p.uuid = holderUuid)
|
||||||
"""))
|
"""))
|
||||||
.withRestrictedViewOrderBy(SQL.expression(
|
.withRestrictedViewOrderBy(SQL.expression(
|
||||||
"(select idName from hs_office_person_iv p where p.uuid = target.relHolderUuid)"))
|
"(select idName from hs_office_person_iv p where p.uuid = target.holderUuid)"))
|
||||||
.withUpdatableColumns("contactUuid")
|
.withUpdatableColumns("contactUuid")
|
||||||
.importEntityAlias("anchorPerson", HsOfficePersonEntity.class,
|
.importEntityAlias("anchorPerson", HsOfficePersonEntity.class,
|
||||||
dependsOnColumn("relAnchorUuid"),
|
dependsOnColumn("anchorUuid"),
|
||||||
fetchedBySql("select * from hs_office_person as p where p.uuid = ${REF}.relAnchorUuid")
|
fetchedBySql("select * from hs_office_person as p where p.uuid = ${REF}.anchorUuid")
|
||||||
)
|
)
|
||||||
.importEntityAlias("holderPerson", HsOfficePersonEntity.class,
|
.importEntityAlias("holderPerson", HsOfficePersonEntity.class,
|
||||||
dependsOnColumn("relHolderUuid"),
|
dependsOnColumn("holderUuid"),
|
||||||
fetchedBySql("select * from hs_office_person as p where p.uuid = ${REF}.relHolderUuid")
|
fetchedBySql("select * from hs_office_person as p where p.uuid = ${REF}.holderUuid")
|
||||||
)
|
)
|
||||||
.importEntityAlias("contact", HsOfficeContactEntity.class,
|
.importEntityAlias("contact", HsOfficeContactEntity.class,
|
||||||
dependsOnColumn("contactUuid"),
|
dependsOnColumn("contactUuid"),
|
||||||
@ -123,6 +123,6 @@ public class HsOfficeRelationshipEntity implements HasUuid, Stringifyable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) throws IOException {
|
public static void main(String[] args) throws IOException {
|
||||||
rbac().generateWithBaseFileName("223-hs-office-relationship-rbac-generated");
|
rbac().generateWithBaseFileName("223-hs-office-relation-rbac-generated");
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,25 +1,25 @@
|
|||||||
package net.hostsharing.hsadminng.hs.office.relationship;
|
package net.hostsharing.hsadminng.hs.office.relation;
|
||||||
|
|
||||||
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactEntity;
|
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactEntity;
|
||||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeRelationshipPatchResource;
|
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeRelationPatchResource;
|
||||||
import net.hostsharing.hsadminng.mapper.EntityPatcher;
|
import net.hostsharing.hsadminng.mapper.EntityPatcher;
|
||||||
import net.hostsharing.hsadminng.mapper.OptionalFromJson;
|
import net.hostsharing.hsadminng.mapper.OptionalFromJson;
|
||||||
|
|
||||||
import jakarta.persistence.EntityManager;
|
import jakarta.persistence.EntityManager;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
class HsOfficeRelationshipEntityPatcher implements EntityPatcher<HsOfficeRelationshipPatchResource> {
|
class HsOfficeRelationEntityPatcher implements EntityPatcher<HsOfficeRelationPatchResource> {
|
||||||
|
|
||||||
private final EntityManager em;
|
private final EntityManager em;
|
||||||
private final HsOfficeRelationshipEntity entity;
|
private final HsOfficeRelationEntity entity;
|
||||||
|
|
||||||
HsOfficeRelationshipEntityPatcher(final EntityManager em, final HsOfficeRelationshipEntity entity) {
|
HsOfficeRelationEntityPatcher(final EntityManager em, final HsOfficeRelationEntity entity) {
|
||||||
this.em = em;
|
this.em = em;
|
||||||
this.entity = entity;
|
this.entity = entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void apply(final HsOfficeRelationshipPatchResource resource) {
|
public void apply(final HsOfficeRelationPatchResource resource) {
|
||||||
OptionalFromJson.of(resource.getContactUuid()).ifPresent(newValue -> {
|
OptionalFromJson.of(resource.getContactUuid()).ifPresent(newValue -> {
|
||||||
verifyNotNull(newValue, "contact");
|
verifyNotNull(newValue, "contact");
|
||||||
entity.setContact(em.getReference(HsOfficeContactEntity.class, newValue));
|
entity.setContact(em.getReference(HsOfficeContactEntity.class, newValue));
|
@ -0,0 +1,37 @@
|
|||||||
|
package net.hostsharing.hsadminng.hs.office.relation;
|
||||||
|
|
||||||
|
import org.springframework.data.jpa.repository.Query;
|
||||||
|
import org.springframework.data.repository.Repository;
|
||||||
|
|
||||||
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public interface HsOfficeRelationRepository extends Repository<HsOfficeRelationEntity, UUID> {
|
||||||
|
|
||||||
|
Optional<HsOfficeRelationEntity> findByUuid(UUID id);
|
||||||
|
|
||||||
|
default List<HsOfficeRelationEntity> findRelationRelatedToPersonUuidAndRelationType(@NotNull UUID personUuid, HsOfficeRelationType relationType) {
|
||||||
|
return findRelationRelatedToPersonUuidAndRelationTypeString(personUuid, relationType.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Query(value = """
|
||||||
|
SELECT p.* FROM hs_office_relation_rv AS p
|
||||||
|
WHERE p.anchorUuid = :personUuid OR p.holderUuid = :personUuid
|
||||||
|
""", nativeQuery = true)
|
||||||
|
List<HsOfficeRelationEntity> findRelationRelatedToPersonUuid(@NotNull UUID personUuid);
|
||||||
|
|
||||||
|
@Query(value = """
|
||||||
|
SELECT p.* FROM hs_office_relation_rv AS p
|
||||||
|
WHERE (:relationType IS NULL OR p.type = cast(:relationType AS HsOfficeRelationType))
|
||||||
|
AND ( p.anchorUuid = :personUuid OR p.holderUuid = :personUuid)
|
||||||
|
""", nativeQuery = true)
|
||||||
|
List<HsOfficeRelationEntity> findRelationRelatedToPersonUuidAndRelationTypeString(@NotNull UUID personUuid, String relationType);
|
||||||
|
|
||||||
|
HsOfficeRelationEntity save(final HsOfficeRelationEntity entity);
|
||||||
|
|
||||||
|
long count();
|
||||||
|
|
||||||
|
int deleteByUuid(UUID uuid);
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
package net.hostsharing.hsadminng.hs.office.relationship;
|
package net.hostsharing.hsadminng.hs.office.relation;
|
||||||
|
|
||||||
public enum HsOfficeRelationshipType {
|
public enum HsOfficeRelationType {
|
||||||
UNKNOWN,
|
UNKNOWN,
|
||||||
PARTNER,
|
PARTNER,
|
||||||
EX_PARTNER,
|
EX_PARTNER,
|
@ -1,37 +0,0 @@
|
|||||||
package net.hostsharing.hsadminng.hs.office.relationship;
|
|
||||||
|
|
||||||
import org.springframework.data.jpa.repository.Query;
|
|
||||||
import org.springframework.data.repository.Repository;
|
|
||||||
|
|
||||||
import jakarta.validation.constraints.NotNull;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public interface HsOfficeRelationshipRepository extends Repository<HsOfficeRelationshipEntity, UUID> {
|
|
||||||
|
|
||||||
Optional<HsOfficeRelationshipEntity> findByUuid(UUID id);
|
|
||||||
|
|
||||||
default List<HsOfficeRelationshipEntity> findRelationshipRelatedToPersonUuidAndRelationshipType(@NotNull UUID personUuid, HsOfficeRelationshipType relationshipType) {
|
|
||||||
return findRelationshipRelatedToPersonUuidAndRelationshipTypeString(personUuid, relationshipType.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Query(value = """
|
|
||||||
SELECT p.* FROM hs_office_relationship_rv AS p
|
|
||||||
WHERE p.relAnchorUuid = :personUuid OR p.relHolderUuid = :personUuid
|
|
||||||
""", nativeQuery = true)
|
|
||||||
List<HsOfficeRelationshipEntity> findRelationshipRelatedToPersonUuid(@NotNull UUID personUuid);
|
|
||||||
|
|
||||||
@Query(value = """
|
|
||||||
SELECT p.* FROM hs_office_relationship_rv AS p
|
|
||||||
WHERE (:relationshipType IS NULL OR p.relType = cast(:relationshipType AS HsOfficeRelationshipType))
|
|
||||||
AND ( p.relAnchorUuid = :personUuid OR p.relHolderUuid = :personUuid)
|
|
||||||
""", nativeQuery = true)
|
|
||||||
List<HsOfficeRelationshipEntity> findRelationshipRelatedToPersonUuidAndRelationshipTypeString(@NotNull UUID personUuid, String relationshipType);
|
|
||||||
|
|
||||||
HsOfficeRelationshipEntity save(final HsOfficeRelationshipEntity entity);
|
|
||||||
|
|
||||||
long count();
|
|
||||||
|
|
||||||
int deleteByUuid(UUID uuid);
|
|
||||||
}
|
|
@ -6,7 +6,7 @@ import lombok.*;
|
|||||||
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.debitor.HsOfficeDebitorEntity;
|
import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorEntity;
|
||||||
import net.hostsharing.hsadminng.hs.office.relationship.HsOfficeRelationshipEntity;
|
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationEntity;
|
||||||
import net.hostsharing.hsadminng.persistence.HasUuid;
|
import net.hostsharing.hsadminng.persistence.HasUuid;
|
||||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
|
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
|
||||||
import net.hostsharing.hsadminng.stringify.Stringify;
|
import net.hostsharing.hsadminng.stringify.Stringify;
|
||||||
@ -99,7 +99,7 @@ public class HsOfficeSepaMandateEntity implements Stringifyable, HasUuid {
|
|||||||
.withIdentityView(projection("concat(tradeName, familyName, givenName)"))
|
.withIdentityView(projection("concat(tradeName, familyName, givenName)"))
|
||||||
.withUpdatableColumns("reference", "agreement", "validity")
|
.withUpdatableColumns("reference", "agreement", "validity")
|
||||||
|
|
||||||
.importEntityAlias("debitorRel", HsOfficeRelationshipEntity.class, dependsOnColumn("debitorRelUuid"))
|
.importEntityAlias("debitorRel", HsOfficeRelationEntity.class, dependsOnColumn("debitorRelUuid"))
|
||||||
.importEntityAlias("bankAccount", HsOfficeBankAccountEntity.class, dependsOnColumn("bankAccountUuid"))
|
.importEntityAlias("bankAccount", HsOfficeBankAccountEntity.class, dependsOnColumn("bankAccountUuid"))
|
||||||
|
|
||||||
.createRole(OWNER, (with) -> {
|
.createRole(OWNER, (with) -> {
|
||||||
|
@ -11,7 +11,7 @@ import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipEntity;
|
|||||||
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerDetailsEntity;
|
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerDetailsEntity;
|
||||||
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity;
|
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity;
|
||||||
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity;
|
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity;
|
||||||
import net.hostsharing.hsadminng.hs.office.relationship.HsOfficeRelationshipEntity;
|
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationEntity;
|
||||||
import net.hostsharing.hsadminng.hs.office.sepamandate.HsOfficeSepaMandateEntity;
|
import net.hostsharing.hsadminng.hs.office.sepamandate.HsOfficeSepaMandateEntity;
|
||||||
import net.hostsharing.hsadminng.persistence.HasUuid;
|
import net.hostsharing.hsadminng.persistence.HasUuid;
|
||||||
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject;
|
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject;
|
||||||
@ -804,7 +804,7 @@ public class RbacView {
|
|||||||
HsOfficePartnerDetailsEntity.class,
|
HsOfficePartnerDetailsEntity.class,
|
||||||
HsOfficeBankAccountEntity.class,
|
HsOfficeBankAccountEntity.class,
|
||||||
HsOfficeDebitorEntity.class,
|
HsOfficeDebitorEntity.class,
|
||||||
HsOfficeRelationshipEntity.class,
|
HsOfficeRelationEntity.class,
|
||||||
HsOfficeCoopAssetsTransactionEntity.class,
|
HsOfficeCoopAssetsTransactionEntity.class,
|
||||||
HsOfficeContactEntity.class,
|
HsOfficeContactEntity.class,
|
||||||
HsOfficeSepaMandateEntity.class,
|
HsOfficeSepaMandateEntity.class,
|
||||||
|
@ -23,7 +23,7 @@ map:
|
|||||||
null: org.openapitools.jackson.nullable.JsonNullable
|
null: org.openapitools.jackson.nullable.JsonNullable
|
||||||
/api/hs/office/persons/{personUUID}:
|
/api/hs/office/persons/{personUUID}:
|
||||||
null: org.openapitools.jackson.nullable.JsonNullable
|
null: org.openapitools.jackson.nullable.JsonNullable
|
||||||
/api/hs/office/relationships/{relationshipUUID}:
|
/api/hs/office/relations/{relationUUID}:
|
||||||
null: org.openapitools.jackson.nullable.JsonNullable
|
null: org.openapitools.jackson.nullable.JsonNullable
|
||||||
/api/hs/office/bankaccounts/{bankAccountUUID}:
|
/api/hs/office/bankaccounts/{bankAccountUUID}:
|
||||||
null: org.openapitools.jackson.nullable.JsonNullable
|
null: org.openapitools.jackson.nullable.JsonNullable
|
||||||
|
@ -96,8 +96,8 @@ components:
|
|||||||
format: int8
|
format: int8
|
||||||
minimum: 10000
|
minimum: 10000
|
||||||
maximum: 99999
|
maximum: 99999
|
||||||
partnerRole:
|
partnerRel:
|
||||||
$ref: '#/components/schemas/HsOfficePartnerRoleInsert'
|
$ref: '#/components/schemas/HsOfficePartnerRelInsert'
|
||||||
personUuid:
|
personUuid:
|
||||||
type: string
|
type: string
|
||||||
format: uuid
|
format: uuid
|
||||||
@ -112,22 +112,22 @@ components:
|
|||||||
- contactUuid
|
- contactUuid
|
||||||
- details
|
- details
|
||||||
|
|
||||||
HsOfficePartnerRoleInsert:
|
HsOfficePartnerRelInsert:
|
||||||
type: object
|
type: object
|
||||||
nullable: false
|
nullable: false
|
||||||
properties:
|
properties:
|
||||||
relAnchorUuid:
|
anchorUuid:
|
||||||
type: string
|
type: string
|
||||||
format: uuid
|
format: uuid
|
||||||
relHolderUuid:
|
holderUuid:
|
||||||
type: string
|
type: string
|
||||||
format: uuid
|
format: uuid
|
||||||
contactUuid:
|
contactUuid:
|
||||||
type: string
|
type: string
|
||||||
format: uuid
|
format: uuid
|
||||||
required:
|
required:
|
||||||
- relAnchorUuid
|
- anchorUuid
|
||||||
- relHolderUuid
|
- holderUuid
|
||||||
- relContactUuid
|
- relContactUuid
|
||||||
|
|
||||||
HsOfficePartnerDetailsInsert:
|
HsOfficePartnerDetailsInsert:
|
||||||
|
@ -3,37 +3,37 @@ components:
|
|||||||
|
|
||||||
schemas:
|
schemas:
|
||||||
|
|
||||||
HsOfficeRelationshipType:
|
HsOfficeRelationType:
|
||||||
type: string
|
type: string
|
||||||
enum:
|
enum:
|
||||||
- UNKNOWN
|
- UNKNOWN
|
||||||
- PARTNER
|
- PARTNER
|
||||||
- EX_PARTNER
|
- EX_PARTNER
|
||||||
- REPRESENTATIVE,
|
- DEBITOR
|
||||||
|
- REPRESENTATIVE
|
||||||
- VIP_CONTACT
|
- VIP_CONTACT
|
||||||
- ACCOUNTING,
|
|
||||||
- OPERATIONS
|
- OPERATIONS
|
||||||
- SUBSCRIBER
|
- SUBSCRIBER
|
||||||
|
|
||||||
HsOfficeRelationship:
|
HsOfficeRelation:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
uuid:
|
uuid:
|
||||||
type: string
|
type: string
|
||||||
format: uuid
|
format: uuid
|
||||||
relAnchor:
|
anchor:
|
||||||
$ref: './hs-office-person-schemas.yaml#/components/schemas/HsOfficePerson'
|
$ref: './hs-office-person-schemas.yaml#/components/schemas/HsOfficePerson'
|
||||||
relHolder:
|
holder:
|
||||||
$ref: './hs-office-person-schemas.yaml#/components/schemas/HsOfficePerson'
|
$ref: './hs-office-person-schemas.yaml#/components/schemas/HsOfficePerson'
|
||||||
relType:
|
type:
|
||||||
type: string
|
type: string
|
||||||
relMark:
|
mark:
|
||||||
type: string
|
type: string
|
||||||
nullable: true
|
nullable: true
|
||||||
contact:
|
contact:
|
||||||
$ref: './hs-office-contact-schemas.yaml#/components/schemas/HsOfficeContact'
|
$ref: './hs-office-contact-schemas.yaml#/components/schemas/HsOfficeContact'
|
||||||
|
|
||||||
HsOfficeRelationshipPatch:
|
HsOfficeRelationPatch:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
contactUuid:
|
contactUuid:
|
||||||
@ -41,25 +41,25 @@ components:
|
|||||||
format: uuid
|
format: uuid
|
||||||
nullable: true
|
nullable: true
|
||||||
|
|
||||||
HsOfficeRelationshipInsert:
|
HsOfficeRelationInsert:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
relAnchorUuid:
|
anchorUuid:
|
||||||
type: string
|
type: string
|
||||||
format: uuid
|
format: uuid
|
||||||
relHolderUuid:
|
holderUuid:
|
||||||
type: string
|
type: string
|
||||||
format: uuid
|
format: uuid
|
||||||
relType:
|
type:
|
||||||
type: string
|
type: string
|
||||||
nullable: true
|
nullable: true
|
||||||
relMark:
|
mark:
|
||||||
type: string
|
type: string
|
||||||
contactUuid:
|
contactUuid:
|
||||||
type: string
|
type: string
|
||||||
format: uuid
|
format: uuid
|
||||||
required:
|
required:
|
||||||
- relAnchorUuid
|
- anchorUuid
|
||||||
- relHolderUuid
|
- holderUuid
|
||||||
- relType
|
- type
|
||||||
- relContactUuid
|
- relContactUuid
|
@ -1,25 +1,25 @@
|
|||||||
get:
|
get:
|
||||||
tags:
|
tags:
|
||||||
- hs-office-relationships
|
- hs-office-relations
|
||||||
description: 'Fetch a single person relationship by its uuid, if visible for the current subject.'
|
description: 'Fetch a single person relation by its uuid, if visible for the current subject.'
|
||||||
operationId: getRelationshipByUuid
|
operationId: getRelationByUuid
|
||||||
parameters:
|
parameters:
|
||||||
- $ref: './auth.yaml#/components/parameters/currentUser'
|
- $ref: './auth.yaml#/components/parameters/currentUser'
|
||||||
- $ref: './auth.yaml#/components/parameters/assumedRoles'
|
- $ref: './auth.yaml#/components/parameters/assumedRoles'
|
||||||
- name: relationshipUUID
|
- name: relationUUID
|
||||||
in: path
|
in: path
|
||||||
required: true
|
required: true
|
||||||
schema:
|
schema:
|
||||||
type: string
|
type: string
|
||||||
format: uuid
|
format: uuid
|
||||||
description: UUID of the relationship to fetch.
|
description: UUID of the relation to fetch.
|
||||||
responses:
|
responses:
|
||||||
"200":
|
"200":
|
||||||
description: OK
|
description: OK
|
||||||
content:
|
content:
|
||||||
'application/json':
|
'application/json':
|
||||||
schema:
|
schema:
|
||||||
$ref: './hs-office-relationship-schemas.yaml#/components/schemas/HsOfficeRelationship'
|
$ref: './hs-office-relations-schemas.yaml#/components/schemas/HsOfficeRelation'
|
||||||
|
|
||||||
"401":
|
"401":
|
||||||
$ref: './error-responses.yaml#/components/responses/Unauthorized'
|
$ref: './error-responses.yaml#/components/responses/Unauthorized'
|
||||||
@ -28,13 +28,13 @@ get:
|
|||||||
|
|
||||||
patch:
|
patch:
|
||||||
tags:
|
tags:
|
||||||
- hs-office-relationships
|
- hs-office-relations
|
||||||
description: 'Updates a single person relationship by its uuid, if permitted for the current subject.'
|
description: 'Updates a single person relation by its uuid, if permitted for the current subject.'
|
||||||
operationId: patchRelationship
|
operationId: patchRelation
|
||||||
parameters:
|
parameters:
|
||||||
- $ref: './auth.yaml#/components/parameters/currentUser'
|
- $ref: './auth.yaml#/components/parameters/currentUser'
|
||||||
- $ref: './auth.yaml#/components/parameters/assumedRoles'
|
- $ref: './auth.yaml#/components/parameters/assumedRoles'
|
||||||
- name: relationshipUUID
|
- name: relationUUID
|
||||||
in: path
|
in: path
|
||||||
required: true
|
required: true
|
||||||
schema:
|
schema:
|
||||||
@ -44,14 +44,14 @@ patch:
|
|||||||
content:
|
content:
|
||||||
'application/json':
|
'application/json':
|
||||||
schema:
|
schema:
|
||||||
$ref: './hs-office-relationship-schemas.yaml#/components/schemas/HsOfficeRelationshipPatch'
|
$ref: './hs-office-relations-schemas.yaml#/components/schemas/HsOfficeRelationPatch'
|
||||||
responses:
|
responses:
|
||||||
"200":
|
"200":
|
||||||
description: OK
|
description: OK
|
||||||
content:
|
content:
|
||||||
'application/json':
|
'application/json':
|
||||||
schema:
|
schema:
|
||||||
$ref: './hs-office-relationship-schemas.yaml#/components/schemas/HsOfficeRelationship'
|
$ref: './hs-office-relations-schemas.yaml#/components/schemas/HsOfficeRelation'
|
||||||
"401":
|
"401":
|
||||||
$ref: './error-responses.yaml#/components/responses/Unauthorized'
|
$ref: './error-responses.yaml#/components/responses/Unauthorized'
|
||||||
"403":
|
"403":
|
||||||
@ -59,19 +59,19 @@ patch:
|
|||||||
|
|
||||||
delete:
|
delete:
|
||||||
tags:
|
tags:
|
||||||
- hs-office-relationships
|
- hs-office-relations
|
||||||
description: 'Delete a single person relationship by its uuid, if permitted for the current subject.'
|
description: 'Delete a single person relation by its uuid, if permitted for the current subject.'
|
||||||
operationId: deleteRelationshipByUuid
|
operationId: deleteRelationByUuid
|
||||||
parameters:
|
parameters:
|
||||||
- $ref: './auth.yaml#/components/parameters/currentUser'
|
- $ref: './auth.yaml#/components/parameters/currentUser'
|
||||||
- $ref: './auth.yaml#/components/parameters/assumedRoles'
|
- $ref: './auth.yaml#/components/parameters/assumedRoles'
|
||||||
- name: relationshipUUID
|
- name: relationUUID
|
||||||
in: path
|
in: path
|
||||||
required: true
|
required: true
|
||||||
schema:
|
schema:
|
||||||
type: string
|
type: string
|
||||||
format: uuid
|
format: uuid
|
||||||
description: UUID of the relationship to delete.
|
description: UUID of the relation to delete.
|
||||||
responses:
|
responses:
|
||||||
"204":
|
"204":
|
||||||
description: No Content
|
description: No Content
|
@ -1,9 +1,9 @@
|
|||||||
get:
|
get:
|
||||||
summary: Returns a list of (optionally filtered) person relationships for a given person.
|
summary: Returns a list of (optionally filtered) person relations for a given person.
|
||||||
description: Returns the list of (optionally filtered) person relationships of a given person and which are visible to the current user or any of it's assumed roles.
|
description: Returns the list of (optionally filtered) person relations of a given person and which are visible to the current user or any of it's assumed roles.
|
||||||
tags:
|
tags:
|
||||||
- hs-office-relationships
|
- hs-office-relations
|
||||||
operationId: listRelationships
|
operationId: listRelations
|
||||||
parameters:
|
parameters:
|
||||||
- $ref: './auth.yaml#/components/parameters/currentUser'
|
- $ref: './auth.yaml#/components/parameters/currentUser'
|
||||||
- $ref: './auth.yaml#/components/parameters/assumedRoles'
|
- $ref: './auth.yaml#/components/parameters/assumedRoles'
|
||||||
@ -13,13 +13,13 @@ get:
|
|||||||
schema:
|
schema:
|
||||||
type: string
|
type: string
|
||||||
format: uuid
|
format: uuid
|
||||||
description: Prefix of name properties from relHolder or contact to filter the results.
|
description: Prefix of name properties from holder or contact to filter the results.
|
||||||
- name: relationshipType
|
- name: relationType
|
||||||
in: query
|
in: query
|
||||||
required: false
|
required: false
|
||||||
schema:
|
schema:
|
||||||
$ref: './hs-office-relationship-schemas.yaml#/components/schemas/HsOfficeRelationshipType'
|
$ref: './hs-office-relations-schemas.yaml#/components/schemas/HsOfficeRelationType'
|
||||||
description: Prefix of name properties from relHolder or contact to filter the results.
|
description: Prefix of name properties from holder or contact to filter the results.
|
||||||
responses:
|
responses:
|
||||||
"200":
|
"200":
|
||||||
description: OK
|
description: OK
|
||||||
@ -28,17 +28,17 @@ get:
|
|||||||
schema:
|
schema:
|
||||||
type: array
|
type: array
|
||||||
items:
|
items:
|
||||||
$ref: './hs-office-relationship-schemas.yaml#/components/schemas/HsOfficeRelationship'
|
$ref: './hs-office-relations-schemas.yaml#/components/schemas/HsOfficeRelation'
|
||||||
"401":
|
"401":
|
||||||
$ref: './error-responses.yaml#/components/responses/Unauthorized'
|
$ref: './error-responses.yaml#/components/responses/Unauthorized'
|
||||||
"403":
|
"403":
|
||||||
$ref: './error-responses.yaml#/components/responses/Forbidden'
|
$ref: './error-responses.yaml#/components/responses/Forbidden'
|
||||||
|
|
||||||
post:
|
post:
|
||||||
summary: Adds a new person relationship.
|
summary: Adds a new person relation.
|
||||||
tags:
|
tags:
|
||||||
- hs-office-relationships
|
- hs-office-relations
|
||||||
operationId: addRelationship
|
operationId: addRelation
|
||||||
parameters:
|
parameters:
|
||||||
- $ref: './auth.yaml#/components/parameters/currentUser'
|
- $ref: './auth.yaml#/components/parameters/currentUser'
|
||||||
- $ref: './auth.yaml#/components/parameters/assumedRoles'
|
- $ref: './auth.yaml#/components/parameters/assumedRoles'
|
||||||
@ -46,7 +46,7 @@ post:
|
|||||||
content:
|
content:
|
||||||
'application/json':
|
'application/json':
|
||||||
schema:
|
schema:
|
||||||
$ref: './hs-office-relationship-schemas.yaml#/components/schemas/HsOfficeRelationshipInsert'
|
$ref: './hs-office-relations-schemas.yaml#/components/schemas/HsOfficeRelationInsert'
|
||||||
required: true
|
required: true
|
||||||
responses:
|
responses:
|
||||||
"201":
|
"201":
|
||||||
@ -54,7 +54,7 @@ post:
|
|||||||
content:
|
content:
|
||||||
'application/json':
|
'application/json':
|
||||||
schema:
|
schema:
|
||||||
$ref: './hs-office-relationship-schemas.yaml#/components/schemas/HsOfficeRelationship'
|
$ref: './hs-office-relations-schemas.yaml#/components/schemas/HsOfficeRelation'
|
||||||
"401":
|
"401":
|
||||||
$ref: './error-responses.yaml#/components/responses/Unauthorized'
|
$ref: './error-responses.yaml#/components/responses/Unauthorized'
|
||||||
"403":
|
"403":
|
@ -35,13 +35,13 @@ paths:
|
|||||||
$ref: "./hs-office-persons-with-uuid.yaml"
|
$ref: "./hs-office-persons-with-uuid.yaml"
|
||||||
|
|
||||||
|
|
||||||
# Relationships
|
# Relations
|
||||||
|
|
||||||
/api/hs/office/relationships:
|
/api/hs/office/relations:
|
||||||
$ref: "./hs-office-relationships.yaml"
|
$ref: "./hs-office-relations.yaml"
|
||||||
|
|
||||||
/api/hs/office/relationships/{relationshipUUID}:
|
/api/hs/office/relations/{relationUUID}:
|
||||||
$ref: "./hs-office-relationships-with-uuid.yaml"
|
$ref: "./hs-office-relations-with-uuid.yaml"
|
||||||
|
|
||||||
|
|
||||||
# BankAccounts
|
# BankAccounts
|
||||||
|
36
src/main/resources/db/changelog/220-hs-office-relation.sql
Normal file
36
src/main/resources/db/changelog/220-hs-office-relation.sql
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
--liquibase formatted sql
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
--changeset hs-office-relation-MAIN-TABLE:1 endDelimiter:--//
|
||||||
|
-- ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
CREATE TYPE HsOfficeRelationType AS ENUM (
|
||||||
|
'UNKNOWN',
|
||||||
|
'PARTNER',
|
||||||
|
'EX_PARTNER',
|
||||||
|
'REPRESENTATIVE',
|
||||||
|
'DEBITOR',
|
||||||
|
'VIP_CONTACT',
|
||||||
|
'OPERATIONS',
|
||||||
|
'SUBSCRIBER');
|
||||||
|
|
||||||
|
CREATE CAST (character varying as HsOfficeRelationType) WITH INOUT AS IMPLICIT;
|
||||||
|
|
||||||
|
create table if not exists hs_office_relation
|
||||||
|
(
|
||||||
|
uuid uuid unique references RbacObject (uuid) initially deferred, -- on delete cascade
|
||||||
|
anchorUuid uuid not null references hs_office_person(uuid),
|
||||||
|
holderUuid uuid not null references hs_office_person(uuid),
|
||||||
|
contactUuid uuid references hs_office_contact(uuid),
|
||||||
|
type HsOfficeRelationType not null,
|
||||||
|
mark varchar(24)
|
||||||
|
);
|
||||||
|
--//
|
||||||
|
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
--changeset hs-office-relation-MAIN-TABLE-JOURNAL:1 endDelimiter:--//
|
||||||
|
-- ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
call create_journal('hs_office_relation');
|
||||||
|
--//
|
@ -1,36 +0,0 @@
|
|||||||
--liquibase formatted sql
|
|
||||||
|
|
||||||
-- ============================================================================
|
|
||||||
--changeset hs-office-relationship-MAIN-TABLE:1 endDelimiter:--//
|
|
||||||
-- ----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
CREATE TYPE HsOfficeRelationshipType AS ENUM (
|
|
||||||
'UNKNOWN',
|
|
||||||
'PARTNER',
|
|
||||||
'EX_PARTNER',
|
|
||||||
'REPRESENTATIVE',
|
|
||||||
'DEBITOR',
|
|
||||||
'VIP_CONTACT',
|
|
||||||
'OPERATIONS',
|
|
||||||
'SUBSCRIBER');
|
|
||||||
|
|
||||||
CREATE CAST (character varying as HsOfficeRelationshipType) WITH INOUT AS IMPLICIT;
|
|
||||||
|
|
||||||
create table if not exists hs_office_relationship
|
|
||||||
(
|
|
||||||
uuid uuid unique references RbacObject (uuid) initially deferred, -- on delete cascade
|
|
||||||
relAnchorUuid uuid not null references hs_office_person(uuid),
|
|
||||||
relHolderUuid uuid not null references hs_office_person(uuid),
|
|
||||||
contactUuid uuid references hs_office_contact(uuid),
|
|
||||||
relType HsOfficeRelationshipType not null,
|
|
||||||
relMark varchar(24)
|
|
||||||
);
|
|
||||||
--//
|
|
||||||
|
|
||||||
|
|
||||||
-- ============================================================================
|
|
||||||
--changeset hs-office-relationship-MAIN-TABLE-JOURNAL:1 endDelimiter:--//
|
|
||||||
-- ----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
call create_journal('hs_office_relationship');
|
|
||||||
--//
|
|
@ -1,4 +1,4 @@
|
|||||||
### hs_office_relationship RBAC
|
### hs_office_relation RBAC
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
|
|
||||||
@ -28,17 +28,17 @@ subgraph hsOfficePerson
|
|||||||
--> role:hsOfficePerson.guest[person.guest]
|
--> role:hsOfficePerson.guest[person.guest]
|
||||||
end
|
end
|
||||||
|
|
||||||
subgraph hsOfficeRelationship
|
subgraph hsOfficeRelation
|
||||||
|
|
||||||
role:hsOfficePerson#relAnchor.admin[person#anchor.admin]
|
role:hsOfficePerson#anchor.admin[person#anchor.admin]
|
||||||
--- role:hsOfficePerson.admin
|
--- role:hsOfficePerson.admin
|
||||||
|
|
||||||
role:hsOfficeRelationship.owner[relationship.owner]
|
role:hsOfficeRelation.owner[relation.owner]
|
||||||
%% permissions
|
%% permissions
|
||||||
role:hsOfficeRelationship.owner --> perm:hsOfficeRelationship.*{{relationship.*}}
|
role:hsOfficeRelation.owner --> perm:hsOfficeRelation.*{{relation.*}}
|
||||||
%% incoming
|
%% incoming
|
||||||
role:global.admin ---> role:hsOfficeRelationship.owner
|
role:global.admin ---> role:hsOfficeRelation.owner
|
||||||
role:hsOfficePersonAdmin#relAnchor.admin
|
role:hsOfficePersonAdmin#anchor.admin
|
||||||
end
|
end
|
||||||
```
|
```
|
||||||
|
|
@ -1,97 +1,97 @@
|
|||||||
--liquibase formatted sql
|
--liquibase formatted sql
|
||||||
|
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
--changeset hs-office-relationship-rbac-OBJECT:1 endDelimiter:--//
|
--changeset hs-office-relation-rbac-OBJECT:1 endDelimiter:--//
|
||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
call generateRelatedRbacObject('hs_office_relationship');
|
call generateRelatedRbacObject('hs_office_relation');
|
||||||
--//
|
--//
|
||||||
|
|
||||||
|
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
--changeset hs-office-relationship-rbac-ROLE-DESCRIPTORS:1 endDelimiter:--//
|
--changeset hs-office-relation-rbac-ROLE-DESCRIPTORS:1 endDelimiter:--//
|
||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
call generateRbacRoleDescriptors('hsOfficeRelationship', 'hs_office_relationship');
|
call generateRbacRoleDescriptors('hsOfficeRelation', 'hs_office_relation');
|
||||||
--//
|
--//
|
||||||
|
|
||||||
|
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
--changeset hs-office-relationship-rbac-ROLES-CREATION:1 endDelimiter:--//
|
--changeset hs-office-relation-rbac-ROLES-CREATION:1 endDelimiter:--//
|
||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Creates and updates the roles and their assignments for relationship entities.
|
Creates and updates the roles and their assignments for relation entities.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
create or replace function hsOfficeRelationshipRbacRolesTrigger()
|
create or replace function hsOfficeRelationRbacRolesTrigger()
|
||||||
returns trigger
|
returns trigger
|
||||||
language plpgsql
|
language plpgsql
|
||||||
strict as $$
|
strict as $$
|
||||||
declare
|
declare
|
||||||
hsOfficeRelationshipTenant RbacRoleDescriptor;
|
hsOfficeRelationTenant RbacRoleDescriptor;
|
||||||
newRelAnchor hs_office_person;
|
newAnchor hs_office_person;
|
||||||
newRelHolder hs_office_person;
|
newHolder hs_office_person;
|
||||||
oldContact hs_office_contact;
|
oldContact hs_office_contact;
|
||||||
newContact hs_office_contact;
|
newContact hs_office_contact;
|
||||||
begin
|
begin
|
||||||
call enterTriggerForObjectUuid(NEW.uuid);
|
call enterTriggerForObjectUuid(NEW.uuid);
|
||||||
|
|
||||||
hsOfficeRelationshipTenant := hsOfficeRelationshipTenant(NEW);
|
hsOfficeRelationTenant := hsOfficeRelationTenant(NEW);
|
||||||
|
|
||||||
select * from hs_office_person as p where p.uuid = NEW.relAnchorUuid into newRelAnchor;
|
select * from hs_office_person as p where p.uuid = NEW.anchorUuid into newAnchor;
|
||||||
select * from hs_office_person as p where p.uuid = NEW.relHolderUuid into newRelHolder;
|
select * from hs_office_person as p where p.uuid = NEW.holderUuid into newHolder;
|
||||||
select * from hs_office_contact as c where c.uuid = NEW.contactUuid into newContact;
|
select * from hs_office_contact as c where c.uuid = NEW.contactUuid into newContact;
|
||||||
|
|
||||||
if TG_OP = 'INSERT' then
|
if TG_OP = 'INSERT' then
|
||||||
|
|
||||||
perform createRoleWithGrants(
|
perform createRoleWithGrants(
|
||||||
hsOfficeRelationshipOwner(NEW),
|
hsOfficeRelationOwner(NEW),
|
||||||
permissions => array['DELETE'],
|
permissions => array['DELETE'],
|
||||||
incomingSuperRoles => array[
|
incomingSuperRoles => array[
|
||||||
globalAdmin(),
|
globalAdmin(),
|
||||||
hsOfficePersonAdmin(newRelAnchor)]
|
hsOfficePersonAdmin(newAnchor)]
|
||||||
);
|
);
|
||||||
|
|
||||||
perform createRoleWithGrants(
|
perform createRoleWithGrants(
|
||||||
hsOfficeRelationshipAdmin(NEW),
|
hsOfficeRelationAdmin(NEW),
|
||||||
permissions => array['UPDATE'],
|
permissions => array['UPDATE'],
|
||||||
incomingSuperRoles => array[hsOfficeRelationshipOwner(NEW)]
|
incomingSuperRoles => array[hsOfficeRelationOwner(NEW)]
|
||||||
);
|
);
|
||||||
|
|
||||||
-- the tenant role for those related users who can view the data
|
-- the tenant role for those related users who can view the data
|
||||||
perform createRoleWithGrants(
|
perform createRoleWithGrants(
|
||||||
hsOfficeRelationshipTenant,
|
hsOfficeRelationTenant,
|
||||||
permissions => array['SELECT'],
|
permissions => array['SELECT'],
|
||||||
incomingSuperRoles => array[
|
incomingSuperRoles => array[
|
||||||
hsOfficeRelationshipAdmin(NEW),
|
hsOfficeRelationAdmin(NEW),
|
||||||
hsOfficePersonAdmin(newRelAnchor),
|
hsOfficePersonAdmin(newAnchor),
|
||||||
hsOfficePersonAdmin(newRelHolder),
|
hsOfficePersonAdmin(newHolder),
|
||||||
hsOfficeContactAdmin(newContact)],
|
hsOfficeContactAdmin(newContact)],
|
||||||
outgoingSubRoles => array[
|
outgoingSubRoles => array[
|
||||||
hsOfficePersonTenant(newRelAnchor),
|
hsOfficePersonTenant(newAnchor),
|
||||||
hsOfficePersonTenant(newRelHolder),
|
hsOfficePersonTenant(newHolder),
|
||||||
hsOfficeContactTenant(newContact)]
|
hsOfficeContactTenant(newContact)]
|
||||||
);
|
);
|
||||||
|
|
||||||
-- anchor and holder admin roles need each others tenant role
|
-- anchor and holder admin roles need each others tenant role
|
||||||
-- to be able to see the joined relationship
|
-- to be able to see the joined relation
|
||||||
-- TODO: this can probably be avoided through agent+guest roles
|
-- TODO: this can probably be avoided through agent+guest roles
|
||||||
call grantRoleToRole(hsOfficePersonTenant(newRelAnchor), hsOfficePersonAdmin(newRelHolder));
|
call grantRoleToRole(hsOfficePersonTenant(newAnchor), hsOfficePersonAdmin(newHolder));
|
||||||
call grantRoleToRole(hsOfficePersonTenant(newRelHolder), hsOfficePersonAdmin(newRelAnchor));
|
call grantRoleToRole(hsOfficePersonTenant(newHolder), hsOfficePersonAdmin(newAnchor));
|
||||||
call grantRoleToRoleIfNotNull(hsOfficePersonTenant(newRelHolder), hsOfficeContactAdmin(newContact));
|
call grantRoleToRoleIfNotNull(hsOfficePersonTenant(newHolder), hsOfficeContactAdmin(newContact));
|
||||||
|
|
||||||
elsif TG_OP = 'UPDATE' then
|
elsif TG_OP = 'UPDATE' then
|
||||||
|
|
||||||
if OLD.contactUuid <> NEW.contactUuid then
|
if OLD.contactUuid <> NEW.contactUuid then
|
||||||
-- nothing but the contact can be updated,
|
-- nothing but the contact can be updated,
|
||||||
-- in other cases, a new relationship needs to be created and the old updated
|
-- in other cases, a new relation needs to be created and the old updated
|
||||||
|
|
||||||
select * from hs_office_contact as c where c.uuid = OLD.contactUuid into oldContact;
|
select * from hs_office_contact as c where c.uuid = OLD.contactUuid into oldContact;
|
||||||
|
|
||||||
call revokeRoleFromRole( hsOfficeRelationshipTenant, hsOfficeContactAdmin(oldContact) );
|
call revokeRoleFromRole( hsOfficeRelationTenant, hsOfficeContactAdmin(oldContact) );
|
||||||
call grantRoleToRole( hsOfficeRelationshipTenant, hsOfficeContactAdmin(newContact) );
|
call grantRoleToRole( hsOfficeRelationTenant, hsOfficeContactAdmin(newContact) );
|
||||||
|
|
||||||
call revokeRoleFromRole( hsOfficeContactTenant(oldContact), hsOfficeRelationshipTenant );
|
call revokeRoleFromRole( hsOfficeContactTenant(oldContact), hsOfficeRelationTenant );
|
||||||
call grantRoleToRole( hsOfficeContactTenant(newContact), hsOfficeRelationshipTenant );
|
call grantRoleToRole( hsOfficeContactTenant(newContact), hsOfficeRelationTenant );
|
||||||
end if;
|
end if;
|
||||||
else
|
else
|
||||||
raise exception 'invalid usage of TRIGGER';
|
raise exception 'invalid usage of TRIGGER';
|
||||||
@ -104,39 +104,39 @@ end; $$;
|
|||||||
/*
|
/*
|
||||||
An AFTER INSERT TRIGGER which creates the role structure for a new customer.
|
An AFTER INSERT TRIGGER which creates the role structure for a new customer.
|
||||||
*/
|
*/
|
||||||
create trigger createRbacRolesForHsOfficeRelationship_Trigger
|
create trigger createRbacRolesForHsOfficeRelation_Trigger
|
||||||
after insert
|
after insert
|
||||||
on hs_office_relationship
|
on hs_office_relation
|
||||||
for each row
|
for each row
|
||||||
execute procedure hsOfficeRelationshipRbacRolesTrigger();
|
execute procedure hsOfficeRelationRbacRolesTrigger();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
An AFTER UPDATE TRIGGER which updates the role structure of a customer.
|
An AFTER UPDATE TRIGGER which updates the role structure of a customer.
|
||||||
*/
|
*/
|
||||||
create trigger updateRbacRolesForHsOfficeRelationship_Trigger
|
create trigger updateRbacRolesForHsOfficeRelation_Trigger
|
||||||
after update
|
after update
|
||||||
on hs_office_relationship
|
on hs_office_relation
|
||||||
for each row
|
for each row
|
||||||
execute procedure hsOfficeRelationshipRbacRolesTrigger();
|
execute procedure hsOfficeRelationRbacRolesTrigger();
|
||||||
--//
|
--//
|
||||||
|
|
||||||
|
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
--changeset hs-office-relationship-rbac-IDENTITY-VIEW:1 endDelimiter:--//
|
--changeset hs-office-relation-rbac-IDENTITY-VIEW:1 endDelimiter:--//
|
||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
call generateRbacIdentityViewFromProjection('hs_office_relationship', $idName$
|
call generateRbacIdentityViewFromProjection('hs_office_relation', $idName$
|
||||||
(select idName from hs_office_person_iv p where p.uuid = target.relAnchorUuid)
|
(select idName from hs_office_person_iv p where p.uuid = target.anchorUuid)
|
||||||
|| '-with-' || target.relType || '-' ||
|
|| '-with-' || target.type || '-' ||
|
||||||
(select idName from hs_office_person_iv p where p.uuid = target.relHolderUuid)
|
(select idName from hs_office_person_iv p where p.uuid = target.holderUuid)
|
||||||
$idName$);
|
$idName$);
|
||||||
--//
|
--//
|
||||||
|
|
||||||
|
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
--changeset hs-office-relationship-rbac-RESTRICTED-VIEW:1 endDelimiter:--//
|
--changeset hs-office-relation-rbac-RESTRICTED-VIEW:1 endDelimiter:--//
|
||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
call generateRbacRestrictedView('hs_office_relationship',
|
call generateRbacRestrictedView('hs_office_relation',
|
||||||
'(select idName from hs_office_person_iv p where p.uuid = target.relHolderUuid)',
|
'(select idName from hs_office_person_iv p where p.uuid = target.holderUuid)',
|
||||||
$updates$
|
$updates$
|
||||||
contactUuid = new.contactUuid
|
contactUuid = new.contactUuid
|
||||||
$updates$);
|
$updates$);
|
||||||
@ -146,10 +146,10 @@ call generateRbacRestrictedView('hs_office_relationship',
|
|||||||
|
|
||||||
|
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
--changeset hs-office-relationship-rbac-NEW-RELATHIONSHIP:1 endDelimiter:--//
|
--changeset hs-office-relation-rbac-NEW-RELATHIONSHIP:1 endDelimiter:--//
|
||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
/*
|
/*
|
||||||
Creates a global permission for new-relationship and assigns it to the hostsharing admins role.
|
Creates a global permission for new-relation and assigns it to the hostsharing admins role.
|
||||||
*/
|
*/
|
||||||
do language plpgsql $$
|
do language plpgsql $$
|
||||||
declare
|
declare
|
||||||
@ -157,11 +157,11 @@ do language plpgsql $$
|
|||||||
globalObjectUuid uuid;
|
globalObjectUuid uuid;
|
||||||
globalAdminRoleUuid uuid ;
|
globalAdminRoleUuid uuid ;
|
||||||
begin
|
begin
|
||||||
call defineContext('granting global new-relationship permission to global admin role', null, null, null);
|
call defineContext('granting global new-relation permission to global admin role', null, null, null);
|
||||||
|
|
||||||
globalAdminRoleUuid := findRoleId(globalAdmin());
|
globalAdminRoleUuid := findRoleId(globalAdmin());
|
||||||
globalObjectUuid := (select uuid from global);
|
globalObjectUuid := (select uuid from global);
|
||||||
addCustomerPermissions := createPermissions(globalObjectUuid, array ['new-relationship']);
|
addCustomerPermissions := createPermissions(globalObjectUuid, array ['new-relation']);
|
||||||
call grantPermissionsToRole(globalAdminRoleUuid, addCustomerPermissions);
|
call grantPermissionsToRole(globalAdminRoleUuid, addCustomerPermissions);
|
||||||
end;
|
end;
|
||||||
$$;
|
$$;
|
||||||
@ -169,24 +169,24 @@ $$;
|
|||||||
/**
|
/**
|
||||||
Used by the trigger to prevent the add-customer to current user respectively assumed roles.
|
Used by the trigger to prevent the add-customer to current user respectively assumed roles.
|
||||||
*/
|
*/
|
||||||
create or replace function addHsOfficeRelationshipNotAllowedForCurrentSubjects()
|
create or replace function addHsOfficeRelationNotAllowedForCurrentSubjects()
|
||||||
returns trigger
|
returns trigger
|
||||||
language PLPGSQL
|
language PLPGSQL
|
||||||
as $$
|
as $$
|
||||||
begin
|
begin
|
||||||
raise exception '[403] new-relationship not permitted for %',
|
raise exception '[403] new-relation not permitted for %',
|
||||||
array_to_string(currentSubjects(), ';', 'null');
|
array_to_string(currentSubjects(), ';', 'null');
|
||||||
end; $$;
|
end; $$;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Checks if the user or assumed roles are allowed to create a new customer.
|
Checks if the user or assumed roles are allowed to create a new customer.
|
||||||
*/
|
*/
|
||||||
create trigger hs_office_relationship_insert_trigger
|
create trigger hs_office_relation_insert_trigger
|
||||||
before insert
|
before insert
|
||||||
on hs_office_relationship
|
on hs_office_relation
|
||||||
for each row
|
for each row
|
||||||
-- TODO.spec: who is allowed to create new relationships
|
-- TODO.spec: who is allowed to create new relations
|
||||||
when ( not hasAssumedRole() )
|
when ( not hasAssumedRole() )
|
||||||
execute procedure addHsOfficeRelationshipNotAllowedForCurrentSubjects();
|
execute procedure addHsOfficeRelationNotAllowedForCurrentSubjects();
|
||||||
--//
|
--//
|
||||||
|
|
@ -2,15 +2,15 @@
|
|||||||
|
|
||||||
|
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
--changeset hs-office-relationship-TEST-DATA-GENERATOR:1 endDelimiter:--//
|
--changeset hs-office-relation-TEST-DATA-GENERATOR:1 endDelimiter:--//
|
||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Creates a single relationship test record.
|
Creates a single relation test record.
|
||||||
*/
|
*/
|
||||||
create or replace procedure createHsOfficeRelationshipTestData(
|
create or replace procedure createHsOfficeRelationTestData(
|
||||||
holderPersonName varchar,
|
holderPersonName varchar,
|
||||||
relationshipType HsOfficeRelationshipType,
|
relationType HsOfficeRelationType,
|
||||||
anchorPersonTradeName varchar,
|
anchorPersonTradeName varchar,
|
||||||
contactLabel varchar,
|
contactLabel varchar,
|
||||||
mark varchar default null)
|
mark varchar default null)
|
||||||
@ -24,7 +24,7 @@ declare
|
|||||||
|
|
||||||
begin
|
begin
|
||||||
idName := cleanIdentifier( anchorPersonTradeName || '-' || holderPersonName);
|
idName := cleanIdentifier( anchorPersonTradeName || '-' || holderPersonName);
|
||||||
currentTask := 'creating relationship test-data ' || idName;
|
currentTask := 'creating relation test-data ' || idName;
|
||||||
call defineContext(currentTask, null, 'superuser-alex@hostsharing.net', 'global#global.admin');
|
call defineContext(currentTask, null, 'superuser-alex@hostsharing.net', 'global#global.admin');
|
||||||
execute format('set local hsadminng.currentTask to %L', currentTask);
|
execute format('set local hsadminng.currentTask to %L', currentTask);
|
||||||
|
|
||||||
@ -45,20 +45,20 @@ begin
|
|||||||
raise exception 'contact "%" not found', contactLabel;
|
raise exception 'contact "%" not found', contactLabel;
|
||||||
end if;
|
end if;
|
||||||
|
|
||||||
raise notice 'creating test relationship: %', idName;
|
raise notice 'creating test relation: %', idName;
|
||||||
raise notice '- using anchor person (%): %', anchorPerson.uuid, anchorPerson;
|
raise notice '- using anchor person (%): %', anchorPerson.uuid, anchorPerson;
|
||||||
raise notice '- using holder person (%): %', holderPerson.uuid, holderPerson;
|
raise notice '- using holder person (%): %', holderPerson.uuid, holderPerson;
|
||||||
raise notice '- using contact (%): %', contact.uuid, contact;
|
raise notice '- using contact (%): %', contact.uuid, contact;
|
||||||
insert
|
insert
|
||||||
into hs_office_relationship (uuid, relanchoruuid, relholderuuid, reltype, relmark, contactUuid)
|
into hs_office_relation (uuid, anchoruuid, holderuuid, type, mark, contactUuid)
|
||||||
values (uuid_generate_v4(), anchorPerson.uuid, holderPerson.uuid, relationshipType, mark, contact.uuid);
|
values (uuid_generate_v4(), anchorPerson.uuid, holderPerson.uuid, relationType, mark, contact.uuid);
|
||||||
end; $$;
|
end; $$;
|
||||||
--//
|
--//
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Creates a range of test relationship for mass data generation.
|
Creates a range of test relation for mass data generation.
|
||||||
*/
|
*/
|
||||||
create or replace procedure createHsOfficeRelationshipTestData(
|
create or replace procedure createHsOfficeRelationTestData(
|
||||||
startCount integer, -- count of auto generated rows before the run
|
startCount integer, -- count of auto generated rows before the run
|
||||||
endCount integer -- count of auto generated rows after the run
|
endCount integer -- count of auto generated rows after the run
|
||||||
)
|
)
|
||||||
@ -72,7 +72,7 @@ begin
|
|||||||
select p.* from hs_office_person p where tradeName = intToVarChar(t, 4) into person;
|
select p.* from hs_office_person p where tradeName = intToVarChar(t, 4) into person;
|
||||||
select c.* from hs_office_contact c where c.label = intToVarChar(t, 4) || '#' || t into contact;
|
select c.* from hs_office_contact c where c.label = intToVarChar(t, 4) || '#' || t into contact;
|
||||||
|
|
||||||
call createHsOfficeRelationshipTestData(person.uuid, contact.uuid, 'REPRESENTATIVE');
|
call createHsOfficeRelationTestData(person.uuid, contact.uuid, 'REPRESENTATIVE');
|
||||||
commit;
|
commit;
|
||||||
end loop;
|
end loop;
|
||||||
end; $$;
|
end; $$;
|
||||||
@ -80,25 +80,25 @@ end; $$;
|
|||||||
|
|
||||||
|
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
--changeset hs-office-relationship-TEST-DATA-GENERATION:1 –context=dev,tc endDelimiter:--//
|
--changeset hs-office-relation-TEST-DATA-GENERATION:1 –context=dev,tc endDelimiter:--//
|
||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
|
|
||||||
do language plpgsql $$
|
do language plpgsql $$
|
||||||
begin
|
begin
|
||||||
call createHsOfficeRelationshipTestData('First GmbH', 'PARTNER', 'Hostsharing eG', 'first contact');
|
call createHsOfficeRelationTestData('First GmbH', 'PARTNER', 'Hostsharing eG', 'first contact');
|
||||||
call createHsOfficeRelationshipTestData('Firby', 'REPRESENTATIVE', 'First GmbH', 'first contact');
|
call createHsOfficeRelationTestData('Firby', 'REPRESENTATIVE', 'First GmbH', 'first contact');
|
||||||
|
|
||||||
call createHsOfficeRelationshipTestData('Second e.K.', 'PARTNER', 'Hostsharing eG', 'second contact');
|
call createHsOfficeRelationTestData('Second e.K.', 'PARTNER', 'Hostsharing eG', 'second contact');
|
||||||
call createHsOfficeRelationshipTestData('Smith', 'REPRESENTATIVE', 'Second e.K.', 'second contact');
|
call createHsOfficeRelationTestData('Smith', 'REPRESENTATIVE', 'Second e.K.', 'second contact');
|
||||||
|
|
||||||
call createHsOfficeRelationshipTestData('Third OHG', 'PARTNER', 'Hostsharing eG', 'third contact');
|
call createHsOfficeRelationTestData('Third OHG', 'PARTNER', 'Hostsharing eG', 'third contact');
|
||||||
call createHsOfficeRelationshipTestData('Tucker', 'REPRESENTATIVE', 'Third OHG', 'third contact');
|
call createHsOfficeRelationTestData('Tucker', 'REPRESENTATIVE', 'Third OHG', 'third contact');
|
||||||
|
|
||||||
call createHsOfficeRelationshipTestData('Fourth eG', 'PARTNER', 'Hostsharing eG', 'fourth contact');
|
call createHsOfficeRelationTestData('Fourth eG', 'PARTNER', 'Hostsharing eG', 'fourth contact');
|
||||||
call createHsOfficeRelationshipTestData('Fouler', 'REPRESENTATIVE', 'Third OHG', 'third contact');
|
call createHsOfficeRelationTestData('Fouler', 'REPRESENTATIVE', 'Third OHG', 'third contact');
|
||||||
|
|
||||||
call createHsOfficeRelationshipTestData('Smith', 'PARTNER', 'Hostsharing eG', 'sixth contact');
|
call createHsOfficeRelationTestData('Smith', 'PARTNER', 'Hostsharing eG', 'sixth contact');
|
||||||
call createHsOfficeRelationshipTestData('Smith', 'SUBSCRIBER', 'Third OHG', 'third contact', 'members-announce');
|
call createHsOfficeRelationTestData('Smith', 'SUBSCRIBER', 'Third OHG', 'third contact', 'members-announce');
|
||||||
end;
|
end;
|
||||||
$$;
|
$$;
|
||||||
--//
|
--//
|
@ -33,9 +33,9 @@ create table hs_office_partner
|
|||||||
(
|
(
|
||||||
uuid uuid unique references RbacObject (uuid) initially deferred,
|
uuid uuid unique references RbacObject (uuid) initially deferred,
|
||||||
partnerNumber numeric(5) unique not null,
|
partnerNumber numeric(5) unique not null,
|
||||||
partnerRoleUuid uuid not null references hs_office_relationship(uuid), -- TODO: delete in after delete trigger
|
partnerRelUuid uuid not null references hs_office_relation(uuid), -- TODO: delete in after delete trigger
|
||||||
personUuid uuid not null references hs_office_person(uuid), -- TODO: remove, replaced by partnerRoleUuid
|
personUuid uuid not null references hs_office_person(uuid), -- TODO: remove, replaced by partnerRelUuid
|
||||||
contactUuid uuid not null references hs_office_contact(uuid), -- TODO: remove, replaced by partnerRoleUuid
|
contactUuid uuid not null references hs_office_contact(uuid), -- TODO: remove, replaced by partnerRelUuid
|
||||||
detailsUuid uuid not null references hs_office_partner_details(uuid) -- deleted in after delete trigger
|
detailsUuid uuid not null references hs_office_partner_details(uuid) -- deleted in after delete trigger
|
||||||
);
|
);
|
||||||
--//
|
--//
|
||||||
|
@ -27,8 +27,8 @@ create or replace function hsOfficePartnerRbacRolesTrigger()
|
|||||||
language plpgsql
|
language plpgsql
|
||||||
strict as $$
|
strict as $$
|
||||||
declare
|
declare
|
||||||
oldPartnerRole hs_office_relationship;
|
oldPartnerRel hs_office_relation;
|
||||||
newPartnerRole hs_office_relationship;
|
newPartnerRel hs_office_relation;
|
||||||
|
|
||||||
oldPerson hs_office_person;
|
oldPerson hs_office_person;
|
||||||
newPerson hs_office_person;
|
newPerson hs_office_person;
|
||||||
@ -38,7 +38,7 @@ declare
|
|||||||
begin
|
begin
|
||||||
call enterTriggerForObjectUuid(NEW.uuid);
|
call enterTriggerForObjectUuid(NEW.uuid);
|
||||||
|
|
||||||
select * from hs_office_relationship as r where r.uuid = NEW.partnerroleuuid into newPartnerRole;
|
select * from hs_office_relation as r where r.uuid = NEW.partnerReluuid into newPartnerRel;
|
||||||
select * from hs_office_person as p where p.uuid = NEW.personUuid into newPerson;
|
select * from hs_office_person as p where p.uuid = NEW.personUuid into newPerson;
|
||||||
select * from hs_office_contact as c where c.uuid = NEW.contactUuid into newContact;
|
select * from hs_office_contact as c where c.uuid = NEW.contactUuid into newContact;
|
||||||
|
|
||||||
@ -58,7 +58,7 @@ begin
|
|||||||
incomingSuperRoles => array[
|
incomingSuperRoles => array[
|
||||||
hsOfficePartnerOwner(NEW)],
|
hsOfficePartnerOwner(NEW)],
|
||||||
outgoingSubRoles => array[
|
outgoingSubRoles => array[
|
||||||
hsOfficeRelationshipTenant(newPartnerRole),
|
hsOfficeRelationTenant(newPartnerRel),
|
||||||
hsOfficePersonTenant(newPerson),
|
hsOfficePersonTenant(newPerson),
|
||||||
hsOfficeContactTenant(newContact)]
|
hsOfficeContactTenant(newContact)]
|
||||||
);
|
);
|
||||||
@ -67,7 +67,7 @@ begin
|
|||||||
hsOfficePartnerAgent(NEW),
|
hsOfficePartnerAgent(NEW),
|
||||||
incomingSuperRoles => array[
|
incomingSuperRoles => array[
|
||||||
hsOfficePartnerAdmin(NEW),
|
hsOfficePartnerAdmin(NEW),
|
||||||
hsOfficeRelationshipAdmin(newPartnerRole),
|
hsOfficeRelationAdmin(newPartnerRel),
|
||||||
hsOfficePersonAdmin(newPerson),
|
hsOfficePersonAdmin(newPerson),
|
||||||
hsOfficeContactAdmin(newContact)]
|
hsOfficeContactAdmin(newContact)]
|
||||||
);
|
);
|
||||||
@ -77,7 +77,7 @@ begin
|
|||||||
incomingSuperRoles => array[
|
incomingSuperRoles => array[
|
||||||
hsOfficePartnerAgent(NEW)],
|
hsOfficePartnerAgent(NEW)],
|
||||||
outgoingSubRoles => array[
|
outgoingSubRoles => array[
|
||||||
hsOfficeRelationshipTenant(newPartnerRole),
|
hsOfficeRelationTenant(newPartnerRel),
|
||||||
hsOfficePersonGuest(newPerson),
|
hsOfficePersonGuest(newPerson),
|
||||||
hsOfficeContactGuest(newContact)]
|
hsOfficeContactGuest(newContact)]
|
||||||
);
|
);
|
||||||
@ -118,17 +118,17 @@ begin
|
|||||||
|
|
||||||
elsif TG_OP = 'UPDATE' then
|
elsif TG_OP = 'UPDATE' then
|
||||||
|
|
||||||
if OLD.partnerRoleUuid <> NEW.partnerRoleUuid then
|
if OLD.partnerRelUuid <> NEW.partnerRelUuid then
|
||||||
select * from hs_office_relationship as r where r.uuid = OLD.partnerRoleUuid into oldPartnerRole;
|
select * from hs_office_relation as r where r.uuid = OLD.partnerRelUuid into oldPartnerRel;
|
||||||
|
|
||||||
call revokeRoleFromRole(hsOfficeRelationshipTenant(oldPartnerRole), hsOfficePartnerAdmin(OLD));
|
call revokeRoleFromRole(hsOfficeRelationTenant(oldPartnerRel), hsOfficePartnerAdmin(OLD));
|
||||||
call grantRoleToRole(hsOfficeRelationshipTenant(newPartnerRole), hsOfficePartnerAdmin(NEW));
|
call grantRoleToRole(hsOfficeRelationTenant(newPartnerRel), hsOfficePartnerAdmin(NEW));
|
||||||
|
|
||||||
call revokeRoleFromRole(hsOfficePartnerAgent(OLD), hsOfficeRelationshipAdmin(oldPartnerRole));
|
call revokeRoleFromRole(hsOfficePartnerAgent(OLD), hsOfficeRelationAdmin(oldPartnerRel));
|
||||||
call grantRoleToRole(hsOfficePartnerAgent(NEW), hsOfficeRelationshipAdmin(newPartnerRole));
|
call grantRoleToRole(hsOfficePartnerAgent(NEW), hsOfficeRelationAdmin(newPartnerRel));
|
||||||
|
|
||||||
call revokeRoleFromRole(hsOfficeRelationshipGuest(oldPartnerRole), hsOfficePartnerTenant(OLD));
|
call revokeRoleFromRole(hsOfficeRelationGuest(oldPartnerRel), hsOfficePartnerTenant(OLD));
|
||||||
call grantRoleToRole(hsOfficeRelationshipGuest(newPartnerRole), hsOfficePartnerTenant(NEW));
|
call grantRoleToRole(hsOfficeRelationGuest(newPartnerRel), hsOfficePartnerTenant(NEW));
|
||||||
end if;
|
end if;
|
||||||
|
|
||||||
if OLD.personUuid <> NEW.personUuid then
|
if OLD.personUuid <> NEW.personUuid then
|
||||||
@ -202,7 +202,7 @@ call generateRbacIdentityViewFromProjection('hs_office_partner', $idName$
|
|||||||
call generateRbacRestrictedView('hs_office_partner',
|
call generateRbacRestrictedView('hs_office_partner',
|
||||||
'(select idName from hs_office_person_iv p where p.uuid = target.personUuid)',
|
'(select idName from hs_office_person_iv p where p.uuid = target.personUuid)',
|
||||||
$updates$
|
$updates$
|
||||||
partnerRoleUuid = new.partnerRoleUuid,
|
partnerRelUuid = new.partnerRelUuid,
|
||||||
personUuid = new.personUuid,
|
personUuid = new.personUuid,
|
||||||
contactUuid = new.contactUuid
|
contactUuid = new.contactUuid
|
||||||
$updates$);
|
$updates$);
|
||||||
|
@ -18,7 +18,7 @@ declare
|
|||||||
currentTask varchar;
|
currentTask varchar;
|
||||||
idName varchar;
|
idName varchar;
|
||||||
mandantPerson hs_office_person;
|
mandantPerson hs_office_person;
|
||||||
partnerRole hs_office_relationship;
|
partnerRel hs_office_relation;
|
||||||
relatedPerson hs_office_person;
|
relatedPerson hs_office_person;
|
||||||
relatedContact hs_office_contact;
|
relatedContact hs_office_contact;
|
||||||
relatedDetailsUuid uuid;
|
relatedDetailsUuid uuid;
|
||||||
@ -42,16 +42,16 @@ begin
|
|||||||
where c.label = contactLabel
|
where c.label = contactLabel
|
||||||
into relatedContact;
|
into relatedContact;
|
||||||
|
|
||||||
select r.* from hs_office_relationship r
|
select r.* from hs_office_relation r
|
||||||
where r.reltype = 'PARTNER'
|
where r.type = 'PARTNER'
|
||||||
and r.relanchoruuid = mandantPerson.uuid and r.relholderuuid = relatedPerson.uuid
|
and r.anchoruuid = mandantPerson.uuid and r.holderuuid = relatedPerson.uuid
|
||||||
into partnerRole;
|
into partnerRel;
|
||||||
if partnerRole is null then
|
if partnerRel is null then
|
||||||
raise exception 'partnerRole "%"-"%" not found', mandantPerson.tradename, partnerPersonName;
|
raise exception 'partnerRel "%"-"%" not found', mandantPerson.tradename, partnerPersonName;
|
||||||
end if;
|
end if;
|
||||||
|
|
||||||
raise notice 'creating test partner: %', idName;
|
raise notice 'creating test partner: %', idName;
|
||||||
raise notice '- using partnerRole (%): %', partnerRole.uuid, partnerRole;
|
raise notice '- using partnerRel (%): %', partnerRel.uuid, partnerRel;
|
||||||
raise notice '- using person (%): %', relatedPerson.uuid, relatedPerson;
|
raise notice '- using person (%): %', relatedPerson.uuid, relatedPerson;
|
||||||
raise notice '- using contact (%): %', relatedContact.uuid, relatedContact;
|
raise notice '- using contact (%): %', relatedContact.uuid, relatedContact;
|
||||||
|
|
||||||
@ -68,8 +68,8 @@ begin
|
|||||||
end if;
|
end if;
|
||||||
|
|
||||||
insert
|
insert
|
||||||
into hs_office_partner (uuid, partnerNumber, partnerRoleUuid, personuuid, contactuuid, detailsUuid)
|
into hs_office_partner (uuid, partnerNumber, partnerRelUuid, personuuid, contactuuid, detailsUuid)
|
||||||
values (uuid_generate_v4(), partnerNumber, partnerRole.uuid, relatedPerson.uuid, relatedContact.uuid, relatedDetailsUuid);
|
values (uuid_generate_v4(), partnerNumber, partnerRel.uuid, relatedPerson.uuid, relatedContact.uuid, relatedDetailsUuid);
|
||||||
end; $$;
|
end; $$;
|
||||||
--//
|
--//
|
||||||
|
|
||||||
|
@ -68,11 +68,11 @@ databaseChangeLog:
|
|||||||
- include:
|
- include:
|
||||||
file: db/changelog/218-hs-office-person-test-data.sql
|
file: db/changelog/218-hs-office-person-test-data.sql
|
||||||
- include:
|
- include:
|
||||||
file: db/changelog/220-hs-office-relationship.sql
|
file: db/changelog/220-hs-office-relation.sql
|
||||||
- include:
|
- include:
|
||||||
file: db/changelog/223-hs-office-relationship-rbac.sql
|
file: db/changelog/223-hs-office-relation-rbac.sql
|
||||||
- include:
|
- include:
|
||||||
file: db/changelog/228-hs-office-relationship-test-data.sql
|
file: db/changelog/228-hs-office-relation-test-data.sql
|
||||||
- include:
|
- include:
|
||||||
file: db/changelog/230-hs-office-partner.sql
|
file: db/changelog/230-hs-office-partner.sql
|
||||||
- include:
|
- include:
|
||||||
|
@ -41,7 +41,7 @@ public class ArchitectureTest {
|
|||||||
"..hs.office.migration",
|
"..hs.office.migration",
|
||||||
"..hs.office.partner",
|
"..hs.office.partner",
|
||||||
"..hs.office.person",
|
"..hs.office.person",
|
||||||
"..hs.office.relationship",
|
"..hs.office.relation",
|
||||||
"..hs.office.sepamandate",
|
"..hs.office.sepamandate",
|
||||||
"..errors",
|
"..errors",
|
||||||
"..mapper",
|
"..mapper",
|
||||||
@ -148,7 +148,7 @@ public class ArchitectureTest {
|
|||||||
public static final ArchRule hsOfficeContactPackageRule = classes()
|
public static final ArchRule hsOfficeContactPackageRule = classes()
|
||||||
.that().resideInAPackage("..hs.office.contact..")
|
.that().resideInAPackage("..hs.office.contact..")
|
||||||
.should().onlyBeAccessed().byClassesThat()
|
.should().onlyBeAccessed().byClassesThat()
|
||||||
.resideInAnyPackage("..hs.office.contact..", "..hs.office.relationship..",
|
.resideInAnyPackage("..hs.office.contact..", "..hs.office.relation..",
|
||||||
"..hs.office.partner..",
|
"..hs.office.partner..",
|
||||||
"..hs.office.debitor..",
|
"..hs.office.debitor..",
|
||||||
"..hs.office.membership..",
|
"..hs.office.membership..",
|
||||||
@ -159,7 +159,7 @@ public class ArchitectureTest {
|
|||||||
public static final ArchRule hsOfficePersonPackageRule = classes()
|
public static final ArchRule hsOfficePersonPackageRule = classes()
|
||||||
.that().resideInAPackage("..hs.office.person..")
|
.that().resideInAPackage("..hs.office.person..")
|
||||||
.should().onlyBeAccessed().byClassesThat()
|
.should().onlyBeAccessed().byClassesThat()
|
||||||
.resideInAnyPackage("..hs.office.person..", "..hs.office.relationship..",
|
.resideInAnyPackage("..hs.office.person..", "..hs.office.relation..",
|
||||||
"..hs.office.partner..",
|
"..hs.office.partner..",
|
||||||
"..hs.office.debitor..",
|
"..hs.office.debitor..",
|
||||||
"..hs.office.membership..",
|
"..hs.office.membership..",
|
||||||
@ -167,10 +167,10 @@ public class ArchitectureTest {
|
|||||||
|
|
||||||
@ArchTest
|
@ArchTest
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public static final ArchRule hsOfficeRelationshipPackageRule = classes()
|
public static final ArchRule hsOfficeRelationPackageRule = classes()
|
||||||
.that().resideInAPackage("..hs.office.relationship..")
|
.that().resideInAPackage("..hs.office.relation..")
|
||||||
.should().onlyBeAccessed().byClassesThat()
|
.should().onlyBeAccessed().byClassesThat()
|
||||||
.resideInAnyPackage("..hs.office.relationship..",
|
.resideInAnyPackage("..hs.office.relation..",
|
||||||
"..hs.office.partner..",
|
"..hs.office.partner..",
|
||||||
"..hs.office.migration..");
|
"..hs.office.migration..");
|
||||||
|
|
||||||
|
@ -18,8 +18,8 @@ import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerDetailsEntity;
|
|||||||
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity;
|
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity;
|
||||||
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity;
|
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity;
|
||||||
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonType;
|
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonType;
|
||||||
import net.hostsharing.hsadminng.hs.office.relationship.HsOfficeRelationshipEntity;
|
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationEntity;
|
||||||
import net.hostsharing.hsadminng.hs.office.relationship.HsOfficeRelationshipType;
|
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationType;
|
||||||
import net.hostsharing.hsadminng.hs.office.sepamandate.HsOfficeSepaMandateEntity;
|
import net.hostsharing.hsadminng.hs.office.sepamandate.HsOfficeSepaMandateEntity;
|
||||||
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject;
|
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject;
|
||||||
import net.hostsharing.test.JpaAttempt;
|
import net.hostsharing.test.JpaAttempt;
|
||||||
@ -127,7 +127,7 @@ public class ImportOfficeData extends ContextBasedTest {
|
|||||||
new String[]{"partner", "vip-contact", "ex-partner", "billing", "contractual", "operation"},
|
new String[]{"partner", "vip-contact", "ex-partner", "billing", "contractual", "operation"},
|
||||||
SUBSCRIBER_ROLES);
|
SUBSCRIBER_ROLES);
|
||||||
|
|
||||||
static int relationshipId = 2000000;
|
static int relationId = 2000000;
|
||||||
|
|
||||||
@Value("${spring.datasource.url}")
|
@Value("${spring.datasource.url}")
|
||||||
private String jdbcUrl;
|
private String jdbcUrl;
|
||||||
@ -144,7 +144,7 @@ public class ImportOfficeData extends ContextBasedTest {
|
|||||||
private static Map<Integer, HsOfficeDebitorEntity> debitors = new WriteOnceMap<>();
|
private static Map<Integer, HsOfficeDebitorEntity> debitors = new WriteOnceMap<>();
|
||||||
private static Map<Integer, HsOfficeMembershipEntity> memberships = new WriteOnceMap<>();
|
private static Map<Integer, HsOfficeMembershipEntity> memberships = new WriteOnceMap<>();
|
||||||
|
|
||||||
private static Map<Integer, HsOfficeRelationshipEntity> relationships = new WriteOnceMap<>();
|
private static Map<Integer, HsOfficeRelationEntity> relations = new WriteOnceMap<>();
|
||||||
private static Map<Integer, HsOfficeSepaMandateEntity> sepaMandates = new WriteOnceMap<>();
|
private static Map<Integer, HsOfficeSepaMandateEntity> sepaMandates = new WriteOnceMap<>();
|
||||||
private static Map<Integer, HsOfficeBankAccountEntity> bankAccounts = new WriteOnceMap<>();
|
private static Map<Integer, HsOfficeBankAccountEntity> bankAccounts = new WriteOnceMap<>();
|
||||||
private static Map<Integer, HsOfficeCoopSharesTransactionEntity> coopShares = new WriteOnceMap<>();
|
private static Map<Integer, HsOfficeCoopSharesTransactionEntity> coopShares = new WriteOnceMap<>();
|
||||||
@ -220,17 +220,17 @@ public class ImportOfficeData extends ContextBasedTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Order(1021)
|
@Order(1021)
|
||||||
void buildDebitorRelationships() {
|
void buildDebitorRelations() {
|
||||||
debitors.forEach( (id, debitor) -> {
|
debitors.forEach( (id, debitor) -> {
|
||||||
final var debitorRel = HsOfficeRelationshipEntity.builder()
|
final var debitorRel = HsOfficeRelationEntity.builder()
|
||||||
.relType(HsOfficeRelationshipType.DEBITOR)
|
.type(HsOfficeRelationType.DEBITOR)
|
||||||
.relAnchor(debitor.getPartner().getPartnerRole().getRelHolder())
|
.anchor(debitor.getPartner().getPartnerRel().getHolder())
|
||||||
.relHolder(debitor.getPartner().getPartnerRole().getRelHolder()) // just 1 debitor/partner in legacy hsadmin
|
.holder(debitor.getPartner().getPartnerRel().getHolder()) // just 1 debitor/partner in legacy hsadmin
|
||||||
.contact(debitor.getBillingContact())
|
.contact(debitor.getBillingContact())
|
||||||
.build();
|
.build();
|
||||||
if (debitorRel.getRelAnchor() != null && debitorRel.getRelHolder() != null &&
|
if (debitorRel.getAnchor() != null && debitorRel.getHolder() != null &&
|
||||||
debitorRel.getContact() != null ) {
|
debitorRel.getContact() != null ) {
|
||||||
relationships.put(relationshipId++, debitorRel);
|
relations.put(relationId++, debitorRel);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -288,28 +288,28 @@ public class ImportOfficeData extends ContextBasedTest {
|
|||||||
22=Membership(M-1102200, ?? Test PS, D-1102200, [2021-04-01,), NONE)
|
22=Membership(M-1102200, ?? Test PS, D-1102200, [2021-04-01,), NONE)
|
||||||
}
|
}
|
||||||
""");
|
""");
|
||||||
assertThat(toFormattedString(relationships)).isEqualToIgnoringWhitespace("""
|
assertThat(toFormattedString(relations)).isEqualToIgnoringWhitespace("""
|
||||||
{
|
{
|
||||||
2000000=rel(relAnchor='LP Hostsharing eG', relType='PARTNER', relHolder='NP Mellies, Michael', contact='Herr Michael Mellies '),
|
2000000=rel(anchor='LP Hostsharing eG', type='PARTNER', holder='NP Mellies, Michael', contact='Herr Michael Mellies '),
|
||||||
2000001=rel(relAnchor='LP Hostsharing eG', relType='PARTNER', relHolder='LP JM GmbH', contact='Herr Philip Meyer-Contract , JM GmbH'),
|
2000001=rel(anchor='LP Hostsharing eG', type='PARTNER', holder='LP JM GmbH', contact='Herr Philip Meyer-Contract , JM GmbH'),
|
||||||
2000002=rel(relAnchor='LP Hostsharing eG', relType='PARTNER', relHolder='?? Test PS', contact='Petra Schmidt , Test PS'),
|
2000002=rel(anchor='LP Hostsharing eG', type='PARTNER', holder='?? Test PS', contact='Petra Schmidt , Test PS'),
|
||||||
2000003=rel(relAnchor='LP Hostsharing eG', relType='PARTNER', relHolder='null null, null'),
|
2000003=rel(anchor='LP Hostsharing eG', type='PARTNER', holder='null null, null'),
|
||||||
2000004=rel(relAnchor='NP Mellies, Michael', relType='OPERATIONS', relHolder='NP Mellies, Michael', contact='Herr Michael Mellies '),
|
2000004=rel(anchor='NP Mellies, Michael', type='OPERATIONS', holder='NP Mellies, Michael', contact='Herr Michael Mellies '),
|
||||||
2000005=rel(relAnchor='NP Mellies, Michael', relType='REPRESENTATIVE', relHolder='NP Mellies, Michael', contact='Herr Michael Mellies '),
|
2000005=rel(anchor='NP Mellies, Michael', type='REPRESENTATIVE', holder='NP Mellies, Michael', contact='Herr Michael Mellies '),
|
||||||
2000006=rel(relAnchor='LP JM GmbH', relType='EX_PARTNER', relHolder='LP JM e.K.', contact='JM e.K.'),
|
2000006=rel(anchor='LP JM GmbH', type='EX_PARTNER', holder='LP JM e.K.', contact='JM e.K.'),
|
||||||
2000007=rel(relAnchor='LP JM GmbH', relType='OPERATIONS', relHolder='LP JM GmbH', contact='Herr Andrew Meyer-Operation , JM GmbH'),
|
2000007=rel(anchor='LP JM GmbH', type='OPERATIONS', holder='LP JM GmbH', contact='Herr Andrew Meyer-Operation , JM GmbH'),
|
||||||
2000008=rel(relAnchor='LP JM GmbH', relType='VIP_CONTACT', relHolder='LP JM GmbH', contact='Herr Andrew Meyer-Operation , JM GmbH'),
|
2000008=rel(anchor='LP JM GmbH', type='VIP_CONTACT', holder='LP JM GmbH', contact='Herr Andrew Meyer-Operation , JM GmbH'),
|
||||||
2000009=rel(relAnchor='LP JM GmbH', relType='SUBSCRIBER', relMark='operations-announce', relHolder='LP JM GmbH', contact='Herr Andrew Meyer-Operation , JM GmbH'),
|
2000009=rel(anchor='LP JM GmbH', type='SUBSCRIBER', mark='operations-announce', holder='LP JM GmbH', contact='Herr Andrew Meyer-Operation , JM GmbH'),
|
||||||
2000010=rel(relAnchor='LP JM GmbH', relType='REPRESENTATIVE', relHolder='LP JM GmbH', contact='Herr Philip Meyer-Contract , JM GmbH'),
|
2000010=rel(anchor='LP JM GmbH', type='REPRESENTATIVE', holder='LP JM GmbH', contact='Herr Philip Meyer-Contract , JM GmbH'),
|
||||||
2000011=rel(relAnchor='LP JM GmbH', relType='SUBSCRIBER', relMark='members-announce', relHolder='LP JM GmbH', contact='Herr Philip Meyer-Contract , JM GmbH'),
|
2000011=rel(anchor='LP JM GmbH', type='SUBSCRIBER', mark='members-announce', holder='LP JM GmbH', contact='Herr Philip Meyer-Contract , JM GmbH'),
|
||||||
2000012=rel(relAnchor='LP JM GmbH', relType='SUBSCRIBER', relMark='customers-announce', relHolder='LP JM GmbH', contact='Herr Philip Meyer-Contract , JM GmbH'),
|
2000012=rel(anchor='LP JM GmbH', type='SUBSCRIBER', mark='customers-announce', holder='LP JM GmbH', contact='Herr Philip Meyer-Contract , JM GmbH'),
|
||||||
2000013=rel(relAnchor='LP JM GmbH', relType='VIP_CONTACT', relHolder='LP JM GmbH', contact='Frau Tammy Meyer-VIP , JM GmbH'),
|
2000013=rel(anchor='LP JM GmbH', type='VIP_CONTACT', holder='LP JM GmbH', contact='Frau Tammy Meyer-VIP , JM GmbH'),
|
||||||
2000014=rel(relAnchor='?? Test PS', relType='OPERATIONS', relHolder='?? Test PS', contact='Petra Schmidt , Test PS'),
|
2000014=rel(anchor='?? Test PS', type='OPERATIONS', holder='?? Test PS', contact='Petra Schmidt , Test PS'),
|
||||||
2000015=rel(relAnchor='?? Test PS', relType='REPRESENTATIVE', relHolder='?? Test PS', contact='Petra Schmidt , Test PS'),
|
2000015=rel(anchor='?? Test PS', type='REPRESENTATIVE', holder='?? Test PS', contact='Petra Schmidt , Test PS'),
|
||||||
2000016=rel(relAnchor='NP Mellies, Michael', relType='SUBSCRIBER', relMark='operations-announce', relHolder='NP Fanninga, Frauke', contact='Frau Frauke Fanninga '),
|
2000016=rel(anchor='NP Mellies, Michael', type='SUBSCRIBER', mark='operations-announce', holder='NP Fanninga, Frauke', contact='Frau Frauke Fanninga '),
|
||||||
2000017=rel(relAnchor='NP Mellies, Michael', relType='DEBITOR', relHolder='NP Mellies, Michael', contact='Herr Michael Mellies '),
|
2000017=rel(anchor='NP Mellies, Michael', type='DEBITOR', holder='NP Mellies, Michael', contact='Herr Michael Mellies '),
|
||||||
2000018=rel(relAnchor='LP JM GmbH', relType='DEBITOR', relHolder='LP JM GmbH', contact='Frau Dr. Jenny Meyer-Billing , JM GmbH'),
|
2000018=rel(anchor='LP JM GmbH', type='DEBITOR', holder='LP JM GmbH', contact='Frau Dr. Jenny Meyer-Billing , JM GmbH'),
|
||||||
2000019=rel(relAnchor='?? Test PS', relType='DEBITOR', relHolder='?? Test PS', contact='Petra Schmidt , Test PS')
|
2000019=rel(anchor='?? Test PS', type='DEBITOR', holder='?? Test PS', contact='Petra Schmidt , Test PS')
|
||||||
}
|
}
|
||||||
""");
|
""");
|
||||||
}
|
}
|
||||||
@ -419,20 +419,20 @@ public class ImportOfficeData extends ContextBasedTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Order(2009)
|
@Order(2009)
|
||||||
void removeEmptyRelationships() {
|
void removeEmptyRelations() {
|
||||||
assumeThatWeAreImportingControlledTestData();
|
assumeThatWeAreImportingControlledTestData();
|
||||||
|
|
||||||
// avoid a error when persisting the deliberetely invalid partner entry #99
|
// avoid a error when persisting the deliberetely invalid partner entry #99
|
||||||
final var idsToRemove = new HashSet<Integer>();
|
final var idsToRemove = new HashSet<Integer>();
|
||||||
relationships.forEach( (id, r) -> {
|
relations.forEach( (id, r) -> {
|
||||||
// such a record
|
// such a record
|
||||||
if (r.getContact() == null || r.getContact().getLabel() == null ||
|
if (r.getContact() == null || r.getContact().getLabel() == null ||
|
||||||
r.getRelHolder() == null | r.getRelHolder().getPersonType() == null ) {
|
r.getHolder() == null | r.getHolder().getPersonType() == null ) {
|
||||||
idsToRemove.add(id);
|
idsToRemove.add(id);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
assertThat(idsToRemove.size()).isEqualTo(1); // only from partner #99 (partner+contractual roles)
|
assertThat(idsToRemove.size()).isEqualTo(1); // only from partner #99 (partner+contractual roles)
|
||||||
idsToRemove.forEach(id -> relationships.remove(id));
|
idsToRemove.forEach(id -> relations.remove(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -495,7 +495,7 @@ public class ImportOfficeData extends ContextBasedTest {
|
|||||||
|
|
||||||
jpaAttempt.transacted(() -> {
|
jpaAttempt.transacted(() -> {
|
||||||
context(rbacSuperuser);
|
context(rbacSuperuser);
|
||||||
relationships.forEach(this::persist);
|
relations.forEach(this::persist);
|
||||||
}).assertSuccessful();
|
}).assertSuccessful();
|
||||||
|
|
||||||
jpaAttempt.transacted(() -> {
|
jpaAttempt.transacted(() -> {
|
||||||
@ -572,7 +572,7 @@ public class ImportOfficeData extends ContextBasedTest {
|
|||||||
em.createNativeQuery("delete from hs_office_bankaccount where true").executeUpdate();
|
em.createNativeQuery("delete from hs_office_bankaccount where true").executeUpdate();
|
||||||
em.createNativeQuery("delete from hs_office_partner where true").executeUpdate();
|
em.createNativeQuery("delete from hs_office_partner where true").executeUpdate();
|
||||||
em.createNativeQuery("delete from hs_office_partner_details where true").executeUpdate();
|
em.createNativeQuery("delete from hs_office_partner_details where true").executeUpdate();
|
||||||
em.createNativeQuery("delete from hs_office_relationship where true").executeUpdate();
|
em.createNativeQuery("delete from hs_office_relation where true").executeUpdate();
|
||||||
em.createNativeQuery("delete from hs_office_contact where true").executeUpdate();
|
em.createNativeQuery("delete from hs_office_contact where true").executeUpdate();
|
||||||
em.createNativeQuery("delete from hs_office_person where true").executeUpdate();
|
em.createNativeQuery("delete from hs_office_person where true").executeUpdate();
|
||||||
}).assertSuccessful();
|
}).assertSuccessful();
|
||||||
@ -676,18 +676,18 @@ public class ImportOfficeData extends ContextBasedTest {
|
|||||||
.forEach(rec -> {
|
.forEach(rec -> {
|
||||||
final var person = HsOfficePersonEntity.builder().build();
|
final var person = HsOfficePersonEntity.builder().build();
|
||||||
|
|
||||||
final var partnerRelationship = HsOfficeRelationshipEntity.builder()
|
final var partnerRelation = HsOfficeRelationEntity.builder()
|
||||||
.relHolder(person)
|
.holder(person)
|
||||||
.relType(HsOfficeRelationshipType.PARTNER)
|
.type(HsOfficeRelationType.PARTNER)
|
||||||
.relAnchor(mandant)
|
.anchor(mandant)
|
||||||
.contact(null) // is set during contacts import depending on assigned roles
|
.contact(null) // is set during contacts import depending on assigned roles
|
||||||
.build();
|
.build();
|
||||||
relationships.put(relationshipId++, partnerRelationship);
|
relations.put(relationId++, partnerRelation);
|
||||||
|
|
||||||
final var partner = HsOfficePartnerEntity.builder()
|
final var partner = HsOfficePartnerEntity.builder()
|
||||||
.partnerNumber(rec.getInteger("member_id"))
|
.partnerNumber(rec.getInteger("member_id"))
|
||||||
.details(HsOfficePartnerDetailsEntity.builder().build())
|
.details(HsOfficePartnerDetailsEntity.builder().build())
|
||||||
.partnerRole(partnerRelationship)
|
.partnerRel(partnerRelation)
|
||||||
.contact(null) // is set during contacts import depending on assigned roles
|
.contact(null) // is set during contacts import depending on assigned roles
|
||||||
.person(person)
|
.person(person)
|
||||||
.build();
|
.build();
|
||||||
@ -845,7 +845,7 @@ public class ImportOfficeData extends ContextBasedTest {
|
|||||||
final var debitor = debitors.get(bpId);
|
final var debitor = debitors.get(bpId);
|
||||||
|
|
||||||
final var partnerPerson = partner.getPerson();
|
final var partnerPerson = partner.getPerson();
|
||||||
if (containsPartnerRole(rec)) {
|
if (containsPartnerRel(rec)) {
|
||||||
initPerson(partner.getPerson(), rec);
|
initPerson(partner.getPerson(), rec);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -859,46 +859,46 @@ public class ImportOfficeData extends ContextBasedTest {
|
|||||||
final var contact = HsOfficeContactEntity.builder().build();
|
final var contact = HsOfficeContactEntity.builder().build();
|
||||||
initContact(contact, rec);
|
initContact(contact, rec);
|
||||||
|
|
||||||
if (containsPartnerRole(rec)) {
|
if (containsPartnerRel(rec)) {
|
||||||
assertThat(partner.getContact()).isNull();
|
assertThat(partner.getContact()).isNull();
|
||||||
partner.setContact(contact);
|
partner.setContact(contact);
|
||||||
partner.getPartnerRole().setContact(contact);
|
partner.getPartnerRel().setContact(contact);
|
||||||
}
|
}
|
||||||
if (containsRole(rec, "billing")) {
|
if (containsRole(rec, "billing")) {
|
||||||
assertThat(debitor.getBillingContact()).isNull();
|
assertThat(debitor.getBillingContact()).isNull();
|
||||||
debitor.setBillingContact(contact);
|
debitor.setBillingContact(contact);
|
||||||
}
|
}
|
||||||
if (containsRole(rec, "operation")) {
|
if (containsRole(rec, "operation")) {
|
||||||
addRelationship(partnerPerson, contactPerson, contact, HsOfficeRelationshipType.OPERATIONS);
|
addRelation(partnerPerson, contactPerson, contact, HsOfficeRelationType.OPERATIONS);
|
||||||
}
|
}
|
||||||
if (containsRole(rec, "contractual")) {
|
if (containsRole(rec, "contractual")) {
|
||||||
addRelationship(partnerPerson, contactPerson, contact, HsOfficeRelationshipType.REPRESENTATIVE);
|
addRelation(partnerPerson, contactPerson, contact, HsOfficeRelationType.REPRESENTATIVE);
|
||||||
}
|
}
|
||||||
if (containsRole(rec, "ex-partner")) {
|
if (containsRole(rec, "ex-partner")) {
|
||||||
addRelationship(partnerPerson, contactPerson, contact, HsOfficeRelationshipType.EX_PARTNER);
|
addRelation(partnerPerson, contactPerson, contact, HsOfficeRelationType.EX_PARTNER);
|
||||||
}
|
}
|
||||||
if (containsRole(rec, "vip-contact")) {
|
if (containsRole(rec, "vip-contact")) {
|
||||||
addRelationship(partnerPerson, contactPerson, contact, HsOfficeRelationshipType.VIP_CONTACT);
|
addRelation(partnerPerson, contactPerson, contact, HsOfficeRelationType.VIP_CONTACT);
|
||||||
}
|
}
|
||||||
for (String subscriberRole: SUBSCRIBER_ROLES) {
|
for (String subscriberRole: SUBSCRIBER_ROLES) {
|
||||||
if (containsRole(rec, subscriberRole)) {
|
if (containsRole(rec, subscriberRole)) {
|
||||||
addRelationship(partnerPerson, contactPerson, contact, HsOfficeRelationshipType.SUBSCRIBER)
|
addRelation(partnerPerson, contactPerson, contact, HsOfficeRelationType.SUBSCRIBER)
|
||||||
.setRelMark(subscriberRole.split(":")[1])
|
.setMark(subscriberRole.split(":")[1])
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
verifyContainsOnlyKnownRoles(rec.getString("roles"));
|
verifyContainsOnlyKnownRoles(rec.getString("roles"));
|
||||||
});
|
});
|
||||||
|
|
||||||
optionallyAddMissingContractualRelationships();
|
optionallyAddMissingContractualRelations();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void optionallyAddMissingContractualRelationships() {
|
private static void optionallyAddMissingContractualRelations() {
|
||||||
final var contractualMissing = new HashSet<Integer>();
|
final var contractualMissing = new HashSet<Integer>();
|
||||||
partners.forEach( (id, partner) -> {
|
partners.forEach( (id, partner) -> {
|
||||||
final var partnerPerson = partner.getPerson();
|
final var partnerPerson = partner.getPerson();
|
||||||
if (relationships.values().stream()
|
if (relations.values().stream()
|
||||||
.filter(rel -> rel.getRelAnchor() == partnerPerson && rel.getRelType() == HsOfficeRelationshipType.REPRESENTATIVE)
|
.filter(rel -> rel.getAnchor() == partnerPerson && rel.getType() == HsOfficeRelationType.REPRESENTATIVE)
|
||||||
.findFirst().isEmpty()) {
|
.findFirst().isEmpty()) {
|
||||||
contractualMissing.add(partner.getPartnerNumber());
|
contractualMissing.add(partner.getPartnerNumber());
|
||||||
}
|
}
|
||||||
@ -909,22 +909,22 @@ public class ImportOfficeData extends ContextBasedTest {
|
|||||||
return ("," + roles + ",").contains("," + role + ",");
|
return ("," + roles + ",").contains("," + role + ",");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean containsPartnerRole(final Record rec) {
|
private static boolean containsPartnerRel(final Record rec) {
|
||||||
return containsRole(rec, "partner");
|
return containsRole(rec, "partner");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static HsOfficeRelationshipEntity addRelationship(
|
private static HsOfficeRelationEntity addRelation(
|
||||||
final HsOfficePersonEntity partnerPerson,
|
final HsOfficePersonEntity partnerPerson,
|
||||||
final HsOfficePersonEntity contactPerson,
|
final HsOfficePersonEntity contactPerson,
|
||||||
final HsOfficeContactEntity contact,
|
final HsOfficeContactEntity contact,
|
||||||
final HsOfficeRelationshipType representative) {
|
final HsOfficeRelationType representative) {
|
||||||
final var rel = HsOfficeRelationshipEntity.builder()
|
final var rel = HsOfficeRelationEntity.builder()
|
||||||
.relAnchor(partnerPerson)
|
.anchor(partnerPerson)
|
||||||
.relHolder(contactPerson)
|
.holder(contactPerson)
|
||||||
.contact(contact)
|
.contact(contact)
|
||||||
.relType(representative)
|
.type(representative)
|
||||||
.build();
|
.build();
|
||||||
relationships.put(relationshipId++, rel);
|
relations.put(relationId++, rel);
|
||||||
return rel;
|
return rel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,9 +7,9 @@ import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactEntity;
|
|||||||
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRepository;
|
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRepository;
|
||||||
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity;
|
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity;
|
||||||
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRepository;
|
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRepository;
|
||||||
import net.hostsharing.hsadminng.hs.office.relationship.HsOfficeRelationshipEntity;
|
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationEntity;
|
||||||
import net.hostsharing.hsadminng.hs.office.relationship.HsOfficeRelationshipRepository;
|
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRepository;
|
||||||
import net.hostsharing.hsadminng.hs.office.relationship.HsOfficeRelationshipType;
|
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationType;
|
||||||
import net.hostsharing.hsadminng.hs.office.test.ContextBasedTestWithCleanup;
|
import net.hostsharing.hsadminng.hs.office.test.ContextBasedTestWithCleanup;
|
||||||
import net.hostsharing.test.Accepts;
|
import net.hostsharing.test.Accepts;
|
||||||
import net.hostsharing.test.JpaAttempt;
|
import net.hostsharing.test.JpaAttempt;
|
||||||
@ -41,7 +41,7 @@ class HsOfficePartnerControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
|||||||
HsOfficePartnerRepository partnerRepo;
|
HsOfficePartnerRepository partnerRepo;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
HsOfficeRelationshipRepository relationshipRepository;
|
HsOfficeRelationRepository relationRepository;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
HsOfficePersonRepository personRepo;
|
HsOfficePersonRepository personRepo;
|
||||||
@ -102,9 +102,9 @@ class HsOfficePartnerControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
|||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
"partnerNumber": "20002",
|
"partnerNumber": "20002",
|
||||||
"partnerRole": {
|
"partnerRel": {
|
||||||
"relAnchorUuid": "%s",
|
"anchorUuid": "%s",
|
||||||
"relHolderUuid": "%s",
|
"holderUuid": "%s",
|
||||||
"contactUuid": "%s"
|
"contactUuid": "%s"
|
||||||
},
|
},
|
||||||
"personUuid": "%s",
|
"personUuid": "%s",
|
||||||
@ -155,9 +155,9 @@ class HsOfficePartnerControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
|||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
"partnerNumber": "20003",
|
"partnerNumber": "20003",
|
||||||
"partnerRole": {
|
"partnerRel": {
|
||||||
"relAnchorUuid": "%s",
|
"anchorUuid": "%s",
|
||||||
"relHolderUuid": "%s",
|
"holderUuid": "%s",
|
||||||
"contactUuid": "%s"
|
"contactUuid": "%s"
|
||||||
},
|
},
|
||||||
"personUuid": "%s",
|
"personUuid": "%s",
|
||||||
@ -193,9 +193,9 @@ class HsOfficePartnerControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
|||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
"partnerNumber": "20004",
|
"partnerNumber": "20004",
|
||||||
"partnerRole": {
|
"partnerRel": {
|
||||||
"relAnchorUuid": "%s",
|
"anchorUuid": "%s",
|
||||||
"relHolderUuid": "%s",
|
"holderUuid": "%s",
|
||||||
"contactUuid": "%s"
|
"contactUuid": "%s"
|
||||||
},
|
},
|
||||||
"personUuid": "%s",
|
"personUuid": "%s",
|
||||||
@ -413,7 +413,7 @@ class HsOfficePartnerControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
|||||||
|
|
||||||
// then the given partner is gone
|
// then the given partner is gone
|
||||||
assertThat(partnerRepo.findByUuid(givenPartner.getUuid())).isEmpty();
|
assertThat(partnerRepo.findByUuid(givenPartner.getUuid())).isEmpty();
|
||||||
assertThat(relationshipRepository.findByUuid(givenPartner.getPartnerRole().getUuid())).isEmpty();
|
assertThat(relationRepository.findByUuid(givenPartner.getPartnerRel().getUuid())).isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -465,15 +465,15 @@ class HsOfficePartnerControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
|||||||
final var givenPerson = personRepo.findPersonByOptionalNameLike("Erben Bessler").get(0);
|
final var givenPerson = personRepo.findPersonByOptionalNameLike("Erben Bessler").get(0);
|
||||||
final var givenContact = contactRepo.findContactByOptionalLabelLike("fourth contact").get(0);
|
final var givenContact = contactRepo.findContactByOptionalLabelLike("fourth contact").get(0);
|
||||||
|
|
||||||
final var partnerRole = new HsOfficeRelationshipEntity();
|
final var partnerRel = new HsOfficeRelationEntity();
|
||||||
partnerRole.setRelType(HsOfficeRelationshipType.PARTNER);
|
partnerRel.setType(HsOfficeRelationType.PARTNER);
|
||||||
partnerRole.setRelAnchor(givenMandantPerson);
|
partnerRel.setAnchor(givenMandantPerson);
|
||||||
partnerRole.setRelHolder(givenPerson);
|
partnerRel.setHolder(givenPerson);
|
||||||
partnerRole.setContact(givenContact);
|
partnerRel.setContact(givenContact);
|
||||||
em.persist(partnerRole);
|
em.persist(partnerRel);
|
||||||
|
|
||||||
final var newPartner = HsOfficePartnerEntity.builder()
|
final var newPartner = HsOfficePartnerEntity.builder()
|
||||||
.partnerRole(partnerRole)
|
.partnerRel(partnerRel)
|
||||||
.partnerNumber(partnerNumber)
|
.partnerNumber(partnerNumber)
|
||||||
.person(givenPerson)
|
.person(givenPerson)
|
||||||
.contact(givenContact)
|
.contact(givenContact)
|
||||||
@ -492,6 +492,6 @@ class HsOfficePartnerControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
|||||||
cleanupAllNew(HsOfficePartnerEntity.class);
|
cleanupAllNew(HsOfficePartnerEntity.class);
|
||||||
|
|
||||||
// TODO: should not be necessary anymore, once it's deleted via after delete trigger
|
// TODO: should not be necessary anymore, once it's deleted via after delete trigger
|
||||||
cleanupAllNew(HsOfficeRelationshipEntity.class);
|
cleanupAllNew(HsOfficeRelationEntity.class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,8 +3,8 @@ package net.hostsharing.hsadminng.hs.office.partner;
|
|||||||
import net.hostsharing.hsadminng.context.Context;
|
import net.hostsharing.hsadminng.context.Context;
|
||||||
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactEntity;
|
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactEntity;
|
||||||
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity;
|
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity;
|
||||||
import net.hostsharing.hsadminng.hs.office.relationship.HsOfficeRelationshipEntity;
|
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationEntity;
|
||||||
import net.hostsharing.hsadminng.hs.office.relationship.HsOfficeRelationshipRepository;
|
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRepository;
|
||||||
import net.hostsharing.hsadminng.mapper.Mapper;
|
import net.hostsharing.hsadminng.mapper.Mapper;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Nested;
|
import org.junit.jupiter.api.Nested;
|
||||||
@ -54,7 +54,7 @@ class HsOfficePartnerControllerRestTest {
|
|||||||
HsOfficePartnerRepository partnerRepo;
|
HsOfficePartnerRepository partnerRepo;
|
||||||
|
|
||||||
@MockBean
|
@MockBean
|
||||||
HsOfficeRelationshipRepository relationshipRepo;
|
HsOfficeRelationRepository relationRepo;
|
||||||
|
|
||||||
@MockBean
|
@MockBean
|
||||||
EntityManager em;
|
EntityManager em;
|
||||||
@ -100,9 +100,9 @@ class HsOfficePartnerControllerRestTest {
|
|||||||
.content("""
|
.content("""
|
||||||
{
|
{
|
||||||
"partnerNumber": "20002",
|
"partnerNumber": "20002",
|
||||||
"partnerRole": {
|
"partnerRel": {
|
||||||
"relAnchorUuid": "%s",
|
"anchorUuid": "%s",
|
||||||
"relHolderUuid": "%s",
|
"holderUuid": "%s",
|
||||||
"contactUuid": "%s"
|
"contactUuid": "%s"
|
||||||
},
|
},
|
||||||
"personUuid": "%s",
|
"personUuid": "%s",
|
||||||
@ -137,9 +137,9 @@ class HsOfficePartnerControllerRestTest {
|
|||||||
.content("""
|
.content("""
|
||||||
{
|
{
|
||||||
"partnerNumber": "20002",
|
"partnerNumber": "20002",
|
||||||
"partnerRole": {
|
"partnerRel": {
|
||||||
"relAnchorUuid": "%s",
|
"anchorUuid": "%s",
|
||||||
"relHolderUuid": "%s",
|
"holderUuid": "%s",
|
||||||
"contactUuid": "%s"
|
"contactUuid": "%s"
|
||||||
},
|
},
|
||||||
"personUuid": "%s",
|
"personUuid": "%s",
|
||||||
@ -175,11 +175,11 @@ class HsOfficePartnerControllerRestTest {
|
|||||||
when(partnerRepo.findByUuid(givenPartnerUuid)).thenReturn(Optional.of(partnerMock));
|
when(partnerRepo.findByUuid(givenPartnerUuid)).thenReturn(Optional.of(partnerMock));
|
||||||
when(partnerRepo.deleteByUuid(givenPartnerUuid)).thenReturn(0);
|
when(partnerRepo.deleteByUuid(givenPartnerUuid)).thenReturn(0);
|
||||||
|
|
||||||
final UUID givenRelationshipUuid = UUID.randomUUID();
|
final UUID givenRelationUuid = UUID.randomUUID();
|
||||||
when(partnerMock.getPartnerRole()).thenReturn(HsOfficeRelationshipEntity.builder()
|
when(partnerMock.getPartnerRel()).thenReturn(HsOfficeRelationEntity.builder()
|
||||||
.uuid(givenRelationshipUuid)
|
.uuid(givenRelationUuid)
|
||||||
.build());
|
.build());
|
||||||
when(relationshipRepo.deleteByUuid(givenRelationshipUuid)).thenReturn(0);
|
when(relationRepo.deleteByUuid(givenRelationUuid)).thenReturn(0);
|
||||||
|
|
||||||
// when
|
// when
|
||||||
mockMvc.perform(MockMvcRequestBuilders
|
mockMvc.perform(MockMvcRequestBuilders
|
||||||
@ -193,18 +193,18 @@ class HsOfficePartnerControllerRestTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void respondBadRequest_ifRelationshipCannotBeDeleted() throws Exception {
|
void respondBadRequest_ifRelationCannotBeDeleted() throws Exception {
|
||||||
// given
|
// given
|
||||||
final UUID givenPartnerUuid = UUID.randomUUID();
|
final UUID givenPartnerUuid = UUID.randomUUID();
|
||||||
when(partnerRepo.findByUuid(givenPartnerUuid)).thenReturn(Optional.of(partnerMock));
|
when(partnerRepo.findByUuid(givenPartnerUuid)).thenReturn(Optional.of(partnerMock));
|
||||||
when(partnerRepo.deleteByUuid(givenPartnerUuid)).thenReturn(1);
|
when(partnerRepo.deleteByUuid(givenPartnerUuid)).thenReturn(1);
|
||||||
when(relationshipRepo.deleteByUuid(any())).thenReturn(0);
|
when(relationRepo.deleteByUuid(any())).thenReturn(0);
|
||||||
|
|
||||||
final UUID givenRelationshipUuid = UUID.randomUUID();
|
final UUID givenRelationUuid = UUID.randomUUID();
|
||||||
when(partnerMock.getPartnerRole()).thenReturn(HsOfficeRelationshipEntity.builder()
|
when(partnerMock.getPartnerRel()).thenReturn(HsOfficeRelationEntity.builder()
|
||||||
.uuid(givenRelationshipUuid)
|
.uuid(givenRelationUuid)
|
||||||
.build());
|
.build());
|
||||||
when(relationshipRepo.deleteByUuid(givenRelationshipUuid)).thenReturn(0);
|
when(relationRepo.deleteByUuid(givenRelationUuid)).thenReturn(0);
|
||||||
|
|
||||||
// when
|
// when
|
||||||
mockMvc.perform(MockMvcRequestBuilders
|
mockMvc.perform(MockMvcRequestBuilders
|
||||||
|
@ -3,9 +3,9 @@ package net.hostsharing.hsadminng.hs.office.partner;
|
|||||||
import net.hostsharing.hsadminng.context.Context;
|
import net.hostsharing.hsadminng.context.Context;
|
||||||
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRepository;
|
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRepository;
|
||||||
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRepository;
|
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRepository;
|
||||||
import net.hostsharing.hsadminng.hs.office.relationship.HsOfficeRelationshipEntity;
|
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationEntity;
|
||||||
import net.hostsharing.hsadminng.hs.office.relationship.HsOfficeRelationshipRepository;
|
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRepository;
|
||||||
import net.hostsharing.hsadminng.hs.office.relationship.HsOfficeRelationshipType;
|
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationType;
|
||||||
import net.hostsharing.hsadminng.hs.office.test.ContextBasedTestWithCleanup;
|
import net.hostsharing.hsadminng.hs.office.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;
|
||||||
@ -43,7 +43,7 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTestWithClean
|
|||||||
HsOfficePartnerRepository partnerRepo;
|
HsOfficePartnerRepository partnerRepo;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
HsOfficeRelationshipRepository relationshipRepo;
|
HsOfficeRelationRepository relationRepo;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
HsOfficePersonRepository personRepo;
|
HsOfficePersonRepository personRepo;
|
||||||
@ -80,19 +80,19 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTestWithClean
|
|||||||
final var givenPartnerPerson = personRepo.findPersonByOptionalNameLike("First GmbH").get(0);
|
final var givenPartnerPerson = personRepo.findPersonByOptionalNameLike("First GmbH").get(0);
|
||||||
final var givenContact = contactRepo.findContactByOptionalLabelLike("first contact").get(0);
|
final var givenContact = contactRepo.findContactByOptionalLabelLike("first contact").get(0);
|
||||||
|
|
||||||
final var partnerRole = HsOfficeRelationshipEntity.builder()
|
final var partnerRel = HsOfficeRelationEntity.builder()
|
||||||
.relHolder(givenPartnerPerson)
|
.holder(givenPartnerPerson)
|
||||||
.relType(HsOfficeRelationshipType.PARTNER)
|
.type(HsOfficeRelationType.PARTNER)
|
||||||
.relAnchor(givenMandantorPerson)
|
.anchor(givenMandantorPerson)
|
||||||
.contact(givenContact)
|
.contact(givenContact)
|
||||||
.build();
|
.build();
|
||||||
relationshipRepo.save(partnerRole);
|
relationRepo.save(partnerRel);
|
||||||
|
|
||||||
// when
|
// when
|
||||||
final var result = attempt(em, () -> {
|
final var result = attempt(em, () -> {
|
||||||
final var newPartner = HsOfficePartnerEntity.builder()
|
final var newPartner = HsOfficePartnerEntity.builder()
|
||||||
.partnerNumber(20031)
|
.partnerNumber(20031)
|
||||||
.partnerRole(partnerRole)
|
.partnerRel(partnerRel)
|
||||||
.person(givenPartnerPerson)
|
.person(givenPartnerPerson)
|
||||||
.contact(givenContact)
|
.contact(givenContact)
|
||||||
.details(HsOfficePartnerDetailsEntity.builder()
|
.details(HsOfficePartnerDetailsEntity.builder()
|
||||||
@ -125,17 +125,17 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTestWithClean
|
|||||||
final var givenContact = contactRepo.findContactByOptionalLabelLike("fourth contact").get(0);
|
final var givenContact = contactRepo.findContactByOptionalLabelLike("fourth contact").get(0);
|
||||||
final var givenMandantPerson = personRepo.findPersonByOptionalNameLike("Hostsharing eG").get(0);
|
final var givenMandantPerson = personRepo.findPersonByOptionalNameLike("Hostsharing eG").get(0);
|
||||||
|
|
||||||
final var newRelationship = HsOfficeRelationshipEntity.builder()
|
final var newRelation = HsOfficeRelationEntity.builder()
|
||||||
.relHolder(givenPartnerPerson)
|
.holder(givenPartnerPerson)
|
||||||
.relType(HsOfficeRelationshipType.PARTNER)
|
.type(HsOfficeRelationType.PARTNER)
|
||||||
.relAnchor(givenMandantPerson)
|
.anchor(givenMandantPerson)
|
||||||
.contact(givenContact)
|
.contact(givenContact)
|
||||||
.build();
|
.build();
|
||||||
relationshipRepo.save(newRelationship);
|
relationRepo.save(newRelation);
|
||||||
|
|
||||||
final var newPartner = HsOfficePartnerEntity.builder()
|
final var newPartner = HsOfficePartnerEntity.builder()
|
||||||
.partnerNumber(20032)
|
.partnerNumber(20032)
|
||||||
.partnerRole(newRelationship)
|
.partnerRel(newRelation)
|
||||||
.person(givenPartnerPerson)
|
.person(givenPartnerPerson)
|
||||||
.contact(givenContact)
|
.contact(givenContact)
|
||||||
.details(HsOfficePartnerDetailsEntity.builder().build())
|
.details(HsOfficePartnerDetailsEntity.builder().build())
|
||||||
@ -146,9 +146,9 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTestWithClean
|
|||||||
// then
|
// then
|
||||||
assertThat(distinctRoleNamesOf(rawRoleRepo.findAll())).containsExactlyInAnyOrder(Array.from(
|
assertThat(distinctRoleNamesOf(rawRoleRepo.findAll())).containsExactlyInAnyOrder(Array.from(
|
||||||
initialRoleNames,
|
initialRoleNames,
|
||||||
"hs_office_relationship#HostsharingeG-with-PARTNER-ErbenBesslerMelBessler.admin",
|
"hs_office_relation#HostsharingeG-with-PARTNER-ErbenBesslerMelBessler.admin",
|
||||||
"hs_office_relationship#HostsharingeG-with-PARTNER-ErbenBesslerMelBessler.owner",
|
"hs_office_relation#HostsharingeG-with-PARTNER-ErbenBesslerMelBessler.owner",
|
||||||
"hs_office_relationship#HostsharingeG-with-PARTNER-ErbenBesslerMelBessler.tenant",
|
"hs_office_relation#HostsharingeG-with-PARTNER-ErbenBesslerMelBessler.tenant",
|
||||||
"hs_office_partner#20032:ErbenBesslerMelBessler-fourthcontact.admin",
|
"hs_office_partner#20032:ErbenBesslerMelBessler-fourthcontact.admin",
|
||||||
"hs_office_partner#20032:ErbenBesslerMelBessler-fourthcontact.agent",
|
"hs_office_partner#20032:ErbenBesslerMelBessler-fourthcontact.agent",
|
||||||
"hs_office_partner#20032:ErbenBesslerMelBessler-fourthcontact.owner",
|
"hs_office_partner#20032:ErbenBesslerMelBessler-fourthcontact.owner",
|
||||||
@ -160,25 +160,25 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTestWithClean
|
|||||||
.map(s -> s.replace("hs_office_", ""))
|
.map(s -> s.replace("hs_office_", ""))
|
||||||
.containsExactlyInAnyOrder(distinct(fromFormatted(
|
.containsExactlyInAnyOrder(distinct(fromFormatted(
|
||||||
initialGrantNames,
|
initialGrantNames,
|
||||||
// relationship - TODO: check and cleanup
|
// relation - TODO: check and cleanup
|
||||||
"{ grant role person#HostsharingeG.tenant to role person#EBess.admin by system and assume }",
|
"{ grant role person#HostsharingeG.tenant to role person#EBess.admin by system and assume }",
|
||||||
"{ grant role person#EBess.tenant to role person#HostsharingeG.admin by system and assume }",
|
"{ grant role person#EBess.tenant to role person#HostsharingeG.admin by system and assume }",
|
||||||
"{ grant role relationship#HostsharingeG-with-PARTNER-EBess.tenant to role partner#20032:EBess-4th.admin by system and assume }",
|
"{ grant role relation#HostsharingeG-with-PARTNER-EBess.tenant to role partner#20032:EBess-4th.admin by system and assume }",
|
||||||
"{ grant role relationship#HostsharingeG-with-PARTNER-EBess.tenant to role partner#20032:EBess-4th.tenant by system and assume }",
|
"{ grant role relation#HostsharingeG-with-PARTNER-EBess.tenant to role partner#20032:EBess-4th.tenant by system and assume }",
|
||||||
"{ grant role partner#20032:EBess-4th.agent to role relationship#HostsharingeG-with-PARTNER-EBess.admin by system and assume }",
|
"{ grant role partner#20032:EBess-4th.agent to role relation#HostsharingeG-with-PARTNER-EBess.admin by system and assume }",
|
||||||
"{ grant role relationship#HostsharingeG-with-PARTNER-EBess.owner to role global#global.admin by system and assume }",
|
"{ grant role relation#HostsharingeG-with-PARTNER-EBess.owner to role global#global.admin by system and assume }",
|
||||||
"{ grant role relationship#HostsharingeG-with-PARTNER-EBess.tenant to role contact#4th.admin by system and assume }",
|
"{ grant role relation#HostsharingeG-with-PARTNER-EBess.tenant to role contact#4th.admin by system and assume }",
|
||||||
"{ grant role relationship#HostsharingeG-with-PARTNER-EBess.tenant to role person#EBess.admin by system and assume }",
|
"{ grant role relation#HostsharingeG-with-PARTNER-EBess.tenant to role person#EBess.admin by system and assume }",
|
||||||
"{ grant role relationship#HostsharingeG-with-PARTNER-EBess.owner to role person#HostsharingeG.admin by system and assume }",
|
"{ grant role relation#HostsharingeG-with-PARTNER-EBess.owner to role person#HostsharingeG.admin by system and assume }",
|
||||||
"{ grant role relationship#HostsharingeG-with-PARTNER-EBess.tenant to role person#HostsharingeG.admin by system and assume }",
|
"{ grant role relation#HostsharingeG-with-PARTNER-EBess.tenant to role person#HostsharingeG.admin by system and assume }",
|
||||||
"{ grant perm UPDATE on relationship#HostsharingeG-with-PARTNER-EBess to role relationship#HostsharingeG-with-PARTNER-EBess.admin by system and assume }",
|
"{ grant perm UPDATE on relation#HostsharingeG-with-PARTNER-EBess to role relation#HostsharingeG-with-PARTNER-EBess.admin by system and assume }",
|
||||||
"{ grant role relationship#HostsharingeG-with-PARTNER-EBess.tenant to role relationship#HostsharingeG-with-PARTNER-EBess.admin by system and assume }",
|
"{ grant role relation#HostsharingeG-with-PARTNER-EBess.tenant to role relation#HostsharingeG-with-PARTNER-EBess.admin by system and assume }",
|
||||||
"{ grant perm DELETE on relationship#HostsharingeG-with-PARTNER-EBess to role relationship#HostsharingeG-with-PARTNER-EBess.owner by system and assume }",
|
"{ grant perm DELETE on relation#HostsharingeG-with-PARTNER-EBess to role relation#HostsharingeG-with-PARTNER-EBess.owner by system and assume }",
|
||||||
"{ grant role relationship#HostsharingeG-with-PARTNER-EBess.admin to role relationship#HostsharingeG-with-PARTNER-EBess.owner by system and assume }",
|
"{ grant role relation#HostsharingeG-with-PARTNER-EBess.admin to role relation#HostsharingeG-with-PARTNER-EBess.owner by system and assume }",
|
||||||
"{ grant perm SELECT on relationship#HostsharingeG-with-PARTNER-EBess to role relationship#HostsharingeG-with-PARTNER-EBess.tenant by system and assume }",
|
"{ grant perm SELECT on relation#HostsharingeG-with-PARTNER-EBess to role relation#HostsharingeG-with-PARTNER-EBess.tenant by system and assume }",
|
||||||
"{ grant role contact#4th.tenant to role relationship#HostsharingeG-with-PARTNER-EBess.tenant by system and assume }",
|
"{ grant role contact#4th.tenant to role relation#HostsharingeG-with-PARTNER-EBess.tenant by system and assume }",
|
||||||
"{ grant role person#EBess.tenant to role relationship#HostsharingeG-with-PARTNER-EBess.tenant by system and assume }",
|
"{ grant role person#EBess.tenant to role relation#HostsharingeG-with-PARTNER-EBess.tenant by system and assume }",
|
||||||
"{ grant role person#HostsharingeG.tenant to role relationship#HostsharingeG-with-PARTNER-EBess.tenant by system and assume }",
|
"{ grant role person#HostsharingeG.tenant to role relation#HostsharingeG-with-PARTNER-EBess.tenant by system and assume }",
|
||||||
|
|
||||||
// owner
|
// owner
|
||||||
"{ grant perm DELETE on partner#20032:EBess-4th to role partner#20032:EBess-4th.owner by system and assume }",
|
"{ grant perm DELETE on partner#20032:EBess-4th to role partner#20032:EBess-4th.owner by system and assume }",
|
||||||
@ -426,15 +426,15 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTestWithClean
|
|||||||
// when
|
// when
|
||||||
final var result = jpaAttempt.transacted(() -> {
|
final var result = jpaAttempt.transacted(() -> {
|
||||||
context("superuser-alex@hostsharing.net");
|
context("superuser-alex@hostsharing.net");
|
||||||
// TODO: should deleting a partner automatically delete the PARTNER relationship? (same for debitor)
|
// TODO: should deleting a partner automatically delete the PARTNER relation? (same for debitor)
|
||||||
// TODO: why did the test cleanup check does not notice this, if missing?
|
// TODO: why did the test cleanup check does not notice this, if missing?
|
||||||
return partnerRepo.deleteByUuid(givenPartner.getUuid()) +
|
return partnerRepo.deleteByUuid(givenPartner.getUuid()) +
|
||||||
relationshipRepo.deleteByUuid(givenPartner.getPartnerRole().getUuid());
|
relationRepo.deleteByUuid(givenPartner.getPartnerRel().getUuid());
|
||||||
});
|
});
|
||||||
|
|
||||||
// then
|
// then
|
||||||
result.assertSuccessful();
|
result.assertSuccessful();
|
||||||
assertThat(result.returnedValue()).isEqualTo(2); // partner+relationship
|
assertThat(result.returnedValue()).isEqualTo(2); // partner+relation
|
||||||
assertThat(distinctRoleNamesOf(rawRoleRepo.findAll())).containsExactlyInAnyOrder(initialRoleNames);
|
assertThat(distinctRoleNamesOf(rawRoleRepo.findAll())).containsExactlyInAnyOrder(initialRoleNames);
|
||||||
assertThat(distinctGrantDisplaysOf(rawGrantRepo.findAll())).containsExactlyInAnyOrder(initialGrantNames);
|
assertThat(distinctGrantDisplaysOf(rawGrantRepo.findAll())).containsExactlyInAnyOrder(initialGrantNames);
|
||||||
}
|
}
|
||||||
@ -466,17 +466,17 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTestWithClean
|
|||||||
final var givenPartnerPerson = personRepo.findPersonByOptionalNameLike(person).get(0);
|
final var givenPartnerPerson = personRepo.findPersonByOptionalNameLike(person).get(0);
|
||||||
final var givenContact = contactRepo.findContactByOptionalLabelLike(contact).get(0);
|
final var givenContact = contactRepo.findContactByOptionalLabelLike(contact).get(0);
|
||||||
|
|
||||||
final var partnerRole = HsOfficeRelationshipEntity.builder()
|
final var partnerRel = HsOfficeRelationEntity.builder()
|
||||||
.relHolder(givenPartnerPerson)
|
.holder(givenPartnerPerson)
|
||||||
.relType(HsOfficeRelationshipType.PARTNER)
|
.type(HsOfficeRelationType.PARTNER)
|
||||||
.relAnchor(givenMandantorPerson)
|
.anchor(givenMandantorPerson)
|
||||||
.contact(givenContact)
|
.contact(givenContact)
|
||||||
.build();
|
.build();
|
||||||
relationshipRepo.save(partnerRole);
|
relationRepo.save(partnerRel);
|
||||||
|
|
||||||
final var newPartner = HsOfficePartnerEntity.builder()
|
final var newPartner = HsOfficePartnerEntity.builder()
|
||||||
.partnerNumber(partnerNumber)
|
.partnerNumber(partnerNumber)
|
||||||
.partnerRole(partnerRole)
|
.partnerRel(partnerRel)
|
||||||
.person(givenPartnerPerson)
|
.person(givenPartnerPerson)
|
||||||
.contact(givenContact)
|
.contact(givenContact)
|
||||||
.details(HsOfficePartnerDetailsEntity.builder().build())
|
.details(HsOfficePartnerDetailsEntity.builder().build())
|
||||||
@ -502,7 +502,7 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTestWithClean
|
|||||||
void cleanup() {
|
void cleanup() {
|
||||||
cleanupAllNew(HsOfficePartnerDetailsEntity.class); // TODO: should not be necessary
|
cleanupAllNew(HsOfficePartnerDetailsEntity.class); // TODO: should not be necessary
|
||||||
cleanupAllNew(HsOfficePartnerEntity.class);
|
cleanupAllNew(HsOfficePartnerEntity.class);
|
||||||
cleanupAllNew(HsOfficeRelationshipEntity.class);
|
cleanupAllNew(HsOfficeRelationEntity.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String[] distinct(final String[] strings) {
|
private String[] distinct(final String[] strings) {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package net.hostsharing.hsadminng.hs.office.relationship;
|
package net.hostsharing.hsadminng.hs.office.relation;
|
||||||
|
|
||||||
import io.restassured.RestAssured;
|
import io.restassured.RestAssured;
|
||||||
import io.restassured.http.ContentType;
|
import io.restassured.http.ContentType;
|
||||||
@ -7,7 +7,7 @@ import net.hostsharing.test.Accepts;
|
|||||||
import net.hostsharing.hsadminng.HsadminNgApplication;
|
import net.hostsharing.hsadminng.HsadminNgApplication;
|
||||||
import net.hostsharing.hsadminng.context.Context;
|
import net.hostsharing.hsadminng.context.Context;
|
||||||
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRepository;
|
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRepository;
|
||||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeRelationshipTypeResource;
|
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeRelationTypeResource;
|
||||||
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRepository;
|
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRepository;
|
||||||
import net.hostsharing.test.JpaAttempt;
|
import net.hostsharing.test.JpaAttempt;
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
@ -31,7 +31,7 @@ import static org.hamcrest.Matchers.startsWith;
|
|||||||
classes = { HsadminNgApplication.class, JpaAttempt.class }
|
classes = { HsadminNgApplication.class, JpaAttempt.class }
|
||||||
)
|
)
|
||||||
@Transactional
|
@Transactional
|
||||||
class HsOfficeRelationshipControllerAcceptanceTest extends ContextBasedTestWithCleanup {
|
class HsOfficeRelationControllerAcceptanceTest extends ContextBasedTestWithCleanup {
|
||||||
|
|
||||||
public static final UUID GIVEN_NON_EXISTING_HOLDER_PERSON_UUID = UUID.fromString("00000000-0000-0000-0000-000000000000");
|
public static final UUID GIVEN_NON_EXISTING_HOLDER_PERSON_UUID = UUID.fromString("00000000-0000-0000-0000-000000000000");
|
||||||
@LocalServerPort
|
@LocalServerPort
|
||||||
@ -44,7 +44,7 @@ class HsOfficeRelationshipControllerAcceptanceTest extends ContextBasedTestWithC
|
|||||||
Context contextMock;
|
Context contextMock;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
HsOfficeRelationshipRepository relationshipRepo;
|
HsOfficeRelationRepository relationRepo;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
HsOfficePersonRepository personRepo;
|
HsOfficePersonRepository personRepo;
|
||||||
@ -56,11 +56,11 @@ class HsOfficeRelationshipControllerAcceptanceTest extends ContextBasedTestWithC
|
|||||||
JpaAttempt jpaAttempt;
|
JpaAttempt jpaAttempt;
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
@Accepts({ "Relationship:F(Find)" })
|
@Accepts({ "Relation:F(Find)" })
|
||||||
class ListRelationships {
|
class ListRelations {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void globalAdmin_withoutAssumedRoles_canViewAllRelationshipsOfGivenPersonAndType_ifNoCriteriaGiven() throws JSONException {
|
void globalAdmin_withoutAssumedRoles_canViewAllRelationsOfGivenPersonAndType_ifNoCriteriaGiven() throws JSONException {
|
||||||
|
|
||||||
// given
|
// given
|
||||||
context.define("superuser-alex@hostsharing.net");
|
context.define("superuser-alex@hostsharing.net");
|
||||||
@ -71,45 +71,45 @@ class HsOfficeRelationshipControllerAcceptanceTest extends ContextBasedTestWithC
|
|||||||
.header("current-user", "superuser-alex@hostsharing.net")
|
.header("current-user", "superuser-alex@hostsharing.net")
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.get("http://localhost/api/hs/office/relationships?personUuid=%s&relationshipType=%s"
|
.get("http://localhost/api/hs/office/relations?personUuid=%s&relationType=%s"
|
||||||
.formatted(givenPerson.getUuid(), HsOfficeRelationshipTypeResource.PARTNER))
|
.formatted(givenPerson.getUuid(), HsOfficeRelationTypeResource.PARTNER))
|
||||||
.then().log().all().assertThat()
|
.then().log().all().assertThat()
|
||||||
.statusCode(200)
|
.statusCode(200)
|
||||||
.contentType("application/json")
|
.contentType("application/json")
|
||||||
.body("", lenientlyEquals("""
|
.body("", lenientlyEquals("""
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"relAnchor": { "personType": "LEGAL_PERSON", "tradeName": "Hostsharing eG" },
|
"anchor": { "personType": "LEGAL_PERSON", "tradeName": "Hostsharing eG" },
|
||||||
"relHolder": { "personType": "LEGAL_PERSON", "tradeName": "First GmbH" },
|
"holder": { "personType": "LEGAL_PERSON", "tradeName": "First GmbH" },
|
||||||
"relType": "PARTNER",
|
"type": "PARTNER",
|
||||||
"relMark": null,
|
"mark": null,
|
||||||
"contact": { "label": "first contact" }
|
"contact": { "label": "first contact" }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"relAnchor": { "personType": "LEGAL_PERSON", "tradeName": "Hostsharing eG" },
|
"anchor": { "personType": "LEGAL_PERSON", "tradeName": "Hostsharing eG" },
|
||||||
"relHolder": { "personType": "INCORPORATED_FIRM", "tradeName": "Fourth eG" },
|
"holder": { "personType": "INCORPORATED_FIRM", "tradeName": "Fourth eG" },
|
||||||
"relType": "PARTNER",
|
"type": "PARTNER",
|
||||||
"contact": { "label": "fourth contact" }
|
"contact": { "label": "fourth contact" }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"relAnchor": { "personType": "LEGAL_PERSON", "tradeName": "Hostsharing eG" },
|
"anchor": { "personType": "LEGAL_PERSON", "tradeName": "Hostsharing eG" },
|
||||||
"relHolder": { "personType": "LEGAL_PERSON", "tradeName": "Second e.K.", "givenName": "Peter", "familyName": "Smith" },
|
"holder": { "personType": "LEGAL_PERSON", "tradeName": "Second e.K.", "givenName": "Peter", "familyName": "Smith" },
|
||||||
"relType": "PARTNER",
|
"type": "PARTNER",
|
||||||
"relMark": null,
|
"mark": null,
|
||||||
"contact": { "label": "second contact" }
|
"contact": { "label": "second contact" }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"relAnchor": { "personType": "LEGAL_PERSON", "tradeName": "Hostsharing eG" },
|
"anchor": { "personType": "LEGAL_PERSON", "tradeName": "Hostsharing eG" },
|
||||||
"relHolder": { "personType": "NATURAL_PERSON", "givenName": "Peter", "familyName": "Smith" },
|
"holder": { "personType": "NATURAL_PERSON", "givenName": "Peter", "familyName": "Smith" },
|
||||||
"relType": "PARTNER",
|
"type": "PARTNER",
|
||||||
"relMark": null,
|
"mark": null,
|
||||||
"contact": { "label": "sixth contact" }
|
"contact": { "label": "sixth contact" }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"relAnchor": { "personType": "LEGAL_PERSON", "tradeName": "Hostsharing eG" },
|
"anchor": { "personType": "LEGAL_PERSON", "tradeName": "Hostsharing eG" },
|
||||||
"relHolder": { "personType": "INCORPORATED_FIRM", "tradeName": "Third OHG" },
|
"holder": { "personType": "INCORPORATED_FIRM", "tradeName": "Third OHG" },
|
||||||
"relType": "PARTNER",
|
"type": "PARTNER",
|
||||||
"relMark": null,
|
"mark": null,
|
||||||
"contact": { "label": "third contact" }
|
"contact": { "label": "third contact" }
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@ -119,11 +119,11 @@ class HsOfficeRelationshipControllerAcceptanceTest extends ContextBasedTestWithC
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
@Accepts({ "Relationship:C(Create)" })
|
@Accepts({ "Relation:C(Create)" })
|
||||||
class AddRelationship {
|
class AddRelation {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void globalAdmin_withoutAssumedRole_canAddRelationship() {
|
void globalAdmin_withoutAssumedRole_canAddRelation() {
|
||||||
|
|
||||||
context.define("superuser-alex@hostsharing.net");
|
context.define("superuser-alex@hostsharing.net");
|
||||||
final var givenAnchorPerson = personRepo.findPersonByOptionalNameLike("Third").get(0);
|
final var givenAnchorPerson = personRepo.findPersonByOptionalNameLike("Third").get(0);
|
||||||
@ -136,38 +136,38 @@ class HsOfficeRelationshipControllerAcceptanceTest extends ContextBasedTestWithC
|
|||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
"relType": "%s",
|
"type": "%s",
|
||||||
"relAnchorUuid": "%s",
|
"anchorUuid": "%s",
|
||||||
"relHolderUuid": "%s",
|
"holderUuid": "%s",
|
||||||
"contactUuid": "%s"
|
"contactUuid": "%s"
|
||||||
}
|
}
|
||||||
""".formatted(
|
""".formatted(
|
||||||
HsOfficeRelationshipTypeResource.ACCOUNTING,
|
HsOfficeRelationTypeResource.DEBITOR,
|
||||||
givenAnchorPerson.getUuid(),
|
givenAnchorPerson.getUuid(),
|
||||||
givenHolderPerson.getUuid(),
|
givenHolderPerson.getUuid(),
|
||||||
givenContact.getUuid()))
|
givenContact.getUuid()))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.post("http://localhost/api/hs/office/relationships")
|
.post("http://localhost/api/hs/office/relations")
|
||||||
.then().log().all().assertThat()
|
.then().log().all().assertThat()
|
||||||
.statusCode(201)
|
.statusCode(201)
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("uuid", isUuidValid())
|
.body("uuid", isUuidValid())
|
||||||
.body("relType", is("ACCOUNTING"))
|
.body("type", is("DEBITOR"))
|
||||||
.body("relAnchor.tradeName", is("Third OHG"))
|
.body("anchor.tradeName", is("Third OHG"))
|
||||||
.body("relHolder.givenName", is("Paul"))
|
.body("holder.givenName", is("Paul"))
|
||||||
.body("contact.label", is("second contact"))
|
.body("contact.label", is("second contact"))
|
||||||
.header("Location", startsWith("http://localhost"))
|
.header("Location", startsWith("http://localhost"))
|
||||||
.extract().header("Location"); // @formatter:on
|
.extract().header("Location"); // @formatter:on
|
||||||
|
|
||||||
// finally, the new relationship can be accessed under the generated UUID
|
// finally, the new relation can be accessed under the generated UUID
|
||||||
final var newUserUuid = toCleanup(HsOfficeRelationshipEntity.class, UUID.fromString(
|
final var newUserUuid = toCleanup(HsOfficeRelationEntity.class, UUID.fromString(
|
||||||
location.substring(location.lastIndexOf('/') + 1)));
|
location.substring(location.lastIndexOf('/') + 1)));
|
||||||
assertThat(newUserUuid).isNotNull();
|
assertThat(newUserUuid).isNotNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void globalAdmin_canNotAddRelationship_ifAnchorPersonDoesNotExist() {
|
void globalAdmin_canNotAddRelation_ifAnchorPersonDoesNotExist() {
|
||||||
|
|
||||||
context.define("superuser-alex@hostsharing.net");
|
context.define("superuser-alex@hostsharing.net");
|
||||||
final var givenAnchorPersonUuid = GIVEN_NON_EXISTING_HOLDER_PERSON_UUID;
|
final var givenAnchorPersonUuid = GIVEN_NON_EXISTING_HOLDER_PERSON_UUID;
|
||||||
@ -180,27 +180,27 @@ class HsOfficeRelationshipControllerAcceptanceTest extends ContextBasedTestWithC
|
|||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
"relType": "%s",
|
"type": "%s",
|
||||||
"relAnchorUuid": "%s",
|
"anchorUuid": "%s",
|
||||||
"relHolderUuid": "%s",
|
"holderUuid": "%s",
|
||||||
"contactUuid": "%s"
|
"contactUuid": "%s"
|
||||||
}
|
}
|
||||||
""".formatted(
|
""".formatted(
|
||||||
HsOfficeRelationshipTypeResource.ACCOUNTING,
|
HsOfficeRelationTypeResource.DEBITOR,
|
||||||
givenAnchorPersonUuid,
|
givenAnchorPersonUuid,
|
||||||
givenHolderPerson.getUuid(),
|
givenHolderPerson.getUuid(),
|
||||||
givenContact.getUuid()))
|
givenContact.getUuid()))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.post("http://localhost/api/hs/office/relationships")
|
.post("http://localhost/api/hs/office/relations")
|
||||||
.then().log().all().assertThat()
|
.then().log().all().assertThat()
|
||||||
.statusCode(404)
|
.statusCode(404)
|
||||||
.body("message", is("cannot find relAnchorUuid " + GIVEN_NON_EXISTING_HOLDER_PERSON_UUID));
|
.body("message", is("cannot find anchorUuid " + GIVEN_NON_EXISTING_HOLDER_PERSON_UUID));
|
||||||
// @formatter:on
|
// @formatter:on
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void globalAdmin_canNotAddRelationship_ifHolderPersonDoesNotExist() {
|
void globalAdmin_canNotAddRelation_ifHolderPersonDoesNotExist() {
|
||||||
|
|
||||||
context.define("superuser-alex@hostsharing.net");
|
context.define("superuser-alex@hostsharing.net");
|
||||||
final var givenAnchorPerson = personRepo.findPersonByOptionalNameLike("Third").get(0);
|
final var givenAnchorPerson = personRepo.findPersonByOptionalNameLike("Third").get(0);
|
||||||
@ -212,27 +212,27 @@ class HsOfficeRelationshipControllerAcceptanceTest extends ContextBasedTestWithC
|
|||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
"relType": "%s",
|
"type": "%s",
|
||||||
"relAnchorUuid": "%s",
|
"anchorUuid": "%s",
|
||||||
"relHolderUuid": "%s",
|
"holderUuid": "%s",
|
||||||
"contactUuid": "%s"
|
"contactUuid": "%s"
|
||||||
}
|
}
|
||||||
""".formatted(
|
""".formatted(
|
||||||
HsOfficeRelationshipTypeResource.ACCOUNTING,
|
HsOfficeRelationTypeResource.DEBITOR,
|
||||||
givenAnchorPerson.getUuid(),
|
givenAnchorPerson.getUuid(),
|
||||||
GIVEN_NON_EXISTING_HOLDER_PERSON_UUID,
|
GIVEN_NON_EXISTING_HOLDER_PERSON_UUID,
|
||||||
givenContact.getUuid()))
|
givenContact.getUuid()))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.post("http://localhost/api/hs/office/relationships")
|
.post("http://localhost/api/hs/office/relations")
|
||||||
.then().log().all().assertThat()
|
.then().log().all().assertThat()
|
||||||
.statusCode(404)
|
.statusCode(404)
|
||||||
.body("message", is("cannot find relHolderUuid " + GIVEN_NON_EXISTING_HOLDER_PERSON_UUID));
|
.body("message", is("cannot find holderUuid " + GIVEN_NON_EXISTING_HOLDER_PERSON_UUID));
|
||||||
// @formatter:on
|
// @formatter:on
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void globalAdmin_canNotAddRelationship_ifContactDoesNotExist() {
|
void globalAdmin_canNotAddRelation_ifContactDoesNotExist() {
|
||||||
|
|
||||||
context.define("superuser-alex@hostsharing.net");
|
context.define("superuser-alex@hostsharing.net");
|
||||||
final var givenAnchorPerson = personRepo.findPersonByOptionalNameLike("Third").get(0);
|
final var givenAnchorPerson = personRepo.findPersonByOptionalNameLike("Third").get(0);
|
||||||
@ -245,19 +245,19 @@ class HsOfficeRelationshipControllerAcceptanceTest extends ContextBasedTestWithC
|
|||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
"relType": "%s",
|
"type": "%s",
|
||||||
"relAnchorUuid": "%s",
|
"anchorUuid": "%s",
|
||||||
"relHolderUuid": "%s",
|
"holderUuid": "%s",
|
||||||
"contactUuid": "%s"
|
"contactUuid": "%s"
|
||||||
}
|
}
|
||||||
""".formatted(
|
""".formatted(
|
||||||
HsOfficeRelationshipTypeResource.ACCOUNTING,
|
HsOfficeRelationTypeResource.DEBITOR,
|
||||||
givenAnchorPerson.getUuid(),
|
givenAnchorPerson.getUuid(),
|
||||||
givenHolderPerson.getUuid(),
|
givenHolderPerson.getUuid(),
|
||||||
givenContactUuid))
|
givenContactUuid))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.post("http://localhost/api/hs/office/relationships")
|
.post("http://localhost/api/hs/office/relations")
|
||||||
.then().log().all().assertThat()
|
.then().log().all().assertThat()
|
||||||
.statusCode(404)
|
.statusCode(404)
|
||||||
.body("message", is("cannot find contactUuid 00000000-0000-0000-0000-000000000000"));
|
.body("message", is("cannot find contactUuid 00000000-0000-0000-0000-000000000000"));
|
||||||
@ -266,97 +266,97 @@ class HsOfficeRelationshipControllerAcceptanceTest extends ContextBasedTestWithC
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
@Accepts({ "Relationship:R(Read)" })
|
@Accepts({ "Relation:R(Read)" })
|
||||||
class GetRelationship {
|
class GetRelation {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void globalAdmin_withoutAssumedRole_canGetArbitraryRelationship() {
|
void globalAdmin_withoutAssumedRole_canGetArbitraryRelation() {
|
||||||
context.define("superuser-alex@hostsharing.net");
|
context.define("superuser-alex@hostsharing.net");
|
||||||
final UUID givenRelationshipUuid = findRelationship("First", "Firby").getUuid();
|
final UUID givenRelationUuid = findRelation("First", "Firby").getUuid();
|
||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("current-user", "superuser-alex@hostsharing.net")
|
.header("current-user", "superuser-alex@hostsharing.net")
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.get("http://localhost/api/hs/office/relationships/" + givenRelationshipUuid)
|
.get("http://localhost/api/hs/office/relations/" + givenRelationUuid)
|
||||||
.then().log().body().assertThat()
|
.then().log().body().assertThat()
|
||||||
.statusCode(200)
|
.statusCode(200)
|
||||||
.contentType("application/json")
|
.contentType("application/json")
|
||||||
.body("", lenientlyEquals("""
|
.body("", lenientlyEquals("""
|
||||||
{
|
{
|
||||||
"relAnchor": { "tradeName": "First GmbH" },
|
"anchor": { "tradeName": "First GmbH" },
|
||||||
"relHolder": { "familyName": "Firby" },
|
"holder": { "familyName": "Firby" },
|
||||||
"contact": { "label": "first contact" }
|
"contact": { "label": "first contact" }
|
||||||
}
|
}
|
||||||
""")); // @formatter:on
|
""")); // @formatter:on
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Accepts({ "Relationship:X(Access Control)" })
|
@Accepts({ "Relation:X(Access Control)" })
|
||||||
void normalUser_canNotGetUnrelatedRelationship() {
|
void normalUser_canNotGetUnrelatedRelation() {
|
||||||
context.define("superuser-alex@hostsharing.net");
|
context.define("superuser-alex@hostsharing.net");
|
||||||
final UUID givenRelationshipUuid = findRelationship("First", "Firby").getUuid();
|
final UUID givenRelationUuid = findRelation("First", "Firby").getUuid();
|
||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("current-user", "selfregistered-user-drew@hostsharing.org")
|
.header("current-user", "selfregistered-user-drew@hostsharing.org")
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.get("http://localhost/api/hs/office/relationships/" + givenRelationshipUuid)
|
.get("http://localhost/api/hs/office/relations/" + givenRelationUuid)
|
||||||
.then().log().body().assertThat()
|
.then().log().body().assertThat()
|
||||||
.statusCode(404); // @formatter:on
|
.statusCode(404); // @formatter:on
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Accepts({ "Relationship:X(Access Control)" })
|
@Accepts({ "Relation:X(Access Control)" })
|
||||||
void contactAdminUser_canGetRelatedRelationship() {
|
void contactAdminUser_canGetRelatedRelation() {
|
||||||
context.define("superuser-alex@hostsharing.net");
|
context.define("superuser-alex@hostsharing.net");
|
||||||
final var givenRelationship = findRelationship("First", "Firby");
|
final var givenRelation = findRelation("First", "Firby");
|
||||||
assertThat(givenRelationship.getContact().getLabel()).isEqualTo("first contact");
|
assertThat(givenRelation.getContact().getLabel()).isEqualTo("first contact");
|
||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("current-user", "contact-admin@firstcontact.example.com")
|
.header("current-user", "contact-admin@firstcontact.example.com")
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.get("http://localhost/api/hs/office/relationships/" + givenRelationship.getUuid())
|
.get("http://localhost/api/hs/office/relations/" + givenRelation.getUuid())
|
||||||
.then().log().body().assertThat()
|
.then().log().body().assertThat()
|
||||||
.statusCode(200)
|
.statusCode(200)
|
||||||
.contentType("application/json")
|
.contentType("application/json")
|
||||||
.body("", lenientlyEquals("""
|
.body("", lenientlyEquals("""
|
||||||
{
|
{
|
||||||
"relAnchor": { "tradeName": "First GmbH" },
|
"anchor": { "tradeName": "First GmbH" },
|
||||||
"relHolder": { "familyName": "Firby" },
|
"holder": { "familyName": "Firby" },
|
||||||
"contact": { "label": "first contact" }
|
"contact": { "label": "first contact" }
|
||||||
}
|
}
|
||||||
""")); // @formatter:on
|
""")); // @formatter:on
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private HsOfficeRelationshipEntity findRelationship(
|
private HsOfficeRelationEntity findRelation(
|
||||||
final String anchorPersonName,
|
final String anchorPersonName,
|
||||||
final String holderPersoneName) {
|
final String holderPersoneName) {
|
||||||
final var anchorPersonUuid = personRepo.findPersonByOptionalNameLike(anchorPersonName).get(0).getUuid();
|
final var anchorPersonUuid = personRepo.findPersonByOptionalNameLike(anchorPersonName).get(0).getUuid();
|
||||||
final var holderPersonUuid = personRepo.findPersonByOptionalNameLike(holderPersoneName).get(0).getUuid();
|
final var holderPersonUuid = personRepo.findPersonByOptionalNameLike(holderPersoneName).get(0).getUuid();
|
||||||
final var givenRelationship = relationshipRepo
|
final var givenRelation = relationRepo
|
||||||
.findRelationshipRelatedToPersonUuid(anchorPersonUuid)
|
.findRelationRelatedToPersonUuid(anchorPersonUuid)
|
||||||
.stream()
|
.stream()
|
||||||
.filter(r -> r.getRelHolder().getUuid().equals(holderPersonUuid))
|
.filter(r -> r.getHolder().getUuid().equals(holderPersonUuid))
|
||||||
.findFirst().orElseThrow();
|
.findFirst().orElseThrow();
|
||||||
return givenRelationship;
|
return givenRelation;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
@Accepts({ "Relationship:U(Update)" })
|
@Accepts({ "Relation:U(Update)" })
|
||||||
class PatchRelationship {
|
class PatchRelation {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void globalAdmin_withoutAssumedRole_canPatchContactOfArbitraryRelationship() {
|
void globalAdmin_withoutAssumedRole_canPatchContactOfArbitraryRelation() {
|
||||||
|
|
||||||
context.define("superuser-alex@hostsharing.net");
|
context.define("superuser-alex@hostsharing.net");
|
||||||
final var givenRelationship = givenSomeTemporaryRelationshipBessler();
|
final var givenRelation = givenSomeTemporaryRelationBessler();
|
||||||
assertThat(givenRelationship.getContact().getLabel()).isEqualTo("seventh contact");
|
assertThat(givenRelation.getContact().getLabel()).isEqualTo("seventh contact");
|
||||||
final var givenContact = contactRepo.findContactByOptionalLabelLike("fourth").get(0);
|
final var givenContact = contactRepo.findContactByOptionalLabelLike("fourth").get(0);
|
||||||
|
|
||||||
final var location = RestAssured // @formatter:off
|
final var location = RestAssured // @formatter:off
|
||||||
@ -370,109 +370,109 @@ class HsOfficeRelationshipControllerAcceptanceTest extends ContextBasedTestWithC
|
|||||||
""".formatted(givenContact.getUuid()))
|
""".formatted(givenContact.getUuid()))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.patch("http://localhost/api/hs/office/relationships/" + givenRelationship.getUuid())
|
.patch("http://localhost/api/hs/office/relations/" + givenRelation.getUuid())
|
||||||
.then().log().all().assertThat()
|
.then().log().all().assertThat()
|
||||||
.statusCode(200)
|
.statusCode(200)
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("uuid", isUuidValid())
|
.body("uuid", isUuidValid())
|
||||||
.body("relType", is("REPRESENTATIVE"))
|
.body("type", is("REPRESENTATIVE"))
|
||||||
.body("relAnchor.tradeName", is("Erben Bessler"))
|
.body("anchor.tradeName", is("Erben Bessler"))
|
||||||
.body("relHolder.familyName", is("Winkler"))
|
.body("holder.familyName", is("Winkler"))
|
||||||
.body("contact.label", is("fourth contact"));
|
.body("contact.label", is("fourth contact"));
|
||||||
// @formatter:on
|
// @formatter:on
|
||||||
|
|
||||||
// finally, the relationship is actually updated
|
// finally, the relation is actually updated
|
||||||
context.define("superuser-alex@hostsharing.net");
|
context.define("superuser-alex@hostsharing.net");
|
||||||
assertThat(relationshipRepo.findByUuid(givenRelationship.getUuid())).isPresent().get()
|
assertThat(relationRepo.findByUuid(givenRelation.getUuid())).isPresent().get()
|
||||||
.matches(rel -> {
|
.matches(rel -> {
|
||||||
assertThat(rel.getRelAnchor().getTradeName()).contains("Bessler");
|
assertThat(rel.getAnchor().getTradeName()).contains("Bessler");
|
||||||
assertThat(rel.getRelHolder().getFamilyName()).contains("Winkler");
|
assertThat(rel.getHolder().getFamilyName()).contains("Winkler");
|
||||||
assertThat(rel.getContact().getLabel()).isEqualTo("fourth contact");
|
assertThat(rel.getContact().getLabel()).isEqualTo("fourth contact");
|
||||||
assertThat(rel.getRelType()).isEqualTo(HsOfficeRelationshipType.REPRESENTATIVE);
|
assertThat(rel.getType()).isEqualTo(HsOfficeRelationType.REPRESENTATIVE);
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
@Accepts({ "Relationship:D(Delete)" })
|
@Accepts({ "Relation:D(Delete)" })
|
||||||
class DeleteRelationship {
|
class DeleteRelation {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void globalAdmin_withoutAssumedRole_canDeleteArbitraryRelationship() {
|
void globalAdmin_withoutAssumedRole_canDeleteArbitraryRelation() {
|
||||||
context.define("superuser-alex@hostsharing.net");
|
context.define("superuser-alex@hostsharing.net");
|
||||||
final var givenRelationship = givenSomeTemporaryRelationshipBessler();
|
final var givenRelation = givenSomeTemporaryRelationBessler();
|
||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("current-user", "superuser-alex@hostsharing.net")
|
.header("current-user", "superuser-alex@hostsharing.net")
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.delete("http://localhost/api/hs/office/relationships/" + givenRelationship.getUuid())
|
.delete("http://localhost/api/hs/office/relations/" + givenRelation.getUuid())
|
||||||
.then().log().body().assertThat()
|
.then().log().body().assertThat()
|
||||||
.statusCode(204); // @formatter:on
|
.statusCode(204); // @formatter:on
|
||||||
|
|
||||||
// then the given relationship is gone
|
// then the given relation is gone
|
||||||
assertThat(relationshipRepo.findByUuid(givenRelationship.getUuid())).isEmpty();
|
assertThat(relationRepo.findByUuid(givenRelation.getUuid())).isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Accepts({ "Relationship:X(Access Control)" })
|
@Accepts({ "Relation:X(Access Control)" })
|
||||||
void contactAdminUser_canNotDeleteRelatedRelationship() {
|
void contactAdminUser_canNotDeleteRelatedRelation() {
|
||||||
context.define("superuser-alex@hostsharing.net");
|
context.define("superuser-alex@hostsharing.net");
|
||||||
final var givenRelationship = givenSomeTemporaryRelationshipBessler();
|
final var givenRelation = givenSomeTemporaryRelationBessler();
|
||||||
assertThat(givenRelationship.getContact().getLabel()).isEqualTo("seventh contact");
|
assertThat(givenRelation.getContact().getLabel()).isEqualTo("seventh contact");
|
||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("current-user", "contact-admin@seventhcontact.example.com")
|
.header("current-user", "contact-admin@seventhcontact.example.com")
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.delete("http://localhost/api/hs/office/relationships/" + givenRelationship.getUuid())
|
.delete("http://localhost/api/hs/office/relations/" + givenRelation.getUuid())
|
||||||
.then().log().body().assertThat()
|
.then().log().body().assertThat()
|
||||||
.statusCode(403); // @formatter:on
|
.statusCode(403); // @formatter:on
|
||||||
|
|
||||||
// then the given relationship is still there
|
// then the given relation is still there
|
||||||
assertThat(relationshipRepo.findByUuid(givenRelationship.getUuid())).isNotEmpty();
|
assertThat(relationRepo.findByUuid(givenRelation.getUuid())).isNotEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Accepts({ "Relationship:X(Access Control)" })
|
@Accepts({ "Relation:X(Access Control)" })
|
||||||
void normalUser_canNotDeleteUnrelatedRelationship() {
|
void normalUser_canNotDeleteUnrelatedRelation() {
|
||||||
context.define("superuser-alex@hostsharing.net");
|
context.define("superuser-alex@hostsharing.net");
|
||||||
final var givenRelationship = givenSomeTemporaryRelationshipBessler();
|
final var givenRelation = givenSomeTemporaryRelationBessler();
|
||||||
assertThat(givenRelationship.getContact().getLabel()).isEqualTo("seventh contact");
|
assertThat(givenRelation.getContact().getLabel()).isEqualTo("seventh contact");
|
||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("current-user", "selfregistered-user-drew@hostsharing.org")
|
.header("current-user", "selfregistered-user-drew@hostsharing.org")
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.delete("http://localhost/api/hs/office/relationships/" + givenRelationship.getUuid())
|
.delete("http://localhost/api/hs/office/relations/" + givenRelation.getUuid())
|
||||||
.then().log().body().assertThat()
|
.then().log().body().assertThat()
|
||||||
.statusCode(404); // @formatter:on
|
.statusCode(404); // @formatter:on
|
||||||
|
|
||||||
// then the given relationship is still there
|
// then the given relation is still there
|
||||||
assertThat(relationshipRepo.findByUuid(givenRelationship.getUuid())).isNotEmpty();
|
assertThat(relationRepo.findByUuid(givenRelation.getUuid())).isNotEmpty();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private HsOfficeRelationshipEntity givenSomeTemporaryRelationshipBessler() {
|
private HsOfficeRelationEntity givenSomeTemporaryRelationBessler() {
|
||||||
return jpaAttempt.transacted(() -> {
|
return jpaAttempt.transacted(() -> {
|
||||||
context.define("superuser-alex@hostsharing.net");
|
context.define("superuser-alex@hostsharing.net");
|
||||||
final var givenAnchorPerson = personRepo.findPersonByOptionalNameLike("Erben Bessler").get(0);
|
final var givenAnchorPerson = personRepo.findPersonByOptionalNameLike("Erben Bessler").get(0);
|
||||||
final var givenHolderPerson = personRepo.findPersonByOptionalNameLike("Winkler").get(0);
|
final var givenHolderPerson = personRepo.findPersonByOptionalNameLike("Winkler").get(0);
|
||||||
final var givenContact = contactRepo.findContactByOptionalLabelLike("seventh contact").get(0);
|
final var givenContact = contactRepo.findContactByOptionalLabelLike("seventh contact").get(0);
|
||||||
final var newRelationship = HsOfficeRelationshipEntity.builder()
|
final var newRelation = HsOfficeRelationEntity.builder()
|
||||||
.relType(HsOfficeRelationshipType.REPRESENTATIVE)
|
.type(HsOfficeRelationType.REPRESENTATIVE)
|
||||||
.relAnchor(givenAnchorPerson)
|
.anchor(givenAnchorPerson)
|
||||||
.relHolder(givenHolderPerson)
|
.holder(givenHolderPerson)
|
||||||
.contact(givenContact)
|
.contact(givenContact)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
assertThat(toCleanup(relationshipRepo.save(newRelationship))).isEqualTo(newRelationship);
|
assertThat(toCleanup(relationRepo.save(newRelation))).isEqualTo(newRelation);
|
||||||
|
|
||||||
return newRelationship;
|
return newRelation;
|
||||||
}).assertSuccessful().returnedValue();
|
}).assertSuccessful().returnedValue();
|
||||||
}
|
}
|
||||||
|
|
@ -1,7 +1,7 @@
|
|||||||
package net.hostsharing.hsadminng.hs.office.relationship;
|
package net.hostsharing.hsadminng.hs.office.relation;
|
||||||
|
|
||||||
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactEntity;
|
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactEntity;
|
||||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeRelationshipPatchResource;
|
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeRelationPatchResource;
|
||||||
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity;
|
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity;
|
||||||
import net.hostsharing.test.PatchUnitTestBase;
|
import net.hostsharing.test.PatchUnitTestBase;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
@ -21,12 +21,12 @@ import static org.mockito.Mockito.lenient;
|
|||||||
|
|
||||||
@TestInstance(PER_CLASS)
|
@TestInstance(PER_CLASS)
|
||||||
@ExtendWith(MockitoExtension.class)
|
@ExtendWith(MockitoExtension.class)
|
||||||
class HsOfficeRelationshipEntityPatcherUnitTest extends PatchUnitTestBase<
|
class HsOfficeRelationEntityPatcherUnitTest extends PatchUnitTestBase<
|
||||||
HsOfficeRelationshipPatchResource,
|
HsOfficeRelationPatchResource,
|
||||||
HsOfficeRelationshipEntity
|
HsOfficeRelationEntity
|
||||||
> {
|
> {
|
||||||
|
|
||||||
static final UUID INITIAL_RELATIONSHIP_UUID = UUID.randomUUID();
|
static final UUID INITIAL_RELATION_UUID = UUID.randomUUID();
|
||||||
static final UUID PATCHED_CONTACT_UUID = UUID.randomUUID();
|
static final UUID PATCHED_CONTACT_UUID = UUID.randomUUID();
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
@ -49,24 +49,24 @@ class HsOfficeRelationshipEntityPatcherUnitTest extends PatchUnitTestBase<
|
|||||||
.build();
|
.build();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected HsOfficeRelationshipEntity newInitialEntity() {
|
protected HsOfficeRelationEntity newInitialEntity() {
|
||||||
final var entity = new HsOfficeRelationshipEntity();
|
final var entity = new HsOfficeRelationEntity();
|
||||||
entity.setUuid(INITIAL_RELATIONSHIP_UUID);
|
entity.setUuid(INITIAL_RELATION_UUID);
|
||||||
entity.setRelType(HsOfficeRelationshipType.REPRESENTATIVE);
|
entity.setType(HsOfficeRelationType.REPRESENTATIVE);
|
||||||
entity.setRelAnchor(givenInitialAnchorPerson);
|
entity.setAnchor(givenInitialAnchorPerson);
|
||||||
entity.setRelHolder(givenInitialHolderPerson);
|
entity.setHolder(givenInitialHolderPerson);
|
||||||
entity.setContact(givenInitialContact);
|
entity.setContact(givenInitialContact);
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected HsOfficeRelationshipPatchResource newPatchResource() {
|
protected HsOfficeRelationPatchResource newPatchResource() {
|
||||||
return new HsOfficeRelationshipPatchResource();
|
return new HsOfficeRelationPatchResource();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected HsOfficeRelationshipEntityPatcher createPatcher(final HsOfficeRelationshipEntity relationship) {
|
protected HsOfficeRelationEntityPatcher createPatcher(final HsOfficeRelationEntity relation) {
|
||||||
return new HsOfficeRelationshipEntityPatcher(em, relationship);
|
return new HsOfficeRelationEntityPatcher(em, relation);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -74,9 +74,9 @@ class HsOfficeRelationshipEntityPatcherUnitTest extends PatchUnitTestBase<
|
|||||||
return Stream.of(
|
return Stream.of(
|
||||||
new JsonNullableProperty<>(
|
new JsonNullableProperty<>(
|
||||||
"contact",
|
"contact",
|
||||||
HsOfficeRelationshipPatchResource::setContactUuid,
|
HsOfficeRelationPatchResource::setContactUuid,
|
||||||
PATCHED_CONTACT_UUID,
|
PATCHED_CONTACT_UUID,
|
||||||
HsOfficeRelationshipEntity::setContact,
|
HsOfficeRelationEntity::setContact,
|
||||||
newContact(PATCHED_CONTACT_UUID))
|
newContact(PATCHED_CONTACT_UUID))
|
||||||
.notNullable()
|
.notNullable()
|
||||||
);
|
);
|
@ -0,0 +1,43 @@
|
|||||||
|
package net.hostsharing.hsadminng.hs.office.relation;
|
||||||
|
|
||||||
|
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity;
|
||||||
|
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonType;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
class HsOfficeRelationEntityUnitTest {
|
||||||
|
|
||||||
|
private HsOfficePersonEntity anchor = HsOfficePersonEntity.builder()
|
||||||
|
.personType(HsOfficePersonType.LEGAL_PERSON)
|
||||||
|
.tradeName("some trade name")
|
||||||
|
.build();
|
||||||
|
private HsOfficePersonEntity holder = HsOfficePersonEntity.builder()
|
||||||
|
.personType(HsOfficePersonType.NATURAL_PERSON)
|
||||||
|
.familyName("Meier")
|
||||||
|
.givenName("Mellie")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void toStringReturnsAllProperties() {
|
||||||
|
final var given = HsOfficeRelationEntity.builder()
|
||||||
|
.type(HsOfficeRelationType.SUBSCRIBER)
|
||||||
|
.mark("members-announce")
|
||||||
|
.anchor(anchor)
|
||||||
|
.holder(holder)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
assertThat(given.toString()).isEqualTo("rel(anchor='LP some trade name', type='SUBSCRIBER', mark='members-announce', holder='NP Meier, Mellie')");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void toShortString() {
|
||||||
|
final var given = HsOfficeRelationEntity.builder()
|
||||||
|
.type(HsOfficeRelationType.REPRESENTATIVE)
|
||||||
|
.anchor(anchor)
|
||||||
|
.holder(holder)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
assertThat(given.toShortString()).isEqualTo("rel(anchor='LP some trade name', type='REPRESENTATIVE', holder='NP Meier, Mellie')");
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package net.hostsharing.hsadminng.hs.office.relationship;
|
package net.hostsharing.hsadminng.hs.office.relation;
|
||||||
|
|
||||||
import net.hostsharing.hsadminng.context.Context;
|
import net.hostsharing.hsadminng.context.Context;
|
||||||
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRepository;
|
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRepository;
|
||||||
@ -29,10 +29,10 @@ import static org.assertj.core.api.Assertions.assertThat;
|
|||||||
|
|
||||||
@DataJpaTest
|
@DataJpaTest
|
||||||
@Import( { Context.class, JpaAttempt.class })
|
@Import( { Context.class, JpaAttempt.class })
|
||||||
class HsOfficeRelationshipRepositoryIntegrationTest extends ContextBasedTestWithCleanup {
|
class HsOfficeRelationRepositoryIntegrationTest extends ContextBasedTestWithCleanup {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
HsOfficeRelationshipRepository relationshipRepo;
|
HsOfficeRelationRepository relationRepo;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
HsOfficePersonRepository personRepo;
|
HsOfficePersonRepository personRepo;
|
||||||
@ -56,33 +56,33 @@ class HsOfficeRelationshipRepositoryIntegrationTest extends ContextBasedTestWith
|
|||||||
HttpServletRequest request;
|
HttpServletRequest request;
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
class CreateRelationship {
|
class CreateRelation {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testHostsharingAdmin_withoutAssumedRole_canCreateNewRelationship() {
|
public void testHostsharingAdmin_withoutAssumedRole_canCreateNewRelation() {
|
||||||
// given
|
// given
|
||||||
context("superuser-alex@hostsharing.net");
|
context("superuser-alex@hostsharing.net");
|
||||||
final var count = relationshipRepo.count();
|
final var count = relationRepo.count();
|
||||||
final var givenAnchorPerson = personRepo.findPersonByOptionalNameLike("Bessler").get(0);
|
final var givenAnchorPerson = personRepo.findPersonByOptionalNameLike("Bessler").get(0);
|
||||||
final var givenHolderPerson = personRepo.findPersonByOptionalNameLike("Anita").get(0);
|
final var givenHolderPerson = personRepo.findPersonByOptionalNameLike("Anita").get(0);
|
||||||
final var givenContact = contactRepo.findContactByOptionalLabelLike("fourth contact").get(0);
|
final var givenContact = contactRepo.findContactByOptionalLabelLike("fourth contact").get(0);
|
||||||
|
|
||||||
// when
|
// when
|
||||||
final var result = attempt(em, () -> {
|
final var result = attempt(em, () -> {
|
||||||
final var newRelationship = HsOfficeRelationshipEntity.builder()
|
final var newRelation = HsOfficeRelationEntity.builder()
|
||||||
.relAnchor(givenAnchorPerson)
|
.anchor(givenAnchorPerson)
|
||||||
.relHolder(givenHolderPerson)
|
.holder(givenHolderPerson)
|
||||||
.relType(HsOfficeRelationshipType.REPRESENTATIVE)
|
.type(HsOfficeRelationType.REPRESENTATIVE)
|
||||||
.contact(givenContact)
|
.contact(givenContact)
|
||||||
.build();
|
.build();
|
||||||
return toCleanup(relationshipRepo.save(newRelationship));
|
return toCleanup(relationRepo.save(newRelation));
|
||||||
});
|
});
|
||||||
|
|
||||||
// then
|
// then
|
||||||
result.assertSuccessful();
|
result.assertSuccessful();
|
||||||
assertThat(result.returnedValue()).isNotNull().extracting(HsOfficeRelationshipEntity::getUuid).isNotNull();
|
assertThat(result.returnedValue()).isNotNull().extracting(HsOfficeRelationEntity::getUuid).isNotNull();
|
||||||
assertThatRelationshipIsPersisted(result.returnedValue());
|
assertThatRelationIsPersisted(result.returnedValue());
|
||||||
assertThat(relationshipRepo.count()).isEqualTo(count + 1);
|
assertThat(relationRepo.count()).isEqualTo(count + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -97,190 +97,190 @@ class HsOfficeRelationshipRepositoryIntegrationTest extends ContextBasedTestWith
|
|||||||
final var givenAnchorPerson = personRepo.findPersonByOptionalNameLike("Bessler").get(0);
|
final var givenAnchorPerson = personRepo.findPersonByOptionalNameLike("Bessler").get(0);
|
||||||
final var givenHolderPerson = personRepo.findPersonByOptionalNameLike("Anita").get(0);
|
final var givenHolderPerson = personRepo.findPersonByOptionalNameLike("Anita").get(0);
|
||||||
final var givenContact = contactRepo.findContactByOptionalLabelLike("fourth contact").get(0);
|
final var givenContact = contactRepo.findContactByOptionalLabelLike("fourth contact").get(0);
|
||||||
final var newRelationship = HsOfficeRelationshipEntity.builder()
|
final var newRelation = HsOfficeRelationEntity.builder()
|
||||||
.relAnchor(givenAnchorPerson)
|
.anchor(givenAnchorPerson)
|
||||||
.relHolder(givenHolderPerson)
|
.holder(givenHolderPerson)
|
||||||
.relType(HsOfficeRelationshipType.REPRESENTATIVE)
|
.type(HsOfficeRelationType.REPRESENTATIVE)
|
||||||
.contact(givenContact)
|
.contact(givenContact)
|
||||||
.build();
|
.build();
|
||||||
return toCleanup(relationshipRepo.save(newRelationship));
|
return toCleanup(relationRepo.save(newRelation));
|
||||||
});
|
});
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assertThat(distinctRoleNamesOf(rawRoleRepo.findAll())).containsExactlyInAnyOrder(Array.from(
|
assertThat(distinctRoleNamesOf(rawRoleRepo.findAll())).containsExactlyInAnyOrder(Array.from(
|
||||||
initialRoleNames,
|
initialRoleNames,
|
||||||
"hs_office_relationship#BesslerAnita-with-REPRESENTATIVE-BesslerAnita.admin",
|
"hs_office_relation#BesslerAnita-with-REPRESENTATIVE-BesslerAnita.admin",
|
||||||
"hs_office_relationship#BesslerAnita-with-REPRESENTATIVE-BesslerAnita.owner",
|
"hs_office_relation#BesslerAnita-with-REPRESENTATIVE-BesslerAnita.owner",
|
||||||
"hs_office_relationship#BesslerAnita-with-REPRESENTATIVE-BesslerAnita.tenant"));
|
"hs_office_relation#BesslerAnita-with-REPRESENTATIVE-BesslerAnita.tenant"));
|
||||||
assertThat(distinctGrantDisplaysOf(rawGrantRepo.findAll())).containsExactlyInAnyOrder(Array.fromFormatted(
|
assertThat(distinctGrantDisplaysOf(rawGrantRepo.findAll())).containsExactlyInAnyOrder(Array.fromFormatted(
|
||||||
initialGrantNames,
|
initialGrantNames,
|
||||||
|
|
||||||
"{ grant perm DELETE on hs_office_relationship#BesslerAnita-with-REPRESENTATIVE-BesslerAnita to role hs_office_relationship#BesslerAnita-with-REPRESENTATIVE-BesslerAnita.owner by system and assume }",
|
"{ grant perm DELETE on hs_office_relation#BesslerAnita-with-REPRESENTATIVE-BesslerAnita to role hs_office_relation#BesslerAnita-with-REPRESENTATIVE-BesslerAnita.owner by system and assume }",
|
||||||
"{ grant role hs_office_relationship#BesslerAnita-with-REPRESENTATIVE-BesslerAnita.owner to role global#global.admin by system and assume }",
|
"{ grant role hs_office_relation#BesslerAnita-with-REPRESENTATIVE-BesslerAnita.owner to role global#global.admin by system and assume }",
|
||||||
"{ grant role hs_office_relationship#BesslerAnita-with-REPRESENTATIVE-BesslerAnita.owner to role hs_office_person#BesslerAnita.admin by system and assume }",
|
"{ grant role hs_office_relation#BesslerAnita-with-REPRESENTATIVE-BesslerAnita.owner to role hs_office_person#BesslerAnita.admin by system and assume }",
|
||||||
|
|
||||||
"{ grant perm UPDATE on hs_office_relationship#BesslerAnita-with-REPRESENTATIVE-BesslerAnita to role hs_office_relationship#BesslerAnita-with-REPRESENTATIVE-BesslerAnita.admin by system and assume }",
|
"{ grant perm UPDATE on hs_office_relation#BesslerAnita-with-REPRESENTATIVE-BesslerAnita to role hs_office_relation#BesslerAnita-with-REPRESENTATIVE-BesslerAnita.admin by system and assume }",
|
||||||
"{ grant role hs_office_relationship#BesslerAnita-with-REPRESENTATIVE-BesslerAnita.admin to role hs_office_relationship#BesslerAnita-with-REPRESENTATIVE-BesslerAnita.owner by system and assume }",
|
"{ grant role hs_office_relation#BesslerAnita-with-REPRESENTATIVE-BesslerAnita.admin to role hs_office_relation#BesslerAnita-with-REPRESENTATIVE-BesslerAnita.owner by system and assume }",
|
||||||
|
|
||||||
"{ grant perm SELECT on hs_office_relationship#BesslerAnita-with-REPRESENTATIVE-BesslerAnita to role hs_office_relationship#BesslerAnita-with-REPRESENTATIVE-BesslerAnita.tenant by system and assume }",
|
"{ grant perm SELECT on hs_office_relation#BesslerAnita-with-REPRESENTATIVE-BesslerAnita to role hs_office_relation#BesslerAnita-with-REPRESENTATIVE-BesslerAnita.tenant by system and assume }",
|
||||||
"{ grant role hs_office_relationship#BesslerAnita-with-REPRESENTATIVE-BesslerAnita.tenant to role hs_office_contact#fourthcontact.admin by system and assume }",
|
"{ grant role hs_office_relation#BesslerAnita-with-REPRESENTATIVE-BesslerAnita.tenant to role hs_office_contact#fourthcontact.admin by system and assume }",
|
||||||
"{ grant role hs_office_relationship#BesslerAnita-with-REPRESENTATIVE-BesslerAnita.tenant to role hs_office_person#BesslerAnita.admin by system and assume }",
|
"{ grant role hs_office_relation#BesslerAnita-with-REPRESENTATIVE-BesslerAnita.tenant to role hs_office_person#BesslerAnita.admin by system and assume }",
|
||||||
|
|
||||||
"{ grant role hs_office_relationship#BesslerAnita-with-REPRESENTATIVE-BesslerAnita.tenant to role hs_office_relationship#BesslerAnita-with-REPRESENTATIVE-BesslerAnita.admin by system and assume }",
|
"{ grant role hs_office_relation#BesslerAnita-with-REPRESENTATIVE-BesslerAnita.tenant to role hs_office_relation#BesslerAnita-with-REPRESENTATIVE-BesslerAnita.admin by system and assume }",
|
||||||
"{ grant role hs_office_contact#fourthcontact.tenant to role hs_office_relationship#BesslerAnita-with-REPRESENTATIVE-BesslerAnita.tenant by system and assume }",
|
"{ grant role hs_office_contact#fourthcontact.tenant to role hs_office_relation#BesslerAnita-with-REPRESENTATIVE-BesslerAnita.tenant by system and assume }",
|
||||||
"{ grant role hs_office_person#BesslerAnita.tenant to role hs_office_relationship#BesslerAnita-with-REPRESENTATIVE-BesslerAnita.tenant by system and assume }",
|
"{ grant role hs_office_person#BesslerAnita.tenant to role hs_office_relation#BesslerAnita-with-REPRESENTATIVE-BesslerAnita.tenant by system and assume }",
|
||||||
null)
|
null)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertThatRelationshipIsPersisted(final HsOfficeRelationshipEntity saved) {
|
private void assertThatRelationIsPersisted(final HsOfficeRelationEntity saved) {
|
||||||
final var found = relationshipRepo.findByUuid(saved.getUuid());
|
final var found = relationRepo.findByUuid(saved.getUuid());
|
||||||
assertThat(found).isNotEmpty().get().usingRecursiveComparison().isEqualTo(saved);
|
assertThat(found).isNotEmpty().get().usingRecursiveComparison().isEqualTo(saved);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
class FindAllRelationships {
|
class FindAllRelations {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void globalAdmin_withoutAssumedRole_canViewAllRelationshipsOfArbitraryPerson() {
|
public void globalAdmin_withoutAssumedRole_canViewAllRelationsOfArbitraryPerson() {
|
||||||
// given
|
// given
|
||||||
context("superuser-alex@hostsharing.net");
|
context("superuser-alex@hostsharing.net");
|
||||||
final var person = personRepo.findPersonByOptionalNameLike("Second e.K.").stream().findFirst().orElseThrow();
|
final var person = personRepo.findPersonByOptionalNameLike("Second e.K.").stream().findFirst().orElseThrow();
|
||||||
|
|
||||||
// when
|
// when
|
||||||
final var result = relationshipRepo.findRelationshipRelatedToPersonUuid(person.getUuid());
|
final var result = relationRepo.findRelationRelatedToPersonUuid(person.getUuid());
|
||||||
|
|
||||||
// then
|
// then
|
||||||
allTheseRelationshipsAreReturned(
|
allTheseRelationsAreReturned(
|
||||||
result,
|
result,
|
||||||
"rel(relAnchor='LP Hostsharing eG', relType='PARTNER', relHolder='LP Second e.K.', contact='second contact')",
|
"rel(anchor='LP Hostsharing eG', type='PARTNER', holder='LP Second e.K.', contact='second contact')",
|
||||||
"rel(relAnchor='LP Second e.K.', relType='REPRESENTATIVE', relHolder='NP Smith, Peter', contact='second contact')");
|
"rel(anchor='LP Second e.K.', type='REPRESENTATIVE', holder='NP Smith, Peter', contact='second contact')");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void normalUser_canViewRelationshipsOfOwnedPersons() {
|
public void normalUser_canViewRelationsOfOwnedPersons() {
|
||||||
// given:
|
// given:
|
||||||
context("person-FirstGmbH@example.com");
|
context("person-FirstGmbH@example.com");
|
||||||
final var person = personRepo.findPersonByOptionalNameLike("First").stream().findFirst().orElseThrow();
|
final var person = personRepo.findPersonByOptionalNameLike("First").stream().findFirst().orElseThrow();
|
||||||
|
|
||||||
// when:
|
// when:
|
||||||
final var result = relationshipRepo.findRelationshipRelatedToPersonUuid(person.getUuid());
|
final var result = relationRepo.findRelationRelatedToPersonUuid(person.getUuid());
|
||||||
|
|
||||||
// then:
|
// then:
|
||||||
exactlyTheseRelationshipsAreReturned(
|
exactlyTheseRelationsAreReturned(
|
||||||
result,
|
result,
|
||||||
"rel(relAnchor='LP Hostsharing eG', relType='PARTNER', relHolder='LP First GmbH', contact='first contact')",
|
"rel(anchor='LP Hostsharing eG', type='PARTNER', holder='LP First GmbH', contact='first contact')",
|
||||||
"rel(relAnchor='LP First GmbH', relType='REPRESENTATIVE', relHolder='NP Firby, Susan', contact='first contact')");
|
"rel(anchor='LP First GmbH', type='REPRESENTATIVE', holder='NP Firby, Susan', contact='first contact')");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
class UpdateRelationship {
|
class UpdateRelation {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void hostsharingAdmin_withoutAssumedRole_canUpdateContactOfArbitraryRelationship() {
|
public void hostsharingAdmin_withoutAssumedRole_canUpdateContactOfArbitraryRelation() {
|
||||||
// given
|
// given
|
||||||
context("superuser-alex@hostsharing.net");
|
context("superuser-alex@hostsharing.net");
|
||||||
final var givenRelationship = givenSomeTemporaryRelationshipBessler(
|
final var givenRelation = givenSomeTemporaryRelationBessler(
|
||||||
"Anita", "fifth contact");
|
"Anita", "fifth contact");
|
||||||
assertThatRelationshipIsVisibleForUserWithRole(
|
assertThatRelationIsVisibleForUserWithRole(
|
||||||
givenRelationship,
|
givenRelation,
|
||||||
"hs_office_person#ErbenBesslerMelBessler.admin");
|
"hs_office_person#ErbenBesslerMelBessler.admin");
|
||||||
assertThatRelationshipActuallyInDatabase(givenRelationship);
|
assertThatRelationActuallyInDatabase(givenRelation);
|
||||||
context("superuser-alex@hostsharing.net");
|
context("superuser-alex@hostsharing.net");
|
||||||
final var givenContact = contactRepo.findContactByOptionalLabelLike("sixth contact").get(0);
|
final var givenContact = contactRepo.findContactByOptionalLabelLike("sixth contact").get(0);
|
||||||
|
|
||||||
// when
|
// when
|
||||||
final var result = jpaAttempt.transacted(() -> {
|
final var result = jpaAttempt.transacted(() -> {
|
||||||
context("superuser-alex@hostsharing.net");
|
context("superuser-alex@hostsharing.net");
|
||||||
givenRelationship.setContact(givenContact);
|
givenRelation.setContact(givenContact);
|
||||||
return toCleanup(relationshipRepo.save(givenRelationship));
|
return toCleanup(relationRepo.save(givenRelation));
|
||||||
});
|
});
|
||||||
|
|
||||||
// then
|
// then
|
||||||
result.assertSuccessful();
|
result.assertSuccessful();
|
||||||
assertThat(result.returnedValue().getContact().getLabel()).isEqualTo("sixth contact");
|
assertThat(result.returnedValue().getContact().getLabel()).isEqualTo("sixth contact");
|
||||||
assertThatRelationshipIsVisibleForUserWithRole(
|
assertThatRelationIsVisibleForUserWithRole(
|
||||||
result.returnedValue(),
|
result.returnedValue(),
|
||||||
"global#global.admin");
|
"global#global.admin");
|
||||||
assertThatRelationshipIsVisibleForUserWithRole(
|
assertThatRelationIsVisibleForUserWithRole(
|
||||||
result.returnedValue(),
|
result.returnedValue(),
|
||||||
"hs_office_contact#sixthcontact.admin");
|
"hs_office_contact#sixthcontact.admin");
|
||||||
|
|
||||||
assertThatRelationshipIsNotVisibleForUserWithRole(
|
assertThatRelationIsNotVisibleForUserWithRole(
|
||||||
result.returnedValue(),
|
result.returnedValue(),
|
||||||
"hs_office_contact#fifthcontact.admin");
|
"hs_office_contact#fifthcontact.admin");
|
||||||
|
|
||||||
relationshipRepo.deleteByUuid(givenRelationship.getUuid());
|
relationRepo.deleteByUuid(givenRelation.getUuid());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void relHolderAdmin_canNotUpdateRelatedRelationship() {
|
public void holderAdmin_canNotUpdateRelatedRelation() {
|
||||||
// given
|
// given
|
||||||
context("superuser-alex@hostsharing.net");
|
context("superuser-alex@hostsharing.net");
|
||||||
final var givenRelationship = givenSomeTemporaryRelationshipBessler(
|
final var givenRelation = givenSomeTemporaryRelationBessler(
|
||||||
"Anita", "eighth");
|
"Anita", "eighth");
|
||||||
assertThatRelationshipIsVisibleForUserWithRole(
|
assertThatRelationIsVisibleForUserWithRole(
|
||||||
givenRelationship,
|
givenRelation,
|
||||||
"hs_office_person#BesslerAnita.admin");
|
"hs_office_person#BesslerAnita.admin");
|
||||||
assertThatRelationshipActuallyInDatabase(givenRelationship);
|
assertThatRelationActuallyInDatabase(givenRelation);
|
||||||
|
|
||||||
// when
|
// when
|
||||||
final var result = jpaAttempt.transacted(() -> {
|
final var result = jpaAttempt.transacted(() -> {
|
||||||
context("superuser-alex@hostsharing.net", "hs_office_person#BesslerAnita.admin");
|
context("superuser-alex@hostsharing.net", "hs_office_person#BesslerAnita.admin");
|
||||||
givenRelationship.setContact(null);
|
givenRelation.setContact(null);
|
||||||
return relationshipRepo.save(givenRelationship);
|
return relationRepo.save(givenRelation);
|
||||||
});
|
});
|
||||||
|
|
||||||
// then
|
// then
|
||||||
result.assertExceptionWithRootCauseMessage(JpaSystemException.class,
|
result.assertExceptionWithRootCauseMessage(JpaSystemException.class,
|
||||||
"[403] Subject ", " is not allowed to update hs_office_relationship uuid");
|
"[403] Subject ", " is not allowed to update hs_office_relation uuid");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void contactAdmin_canNotUpdateRelatedRelationship() {
|
public void contactAdmin_canNotUpdateRelatedRelation() {
|
||||||
// given
|
// given
|
||||||
context("superuser-alex@hostsharing.net");
|
context("superuser-alex@hostsharing.net");
|
||||||
final var givenRelationship = givenSomeTemporaryRelationshipBessler(
|
final var givenRelation = givenSomeTemporaryRelationBessler(
|
||||||
"Anita", "ninth");
|
"Anita", "ninth");
|
||||||
assertThatRelationshipIsVisibleForUserWithRole(
|
assertThatRelationIsVisibleForUserWithRole(
|
||||||
givenRelationship,
|
givenRelation,
|
||||||
"hs_office_contact#ninthcontact.admin");
|
"hs_office_contact#ninthcontact.admin");
|
||||||
assertThatRelationshipActuallyInDatabase(givenRelationship);
|
assertThatRelationActuallyInDatabase(givenRelation);
|
||||||
|
|
||||||
// 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");
|
||||||
givenRelationship.setContact(null); // TODO
|
givenRelation.setContact(null); // TODO
|
||||||
return relationshipRepo.save(givenRelationship);
|
return relationRepo.save(givenRelation);
|
||||||
});
|
});
|
||||||
|
|
||||||
// then
|
// then
|
||||||
result.assertExceptionWithRootCauseMessage(JpaSystemException.class,
|
result.assertExceptionWithRootCauseMessage(JpaSystemException.class,
|
||||||
"[403] Subject ", " is not allowed to update hs_office_relationship uuid");
|
"[403] Subject ", " is not allowed to update hs_office_relation uuid");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertThatRelationshipActuallyInDatabase(final HsOfficeRelationshipEntity saved) {
|
private void assertThatRelationActuallyInDatabase(final HsOfficeRelationEntity saved) {
|
||||||
final var found = relationshipRepo.findByUuid(saved.getUuid());
|
final var found = relationRepo.findByUuid(saved.getUuid());
|
||||||
assertThat(found).isNotEmpty().get().isNotSameAs(saved).usingRecursiveComparison().isEqualTo(saved);
|
assertThat(found).isNotEmpty().get().isNotSameAs(saved).usingRecursiveComparison().isEqualTo(saved);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertThatRelationshipIsVisibleForUserWithRole(
|
private void assertThatRelationIsVisibleForUserWithRole(
|
||||||
final HsOfficeRelationshipEntity entity,
|
final HsOfficeRelationEntity entity,
|
||||||
final String assumedRoles) {
|
final String assumedRoles) {
|
||||||
jpaAttempt.transacted(() -> {
|
jpaAttempt.transacted(() -> {
|
||||||
context("superuser-alex@hostsharing.net", assumedRoles);
|
context("superuser-alex@hostsharing.net", assumedRoles);
|
||||||
assertThatRelationshipActuallyInDatabase(entity);
|
assertThatRelationActuallyInDatabase(entity);
|
||||||
}).assertSuccessful();
|
}).assertSuccessful();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertThatRelationshipIsNotVisibleForUserWithRole(
|
private void assertThatRelationIsNotVisibleForUserWithRole(
|
||||||
final HsOfficeRelationshipEntity entity,
|
final HsOfficeRelationEntity entity,
|
||||||
final String assumedRoles) {
|
final String assumedRoles) {
|
||||||
jpaAttempt.transacted(() -> {
|
jpaAttempt.transacted(() -> {
|
||||||
context("superuser-alex@hostsharing.net", assumedRoles);
|
context("superuser-alex@hostsharing.net", assumedRoles);
|
||||||
final var found = relationshipRepo.findByUuid(entity.getUuid());
|
final var found = relationRepo.findByUuid(entity.getUuid());
|
||||||
assertThat(found).isEmpty();
|
assertThat(found).isEmpty();
|
||||||
}).assertSuccessful();
|
}).assertSuccessful();
|
||||||
}
|
}
|
||||||
@ -290,63 +290,63 @@ class HsOfficeRelationshipRepositoryIntegrationTest extends ContextBasedTestWith
|
|||||||
class DeleteByUuid {
|
class DeleteByUuid {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void globalAdmin_withoutAssumedRole_canDeleteAnyRelationship() {
|
public void globalAdmin_withoutAssumedRole_canDeleteAnyRelation() {
|
||||||
// given
|
// given
|
||||||
context("superuser-alex@hostsharing.net", null);
|
context("superuser-alex@hostsharing.net", null);
|
||||||
final var givenRelationship = givenSomeTemporaryRelationshipBessler(
|
final var givenRelation = givenSomeTemporaryRelationBessler(
|
||||||
"Anita", "tenth");
|
"Anita", "tenth");
|
||||||
|
|
||||||
// when
|
// when
|
||||||
final var result = jpaAttempt.transacted(() -> {
|
final var result = jpaAttempt.transacted(() -> {
|
||||||
context("superuser-alex@hostsharing.net");
|
context("superuser-alex@hostsharing.net");
|
||||||
relationshipRepo.deleteByUuid(givenRelationship.getUuid());
|
relationRepo.deleteByUuid(givenRelation.getUuid());
|
||||||
});
|
});
|
||||||
|
|
||||||
// then
|
// then
|
||||||
result.assertSuccessful();
|
result.assertSuccessful();
|
||||||
assertThat(jpaAttempt.transacted(() -> {
|
assertThat(jpaAttempt.transacted(() -> {
|
||||||
context("superuser-fran@hostsharing.net", null);
|
context("superuser-fran@hostsharing.net", null);
|
||||||
return relationshipRepo.findByUuid(givenRelationship.getUuid());
|
return relationRepo.findByUuid(givenRelation.getUuid());
|
||||||
}).assertSuccessful().returnedValue()).isEmpty();
|
}).assertSuccessful().returnedValue()).isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void contactUser_canViewButNotDeleteTheirRelatedRelationship() {
|
public void contactUser_canViewButNotDeleteTheirRelatedRelation() {
|
||||||
// given
|
// given
|
||||||
context("superuser-alex@hostsharing.net", null);
|
context("superuser-alex@hostsharing.net", null);
|
||||||
final var givenRelationship = givenSomeTemporaryRelationshipBessler(
|
final var givenRelation = givenSomeTemporaryRelationBessler(
|
||||||
"Anita", "eleventh");
|
"Anita", "eleventh");
|
||||||
|
|
||||||
// when
|
// when
|
||||||
final var result = jpaAttempt.transacted(() -> {
|
final var result = jpaAttempt.transacted(() -> {
|
||||||
context("contact-admin@eleventhcontact.example.com");
|
context("contact-admin@eleventhcontact.example.com");
|
||||||
assertThat(relationshipRepo.findByUuid(givenRelationship.getUuid())).isPresent();
|
assertThat(relationRepo.findByUuid(givenRelation.getUuid())).isPresent();
|
||||||
relationshipRepo.deleteByUuid(givenRelationship.getUuid());
|
relationRepo.deleteByUuid(givenRelation.getUuid());
|
||||||
});
|
});
|
||||||
|
|
||||||
// then
|
// then
|
||||||
result.assertExceptionWithRootCauseMessage(
|
result.assertExceptionWithRootCauseMessage(
|
||||||
JpaSystemException.class,
|
JpaSystemException.class,
|
||||||
"[403] Subject ", " not allowed to delete hs_office_relationship");
|
"[403] Subject ", " not allowed to delete hs_office_relation");
|
||||||
assertThat(jpaAttempt.transacted(() -> {
|
assertThat(jpaAttempt.transacted(() -> {
|
||||||
context("superuser-alex@hostsharing.net");
|
context("superuser-alex@hostsharing.net");
|
||||||
return relationshipRepo.findByUuid(givenRelationship.getUuid());
|
return relationRepo.findByUuid(givenRelation.getUuid());
|
||||||
}).assertSuccessful().returnedValue()).isPresent(); // still there
|
}).assertSuccessful().returnedValue()).isPresent(); // still there
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void deletingARelationshipAlsoDeletesRelatedRolesAndGrants() {
|
public void deletingARelationAlsoDeletesRelatedRolesAndGrants() {
|
||||||
// given
|
// given
|
||||||
context("superuser-alex@hostsharing.net");
|
context("superuser-alex@hostsharing.net");
|
||||||
final var initialRoleNames = Array.from(distinctRoleNamesOf(rawRoleRepo.findAll()));
|
final var initialRoleNames = Array.from(distinctRoleNamesOf(rawRoleRepo.findAll()));
|
||||||
final var initialGrantNames = Array.from(distinctGrantDisplaysOf(rawGrantRepo.findAll()));
|
final var initialGrantNames = Array.from(distinctGrantDisplaysOf(rawGrantRepo.findAll()));
|
||||||
final var givenRelationship = givenSomeTemporaryRelationshipBessler(
|
final var givenRelation = givenSomeTemporaryRelationBessler(
|
||||||
"Anita", "twelfth");
|
"Anita", "twelfth");
|
||||||
|
|
||||||
// when
|
// when
|
||||||
final var result = jpaAttempt.transacted(() -> {
|
final var result = jpaAttempt.transacted(() -> {
|
||||||
context("superuser-alex@hostsharing.net");
|
context("superuser-alex@hostsharing.net");
|
||||||
return relationshipRepo.deleteByUuid(givenRelationship.getUuid());
|
return relationRepo.deleteByUuid(givenRelation.getUuid());
|
||||||
});
|
});
|
||||||
|
|
||||||
// then
|
// then
|
||||||
@ -363,7 +363,7 @@ class HsOfficeRelationshipRepositoryIntegrationTest extends ContextBasedTestWith
|
|||||||
final var query = em.createNativeQuery("""
|
final var query = em.createNativeQuery("""
|
||||||
select currentTask, targetTable, targetOp
|
select currentTask, targetTable, targetOp
|
||||||
from tx_journal_v
|
from tx_journal_v
|
||||||
where targettable = 'hs_office_relationship';
|
where targettable = 'hs_office_relation';
|
||||||
""");
|
""");
|
||||||
|
|
||||||
// when
|
// when
|
||||||
@ -371,40 +371,40 @@ class HsOfficeRelationshipRepositoryIntegrationTest extends ContextBasedTestWith
|
|||||||
|
|
||||||
// then
|
// then
|
||||||
assertThat(customerLogEntries).map(Arrays::toString).contains(
|
assertThat(customerLogEntries).map(Arrays::toString).contains(
|
||||||
"[creating relationship test-data HostsharingeG-FirstGmbH, hs_office_relationship, INSERT]",
|
"[creating relation test-data HostsharingeG-FirstGmbH, hs_office_relation, INSERT]",
|
||||||
"[creating relationship test-data FirstGmbH-Firby, hs_office_relationship, INSERT]");
|
"[creating relation test-data FirstGmbH-Firby, hs_office_relation, INSERT]");
|
||||||
}
|
}
|
||||||
|
|
||||||
private HsOfficeRelationshipEntity givenSomeTemporaryRelationshipBessler(final String holderPerson, final String contact) {
|
private HsOfficeRelationEntity givenSomeTemporaryRelationBessler(final String holderPerson, final String contact) {
|
||||||
return jpaAttempt.transacted(() -> {
|
return jpaAttempt.transacted(() -> {
|
||||||
context("superuser-alex@hostsharing.net");
|
context("superuser-alex@hostsharing.net");
|
||||||
final var givenAnchorPerson = personRepo.findPersonByOptionalNameLike("Erben Bessler").get(0);
|
final var givenAnchorPerson = personRepo.findPersonByOptionalNameLike("Erben Bessler").get(0);
|
||||||
final var givenHolderPerson = personRepo.findPersonByOptionalNameLike(holderPerson).get(0);
|
final var givenHolderPerson = personRepo.findPersonByOptionalNameLike(holderPerson).get(0);
|
||||||
final var givenContact = contactRepo.findContactByOptionalLabelLike(contact).get(0);
|
final var givenContact = contactRepo.findContactByOptionalLabelLike(contact).get(0);
|
||||||
final var newRelationship = HsOfficeRelationshipEntity.builder()
|
final var newRelation = HsOfficeRelationEntity.builder()
|
||||||
.relType(HsOfficeRelationshipType.REPRESENTATIVE)
|
.type(HsOfficeRelationType.REPRESENTATIVE)
|
||||||
.relAnchor(givenAnchorPerson)
|
.anchor(givenAnchorPerson)
|
||||||
.relHolder(givenHolderPerson)
|
.holder(givenHolderPerson)
|
||||||
.contact(givenContact)
|
.contact(givenContact)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
return toCleanup(relationshipRepo.save(newRelationship));
|
return toCleanup(relationRepo.save(newRelation));
|
||||||
}).assertSuccessful().returnedValue();
|
}).assertSuccessful().returnedValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
void exactlyTheseRelationshipsAreReturned(
|
void exactlyTheseRelationsAreReturned(
|
||||||
final List<HsOfficeRelationshipEntity> actualResult,
|
final List<HsOfficeRelationEntity> actualResult,
|
||||||
final String... relationshipNames) {
|
final String... relationNames) {
|
||||||
assertThat(actualResult)
|
assertThat(actualResult)
|
||||||
.extracting(HsOfficeRelationshipEntity::toString)
|
.extracting(HsOfficeRelationEntity::toString)
|
||||||
.containsExactlyInAnyOrder(relationshipNames);
|
.containsExactlyInAnyOrder(relationNames);
|
||||||
}
|
}
|
||||||
|
|
||||||
void allTheseRelationshipsAreReturned(
|
void allTheseRelationsAreReturned(
|
||||||
final List<HsOfficeRelationshipEntity> actualResult,
|
final List<HsOfficeRelationEntity> actualResult,
|
||||||
final String... relationshipNames) {
|
final String... relationNames) {
|
||||||
assertThat(actualResult)
|
assertThat(actualResult)
|
||||||
.extracting(HsOfficeRelationshipEntity::toString)
|
.extracting(HsOfficeRelationEntity::toString)
|
||||||
.contains(relationshipNames);
|
.contains(relationNames);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,44 +0,0 @@
|
|||||||
package net.hostsharing.hsadminng.hs.office.relationship;
|
|
||||||
|
|
||||||
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity;
|
|
||||||
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonType;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
|
||||||
import static org.junit.jupiter.api.Assertions.*;
|
|
||||||
|
|
||||||
class HsOfficeRelationshipEntityUnitTest {
|
|
||||||
|
|
||||||
private HsOfficePersonEntity anchor = HsOfficePersonEntity.builder()
|
|
||||||
.personType(HsOfficePersonType.LEGAL_PERSON)
|
|
||||||
.tradeName("some trade name")
|
|
||||||
.build();
|
|
||||||
private HsOfficePersonEntity holder = HsOfficePersonEntity.builder()
|
|
||||||
.personType(HsOfficePersonType.NATURAL_PERSON)
|
|
||||||
.familyName("Meier")
|
|
||||||
.givenName("Mellie")
|
|
||||||
.build();
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void toStringReturnsAllProperties() {
|
|
||||||
final var given = HsOfficeRelationshipEntity.builder()
|
|
||||||
.relType(HsOfficeRelationshipType.SUBSCRIBER)
|
|
||||||
.relMark("members-announce")
|
|
||||||
.relAnchor(anchor)
|
|
||||||
.relHolder(holder)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
assertThat(given.toString()).isEqualTo("rel(relAnchor='LP some trade name', relType='SUBSCRIBER', relMark='members-announce', relHolder='NP Meier, Mellie')");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void toShortString() {
|
|
||||||
final var given = HsOfficeRelationshipEntity.builder()
|
|
||||||
.relType(HsOfficeRelationshipType.REPRESENTATIVE)
|
|
||||||
.relAnchor(anchor)
|
|
||||||
.relHolder(holder)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
assertThat(given.toShortString()).isEqualTo("rel(relAnchor='LP some trade name', relType='REPRESENTATIVE', relHolder='NP Meier, Mellie')");
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,41 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
sourceLower=partner
|
|
||||||
targetLower=relationship
|
|
||||||
|
|
||||||
sourceStudly=Partner
|
|
||||||
targetStudly=Relationship
|
|
||||||
|
|
||||||
## for source in `find src -iname ""*$sourceLower*"" -type f \( -iname \*.yaml -o -iname \*.sql -o -iname \*.java \)`; do
|
|
||||||
for source in `find src -iname ""*$sourceLower*"" -type f \( -iname \*.yaml \)`; do
|
|
||||||
target=`echo $source | sed -e "s/$sourceStudly/$targetStudly/g" -e "s/$sourceLower/$targetLower/g"`
|
|
||||||
echo "Generating $target from $source:"
|
|
||||||
|
|
||||||
mkdir -p `dirname $target`
|
|
||||||
|
|
||||||
sed -e 's/hs-office-partner/hs-office-relationship/g' \
|
|
||||||
-e 's/hs_office_partner/hs_office_relationship/g' \
|
|
||||||
-e 's/HsOfficePartner/HsOfficeRelationship/g' \
|
|
||||||
-e 's/hsOfficePartner/hsOfficeRelationship/g' \
|
|
||||||
-e 's/partner/relationship/g' \
|
|
||||||
\
|
|
||||||
-e 's/addPartner/addRelationship/g' \
|
|
||||||
-e 's/listPartners/listRelationships/g' \
|
|
||||||
-e 's/getPartnerByUuid/getRelationshipByUuid/g' \
|
|
||||||
-e 's/patchPartner/patchRelationship/g' \
|
|
||||||
-e 's/person/relHolder/g' \
|
|
||||||
-e 's/registrationOffice/relType/g' \
|
|
||||||
<$source >$target
|
|
||||||
|
|
||||||
done
|
|
||||||
|
|
||||||
exit
|
|
||||||
|
|
||||||
cat >>src/main/resources/db/changelog/db.changelog-master.yaml <<EOF
|
|
||||||
- include:
|
|
||||||
file: db/changelog/2X0-hs-office-$sourceLower.sql
|
|
||||||
- include:
|
|
||||||
file: db/changelog/2X3-hs-office-$sourceLower-rbac.sql
|
|
||||||
- include:
|
|
||||||
file: db/changelog/2X8-hs-office-$sourceLower-test-data.sql
|
|
||||||
EOF
|
|
Loading…
Reference in New Issue
Block a user