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