rename partnerRole -> partnerRel, relationship -> relation and remove rel-Prefix (relAnchor etc.) #23
@ -114,9 +114,9 @@ public class HsOfficeDebitorEntity implements HasUuid, Stringifyable {
|
|||||||
'D-' || (SELECT partner.partnerNumber
|
'D-' || (SELECT partner.partnerNumber
|
||||||
FROM hs_office_partner partner
|
FROM hs_office_partner partner
|
||||||
JOIN hs_office_relation partnerRel
|
JOIN hs_office_relation partnerRel
|
||||||
ON partnerRel.uuid = partner.partnerRelUUid AND partnerRel.relType = 'PARTNER'
|
ON partnerRel.uuid = partner.partnerRelUUid AND partnerRel.type = 'PARTNER'
|
||||||
JOIN hs_office_relation debitorRel
|
JOIN hs_office_relation debitorRel
|
||||||
ON debitorRel.relAnchorUuid = partnerRel.relHolderUuid AND partnerRel.relType = 'DEBITOR'
|
ON debitorRel.anchorUuid = partnerRel.holderUuid AND partnerRel.type = 'DEBITOR'
|
||||||
WHERE debitorRel.uuid = debitor.debitorRelUuid)
|
WHERE debitorRel.uuid = debitor.debitorRelUuid)
|
||||||
|| to_char(debitorNumberSuffix, 'fm00')
|
|| to_char(debitorNumberSuffix, 'fm00')
|
||||||
from hs_office_debitor as debitor
|
from hs_office_debitor as debitor
|
||||||
@ -137,7 +137,7 @@ public class HsOfficeDebitorEntity implements HasUuid, Stringifyable {
|
|||||||
fetchedBySql("""
|
fetchedBySql("""
|
||||||
SELECT *
|
SELECT *
|
||||||
FROM hs_office_relation AS r
|
FROM hs_office_relation AS r
|
||||||
WHERE r.relType = 'DEBITOR' AND r.relHolderUuid = ${REF}.debitorRelUuid
|
WHERE r.type = 'DEBITOR' AND r.holderUuid = ${REF}.debitorRelUuid
|
||||||
"""),
|
"""),
|
||||||
dependsOnColumn("debitorRelUuid"))
|
dependsOnColumn("debitorRelUuid"))
|
||||||
.createPermission(DELETE).grantedTo("debitorRel", OWNER)
|
.createPermission(DELETE).grantedTo("debitorRel", OWNER)
|
||||||
@ -148,7 +148,7 @@ public class HsOfficeDebitorEntity implements HasUuid, Stringifyable {
|
|||||||
dependsOnColumn("refundBankAccountUuid"), fetchedBySql("""
|
dependsOnColumn("refundBankAccountUuid"), fetchedBySql("""
|
||||||
SELECT *
|
SELECT *
|
||||||
FROM hs_office_relation AS r
|
FROM hs_office_relation AS r
|
||||||
WHERE r.relType = 'DEBITOR' AND r.relHolderUuid = ${REF}.debitorRelUuid
|
WHERE r.type = 'DEBITOR' AND r.holderUuid = ${REF}.debitorRelUuid
|
||||||
""")
|
""")
|
||||||
)
|
)
|
||||||
.toRole("refundBankAccount", ADMIN).grantRole("debitorRel", AGENT)
|
.toRole("refundBankAccount", ADMIN).grantRole("debitorRel", AGENT)
|
||||||
@ -158,7 +158,7 @@ public class HsOfficeDebitorEntity implements HasUuid, Stringifyable {
|
|||||||
dependsOnColumn("partnerRelUuid"), fetchedBySql("""
|
dependsOnColumn("partnerRelUuid"), fetchedBySql("""
|
||||||
SELECT *
|
SELECT *
|
||||||
FROM hs_office_relation AS partnerRel
|
FROM hs_office_relation AS partnerRel
|
||||||
WHERE ${debitorRel}.relAnchorUuid = partnerRel.relHolderUuid
|
WHERE ${debitorRel}.anchorUuid = partnerRel.holderUuid
|
||||||
""")
|
""")
|
||||||
)
|
)
|
||||||
.toRole("partnerRel", ADMIN).grantRole("debitorRel", ADMIN)
|
.toRole("partnerRel", ADMIN).grantRole("debitorRel", ADMIN)
|
||||||
|
@ -150,9 +150,9 @@ public class HsOfficePartnerController implements HsOfficePartnersApi {
|
|||||||
|
|
||||||
private HsOfficeRelationEntity persistPartnerRel(final HsOfficePartnerRelInsertResource resource) {
|
private HsOfficeRelationEntity persistPartnerRel(final HsOfficePartnerRelInsertResource resource) {
|
||||||
final var entity = new HsOfficeRelationEntity();
|
final var entity = new HsOfficeRelationEntity();
|
||||||
entity.setRelType(HsOfficeRelationType.PARTNER);
|
entity.setType(HsOfficeRelationType.PARTNER);
|
||||||
entity.setRelAnchor(ref(HsOfficePersonEntity.class, resource.getRelAnchorUuid()));
|
entity.setAnchor(ref(HsOfficePersonEntity.class, resource.getAnchorUuid()));
|
||||||
entity.setRelHolder(ref(HsOfficePersonEntity.class, resource.getRelHolderUuid()));
|
entity.setHolder(ref(HsOfficePersonEntity.class, resource.getHolderUuid()));
|
||||||
entity.setContact(ref(HsOfficeContactEntity.class, resource.getContactUuid()));
|
entity.setContact(ref(HsOfficeContactEntity.class, resource.getContactUuid()));
|
||||||
em.persist(entity);
|
em.persist(entity);
|
||||||
return entity;
|
return entity;
|
||||||
|
@ -34,7 +34,7 @@ public class HsOfficeRelationController implements HsOfficeRelationsApi {
|
|||||||
private HsOfficeRelationRepository relationRepo;
|
private HsOfficeRelationRepository relationRepo;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private HsOfficePersonRepository relHolderRepo;
|
private HsOfficePersonRepository holderRepo;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private HsOfficeContactRepository contactRepo;
|
private HsOfficeContactRepository contactRepo;
|
||||||
@ -69,12 +69,12 @@ public class HsOfficeRelationController implements HsOfficeRelationsApi {
|
|||||||
context.define(currentUser, assumedRoles);
|
context.define(currentUser, assumedRoles);
|
||||||
|
|
||||||
final var entityToSave = new HsOfficeRelationEntity();
|
final var entityToSave = new HsOfficeRelationEntity();
|
||||||
entityToSave.setRelType(HsOfficeRelationType.valueOf(body.getRelType()));
|
entityToSave.setType(HsOfficeRelationType.valueOf(body.getType()));
|
||||||
entityToSave.setRelAnchor(relHolderRepo.findByUuid(body.getRelAnchorUuid()).orElseThrow(
|
entityToSave.setAnchor(holderRepo.findByUuid(body.getAnchorUuid()).orElseThrow(
|
||||||
() -> new NoSuchElementException("cannot find relAnchorUuid " + body.getRelAnchorUuid())
|
() -> new NoSuchElementException("cannot find anchorUuid " + body.getAnchorUuid())
|
||||||
));
|
));
|
||||||
entityToSave.setRelHolder(relHolderRepo.findByUuid(body.getRelHolderUuid()).orElseThrow(
|
entityToSave.setHolder(holderRepo.findByUuid(body.getHolderUuid()).orElseThrow(
|
||||||
() -> new NoSuchElementException("cannot find relHolderUuid " + body.getRelHolderUuid())
|
() -> new NoSuchElementException("cannot find holderUuid " + body.getHolderUuid())
|
||||||
));
|
));
|
||||||
entityToSave.setContact(contactRepo.findByUuid(body.getContactUuid()).orElseThrow(
|
entityToSave.setContact(contactRepo.findByUuid(body.getContactUuid()).orElseThrow(
|
||||||
() -> new NoSuchElementException("cannot find contactUuid " + body.getContactUuid())
|
() -> new NoSuchElementException("cannot find contactUuid " + body.getContactUuid())
|
||||||
@ -145,8 +145,8 @@ public class HsOfficeRelationController implements HsOfficeRelationsApi {
|
|||||||
|
|
||||||
|
|
||||||
final BiConsumer<HsOfficeRelationEntity, HsOfficeRelationResource> RELATION_ENTITY_TO_RESOURCE_POSTMAPPER = (entity, resource) -> {
|
final BiConsumer<HsOfficeRelationEntity, HsOfficeRelationResource> RELATION_ENTITY_TO_RESOURCE_POSTMAPPER = (entity, resource) -> {
|
||||||
resource.setRelAnchor(mapper.map(entity.getRelAnchor(), HsOfficePersonResource.class));
|
resource.setAnchor(mapper.map(entity.getAnchor(), HsOfficePersonResource.class));
|
||||||
resource.setRelHolder(mapper.map(entity.getRelHolder(), HsOfficePersonResource.class));
|
resource.setHolder(mapper.map(entity.getHolder(), HsOfficePersonResource.class));
|
||||||
resource.setContact(mapper.map(entity.getContact(), HsOfficeContactResource.class));
|
resource.setContact(mapper.map(entity.getContact(), HsOfficeContactResource.class));
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -34,39 +34,39 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
|||||||
public class HsOfficeRelationEntity implements HasUuid, Stringifyable {
|
public class HsOfficeRelationEntity implements HasUuid, Stringifyable {
|
||||||
|
|
||||||
private static Stringify<HsOfficeRelationEntity> toString = stringify(HsOfficeRelationEntity.class, "rel")
|
private static Stringify<HsOfficeRelationEntity> toString = stringify(HsOfficeRelationEntity.class, "rel")
|
||||||
.withProp(Fields.relAnchor, HsOfficeRelationEntity::getRelAnchor)
|
.withProp(Fields.anchor, HsOfficeRelationEntity::getAnchor)
|
||||||
.withProp(Fields.relType, HsOfficeRelationEntity::getRelType)
|
.withProp(Fields.type, HsOfficeRelationEntity::getType)
|
||||||
.withProp(Fields.relMark, HsOfficeRelationEntity::getRelMark)
|
.withProp(Fields.mark, HsOfficeRelationEntity::getMark)
|
||||||
.withProp(Fields.relHolder, HsOfficeRelationEntity::getRelHolder)
|
.withProp(Fields.holder, HsOfficeRelationEntity::getHolder)
|
||||||
.withProp(Fields.contact, HsOfficeRelationEntity::getContact);
|
.withProp(Fields.contact, HsOfficeRelationEntity::getContact);
|
||||||
|
|
||||||
private static Stringify<HsOfficeRelationEntity> toShortString = stringify(HsOfficeRelationEntity.class, "rel")
|
private static Stringify<HsOfficeRelationEntity> toShortString = stringify(HsOfficeRelationEntity.class, "rel")
|
||||||
.withProp(Fields.relAnchor, HsOfficeRelationEntity::getRelAnchor)
|
.withProp(Fields.anchor, HsOfficeRelationEntity::getAnchor)
|
||||||
.withProp(Fields.relType, HsOfficeRelationEntity::getRelType)
|
.withProp(Fields.type, HsOfficeRelationEntity::getType)
|
||||||
.withProp(Fields.relHolder, HsOfficeRelationEntity::getRelHolder);
|
.withProp(Fields.holder, HsOfficeRelationEntity::getHolder);
|
||||||
|
|
||||||
@Id
|
@Id
|
||||||
@GeneratedValue
|
@GeneratedValue
|
||||||
private UUID uuid;
|
private UUID uuid;
|
||||||
|
|
||||||
@ManyToOne
|
@ManyToOne
|
||||||
@JoinColumn(name = "relanchoruuid")
|
@JoinColumn(name = "anchoruuid")
|
||||||
private HsOfficePersonEntity relAnchor;
|
private HsOfficePersonEntity anchor;
|
||||||
|
|
||||||
@ManyToOne
|
@ManyToOne
|
||||||
@JoinColumn(name = "relholderuuid")
|
@JoinColumn(name = "holderuuid")
|
||||||
private HsOfficePersonEntity relHolder;
|
private HsOfficePersonEntity holder;
|
||||||
|
|
||||||
@ManyToOne
|
@ManyToOne
|
||||||
@JoinColumn(name = "contactuuid")
|
@JoinColumn(name = "contactuuid")
|
||||||
private HsOfficeContactEntity contact;
|
private HsOfficeContactEntity contact;
|
||||||
|
|
||||||
@Column(name = "reltype")
|
@Column(name = "type")
|
||||||
@Enumerated(EnumType.STRING)
|
@Enumerated(EnumType.STRING)
|
||||||
private HsOfficeRelationType relType;
|
private HsOfficeRelationType type;
|
||||||
|
|
||||||
@Column(name = "relmark")
|
@Column(name = "mark")
|
||||||
private String relMark;
|
private String mark;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
@ -81,20 +81,20 @@ public class HsOfficeRelationEntity implements HasUuid, Stringifyable {
|
|||||||
public static RbacView rbac() {
|
public static RbacView rbac() {
|
||||||
return rbacViewFor("relation", HsOfficeRelationEntity.class)
|
return rbacViewFor("relation", HsOfficeRelationEntity.class)
|
||||||
.withIdentityView(SQL.projection("""
|
.withIdentityView(SQL.projection("""
|
||||||
(select idName from hs_office_person_iv p where p.uuid = relAnchorUuid)
|
(select idName from hs_office_person_iv p where p.uuid = anchorUuid)
|
||||||
|| '-with-' || target.relType || '-'
|
|| '-with-' || target.type || '-'
|
||||||
|| (select idName from hs_office_person_iv p where p.uuid = relHolderUuid)
|
|| (select idName from hs_office_person_iv p where p.uuid = holderUuid)
|
||||||
"""))
|
"""))
|
||||||
.withRestrictedViewOrderBy(SQL.expression(
|
.withRestrictedViewOrderBy(SQL.expression(
|
||||||
"(select idName from hs_office_person_iv p where p.uuid = target.relHolderUuid)"))
|
"(select idName from hs_office_person_iv p where p.uuid = target.holderUuid)"))
|
||||||
.withUpdatableColumns("contactUuid")
|
.withUpdatableColumns("contactUuid")
|
||||||
.importEntityAlias("anchorPerson", HsOfficePersonEntity.class,
|
.importEntityAlias("anchorPerson", HsOfficePersonEntity.class,
|
||||||
dependsOnColumn("relAnchorUuid"),
|
dependsOnColumn("anchorUuid"),
|
||||||
fetchedBySql("select * from hs_office_person as p where p.uuid = ${REF}.relAnchorUuid")
|
fetchedBySql("select * from hs_office_person as p where p.uuid = ${REF}.anchorUuid")
|
||||||
)
|
)
|
||||||
.importEntityAlias("holderPerson", HsOfficePersonEntity.class,
|
.importEntityAlias("holderPerson", HsOfficePersonEntity.class,
|
||||||
dependsOnColumn("relHolderUuid"),
|
dependsOnColumn("holderUuid"),
|
||||||
fetchedBySql("select * from hs_office_person as p where p.uuid = ${REF}.relHolderUuid")
|
fetchedBySql("select * from hs_office_person as p where p.uuid = ${REF}.holderUuid")
|
||||||
)
|
)
|
||||||
.importEntityAlias("contact", HsOfficeContactEntity.class,
|
.importEntityAlias("contact", HsOfficeContactEntity.class,
|
||||||
dependsOnColumn("contactUuid"),
|
dependsOnColumn("contactUuid"),
|
||||||
|
@ -18,14 +18,14 @@ public interface HsOfficeRelationRepository extends Repository<HsOfficeRelationE
|
|||||||
|
|
||||||
@Query(value = """
|
@Query(value = """
|
||||||
SELECT p.* FROM hs_office_relation_rv AS p
|
SELECT p.* FROM hs_office_relation_rv AS p
|
||||||
WHERE p.relAnchorUuid = :personUuid OR p.relHolderUuid = :personUuid
|
WHERE p.anchorUuid = :personUuid OR p.holderUuid = :personUuid
|
||||||
""", nativeQuery = true)
|
""", nativeQuery = true)
|
||||||
List<HsOfficeRelationEntity> findRelationRelatedToPersonUuid(@NotNull UUID personUuid);
|
List<HsOfficeRelationEntity> findRelationRelatedToPersonUuid(@NotNull UUID personUuid);
|
||||||
|
|
||||||
@Query(value = """
|
@Query(value = """
|
||||||
SELECT p.* FROM hs_office_relation_rv AS p
|
SELECT p.* FROM hs_office_relation_rv AS p
|
||||||
WHERE (:relationType IS NULL OR p.relType = cast(:relationType AS HsOfficeRelationType))
|
WHERE (:relationType IS NULL OR p.type = cast(:relationType AS HsOfficeRelationType))
|
||||||
AND ( p.relAnchorUuid = :personUuid OR p.relHolderUuid = :personUuid)
|
AND ( p.anchorUuid = :personUuid OR p.holderUuid = :personUuid)
|
||||||
""", nativeQuery = true)
|
""", nativeQuery = true)
|
||||||
List<HsOfficeRelationEntity> findRelationRelatedToPersonUuidAndRelationTypeString(@NotNull UUID personUuid, String relationType);
|
List<HsOfficeRelationEntity> findRelationRelatedToPersonUuidAndRelationTypeString(@NotNull UUID personUuid, String relationType);
|
||||||
|
|
||||||
|
@ -116,18 +116,18 @@ components:
|
|||||||
type: object
|
type: object
|
||||||
nullable: false
|
nullable: false
|
||||||
properties:
|
properties:
|
||||||
relAnchorUuid:
|
anchorUuid:
|
||||||
type: string
|
type: string
|
||||||
format: uuid
|
format: uuid
|
||||||
relHolderUuid:
|
holderUuid:
|
||||||
type: string
|
type: string
|
||||||
format: uuid
|
format: uuid
|
||||||
contactUuid:
|
contactUuid:
|
||||||
type: string
|
type: string
|
||||||
format: uuid
|
format: uuid
|
||||||
required:
|
required:
|
||||||
- relAnchorUuid
|
- anchorUuid
|
||||||
- relHolderUuid
|
- holderUuid
|
||||||
- relContactUuid
|
- relContactUuid
|
||||||
|
|
||||||
HsOfficePartnerDetailsInsert:
|
HsOfficePartnerDetailsInsert:
|
||||||
|
@ -19,11 +19,11 @@ CREATE CAST (character varying as HsOfficeRelationType) WITH INOUT AS IMPLICIT;
|
|||||||
create table if not exists hs_office_relation
|
create table if not exists hs_office_relation
|
||||||
(
|
(
|
||||||
uuid uuid unique references RbacObject (uuid) initially deferred, -- on delete cascade
|
uuid uuid unique references RbacObject (uuid) initially deferred, -- on delete cascade
|
||||||
relAnchorUuid uuid not null references hs_office_person(uuid),
|
anchorUuid uuid not null references hs_office_person(uuid),
|
||||||
relHolderUuid uuid not null references hs_office_person(uuid),
|
holderUuid uuid not null references hs_office_person(uuid),
|
||||||
contactUuid uuid references hs_office_contact(uuid),
|
contactUuid uuid references hs_office_contact(uuid),
|
||||||
relType HsOfficeRelationType not null,
|
type HsOfficeRelationType not null,
|
||||||
relMark varchar(24)
|
mark varchar(24)
|
||||||
);
|
);
|
||||||
--//
|
--//
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ end
|
|||||||
|
|
||||||
subgraph hsOfficeRelation
|
subgraph hsOfficeRelation
|
||||||
|
|
||||||
role:hsOfficePerson#relAnchor.admin[person#anchor.admin]
|
role:hsOfficePerson#anchor.admin[person#anchor.admin]
|
||||||
--- role:hsOfficePerson.admin
|
--- role:hsOfficePerson.admin
|
||||||
|
|
||||||
role:hsOfficeRelation.owner[relation.owner]
|
role:hsOfficeRelation.owner[relation.owner]
|
||||||
@ -38,7 +38,7 @@ subgraph hsOfficeRelation
|
|||||||
role:hsOfficeRelation.owner --> perm:hsOfficeRelation.*{{relation.*}}
|
role:hsOfficeRelation.owner --> perm:hsOfficeRelation.*{{relation.*}}
|
||||||
%% incoming
|
%% incoming
|
||||||
role:global.admin ---> role:hsOfficeRelation.owner
|
role:global.admin ---> role:hsOfficeRelation.owner
|
||||||
role:hsOfficePersonAdmin#relAnchor.admin
|
role:hsOfficePersonAdmin#anchor.admin
|
||||||
end
|
end
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -28,8 +28,8 @@ create or replace function hsOfficeRelationRbacRolesTrigger()
|
|||||||
strict as $$
|
strict as $$
|
||||||
declare
|
declare
|
||||||
hsOfficeRelationTenant RbacRoleDescriptor;
|
hsOfficeRelationTenant RbacRoleDescriptor;
|
||||||
newRelAnchor hs_office_person;
|
newAnchor hs_office_person;
|
||||||
newRelHolder hs_office_person;
|
newHolder hs_office_person;
|
||||||
oldContact hs_office_contact;
|
oldContact hs_office_contact;
|
||||||
newContact hs_office_contact;
|
newContact hs_office_contact;
|
||||||
begin
|
begin
|
||||||
@ -37,8 +37,8 @@ begin
|
|||||||
|
|
||||||
hsOfficeRelationTenant := hsOfficeRelationTenant(NEW);
|
hsOfficeRelationTenant := hsOfficeRelationTenant(NEW);
|
||||||
|
|
||||||
select * from hs_office_person as p where p.uuid = NEW.relAnchorUuid into newRelAnchor;
|
select * from hs_office_person as p where p.uuid = NEW.anchorUuid into newAnchor;
|
||||||
select * from hs_office_person as p where p.uuid = NEW.relHolderUuid into newRelHolder;
|
select * from hs_office_person as p where p.uuid = NEW.holderUuid into newHolder;
|
||||||
select * from hs_office_contact as c where c.uuid = NEW.contactUuid into newContact;
|
select * from hs_office_contact as c where c.uuid = NEW.contactUuid into newContact;
|
||||||
|
|
||||||
if TG_OP = 'INSERT' then
|
if TG_OP = 'INSERT' then
|
||||||
@ -48,7 +48,7 @@ begin
|
|||||||
permissions => array['DELETE'],
|
permissions => array['DELETE'],
|
||||||
incomingSuperRoles => array[
|
incomingSuperRoles => array[
|
||||||
globalAdmin(),
|
globalAdmin(),
|
||||||
hsOfficePersonAdmin(newRelAnchor)]
|
hsOfficePersonAdmin(newAnchor)]
|
||||||
);
|
);
|
||||||
|
|
||||||
perform createRoleWithGrants(
|
perform createRoleWithGrants(
|
||||||
@ -63,21 +63,21 @@ begin
|
|||||||
permissions => array['SELECT'],
|
permissions => array['SELECT'],
|
||||||
incomingSuperRoles => array[
|
incomingSuperRoles => array[
|
||||||
hsOfficeRelationAdmin(NEW),
|
hsOfficeRelationAdmin(NEW),
|
||||||
hsOfficePersonAdmin(newRelAnchor),
|
hsOfficePersonAdmin(newAnchor),
|
||||||
hsOfficePersonAdmin(newRelHolder),
|
hsOfficePersonAdmin(newHolder),
|
||||||
hsOfficeContactAdmin(newContact)],
|
hsOfficeContactAdmin(newContact)],
|
||||||
outgoingSubRoles => array[
|
outgoingSubRoles => array[
|
||||||
hsOfficePersonTenant(newRelAnchor),
|
hsOfficePersonTenant(newAnchor),
|
||||||
hsOfficePersonTenant(newRelHolder),
|
hsOfficePersonTenant(newHolder),
|
||||||
hsOfficeContactTenant(newContact)]
|
hsOfficeContactTenant(newContact)]
|
||||||
);
|
);
|
||||||
|
|
||||||
-- anchor and holder admin roles need each others tenant role
|
-- anchor and holder admin roles need each others tenant role
|
||||||
-- to be able to see the joined relation
|
-- to be able to see the joined relation
|
||||||
-- TODO: this can probably be avoided through agent+guest roles
|
-- TODO: this can probably be avoided through agent+guest roles
|
||||||
call grantRoleToRole(hsOfficePersonTenant(newRelAnchor), hsOfficePersonAdmin(newRelHolder));
|
call grantRoleToRole(hsOfficePersonTenant(newAnchor), hsOfficePersonAdmin(newHolder));
|
||||||
call grantRoleToRole(hsOfficePersonTenant(newRelHolder), hsOfficePersonAdmin(newRelAnchor));
|
call grantRoleToRole(hsOfficePersonTenant(newHolder), hsOfficePersonAdmin(newAnchor));
|
||||||
call grantRoleToRoleIfNotNull(hsOfficePersonTenant(newRelHolder), hsOfficeContactAdmin(newContact));
|
call grantRoleToRoleIfNotNull(hsOfficePersonTenant(newHolder), hsOfficeContactAdmin(newContact));
|
||||||
|
|
||||||
elsif TG_OP = 'UPDATE' then
|
elsif TG_OP = 'UPDATE' then
|
||||||
|
|
||||||
@ -125,9 +125,9 @@ execute procedure hsOfficeRelationRbacRolesTrigger();
|
|||||||
--changeset hs-office-relation-rbac-IDENTITY-VIEW:1 endDelimiter:--//
|
--changeset hs-office-relation-rbac-IDENTITY-VIEW:1 endDelimiter:--//
|
||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
call generateRbacIdentityViewFromProjection('hs_office_relation', $idName$
|
call generateRbacIdentityViewFromProjection('hs_office_relation', $idName$
|
||||||
(select idName from hs_office_person_iv p where p.uuid = target.relAnchorUuid)
|
(select idName from hs_office_person_iv p where p.uuid = target.anchorUuid)
|
||||||
|| '-with-' || target.relType || '-' ||
|
|| '-with-' || target.type || '-' ||
|
||||||
(select idName from hs_office_person_iv p where p.uuid = target.relHolderUuid)
|
(select idName from hs_office_person_iv p where p.uuid = target.holderUuid)
|
||||||
$idName$);
|
$idName$);
|
||||||
--//
|
--//
|
||||||
|
|
||||||
@ -136,7 +136,7 @@ call generateRbacIdentityViewFromProjection('hs_office_relation', $idName$
|
|||||||
--changeset hs-office-relation-rbac-RESTRICTED-VIEW:1 endDelimiter:--//
|
--changeset hs-office-relation-rbac-RESTRICTED-VIEW:1 endDelimiter:--//
|
||||||
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
||||||
call generateRbacRestrictedView('hs_office_relation',
|
call generateRbacRestrictedView('hs_office_relation',
|
||||||
'(select idName from hs_office_person_iv p where p.uuid = target.relHolderUuid)',
|
'(select idName from hs_office_person_iv p where p.uuid = target.holderUuid)',
|
||||||
$updates$
|
$updates$
|
||||||
contactUuid = new.contactUuid
|
contactUuid = new.contactUuid
|
||||||
$updates$);
|
$updates$);
|
||||||
|
@ -50,7 +50,7 @@ begin
|
|||||||
raise notice '- using holder person (%): %', holderPerson.uuid, holderPerson;
|
raise notice '- using holder person (%): %', holderPerson.uuid, holderPerson;
|
||||||
raise notice '- using contact (%): %', contact.uuid, contact;
|
raise notice '- using contact (%): %', contact.uuid, contact;
|
||||||
insert
|
insert
|
||||||
into hs_office_relation (uuid, relanchoruuid, relholderuuid, reltype, relmark, contactUuid)
|
into hs_office_relation (uuid, anchoruuid, holderuuid, type, mark, contactUuid)
|
||||||
values (uuid_generate_v4(), anchorPerson.uuid, holderPerson.uuid, relationType, mark, contact.uuid);
|
values (uuid_generate_v4(), anchorPerson.uuid, holderPerson.uuid, relationType, mark, contact.uuid);
|
||||||
end; $$;
|
end; $$;
|
||||||
--//
|
--//
|
||||||
|
@ -43,8 +43,8 @@ begin
|
|||||||
into relatedContact;
|
into relatedContact;
|
||||||
|
|
||||||
select r.* from hs_office_relation r
|
select r.* from hs_office_relation r
|
||||||
where r.reltype = 'PARTNER'
|
where r.type = 'PARTNER'
|
||||||
and r.relanchoruuid = mandantPerson.uuid and r.relholderuuid = relatedPerson.uuid
|
and r.anchoruuid = mandantPerson.uuid and r.holderuuid = relatedPerson.uuid
|
||||||
into partnerRel;
|
into partnerRel;
|
||||||
if partnerRel is null then
|
if partnerRel is null then
|
||||||
raise exception 'partnerRel "%"-"%" not found', mandantPerson.tradename, partnerPersonName;
|
raise exception 'partnerRel "%"-"%" not found', mandantPerson.tradename, partnerPersonName;
|
||||||
|
@ -223,12 +223,12 @@ public class ImportOfficeData extends ContextBasedTest {
|
|||||||
void buildDebitorRelations() {
|
void buildDebitorRelations() {
|
||||||
debitors.forEach( (id, debitor) -> {
|
debitors.forEach( (id, debitor) -> {
|
||||||
final var debitorRel = HsOfficeRelationEntity.builder()
|
final var debitorRel = HsOfficeRelationEntity.builder()
|
||||||
.relType(HsOfficeRelationType.DEBITOR)
|
.type(HsOfficeRelationType.DEBITOR)
|
||||||
.relAnchor(debitor.getPartner().getPartnerRel().getRelHolder())
|
.anchor(debitor.getPartner().getPartnerRel().getHolder())
|
||||||
.relHolder(debitor.getPartner().getPartnerRel().getRelHolder()) // just 1 debitor/partner in legacy hsadmin
|
.holder(debitor.getPartner().getPartnerRel().getHolder()) // just 1 debitor/partner in legacy hsadmin
|
||||||
.contact(debitor.getBillingContact())
|
.contact(debitor.getBillingContact())
|
||||||
.build();
|
.build();
|
||||||
if (debitorRel.getRelAnchor() != null && debitorRel.getRelHolder() != null &&
|
if (debitorRel.getAnchor() != null && debitorRel.getHolder() != null &&
|
||||||
debitorRel.getContact() != null ) {
|
debitorRel.getContact() != null ) {
|
||||||
relations.put(relationId++, debitorRel);
|
relations.put(relationId++, debitorRel);
|
||||||
}
|
}
|
||||||
@ -290,26 +290,26 @@ public class ImportOfficeData extends ContextBasedTest {
|
|||||||
""");
|
""");
|
||||||
assertThat(toFormattedString(relations)).isEqualToIgnoringWhitespace("""
|
assertThat(toFormattedString(relations)).isEqualToIgnoringWhitespace("""
|
||||||
{
|
{
|
||||||
2000000=rel(relAnchor='LP Hostsharing eG', relType='PARTNER', relHolder='NP Mellies, Michael', contact='Herr Michael Mellies '),
|
2000000=rel(anchor='LP Hostsharing eG', type='PARTNER', holder='NP Mellies, Michael', contact='Herr Michael Mellies '),
|
||||||
2000001=rel(relAnchor='LP Hostsharing eG', relType='PARTNER', relHolder='LP JM GmbH', contact='Herr Philip Meyer-Contract , JM GmbH'),
|
2000001=rel(anchor='LP Hostsharing eG', type='PARTNER', holder='LP JM GmbH', contact='Herr Philip Meyer-Contract , JM GmbH'),
|
||||||
2000002=rel(relAnchor='LP Hostsharing eG', relType='PARTNER', relHolder='?? Test PS', contact='Petra Schmidt , Test PS'),
|
2000002=rel(anchor='LP Hostsharing eG', type='PARTNER', holder='?? Test PS', contact='Petra Schmidt , Test PS'),
|
||||||
2000003=rel(relAnchor='LP Hostsharing eG', relType='PARTNER', relHolder='null null, null'),
|
2000003=rel(anchor='LP Hostsharing eG', type='PARTNER', holder='null null, null'),
|
||||||
2000004=rel(relAnchor='NP Mellies, Michael', relType='OPERATIONS', relHolder='NP Mellies, Michael', contact='Herr Michael Mellies '),
|
2000004=rel(anchor='NP Mellies, Michael', type='OPERATIONS', holder='NP Mellies, Michael', contact='Herr Michael Mellies '),
|
||||||
2000005=rel(relAnchor='NP Mellies, Michael', relType='REPRESENTATIVE', relHolder='NP Mellies, Michael', contact='Herr Michael Mellies '),
|
2000005=rel(anchor='NP Mellies, Michael', type='REPRESENTATIVE', holder='NP Mellies, Michael', contact='Herr Michael Mellies '),
|
||||||
2000006=rel(relAnchor='LP JM GmbH', relType='EX_PARTNER', relHolder='LP JM e.K.', contact='JM e.K.'),
|
2000006=rel(anchor='LP JM GmbH', type='EX_PARTNER', holder='LP JM e.K.', contact='JM e.K.'),
|
||||||
2000007=rel(relAnchor='LP JM GmbH', relType='OPERATIONS', relHolder='LP JM GmbH', contact='Herr Andrew Meyer-Operation , JM GmbH'),
|
2000007=rel(anchor='LP JM GmbH', type='OPERATIONS', holder='LP JM GmbH', contact='Herr Andrew Meyer-Operation , JM GmbH'),
|
||||||
2000008=rel(relAnchor='LP JM GmbH', relType='VIP_CONTACT', relHolder='LP JM GmbH', contact='Herr Andrew Meyer-Operation , JM GmbH'),
|
2000008=rel(anchor='LP JM GmbH', type='VIP_CONTACT', holder='LP JM GmbH', contact='Herr Andrew Meyer-Operation , JM GmbH'),
|
||||||
2000009=rel(relAnchor='LP JM GmbH', relType='SUBSCRIBER', relMark='operations-announce', relHolder='LP JM GmbH', contact='Herr Andrew Meyer-Operation , JM GmbH'),
|
2000009=rel(anchor='LP JM GmbH', type='SUBSCRIBER', mark='operations-announce', holder='LP JM GmbH', contact='Herr Andrew Meyer-Operation , JM GmbH'),
|
||||||
2000010=rel(relAnchor='LP JM GmbH', relType='REPRESENTATIVE', relHolder='LP JM GmbH', contact='Herr Philip Meyer-Contract , JM GmbH'),
|
2000010=rel(anchor='LP JM GmbH', type='REPRESENTATIVE', holder='LP JM GmbH', contact='Herr Philip Meyer-Contract , JM GmbH'),
|
||||||
2000011=rel(relAnchor='LP JM GmbH', relType='SUBSCRIBER', relMark='members-announce', relHolder='LP JM GmbH', contact='Herr Philip Meyer-Contract , JM GmbH'),
|
2000011=rel(anchor='LP JM GmbH', type='SUBSCRIBER', mark='members-announce', holder='LP JM GmbH', contact='Herr Philip Meyer-Contract , JM GmbH'),
|
||||||
2000012=rel(relAnchor='LP JM GmbH', relType='SUBSCRIBER', relMark='customers-announce', relHolder='LP JM GmbH', contact='Herr Philip Meyer-Contract , JM GmbH'),
|
2000012=rel(anchor='LP JM GmbH', type='SUBSCRIBER', mark='customers-announce', holder='LP JM GmbH', contact='Herr Philip Meyer-Contract , JM GmbH'),
|
||||||
2000013=rel(relAnchor='LP JM GmbH', relType='VIP_CONTACT', relHolder='LP JM GmbH', contact='Frau Tammy Meyer-VIP , JM GmbH'),
|
2000013=rel(anchor='LP JM GmbH', type='VIP_CONTACT', holder='LP JM GmbH', contact='Frau Tammy Meyer-VIP , JM GmbH'),
|
||||||
2000014=rel(relAnchor='?? Test PS', relType='OPERATIONS', relHolder='?? Test PS', contact='Petra Schmidt , Test PS'),
|
2000014=rel(anchor='?? Test PS', type='OPERATIONS', holder='?? Test PS', contact='Petra Schmidt , Test PS'),
|
||||||
2000015=rel(relAnchor='?? Test PS', relType='REPRESENTATIVE', relHolder='?? Test PS', contact='Petra Schmidt , Test PS'),
|
2000015=rel(anchor='?? Test PS', type='REPRESENTATIVE', holder='?? Test PS', contact='Petra Schmidt , Test PS'),
|
||||||
2000016=rel(relAnchor='NP Mellies, Michael', relType='SUBSCRIBER', relMark='operations-announce', relHolder='NP Fanninga, Frauke', contact='Frau Frauke Fanninga '),
|
2000016=rel(anchor='NP Mellies, Michael', type='SUBSCRIBER', mark='operations-announce', holder='NP Fanninga, Frauke', contact='Frau Frauke Fanninga '),
|
||||||
2000017=rel(relAnchor='NP Mellies, Michael', relType='DEBITOR', relHolder='NP Mellies, Michael', contact='Herr Michael Mellies '),
|
2000017=rel(anchor='NP Mellies, Michael', type='DEBITOR', holder='NP Mellies, Michael', contact='Herr Michael Mellies '),
|
||||||
2000018=rel(relAnchor='LP JM GmbH', relType='DEBITOR', relHolder='LP JM GmbH', contact='Frau Dr. Jenny Meyer-Billing , JM GmbH'),
|
2000018=rel(anchor='LP JM GmbH', type='DEBITOR', holder='LP JM GmbH', contact='Frau Dr. Jenny Meyer-Billing , JM GmbH'),
|
||||||
2000019=rel(relAnchor='?? Test PS', relType='DEBITOR', relHolder='?? Test PS', contact='Petra Schmidt , Test PS')
|
2000019=rel(anchor='?? Test PS', type='DEBITOR', holder='?? Test PS', contact='Petra Schmidt , Test PS')
|
||||||
}
|
}
|
||||||
""");
|
""");
|
||||||
}
|
}
|
||||||
@ -427,7 +427,7 @@ public class ImportOfficeData extends ContextBasedTest {
|
|||||||
relations.forEach( (id, r) -> {
|
relations.forEach( (id, r) -> {
|
||||||
// such a record
|
// such a record
|
||||||
if (r.getContact() == null || r.getContact().getLabel() == null ||
|
if (r.getContact() == null || r.getContact().getLabel() == null ||
|
||||||
r.getRelHolder() == null | r.getRelHolder().getPersonType() == null ) {
|
r.getHolder() == null | r.getHolder().getPersonType() == null ) {
|
||||||
idsToRemove.add(id);
|
idsToRemove.add(id);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -677,9 +677,9 @@ public class ImportOfficeData extends ContextBasedTest {
|
|||||||
final var person = HsOfficePersonEntity.builder().build();
|
final var person = HsOfficePersonEntity.builder().build();
|
||||||
|
|
||||||
final var partnerRelation = HsOfficeRelationEntity.builder()
|
final var partnerRelation = HsOfficeRelationEntity.builder()
|
||||||
.relHolder(person)
|
.holder(person)
|
||||||
.relType(HsOfficeRelationType.PARTNER)
|
.type(HsOfficeRelationType.PARTNER)
|
||||||
.relAnchor(mandant)
|
.anchor(mandant)
|
||||||
.contact(null) // is set during contacts import depending on assigned roles
|
.contact(null) // is set during contacts import depending on assigned roles
|
||||||
.build();
|
.build();
|
||||||
relations.put(relationId++, partnerRelation);
|
relations.put(relationId++, partnerRelation);
|
||||||
@ -883,7 +883,7 @@ public class ImportOfficeData extends ContextBasedTest {
|
|||||||
for (String subscriberRole: SUBSCRIBER_ROLES) {
|
for (String subscriberRole: SUBSCRIBER_ROLES) {
|
||||||
if (containsRole(rec, subscriberRole)) {
|
if (containsRole(rec, subscriberRole)) {
|
||||||
addRelation(partnerPerson, contactPerson, contact, HsOfficeRelationType.SUBSCRIBER)
|
addRelation(partnerPerson, contactPerson, contact, HsOfficeRelationType.SUBSCRIBER)
|
||||||
.setRelMark(subscriberRole.split(":")[1])
|
.setMark(subscriberRole.split(":")[1])
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -898,7 +898,7 @@ public class ImportOfficeData extends ContextBasedTest {
|
|||||||
partners.forEach( (id, partner) -> {
|
partners.forEach( (id, partner) -> {
|
||||||
final var partnerPerson = partner.getPerson();
|
final var partnerPerson = partner.getPerson();
|
||||||
if (relations.values().stream()
|
if (relations.values().stream()
|
||||||
.filter(rel -> rel.getRelAnchor() == partnerPerson && rel.getRelType() == HsOfficeRelationType.REPRESENTATIVE)
|
.filter(rel -> rel.getAnchor() == partnerPerson && rel.getType() == HsOfficeRelationType.REPRESENTATIVE)
|
||||||
.findFirst().isEmpty()) {
|
.findFirst().isEmpty()) {
|
||||||
contractualMissing.add(partner.getPartnerNumber());
|
contractualMissing.add(partner.getPartnerNumber());
|
||||||
}
|
}
|
||||||
@ -919,10 +919,10 @@ public class ImportOfficeData extends ContextBasedTest {
|
|||||||
final HsOfficeContactEntity contact,
|
final HsOfficeContactEntity contact,
|
||||||
final HsOfficeRelationType representative) {
|
final HsOfficeRelationType representative) {
|
||||||
final var rel = HsOfficeRelationEntity.builder()
|
final var rel = HsOfficeRelationEntity.builder()
|
||||||
.relAnchor(partnerPerson)
|
.anchor(partnerPerson)
|
||||||
.relHolder(contactPerson)
|
.holder(contactPerson)
|
||||||
.contact(contact)
|
.contact(contact)
|
||||||
.relType(representative)
|
.type(representative)
|
||||||
.build();
|
.build();
|
||||||
relations.put(relationId++, rel);
|
relations.put(relationId++, rel);
|
||||||
return rel;
|
return rel;
|
||||||
|
@ -103,8 +103,8 @@ class HsOfficePartnerControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
|||||||
{
|
{
|
||||||
"partnerNumber": "20002",
|
"partnerNumber": "20002",
|
||||||
"partnerRel": {
|
"partnerRel": {
|
||||||
"relAnchorUuid": "%s",
|
"anchorUuid": "%s",
|
||||||
"relHolderUuid": "%s",
|
"holderUuid": "%s",
|
||||||
"contactUuid": "%s"
|
"contactUuid": "%s"
|
||||||
},
|
},
|
||||||
"personUuid": "%s",
|
"personUuid": "%s",
|
||||||
@ -156,8 +156,8 @@ class HsOfficePartnerControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
|||||||
{
|
{
|
||||||
"partnerNumber": "20003",
|
"partnerNumber": "20003",
|
||||||
"partnerRel": {
|
"partnerRel": {
|
||||||
"relAnchorUuid": "%s",
|
"anchorUuid": "%s",
|
||||||
"relHolderUuid": "%s",
|
"holderUuid": "%s",
|
||||||
"contactUuid": "%s"
|
"contactUuid": "%s"
|
||||||
},
|
},
|
||||||
"personUuid": "%s",
|
"personUuid": "%s",
|
||||||
@ -194,8 +194,8 @@ class HsOfficePartnerControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
|||||||
{
|
{
|
||||||
"partnerNumber": "20004",
|
"partnerNumber": "20004",
|
||||||
"partnerRel": {
|
"partnerRel": {
|
||||||
"relAnchorUuid": "%s",
|
"anchorUuid": "%s",
|
||||||
"relHolderUuid": "%s",
|
"holderUuid": "%s",
|
||||||
"contactUuid": "%s"
|
"contactUuid": "%s"
|
||||||
},
|
},
|
||||||
"personUuid": "%s",
|
"personUuid": "%s",
|
||||||
@ -466,9 +466,9 @@ class HsOfficePartnerControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
|||||||
final var givenContact = contactRepo.findContactByOptionalLabelLike("fourth contact").get(0);
|
final var givenContact = contactRepo.findContactByOptionalLabelLike("fourth contact").get(0);
|
||||||
|
|
||||||
final var partnerRel = new HsOfficeRelationEntity();
|
final var partnerRel = new HsOfficeRelationEntity();
|
||||||
partnerRel.setRelType(HsOfficeRelationType.PARTNER);
|
partnerRel.setType(HsOfficeRelationType.PARTNER);
|
||||||
partnerRel.setRelAnchor(givenMandantPerson);
|
partnerRel.setAnchor(givenMandantPerson);
|
||||||
partnerRel.setRelHolder(givenPerson);
|
partnerRel.setHolder(givenPerson);
|
||||||
partnerRel.setContact(givenContact);
|
partnerRel.setContact(givenContact);
|
||||||
em.persist(partnerRel);
|
em.persist(partnerRel);
|
||||||
|
|
||||||
|
@ -101,8 +101,8 @@ class HsOfficePartnerControllerRestTest {
|
|||||||
{
|
{
|
||||||
"partnerNumber": "20002",
|
"partnerNumber": "20002",
|
||||||
"partnerRel": {
|
"partnerRel": {
|
||||||
"relAnchorUuid": "%s",
|
"anchorUuid": "%s",
|
||||||
"relHolderUuid": "%s",
|
"holderUuid": "%s",
|
||||||
"contactUuid": "%s"
|
"contactUuid": "%s"
|
||||||
},
|
},
|
||||||
"personUuid": "%s",
|
"personUuid": "%s",
|
||||||
@ -138,8 +138,8 @@ class HsOfficePartnerControllerRestTest {
|
|||||||
{
|
{
|
||||||
"partnerNumber": "20002",
|
"partnerNumber": "20002",
|
||||||
"partnerRel": {
|
"partnerRel": {
|
||||||
"relAnchorUuid": "%s",
|
"anchorUuid": "%s",
|
||||||
"relHolderUuid": "%s",
|
"holderUuid": "%s",
|
||||||
"contactUuid": "%s"
|
"contactUuid": "%s"
|
||||||
},
|
},
|
||||||
"personUuid": "%s",
|
"personUuid": "%s",
|
||||||
|
@ -81,9 +81,9 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTestWithClean
|
|||||||
final var givenContact = contactRepo.findContactByOptionalLabelLike("first contact").get(0);
|
final var givenContact = contactRepo.findContactByOptionalLabelLike("first contact").get(0);
|
||||||
|
|
||||||
final var partnerRel = HsOfficeRelationEntity.builder()
|
final var partnerRel = HsOfficeRelationEntity.builder()
|
||||||
.relHolder(givenPartnerPerson)
|
.holder(givenPartnerPerson)
|
||||||
.relType(HsOfficeRelationType.PARTNER)
|
.type(HsOfficeRelationType.PARTNER)
|
||||||
.relAnchor(givenMandantorPerson)
|
.anchor(givenMandantorPerson)
|
||||||
.contact(givenContact)
|
.contact(givenContact)
|
||||||
.build();
|
.build();
|
||||||
relationRepo.save(partnerRel);
|
relationRepo.save(partnerRel);
|
||||||
@ -126,9 +126,9 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTestWithClean
|
|||||||
final var givenMandantPerson = personRepo.findPersonByOptionalNameLike("Hostsharing eG").get(0);
|
final var givenMandantPerson = personRepo.findPersonByOptionalNameLike("Hostsharing eG").get(0);
|
||||||
|
|
||||||
final var newRelation = HsOfficeRelationEntity.builder()
|
final var newRelation = HsOfficeRelationEntity.builder()
|
||||||
.relHolder(givenPartnerPerson)
|
.holder(givenPartnerPerson)
|
||||||
.relType(HsOfficeRelationType.PARTNER)
|
.type(HsOfficeRelationType.PARTNER)
|
||||||
.relAnchor(givenMandantPerson)
|
.anchor(givenMandantPerson)
|
||||||
.contact(givenContact)
|
.contact(givenContact)
|
||||||
.build();
|
.build();
|
||||||
relationRepo.save(newRelation);
|
relationRepo.save(newRelation);
|
||||||
@ -467,9 +467,9 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTestWithClean
|
|||||||
final var givenContact = contactRepo.findContactByOptionalLabelLike(contact).get(0);
|
final var givenContact = contactRepo.findContactByOptionalLabelLike(contact).get(0);
|
||||||
|
|
||||||
final var partnerRel = HsOfficeRelationEntity.builder()
|
final var partnerRel = HsOfficeRelationEntity.builder()
|
||||||
.relHolder(givenPartnerPerson)
|
.holder(givenPartnerPerson)
|
||||||
.relType(HsOfficeRelationType.PARTNER)
|
.type(HsOfficeRelationType.PARTNER)
|
||||||
.relAnchor(givenMandantorPerson)
|
.anchor(givenMandantorPerson)
|
||||||
.contact(givenContact)
|
.contact(givenContact)
|
||||||
.build();
|
.build();
|
||||||
relationRepo.save(partnerRel);
|
relationRepo.save(partnerRel);
|
||||||
|
@ -79,37 +79,37 @@ class HsOfficeRelationControllerAcceptanceTest extends ContextBasedTestWithClean
|
|||||||
.body("", lenientlyEquals("""
|
.body("", lenientlyEquals("""
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"relAnchor": { "personType": "LEGAL_PERSON", "tradeName": "Hostsharing eG" },
|
"anchor": { "personType": "LEGAL_PERSON", "tradeName": "Hostsharing eG" },
|
||||||
"relHolder": { "personType": "LEGAL_PERSON", "tradeName": "First GmbH" },
|
"holder": { "personType": "LEGAL_PERSON", "tradeName": "First GmbH" },
|
||||||
"relType": "PARTNER",
|
"type": "PARTNER",
|
||||||
"relMark": null,
|
"mark": null,
|
||||||
"contact": { "label": "first contact" }
|
"contact": { "label": "first contact" }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"relAnchor": { "personType": "LEGAL_PERSON", "tradeName": "Hostsharing eG" },
|
"anchor": { "personType": "LEGAL_PERSON", "tradeName": "Hostsharing eG" },
|
||||||
"relHolder": { "personType": "INCORPORATED_FIRM", "tradeName": "Fourth eG" },
|
"holder": { "personType": "INCORPORATED_FIRM", "tradeName": "Fourth eG" },
|
||||||
"relType": "PARTNER",
|
"type": "PARTNER",
|
||||||
"contact": { "label": "fourth contact" }
|
"contact": { "label": "fourth contact" }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"relAnchor": { "personType": "LEGAL_PERSON", "tradeName": "Hostsharing eG" },
|
"anchor": { "personType": "LEGAL_PERSON", "tradeName": "Hostsharing eG" },
|
||||||
"relHolder": { "personType": "LEGAL_PERSON", "tradeName": "Second e.K.", "givenName": "Peter", "familyName": "Smith" },
|
"holder": { "personType": "LEGAL_PERSON", "tradeName": "Second e.K.", "givenName": "Peter", "familyName": "Smith" },
|
||||||
"relType": "PARTNER",
|
"type": "PARTNER",
|
||||||
"relMark": null,
|
"mark": null,
|
||||||
"contact": { "label": "second contact" }
|
"contact": { "label": "second contact" }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"relAnchor": { "personType": "LEGAL_PERSON", "tradeName": "Hostsharing eG" },
|
"anchor": { "personType": "LEGAL_PERSON", "tradeName": "Hostsharing eG" },
|
||||||
"relHolder": { "personType": "NATURAL_PERSON", "givenName": "Peter", "familyName": "Smith" },
|
"holder": { "personType": "NATURAL_PERSON", "givenName": "Peter", "familyName": "Smith" },
|
||||||
"relType": "PARTNER",
|
"type": "PARTNER",
|
||||||
"relMark": null,
|
"mark": null,
|
||||||
"contact": { "label": "sixth contact" }
|
"contact": { "label": "sixth contact" }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"relAnchor": { "personType": "LEGAL_PERSON", "tradeName": "Hostsharing eG" },
|
"anchor": { "personType": "LEGAL_PERSON", "tradeName": "Hostsharing eG" },
|
||||||
"relHolder": { "personType": "INCORPORATED_FIRM", "tradeName": "Third OHG" },
|
"holder": { "personType": "INCORPORATED_FIRM", "tradeName": "Third OHG" },
|
||||||
"relType": "PARTNER",
|
"type": "PARTNER",
|
||||||
"relMark": null,
|
"mark": null,
|
||||||
"contact": { "label": "third contact" }
|
"contact": { "label": "third contact" }
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@ -136,9 +136,9 @@ class HsOfficeRelationControllerAcceptanceTest extends ContextBasedTestWithClean
|
|||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
"relType": "%s",
|
"type": "%s",
|
||||||
"relAnchorUuid": "%s",
|
"anchorUuid": "%s",
|
||||||
"relHolderUuid": "%s",
|
"holderUuid": "%s",
|
||||||
"contactUuid": "%s"
|
"contactUuid": "%s"
|
||||||
}
|
}
|
||||||
""".formatted(
|
""".formatted(
|
||||||
@ -153,9 +153,9 @@ class HsOfficeRelationControllerAcceptanceTest extends ContextBasedTestWithClean
|
|||||||
.statusCode(201)
|
.statusCode(201)
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("uuid", isUuidValid())
|
.body("uuid", isUuidValid())
|
||||||
.body("relType", is("DEBITOR"))
|
.body("type", is("DEBITOR"))
|
||||||
.body("relAnchor.tradeName", is("Third OHG"))
|
.body("anchor.tradeName", is("Third OHG"))
|
||||||
.body("relHolder.givenName", is("Paul"))
|
.body("holder.givenName", is("Paul"))
|
||||||
.body("contact.label", is("second contact"))
|
.body("contact.label", is("second contact"))
|
||||||
.header("Location", startsWith("http://localhost"))
|
.header("Location", startsWith("http://localhost"))
|
||||||
.extract().header("Location"); // @formatter:on
|
.extract().header("Location"); // @formatter:on
|
||||||
@ -180,9 +180,9 @@ class HsOfficeRelationControllerAcceptanceTest extends ContextBasedTestWithClean
|
|||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
"relType": "%s",
|
"type": "%s",
|
||||||
"relAnchorUuid": "%s",
|
"anchorUuid": "%s",
|
||||||
"relHolderUuid": "%s",
|
"holderUuid": "%s",
|
||||||
"contactUuid": "%s"
|
"contactUuid": "%s"
|
||||||
}
|
}
|
||||||
""".formatted(
|
""".formatted(
|
||||||
@ -195,7 +195,7 @@ class HsOfficeRelationControllerAcceptanceTest extends ContextBasedTestWithClean
|
|||||||
.post("http://localhost/api/hs/office/relations")
|
.post("http://localhost/api/hs/office/relations")
|
||||||
.then().log().all().assertThat()
|
.then().log().all().assertThat()
|
||||||
.statusCode(404)
|
.statusCode(404)
|
||||||
.body("message", is("cannot find relAnchorUuid " + GIVEN_NON_EXISTING_HOLDER_PERSON_UUID));
|
.body("message", is("cannot find anchorUuid " + GIVEN_NON_EXISTING_HOLDER_PERSON_UUID));
|
||||||
// @formatter:on
|
// @formatter:on
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -212,9 +212,9 @@ class HsOfficeRelationControllerAcceptanceTest extends ContextBasedTestWithClean
|
|||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
"relType": "%s",
|
"type": "%s",
|
||||||
"relAnchorUuid": "%s",
|
"anchorUuid": "%s",
|
||||||
"relHolderUuid": "%s",
|
"holderUuid": "%s",
|
||||||
"contactUuid": "%s"
|
"contactUuid": "%s"
|
||||||
}
|
}
|
||||||
""".formatted(
|
""".formatted(
|
||||||
@ -227,7 +227,7 @@ class HsOfficeRelationControllerAcceptanceTest extends ContextBasedTestWithClean
|
|||||||
.post("http://localhost/api/hs/office/relations")
|
.post("http://localhost/api/hs/office/relations")
|
||||||
.then().log().all().assertThat()
|
.then().log().all().assertThat()
|
||||||
.statusCode(404)
|
.statusCode(404)
|
||||||
.body("message", is("cannot find relHolderUuid " + GIVEN_NON_EXISTING_HOLDER_PERSON_UUID));
|
.body("message", is("cannot find holderUuid " + GIVEN_NON_EXISTING_HOLDER_PERSON_UUID));
|
||||||
// @formatter:on
|
// @formatter:on
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -245,9 +245,9 @@ class HsOfficeRelationControllerAcceptanceTest extends ContextBasedTestWithClean
|
|||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
"relType": "%s",
|
"type": "%s",
|
||||||
"relAnchorUuid": "%s",
|
"anchorUuid": "%s",
|
||||||
"relHolderUuid": "%s",
|
"holderUuid": "%s",
|
||||||
"contactUuid": "%s"
|
"contactUuid": "%s"
|
||||||
}
|
}
|
||||||
""".formatted(
|
""".formatted(
|
||||||
@ -285,8 +285,8 @@ class HsOfficeRelationControllerAcceptanceTest extends ContextBasedTestWithClean
|
|||||||
.contentType("application/json")
|
.contentType("application/json")
|
||||||
.body("", lenientlyEquals("""
|
.body("", lenientlyEquals("""
|
||||||
{
|
{
|
||||||
"relAnchor": { "tradeName": "First GmbH" },
|
"anchor": { "tradeName": "First GmbH" },
|
||||||
"relHolder": { "familyName": "Firby" },
|
"holder": { "familyName": "Firby" },
|
||||||
"contact": { "label": "first contact" }
|
"contact": { "label": "first contact" }
|
||||||
}
|
}
|
||||||
""")); // @formatter:on
|
""")); // @formatter:on
|
||||||
@ -326,8 +326,8 @@ class HsOfficeRelationControllerAcceptanceTest extends ContextBasedTestWithClean
|
|||||||
.contentType("application/json")
|
.contentType("application/json")
|
||||||
.body("", lenientlyEquals("""
|
.body("", lenientlyEquals("""
|
||||||
{
|
{
|
||||||
"relAnchor": { "tradeName": "First GmbH" },
|
"anchor": { "tradeName": "First GmbH" },
|
||||||
"relHolder": { "familyName": "Firby" },
|
"holder": { "familyName": "Firby" },
|
||||||
"contact": { "label": "first contact" }
|
"contact": { "label": "first contact" }
|
||||||
}
|
}
|
||||||
""")); // @formatter:on
|
""")); // @formatter:on
|
||||||
@ -342,7 +342,7 @@ class HsOfficeRelationControllerAcceptanceTest extends ContextBasedTestWithClean
|
|||||||
final var givenRelation = relationRepo
|
final var givenRelation = relationRepo
|
||||||
.findRelationRelatedToPersonUuid(anchorPersonUuid)
|
.findRelationRelatedToPersonUuid(anchorPersonUuid)
|
||||||
.stream()
|
.stream()
|
||||||
.filter(r -> r.getRelHolder().getUuid().equals(holderPersonUuid))
|
.filter(r -> r.getHolder().getUuid().equals(holderPersonUuid))
|
||||||
.findFirst().orElseThrow();
|
.findFirst().orElseThrow();
|
||||||
return givenRelation;
|
return givenRelation;
|
||||||
}
|
}
|
||||||
@ -375,9 +375,9 @@ class HsOfficeRelationControllerAcceptanceTest extends ContextBasedTestWithClean
|
|||||||
.statusCode(200)
|
.statusCode(200)
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("uuid", isUuidValid())
|
.body("uuid", isUuidValid())
|
||||||
.body("relType", is("REPRESENTATIVE"))
|
.body("type", is("REPRESENTATIVE"))
|
||||||
.body("relAnchor.tradeName", is("Erben Bessler"))
|
.body("anchor.tradeName", is("Erben Bessler"))
|
||||||
.body("relHolder.familyName", is("Winkler"))
|
.body("holder.familyName", is("Winkler"))
|
||||||
.body("contact.label", is("fourth contact"));
|
.body("contact.label", is("fourth contact"));
|
||||||
// @formatter:on
|
// @formatter:on
|
||||||
|
|
||||||
@ -385,10 +385,10 @@ class HsOfficeRelationControllerAcceptanceTest extends ContextBasedTestWithClean
|
|||||||
context.define("superuser-alex@hostsharing.net");
|
context.define("superuser-alex@hostsharing.net");
|
||||||
assertThat(relationRepo.findByUuid(givenRelation.getUuid())).isPresent().get()
|
assertThat(relationRepo.findByUuid(givenRelation.getUuid())).isPresent().get()
|
||||||
.matches(rel -> {
|
.matches(rel -> {
|
||||||
assertThat(rel.getRelAnchor().getTradeName()).contains("Bessler");
|
assertThat(rel.getAnchor().getTradeName()).contains("Bessler");
|
||||||
assertThat(rel.getRelHolder().getFamilyName()).contains("Winkler");
|
assertThat(rel.getHolder().getFamilyName()).contains("Winkler");
|
||||||
assertThat(rel.getContact().getLabel()).isEqualTo("fourth contact");
|
assertThat(rel.getContact().getLabel()).isEqualTo("fourth contact");
|
||||||
assertThat(rel.getRelType()).isEqualTo(HsOfficeRelationType.REPRESENTATIVE);
|
assertThat(rel.getType()).isEqualTo(HsOfficeRelationType.REPRESENTATIVE);
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -464,9 +464,9 @@ class HsOfficeRelationControllerAcceptanceTest extends ContextBasedTestWithClean
|
|||||||
final var givenHolderPerson = personRepo.findPersonByOptionalNameLike("Winkler").get(0);
|
final var givenHolderPerson = personRepo.findPersonByOptionalNameLike("Winkler").get(0);
|
||||||
final var givenContact = contactRepo.findContactByOptionalLabelLike("seventh contact").get(0);
|
final var givenContact = contactRepo.findContactByOptionalLabelLike("seventh contact").get(0);
|
||||||
final var newRelation = HsOfficeRelationEntity.builder()
|
final var newRelation = HsOfficeRelationEntity.builder()
|
||||||
.relType(HsOfficeRelationType.REPRESENTATIVE)
|
.type(HsOfficeRelationType.REPRESENTATIVE)
|
||||||
.relAnchor(givenAnchorPerson)
|
.anchor(givenAnchorPerson)
|
||||||
.relHolder(givenHolderPerson)
|
.holder(givenHolderPerson)
|
||||||
.contact(givenContact)
|
.contact(givenContact)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
@ -52,9 +52,9 @@ class HsOfficeRelationEntityPatcherUnitTest extends PatchUnitTestBase<
|
|||||||
protected HsOfficeRelationEntity newInitialEntity() {
|
protected HsOfficeRelationEntity newInitialEntity() {
|
||||||
final var entity = new HsOfficeRelationEntity();
|
final var entity = new HsOfficeRelationEntity();
|
||||||
entity.setUuid(INITIAL_RELATION_UUID);
|
entity.setUuid(INITIAL_RELATION_UUID);
|
||||||
entity.setRelType(HsOfficeRelationType.REPRESENTATIVE);
|
entity.setType(HsOfficeRelationType.REPRESENTATIVE);
|
||||||
entity.setRelAnchor(givenInitialAnchorPerson);
|
entity.setAnchor(givenInitialAnchorPerson);
|
||||||
entity.setRelHolder(givenInitialHolderPerson);
|
entity.setHolder(givenInitialHolderPerson);
|
||||||
entity.setContact(givenInitialContact);
|
entity.setContact(givenInitialContact);
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
@ -21,23 +21,23 @@ class HsOfficeRelationEntityUnitTest {
|
|||||||
@Test
|
@Test
|
||||||
void toStringReturnsAllProperties() {
|
void toStringReturnsAllProperties() {
|
||||||
final var given = HsOfficeRelationEntity.builder()
|
final var given = HsOfficeRelationEntity.builder()
|
||||||
.relType(HsOfficeRelationType.SUBSCRIBER)
|
.type(HsOfficeRelationType.SUBSCRIBER)
|
||||||
.relMark("members-announce")
|
.mark("members-announce")
|
||||||
.relAnchor(anchor)
|
.anchor(anchor)
|
||||||
.relHolder(holder)
|
.holder(holder)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
assertThat(given.toString()).isEqualTo("rel(relAnchor='LP some trade name', relType='SUBSCRIBER', relMark='members-announce', relHolder='NP Meier, Mellie')");
|
assertThat(given.toString()).isEqualTo("rel(anchor='LP some trade name', type='SUBSCRIBER', mark='members-announce', holder='NP Meier, Mellie')");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void toShortString() {
|
void toShortString() {
|
||||||
final var given = HsOfficeRelationEntity.builder()
|
final var given = HsOfficeRelationEntity.builder()
|
||||||
.relType(HsOfficeRelationType.REPRESENTATIVE)
|
.type(HsOfficeRelationType.REPRESENTATIVE)
|
||||||
.relAnchor(anchor)
|
.anchor(anchor)
|
||||||
.relHolder(holder)
|
.holder(holder)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
assertThat(given.toShortString()).isEqualTo("rel(relAnchor='LP some trade name', relType='REPRESENTATIVE', relHolder='NP Meier, Mellie')");
|
assertThat(given.toShortString()).isEqualTo("rel(anchor='LP some trade name', type='REPRESENTATIVE', holder='NP Meier, Mellie')");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -70,9 +70,9 @@ class HsOfficeRelationRepositoryIntegrationTest extends ContextBasedTestWithClea
|
|||||||
// when
|
// when
|
||||||
final var result = attempt(em, () -> {
|
final var result = attempt(em, () -> {
|
||||||
final var newRelation = HsOfficeRelationEntity.builder()
|
final var newRelation = HsOfficeRelationEntity.builder()
|
||||||
.relAnchor(givenAnchorPerson)
|
.anchor(givenAnchorPerson)
|
||||||
.relHolder(givenHolderPerson)
|
.holder(givenHolderPerson)
|
||||||
.relType(HsOfficeRelationType.REPRESENTATIVE)
|
.type(HsOfficeRelationType.REPRESENTATIVE)
|
||||||
.contact(givenContact)
|
.contact(givenContact)
|
||||||
.build();
|
.build();
|
||||||
return toCleanup(relationRepo.save(newRelation));
|
return toCleanup(relationRepo.save(newRelation));
|
||||||
@ -98,9 +98,9 @@ class HsOfficeRelationRepositoryIntegrationTest extends ContextBasedTestWithClea
|
|||||||
final var givenHolderPerson = personRepo.findPersonByOptionalNameLike("Anita").get(0);
|
final var givenHolderPerson = personRepo.findPersonByOptionalNameLike("Anita").get(0);
|
||||||
final var givenContact = contactRepo.findContactByOptionalLabelLike("fourth contact").get(0);
|
final var givenContact = contactRepo.findContactByOptionalLabelLike("fourth contact").get(0);
|
||||||
final var newRelation = HsOfficeRelationEntity.builder()
|
final var newRelation = HsOfficeRelationEntity.builder()
|
||||||
.relAnchor(givenAnchorPerson)
|
.anchor(givenAnchorPerson)
|
||||||
.relHolder(givenHolderPerson)
|
.holder(givenHolderPerson)
|
||||||
.relType(HsOfficeRelationType.REPRESENTATIVE)
|
.type(HsOfficeRelationType.REPRESENTATIVE)
|
||||||
.contact(givenContact)
|
.contact(givenContact)
|
||||||
.build();
|
.build();
|
||||||
return toCleanup(relationRepo.save(newRelation));
|
return toCleanup(relationRepo.save(newRelation));
|
||||||
@ -154,8 +154,8 @@ class HsOfficeRelationRepositoryIntegrationTest extends ContextBasedTestWithClea
|
|||||||
// then
|
// then
|
||||||
allTheseRelationsAreReturned(
|
allTheseRelationsAreReturned(
|
||||||
result,
|
result,
|
||||||
"rel(relAnchor='LP Hostsharing eG', relType='PARTNER', relHolder='LP Second e.K.', contact='second contact')",
|
"rel(anchor='LP Hostsharing eG', type='PARTNER', holder='LP Second e.K.', contact='second contact')",
|
||||||
"rel(relAnchor='LP Second e.K.', relType='REPRESENTATIVE', relHolder='NP Smith, Peter', contact='second contact')");
|
"rel(anchor='LP Second e.K.', type='REPRESENTATIVE', holder='NP Smith, Peter', contact='second contact')");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -170,8 +170,8 @@ class HsOfficeRelationRepositoryIntegrationTest extends ContextBasedTestWithClea
|
|||||||
// then:
|
// then:
|
||||||
exactlyTheseRelationsAreReturned(
|
exactlyTheseRelationsAreReturned(
|
||||||
result,
|
result,
|
||||||
"rel(relAnchor='LP Hostsharing eG', relType='PARTNER', relHolder='LP First GmbH', contact='first contact')",
|
"rel(anchor='LP Hostsharing eG', type='PARTNER', holder='LP First GmbH', contact='first contact')",
|
||||||
"rel(relAnchor='LP First GmbH', relType='REPRESENTATIVE', relHolder='NP Firby, Susan', contact='first contact')");
|
"rel(anchor='LP First GmbH', type='REPRESENTATIVE', holder='NP Firby, Susan', contact='first contact')");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -216,7 +216,7 @@ class HsOfficeRelationRepositoryIntegrationTest extends ContextBasedTestWithClea
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void relHolderAdmin_canNotUpdateRelatedRelation() {
|
public void holderAdmin_canNotUpdateRelatedRelation() {
|
||||||
// given
|
// given
|
||||||
context("superuser-alex@hostsharing.net");
|
context("superuser-alex@hostsharing.net");
|
||||||
final var givenRelation = givenSomeTemporaryRelationBessler(
|
final var givenRelation = givenSomeTemporaryRelationBessler(
|
||||||
@ -382,9 +382,9 @@ class HsOfficeRelationRepositoryIntegrationTest extends ContextBasedTestWithClea
|
|||||||
final var givenHolderPerson = personRepo.findPersonByOptionalNameLike(holderPerson).get(0);
|
final var givenHolderPerson = personRepo.findPersonByOptionalNameLike(holderPerson).get(0);
|
||||||
final var givenContact = contactRepo.findContactByOptionalLabelLike(contact).get(0);
|
final var givenContact = contactRepo.findContactByOptionalLabelLike(contact).get(0);
|
||||||
final var newRelation = HsOfficeRelationEntity.builder()
|
final var newRelation = HsOfficeRelationEntity.builder()
|
||||||
.relType(HsOfficeRelationType.REPRESENTATIVE)
|
.type(HsOfficeRelationType.REPRESENTATIVE)
|
||||||
.relAnchor(givenAnchorPerson)
|
.anchor(givenAnchorPerson)
|
||||||
.relHolder(givenHolderPerson)
|
.holder(givenHolderPerson)
|
||||||
.contact(givenContact)
|
.contact(givenContact)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user