1
0

add optional alarm-contact to hosting-asset (#64)

Co-authored-by: Michael Hoennig <michael@hoennig.de>
Reviewed-on: https://dev.hostsharing.net/hostsharing/hs.hsadmin.ng/pulls/64
Reviewed-by: Marc Sandlus <marc.sandlus@hostsharing.net>
This commit is contained in:
Michael Hoennig
2024-06-21 12:02:07 +02:00
parent d157730de7
commit 9418303b7c
17 changed files with 544 additions and 286 deletions

View File

@ -16,7 +16,9 @@ import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.mvc.method.annotation.MvcUriComponentsBuilder;
import jakarta.persistence.EntityManager;
import jakarta.persistence.EntityNotFoundException;
import jakarta.persistence.PersistenceContext;
import java.util.List;
import java.util.UUID;
import java.util.function.BiConsumer;
@ -26,6 +28,9 @@ import static net.hostsharing.hsadminng.hs.hosting.asset.validators.HsHostingAss
@RestController
public class HsHostingAssetController implements HsHostingAssetsApi {
@PersistenceContext
private EntityManager em;
@Autowired
private Context context;
@ -119,7 +124,7 @@ public class HsHostingAssetController implements HsHostingAssetsApi {
final var current = assetRepo.findByUuid(assetUuid).orElseThrow();
new HsHostingAssetEntityPatcher(current).apply(body);
new HsHostingAssetEntityPatcher(em, current).apply(body);
final var saved = validated(assetRepo.save(current));
final var mapped = mapper.map(saved, HsHostingAssetResource.class);

View File

@ -8,6 +8,7 @@ import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity;
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactEntity;
import net.hostsharing.hsadminng.mapper.PatchableMapWrapper;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL;
@ -48,6 +49,7 @@ import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.UPDATE;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.ADMIN;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.AGENT;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.OWNER;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.REFERRER;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.TENANT;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL.directlyFetchedByDependsOnColumn;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.rbacViewFor;
@ -95,6 +97,10 @@ public class HsHostingAssetEntity implements Stringifyable, RbacObject {
@Enumerated(EnumType.STRING)
private HsHostingAssetType type;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "alarmcontactuuid")
private HsOfficeContactEntity alarmContact;
@OneToMany(cascade = CascadeType.REFRESH, orphanRemoval = true, fetch = FetchType.LAZY)
@JoinColumn(name="parentassetuuid", referencedColumnName="uuid")
private List<HsHostingAssetEntity> subHostingAssets;
@ -136,7 +142,7 @@ public class HsHostingAssetEntity implements Stringifyable, RbacObject {
return rbacViewFor("asset", HsHostingAssetEntity.class)
.withIdentityView(SQL.projection("identifier"))
.withRestrictedViewOrderBy(SQL.expression("identifier"))
.withUpdatableColumns("version", "caption", "config")
.withUpdatableColumns("version", "caption", "config", "assignedToAssetUuid", "alarmContactUuid")
.toRole(GLOBAL, ADMIN).grantPermission(INSERT) // TODO.impl: Why is this necessary to insert test data?
.importEntityAlias("bookingItem", HsBookingItemEntity.class, usingDefaultCase(),
@ -155,6 +161,11 @@ public class HsHostingAssetEntity implements Stringifyable, RbacObject {
directlyFetchedByDependsOnColumn(),
NULLABLE)
.importEntityAlias("alarmContact", HsOfficeContactEntity.class, usingDefaultCase(),
dependsOnColumn("alarmContactUuid"),
directlyFetchedByDependsOnColumn(),
NULLABLE)
.createRole(OWNER, (with) -> {
with.incomingSuperRole("bookingItem", ADMIN);
with.incomingSuperRole("parentAsset", ADMIN);
@ -167,13 +178,15 @@ public class HsHostingAssetEntity implements Stringifyable, RbacObject {
})
.createSubRole(AGENT, (with) -> {
with.outgoingSubRole("assignedToAsset", TENANT);
with.outgoingSubRole("alarmContact", REFERRER);
})
.createSubRole(TENANT, (with) -> {
with.outgoingSubRole("bookingItem", TENANT);
with.outgoingSubRole("parentAsset", TENANT);
with.incomingSuperRole("alarmContact", ADMIN);
with.permission(SELECT);
})
.limitDiagramTo("asset", "bookingItem", "bookingItem.debitorRel", "parentAsset", "assignedToAsset", "global");
.limitDiagramTo("asset", "bookingItem", "bookingItem.debitorRel", "parentAsset", "assignedToAsset", "alarmContact", "global");
}
public static void main(String[] args) throws IOException {

View File

@ -1,17 +1,21 @@
package net.hostsharing.hsadminng.hs.hosting.asset;
import net.hostsharing.hsadminng.hs.hosting.generated.api.v1.model.HsHostingAssetPatchResource;
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactEntity;
import net.hostsharing.hsadminng.mapper.EntityPatcher;
import net.hostsharing.hsadminng.mapper.KeyValueMap;
import net.hostsharing.hsadminng.mapper.OptionalFromJson;
import jakarta.persistence.EntityManager;
import java.util.Optional;
public class HsHostingAssetEntityPatcher implements EntityPatcher<HsHostingAssetPatchResource> {
private final EntityManager em;
private final HsHostingAssetEntity entity;
public HsHostingAssetEntityPatcher(final HsHostingAssetEntity entity) {
HsHostingAssetEntityPatcher(final EntityManager em, final HsHostingAssetEntity entity) {
this.em = em;
this.entity = entity;
}
@ -21,5 +25,11 @@ public class HsHostingAssetEntityPatcher implements EntityPatcher<HsHostingAsset
.ifPresent(entity::setCaption);
Optional.ofNullable(resource.getConfig())
.ifPresent(r -> entity.getConfig().patch(KeyValueMap.from(resource.getConfig())));
OptionalFromJson.of(resource.getAlarmContactUuid())
// HOWTO: patch nullable JSON resource uuid to an ntity reference
.ifPresent(newValue -> entity.setAlarmContact(
Optional.ofNullable(newValue)
.map(uuid -> em.getReference(HsOfficeContactEntity.class, newValue))
.orElse(null)));
}
}