update dependend relations when updating partner person (#162)
Co-authored-by: Michael Hoennig <michael@hoennig.de> Reviewed-on: https://dev.hostsharing.net/hostsharing/hs.hsadmin.ng/pulls/162 Reviewed-by: Marc Sandlus <marc.sandlus@hostsharing.net>
This commit is contained in:
@@ -13,15 +13,13 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.MvcUriComponentsBuilder;
|
||||
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
import static net.hostsharing.hsadminng.errors.Validate.validate;
|
||||
import static net.hostsharing.hsadminng.mapper.KeyValueMap.from;
|
||||
|
||||
@RestController
|
||||
|
||||
public class HsOfficeContactController implements HsOfficeContactsApi {
|
||||
|
||||
@Autowired
|
||||
@@ -30,9 +28,20 @@ public class HsOfficeContactController implements HsOfficeContactsApi {
|
||||
@Autowired
|
||||
private StrictMapper mapper;
|
||||
|
||||
@Autowired
|
||||
private HsOfficeContactFromResourceConverter<HsOfficeContactRbacEntity> contactFromResourceConverter;
|
||||
|
||||
@Autowired
|
||||
private HsOfficeContactRbacRepository contactRepo;
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
// HOWTO: add a ModelMapper converter for a generic entity class to a ModelMapper to be used in a certain context
|
||||
// This @PostConstruct could be implemented in the converter, but only without generics.
|
||||
// But this converter is for HsOfficeContactRbacEntity and HsOfficeContactRealEntity.
|
||||
mapper.addConverter(contactFromResourceConverter, HsOfficeContactInsertResource.class, HsOfficeContactRbacEntity.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
@Timed("app.office.contacts.api.getListOfContacts")
|
||||
@@ -62,7 +71,7 @@ public class HsOfficeContactController implements HsOfficeContactsApi {
|
||||
|
||||
context.define(currentSubject, assumedRoles);
|
||||
|
||||
final var entityToSave = mapper.map(body, HsOfficeContactRbacEntity.class, RESOURCE_TO_ENTITY_POSTMAPPER);
|
||||
final var entityToSave = mapper.map(body, HsOfficeContactRbacEntity.class);
|
||||
|
||||
final var saved = contactRepo.save(entityToSave);
|
||||
|
||||
@@ -128,11 +137,4 @@ public class HsOfficeContactController implements HsOfficeContactsApi {
|
||||
final var mapped = mapper.map(saved, HsOfficeContactResource.class);
|
||||
return ResponseEntity.ok(mapped);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
final BiConsumer<HsOfficeContactInsertResource, HsOfficeContactRbacEntity> RESOURCE_TO_ENTITY_POSTMAPPER = (resource, entity) -> {
|
||||
entity.putPostalAddress(from(resource.getPostalAddress()));
|
||||
entity.putEmailAddresses(from(resource.getEmailAddresses()));
|
||||
entity.putPhoneNumbers(from(resource.getPhoneNumbers()));
|
||||
};
|
||||
}
|
||||
|
@@ -0,0 +1,27 @@
|
||||
package net.hostsharing.hsadminng.hs.office.contact;
|
||||
|
||||
import lombok.SneakyThrows;
|
||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeContactInsertResource;
|
||||
import org.modelmapper.Converter;
|
||||
import org.modelmapper.spi.MappingContext;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import static net.hostsharing.hsadminng.mapper.KeyValueMap.from;
|
||||
|
||||
// HOWTO: implement a ModelMapper converter which converts from a (JSON) resource instance to a generic entity instance (RBAC vs. REAL)
|
||||
@Component
|
||||
public class HsOfficeContactFromResourceConverter<E extends HsOfficeContact>
|
||||
implements Converter<HsOfficeContactInsertResource, E> {
|
||||
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public E convert(final MappingContext<HsOfficeContactInsertResource, E> context) {
|
||||
final var resource = context.getSource();
|
||||
final var entity = context.getDestinationType().getDeclaredConstructor().newInstance();
|
||||
entity.setCaption(resource.getCaption());
|
||||
entity.putPostalAddress(from(resource.getPostalAddress()));
|
||||
entity.putEmailAddresses(from(resource.getEmailAddresses()));
|
||||
entity.putPhoneNumbers(from(resource.getPhoneNumbers()));
|
||||
return entity;
|
||||
}
|
||||
}
|
@@ -3,8 +3,10 @@ package net.hostsharing.hsadminng.hs.office.partner;
|
||||
import io.micrometer.core.annotation.Timed;
|
||||
import net.hostsharing.hsadminng.context.Context;
|
||||
import net.hostsharing.hsadminng.errors.ReferenceNotFoundException;
|
||||
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactFromResourceConverter;
|
||||
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRealEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.api.HsOfficePartnersApi;
|
||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeContactInsertResource;
|
||||
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;
|
||||
@@ -22,6 +24,7 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.MvcUriComponentsBuilder;
|
||||
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import jakarta.persistence.EntityManager;
|
||||
import jakarta.persistence.PersistenceContext;
|
||||
import java.util.List;
|
||||
@@ -42,14 +45,22 @@ public class HsOfficePartnerController implements HsOfficePartnersApi {
|
||||
private StrictMapper mapper;
|
||||
|
||||
@Autowired
|
||||
private HsOfficePartnerRbacRepository partnerRepo;
|
||||
private HsOfficeContactFromResourceConverter<HsOfficeContactRealEntity> contactFromResourceConverter;
|
||||
|
||||
@Autowired
|
||||
private HsOfficeRelationRealRepository relationRepo;
|
||||
private HsOfficePartnerRbacRepository rbacPartnerRepo;
|
||||
|
||||
@Autowired
|
||||
private HsOfficeRelationRealRepository realRelationRepo;
|
||||
|
||||
@PersistenceContext
|
||||
private EntityManager em;
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
mapper.addConverter(contactFromResourceConverter, HsOfficeContactInsertResource.class, HsOfficeContactRealEntity.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
@Timed("app.office.partners.api.getListOfPartners")
|
||||
@@ -59,7 +70,7 @@ public class HsOfficePartnerController implements HsOfficePartnersApi {
|
||||
final String name) {
|
||||
context.define(currentSubject, assumedRoles);
|
||||
|
||||
final var entities = partnerRepo.findPartnerByOptionalNameLike(name);
|
||||
final var entities = rbacPartnerRepo.findPartnerByOptionalNameLike(name);
|
||||
|
||||
final var resources = mapper.mapList(entities, HsOfficePartnerResource.class, ENTITY_TO_RESOURCE_POSTMAPPER);
|
||||
return ResponseEntity.ok(resources);
|
||||
@@ -77,7 +88,7 @@ public class HsOfficePartnerController implements HsOfficePartnersApi {
|
||||
|
||||
final var entityToSave = createPartnerEntity(body);
|
||||
|
||||
final var saved = partnerRepo.save(entityToSave);
|
||||
final var saved = rbacPartnerRepo.save(entityToSave);
|
||||
|
||||
final var uri =
|
||||
MvcUriComponentsBuilder.fromController(getClass())
|
||||
@@ -98,7 +109,7 @@ public class HsOfficePartnerController implements HsOfficePartnersApi {
|
||||
|
||||
context.define(currentSubject, assumedRoles);
|
||||
|
||||
final var result = partnerRepo.findByUuid(partnerUuid);
|
||||
final var result = rbacPartnerRepo.findByUuid(partnerUuid);
|
||||
if (result.isEmpty()) {
|
||||
return ResponseEntity.notFound().build();
|
||||
}
|
||||
@@ -116,7 +127,7 @@ public class HsOfficePartnerController implements HsOfficePartnersApi {
|
||||
|
||||
context.define(currentSubject, assumedRoles);
|
||||
|
||||
final var result = partnerRepo.findPartnerByPartnerNumber(partnerNumber);
|
||||
final var result = rbacPartnerRepo.findPartnerByPartnerNumber(partnerNumber);
|
||||
if (result.isEmpty()) {
|
||||
return ResponseEntity.notFound().build();
|
||||
}
|
||||
@@ -133,12 +144,12 @@ public class HsOfficePartnerController implements HsOfficePartnersApi {
|
||||
final UUID partnerUuid) {
|
||||
context.define(currentSubject, assumedRoles);
|
||||
|
||||
final var partnerToDelete = partnerRepo.findByUuid(partnerUuid);
|
||||
final var partnerToDelete = rbacPartnerRepo.findByUuid(partnerUuid);
|
||||
if (partnerToDelete.isEmpty()) {
|
||||
return ResponseEntity.notFound().build();
|
||||
}
|
||||
|
||||
if (partnerRepo.deleteByUuid(partnerUuid) != 1) {
|
||||
if (rbacPartnerRepo.deleteByUuid(partnerUuid) != 1) {
|
||||
return ResponseEntity.status(HttpStatus.FORBIDDEN).build();
|
||||
}
|
||||
|
||||
@@ -156,22 +167,55 @@ public class HsOfficePartnerController implements HsOfficePartnersApi {
|
||||
|
||||
context.define(currentSubject, assumedRoles);
|
||||
|
||||
final var current = partnerRepo.findByUuid(partnerUuid).orElseThrow();
|
||||
final var previousPartnerRel = current.getPartnerRel();
|
||||
final var current = rbacPartnerRepo.findByUuid(partnerUuid).orElseThrow();
|
||||
final var previousPartnerPerson = current.getPartnerRel().getHolder();
|
||||
|
||||
new HsOfficePartnerEntityPatcher(em, current).apply(body);
|
||||
new HsOfficePartnerEntityPatcher(mapper, em, current).apply(body);
|
||||
|
||||
final var saved = partnerRepo.save(current);
|
||||
optionallyCreateExPartnerRelation(saved, previousPartnerRel);
|
||||
final var saved = rbacPartnerRepo.save(current);
|
||||
optionallyCreateExPartnerRelation(saved, previousPartnerPerson);
|
||||
optionallyUpdateRelatedRelations(saved, previousPartnerPerson);
|
||||
|
||||
final var mapped = mapper.map(saved, HsOfficePartnerResource.class, ENTITY_TO_RESOURCE_POSTMAPPER);
|
||||
return ResponseEntity.ok(mapped);
|
||||
}
|
||||
|
||||
private void optionallyCreateExPartnerRelation(final HsOfficePartnerRbacEntity saved, final HsOfficeRelationRealEntity previousPartnerRel) {
|
||||
if (!saved.getPartnerRel().getUuid().equals(previousPartnerRel.getUuid())) {
|
||||
// TODO.impl: we also need to use the new partner-person as the anchor
|
||||
relationRepo.save(previousPartnerRel.toBuilder().uuid(null).type(EX_PARTNER).build());
|
||||
private void optionallyCreateExPartnerRelation(final HsOfficePartnerRbacEntity saved, final HsOfficePersonRealEntity previousPartnerPerson) {
|
||||
|
||||
final var partnerPersonHasChanged = !saved.getPartnerRel().getHolder().getUuid().equals(previousPartnerPerson.getUuid());
|
||||
if (partnerPersonHasChanged) {
|
||||
realRelationRepo.save(saved.getPartnerRel().toBuilder()
|
||||
.uuid(null)
|
||||
.type(EX_PARTNER)
|
||||
.anchor(saved.getPartnerRel().getHolder())
|
||||
.holder(previousPartnerPerson)
|
||||
.build());
|
||||
}
|
||||
}
|
||||
|
||||
private void optionallyUpdateRelatedRelations(final HsOfficePartnerRbacEntity saved, final HsOfficePersonRealEntity previousPartnerPerson) {
|
||||
final var partnerPersonHasChanged = !saved.getPartnerRel().getHolder().getUuid().equals(previousPartnerPerson.getUuid());
|
||||
if (partnerPersonHasChanged) {
|
||||
// self-debitors of the old partner-person become self-debitors of the new partner person
|
||||
em.createNativeQuery("""
|
||||
UPDATE hs_office.relation
|
||||
SET holderUuid = :newPartnerPersonUuid
|
||||
WHERE type = 'DEBITOR' AND
|
||||
holderUuid = :oldPartnerPersonUuid AND anchorUuid = :oldPartnerPersonUuid
|
||||
""")
|
||||
.setParameter("oldPartnerPersonUuid", previousPartnerPerson.getUuid())
|
||||
.setParameter("newPartnerPersonUuid", saved.getPartnerRel().getHolder().getUuid())
|
||||
.executeUpdate();
|
||||
|
||||
// re-anchor all relations from the old partner person to the new partner persion
|
||||
em.createNativeQuery("""
|
||||
UPDATE hs_office.relation
|
||||
SET anchorUuid = :newPartnerPersonUuid
|
||||
WHERE anchorUuid = :oldPartnerPersonUuid
|
||||
""")
|
||||
.setParameter("oldPartnerPersonUuid", previousPartnerPerson.getUuid())
|
||||
.setParameter("newPartnerPersonUuid", saved.getPartnerRel().getHolder().getUuid())
|
||||
.executeUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -1,35 +1,36 @@
|
||||
package net.hostsharing.hsadminng.hs.office.partner;
|
||||
|
||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficePartnerPatchResource;
|
||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationPatcher;
|
||||
import net.hostsharing.hsadminng.mapper.EntityPatcher;
|
||||
import net.hostsharing.hsadminng.mapper.OptionalFromJson;
|
||||
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
||||
|
||||
import jakarta.persistence.EntityManager;
|
||||
|
||||
class HsOfficePartnerEntityPatcher implements EntityPatcher<HsOfficePartnerPatchResource> {
|
||||
|
||||
private final StrictMapper mapper;
|
||||
private final EntityManager em;
|
||||
private final HsOfficePartnerRbacEntity entity;
|
||||
|
||||
HsOfficePartnerEntityPatcher(
|
||||
final StrictMapper mapper,
|
||||
final EntityManager em,
|
||||
final HsOfficePartnerRbacEntity entity) {
|
||||
this.mapper = mapper;
|
||||
this.em = em;
|
||||
this.entity = entity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply(final HsOfficePartnerPatchResource resource) {
|
||||
OptionalFromJson.of(resource.getPartnerRelUuid()).ifPresent(newValue -> {
|
||||
verifyNotNull(newValue, "partnerRel");
|
||||
entity.setPartnerRel(em.getReference(HsOfficeRelationRealEntity.class, newValue));
|
||||
});
|
||||
|
||||
new HsOfficePartnerDetailsEntityPatcher(em, entity.getDetails()).apply(resource.getDetails());
|
||||
}
|
||||
if (resource.getPartnerRel() != null) {
|
||||
new HsOfficeRelationPatcher(mapper, em, entity.getPartnerRel()).apply(resource.getPartnerRel());
|
||||
}
|
||||
|
||||
private void verifyNotNull(final Object newValue, final String propertyName) {
|
||||
if (newValue == null) {
|
||||
throw new IllegalArgumentException("property '" + propertyName + "' must not be null");
|
||||
if (resource.getDetails() != null) {
|
||||
new HsOfficePartnerDetailsEntityPatcher(em, entity.getDetails()).apply(resource.getDetails());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -163,13 +163,13 @@ public class HsOfficeRelationController implements HsOfficeRelationsApi {
|
||||
final String currentSubject,
|
||||
final String assumedRoles,
|
||||
final UUID relationUuid,
|
||||
final HsOfficeRelationPatchResource body) {
|
||||
final HsOfficeRelationContactPatchResource body) {
|
||||
|
||||
context.define(currentSubject, assumedRoles);
|
||||
|
||||
final var current = rbacRelationRepo.findByUuid(relationUuid).orElseThrow();
|
||||
|
||||
new HsOfficeRelationEntityPatcher(em, current).apply(body);
|
||||
new HsOfficeRelationEntityContactPatcher(em, current).apply(body);
|
||||
|
||||
final var saved = rbacRelationRepo.save(current);
|
||||
final var mapped = mapper.map(saved, HsOfficeRelationResource.class);
|
||||
|
@@ -1,25 +1,25 @@
|
||||
package net.hostsharing.hsadminng.hs.office.relation;
|
||||
|
||||
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRealEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeRelationPatchResource;
|
||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeRelationContactPatchResource;
|
||||
import net.hostsharing.hsadminng.mapper.EntityPatcher;
|
||||
import net.hostsharing.hsadminng.mapper.OptionalFromJson;
|
||||
|
||||
import jakarta.persistence.EntityManager;
|
||||
import java.util.UUID;
|
||||
|
||||
class HsOfficeRelationEntityPatcher implements EntityPatcher<HsOfficeRelationPatchResource> {
|
||||
public class HsOfficeRelationEntityContactPatcher implements EntityPatcher<HsOfficeRelationContactPatchResource> {
|
||||
|
||||
private final EntityManager em;
|
||||
private final HsOfficeRelation entity;
|
||||
|
||||
HsOfficeRelationEntityPatcher(final EntityManager em, final HsOfficeRelation entity) {
|
||||
public HsOfficeRelationEntityContactPatcher(final EntityManager em, final HsOfficeRelation entity) {
|
||||
this.em = em;
|
||||
this.entity = entity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply(final HsOfficeRelationPatchResource resource) {
|
||||
public void apply(final HsOfficeRelationContactPatchResource resource) {
|
||||
OptionalFromJson.of(resource.getContactUuid()).ifPresent(newValue -> {
|
||||
verifyNotNull(newValue, "contact");
|
||||
entity.setContact(em.getReference(HsOfficeContactRealEntity.class, newValue));
|
@@ -0,0 +1,50 @@
|
||||
package net.hostsharing.hsadminng.hs.office.relation;
|
||||
|
||||
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRealEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeRelationPatchResource;
|
||||
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRealEntity;
|
||||
import net.hostsharing.hsadminng.mapper.EntityPatcher;
|
||||
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
||||
|
||||
import jakarta.persistence.EntityManager;
|
||||
import jakarta.validation.ValidationException;
|
||||
|
||||
public class HsOfficeRelationPatcher implements EntityPatcher<HsOfficeRelationPatchResource> {
|
||||
|
||||
private final StrictMapper mapper;
|
||||
private final EntityManager em;
|
||||
private final HsOfficeRelation entity;
|
||||
|
||||
public HsOfficeRelationPatcher(final StrictMapper mapper, final EntityManager em, final HsOfficeRelation entity) {
|
||||
this.mapper = mapper;
|
||||
this.em = em;
|
||||
this.entity = entity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply(final HsOfficeRelationPatchResource resource) {
|
||||
if (resource.getHolder() != null && resource.getHolderUuid() != null) {
|
||||
throw new ValidationException("either \"holder\" or \"holder.uuid\" can be given, not both");
|
||||
} else {
|
||||
if (resource.getHolder() != null) {
|
||||
final var newHolder = mapper.map(resource.getHolder(), HsOfficePersonRealEntity.class);
|
||||
em.persist(newHolder);
|
||||
entity.setHolder(newHolder);
|
||||
} else if (resource.getHolderUuid() != null) {
|
||||
entity.setHolder(em.getReference(HsOfficePersonRealEntity.class, resource.getHolderUuid().get()));
|
||||
}
|
||||
}
|
||||
|
||||
if (resource.getContact() != null && resource.getContactUuid() != null) {
|
||||
throw new ValidationException("either \"contact\" or \"contact.uuid\" can be given, not both");
|
||||
} else {
|
||||
if (resource.getContact() != null) {
|
||||
final var newContact = mapper.map(resource.getContact(), HsOfficeContactRealEntity.class);
|
||||
em.persist(newContact);
|
||||
entity.setContact(newContact);
|
||||
} else if (resource.getContactUuid() != null) {
|
||||
entity.setContact(em.getReference(HsOfficeContactRealEntity.class, resource.getContactUuid().get()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -51,7 +51,7 @@ public class HsOfficeRelationRbacEntity extends HsOfficeRelation {
|
||||
"""))
|
||||
.withRestrictedViewOrderBy(SQL.expression(
|
||||
"(select idName from hs_office.person_iv p where p.uuid = target.holderUuid)"))
|
||||
.withUpdatableColumns("contactUuid")
|
||||
.withUpdatableColumns("anchorUuid", "holderUuid", "contactUuid") // BEWARE: additional checks at API-level
|
||||
.importEntityAlias("anchorPerson", HsOfficePersonRbacEntity.class, usingDefaultCase(),
|
||||
dependsOnColumn("anchorUuid"),
|
||||
directlyFetchedByDependsOnColumn(),
|
||||
|
@@ -48,12 +48,11 @@ components:
|
||||
HsOfficePartnerPatch:
|
||||
type: object
|
||||
properties:
|
||||
partnerRel.uuid:
|
||||
type: string
|
||||
format: uuid
|
||||
nullable: true
|
||||
partnerRel:
|
||||
$ref: 'hs-office-relation-schemas.yaml#/components/schemas/HsOfficeRelationPatch'
|
||||
details:
|
||||
$ref: '#/components/schemas/HsOfficePartnerDetailsPatch'
|
||||
additionalProperties: false
|
||||
|
||||
HsOfficePartnerDetailsPatch:
|
||||
type: object
|
||||
|
@@ -34,7 +34,7 @@ components:
|
||||
contact:
|
||||
$ref: 'hs-office-contact-schemas.yaml#/components/schemas/HsOfficeContact'
|
||||
|
||||
HsOfficeRelationPatch:
|
||||
HsOfficeRelationContactPatch:
|
||||
type: object
|
||||
properties:
|
||||
contact.uuid:
|
||||
@@ -42,6 +42,27 @@ components:
|
||||
format: uuid
|
||||
nullable: true
|
||||
|
||||
HsOfficeRelationPatch:
|
||||
type: object
|
||||
properties:
|
||||
anchor.uuid:
|
||||
type: string
|
||||
format: uuid
|
||||
nullable: true
|
||||
holder.uuid:
|
||||
type: string
|
||||
format: uuid
|
||||
nullable: true
|
||||
holder:
|
||||
$ref: 'hs-office-person-schemas.yaml#/components/schemas/HsOfficePersonInsert'
|
||||
contact.uuid:
|
||||
type: string
|
||||
format: uuid
|
||||
nullable: true
|
||||
contact:
|
||||
$ref: 'hs-office-contact-schemas.yaml#/components/schemas/HsOfficeContactInsert'
|
||||
additionalProperties: false
|
||||
|
||||
# arbitrary relation with explicit type
|
||||
HsOfficeRelationInsert:
|
||||
type: object
|
||||
|
@@ -44,7 +44,7 @@ patch:
|
||||
content:
|
||||
'application/json':
|
||||
schema:
|
||||
$ref: 'hs-office-relation-schemas.yaml#/components/schemas/HsOfficeRelationPatch'
|
||||
$ref: 'hs-office-relation-schemas.yaml#/components/schemas/HsOfficeRelationContactPatch'
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
|
@@ -124,7 +124,9 @@ create or replace procedure hs_office.relation_update_rbac_system(
|
||||
language plpgsql as $$
|
||||
begin
|
||||
|
||||
if NEW.contactUuid is distinct from OLD.contactUuid then
|
||||
if NEW.holderUuid is distinct from OLD.holderUuid
|
||||
or NEW.anchorUuid is distinct from OLD.anchorUuid
|
||||
or NEW.contactUuid is distinct from OLD.contactUuid then
|
||||
delete from rbac.grant g where g.grantedbytriggerof = OLD.uuid;
|
||||
call hs_office.relation_build_rbac_system(NEW);
|
||||
end if;
|
||||
@@ -248,6 +250,8 @@ call rbac.generateRbacRestrictedView('hs_office.relation',
|
||||
(select idName from hs_office.person_iv p where p.uuid = target.holderUuid)
|
||||
$orderBy$,
|
||||
$updates$
|
||||
anchorUuid = new.anchorUuid,
|
||||
holderUuid = new.holderUuid,
|
||||
contactUuid = new.contactUuid
|
||||
$updates$);
|
||||
--//
|
||||
|
Reference in New Issue
Block a user