diff --git a/eeg_backend/src/main/java/at/mueller/eeg/backend/community/domain/MeteringPoint.java b/eeg_backend/src/main/java/at/mueller/eeg/backend/community/domain/MeteringPoint.java index 9f26fac..9793192 100644 --- a/eeg_backend/src/main/java/at/mueller/eeg/backend/community/domain/MeteringPoint.java +++ b/eeg_backend/src/main/java/at/mueller/eeg/backend/community/domain/MeteringPoint.java @@ -48,7 +48,7 @@ public class MeteringPoint { @Column(nullable = false) private MakoState makoState = MakoState.NEW; - @OneToMany(mappedBy = "meteringPoint", cascade = CascadeType.ALL, orphanRemoval = true) + @OneToMany(mappedBy = "meteringPoint", cascade = {CascadeType.PERSIST, CascadeType.MERGE}) private List memberships; public void fireTrigger(MakoTrigger trigger) { diff --git a/eeg_backend/src/main/java/at/mueller/eeg/backend/community/service/MembershipService.java b/eeg_backend/src/main/java/at/mueller/eeg/backend/community/service/MembershipService.java index aefb8c8..2132677 100644 --- a/eeg_backend/src/main/java/at/mueller/eeg/backend/community/service/MembershipService.java +++ b/eeg_backend/src/main/java/at/mueller/eeg/backend/community/service/MembershipService.java @@ -16,6 +16,7 @@ import at.mueller.eeg.backend.iam.domain.User; import at.mueller.eeg.backend.iam.repository.UserRepository; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.security.access.AccessDeniedException; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -59,7 +60,7 @@ public class MembershipService { .orElseThrow(() -> new IllegalArgumentException("Zählpunkt nicht gefunden")); if (!point.getUserId().equals(userId)) { - throw new org.springframework.security.access.AccessDeniedException("Keine Berechtigung für diesen Zählpunkt."); + throw new AccessDeniedException("Keine Berechtigung für diesen Zählpunkt."); } EnergyCommunity community = energyCommunityRepository.findById(request.energyCommunityId()) diff --git a/eeg_backend/src/main/java/at/mueller/eeg/backend/community/service/MeteringDataService.java b/eeg_backend/src/main/java/at/mueller/eeg/backend/community/service/MeteringDataService.java index 54bf2c2..24da0a4 100644 --- a/eeg_backend/src/main/java/at/mueller/eeg/backend/community/service/MeteringDataService.java +++ b/eeg_backend/src/main/java/at/mueller/eeg/backend/community/service/MeteringDataService.java @@ -11,6 +11,7 @@ import at.mueller.eeg.backend.community.repository.MeteringDataUploadRepository; import at.mueller.eeg.backend.community.repository.MeteringPointRepository; import jakarta.persistence.EntityManager; import lombok.RequiredArgsConstructor; +import org.springframework.security.access.AccessDeniedException; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -113,7 +114,7 @@ public class MeteringDataService { private void verifyOwnership(UUID userId, UUID meteringPointId) { meteringPointRepository.findById(meteringPointId) .filter(mp -> mp.getUserId().equals(userId)) - .orElseThrow(() -> new org.springframework.security.access.AccessDeniedException( + .orElseThrow(() -> new AccessDeniedException( "Keine Berechtigung zum Zugriff auf diesen Zählpunkt")); } diff --git a/eeg_backend/src/main/java/at/mueller/eeg/backend/community/service/MeteringPointService.java b/eeg_backend/src/main/java/at/mueller/eeg/backend/community/service/MeteringPointService.java index 880139e..e876808 100644 --- a/eeg_backend/src/main/java/at/mueller/eeg/backend/community/service/MeteringPointService.java +++ b/eeg_backend/src/main/java/at/mueller/eeg/backend/community/service/MeteringPointService.java @@ -14,6 +14,7 @@ import at.mueller.eeg.backend.iam.domain.User; import at.mueller.eeg.backend.iam.repository.UserRepository; import lombok.RequiredArgsConstructor; import org.springframework.context.ApplicationEventPublisher; +import org.springframework.security.access.AccessDeniedException; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -76,7 +77,7 @@ public class MeteringPointService { .orElseThrow(() -> new IllegalArgumentException("Zählpunkt nicht gefunden")); if (!point.getUserId().equals(userId)) { - throw new org.springframework.security.access.AccessDeniedException("Keine Berechtigung zum Bearbeiten dieses Zählpunkts"); + throw new AccessDeniedException("Keine Berechtigung zum Bearbeiten dieses Zählpunkts"); } if (point.getMakoState() != MakoState.NEW && point.getMakoState() != MakoState.REJECTED && point.getMakoState() != MakoState.ERROR) { @@ -107,7 +108,7 @@ public class MeteringPointService { .orElseThrow(() -> new IllegalArgumentException("Zählpunkt nicht gefunden")); if (!point.getUserId().equals(userId)) { - throw new org.springframework.security.access.AccessDeniedException("Keine Berechtigung zum Löschen dieses Zählpunkts"); + throw new AccessDeniedException("Keine Berechtigung zum Löschen dieses Zählpunkts"); } if (point.getMakoState() == MakoState.ACTIVE) { diff --git a/eeg_backend/src/main/java/at/mueller/eeg/backend/tariff/service/TariffInviteService.java b/eeg_backend/src/main/java/at/mueller/eeg/backend/tariff/service/TariffInviteService.java index cdd9272..ad95d74 100644 --- a/eeg_backend/src/main/java/at/mueller/eeg/backend/tariff/service/TariffInviteService.java +++ b/eeg_backend/src/main/java/at/mueller/eeg/backend/tariff/service/TariffInviteService.java @@ -9,6 +9,7 @@ import at.mueller.eeg.backend.tariff.domain.TariffInvite; import at.mueller.eeg.backend.tariff.repository.TariffInviteRepository; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.security.access.AccessDeniedException; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -78,7 +79,7 @@ public class TariffInviteService { .orElseThrow(() -> new IllegalArgumentException("Einladung nicht gefunden: " + inviteId)); if (!invite.getConsumerUserId().equals(consumerUserId)) { - throw new org.springframework.security.access.AccessDeniedException( + throw new AccessDeniedException( "Keine Berechtigung zum Annehmen dieser Einladung."); } if (invite.getStatus() != InviteStatus.PENDING) { diff --git a/eeg_backend/src/main/java/at/mueller/eeg/backend/tariff/service/TariffService.java b/eeg_backend/src/main/java/at/mueller/eeg/backend/tariff/service/TariffService.java index 56e2202..c680f8b 100644 --- a/eeg_backend/src/main/java/at/mueller/eeg/backend/tariff/service/TariffService.java +++ b/eeg_backend/src/main/java/at/mueller/eeg/backend/tariff/service/TariffService.java @@ -20,6 +20,7 @@ import at.mueller.eeg.backend.tariff.repository.UserTariffRepository; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.context.ApplicationEventPublisher; +import org.springframework.security.access.AccessDeniedException; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -73,10 +74,6 @@ public class TariffService { @Transactional public UserTariffResponse createUserTariff(UUID userId, UserTariffRequest request) { - if (request.sourceMeteringPointId().equals(request.targetMeteringPointId())) { - throw new IllegalStateException("Quell- und Ziel-Zählpunkt müssen unterschiedlich sein."); - } - userTariffRepository.findBySourceMeteringPointIdAndTargetMeteringPointId( request.sourceMeteringPointId(), request.targetMeteringPointId()) .ifPresent(existing -> { @@ -84,17 +81,10 @@ public class TariffService { "Es existiert bereits ein Tarif zwischen diesen beiden Zählpunkten."); }); - validateUserTariffRequest(request.energyCommunityId(), request); - - MeteringPoint sourcePoint = meteringPointRepository.findById(request.sourceMeteringPointId()) - .orElseThrow(() -> new IllegalArgumentException( - "Quell-Zählpunkt nicht gefunden: " + request.sourceMeteringPointId())); - MeteringPoint targetPoint = meteringPointRepository.findById(request.targetMeteringPointId()) - .orElseThrow(() -> new IllegalArgumentException( - "Ziel-Zählpunkt nicht gefunden: " + request.targetMeteringPointId())); + ValidatedUserTariffPoints validated = validateUserTariffRequest(request.energyCommunityId(), request); if (!tariffInviteRepository.existsByProducerUserIdAndConsumerUserIdAndEnergyCommunityIdAndStatus( - sourcePoint.getUserId(), targetPoint.getUserId(), request.energyCommunityId(), InviteStatus.ACCEPTED)) { + validated.source().getUserId(), validated.target().getUserId(), request.energyCommunityId(), InviteStatus.ACCEPTED)) { throw new IllegalStateException( "Zwischen Produzent und Konsument muss eine angenommene Einladung bestehen."); } @@ -113,7 +103,7 @@ public class TariffService { request.targetMeteringPointId(), request.pricePerKwhCents()); eventPublisher.publishEvent(new UserTariffChangedEvent( - request.energyCommunityId(), sourcePoint.getUserId(), targetPoint.getUserId(), "CREATED")); + request.energyCommunityId(), validated.source().getUserId(), validated.target().getUserId(), "CREATED")); return toUserTariffResponse(saved); } @@ -127,18 +117,11 @@ public class TariffService { .orElseThrow(() -> new IllegalArgumentException("Quell-Zählpunkt nicht gefunden.")); if (!sourcePoint.getUserId().equals(userId)) { - throw new org.springframework.security.access.AccessDeniedException( + throw new AccessDeniedException( "Keine Berechtigung zum Bearbeiten dieses Tarifs."); } - if (request.sourceMeteringPointId().equals(request.targetMeteringPointId())) { - throw new IllegalStateException("Quell- und Ziel-Zählpunkt müssen unterschiedlich sein."); - } - - validateUserTariffRequest(request.energyCommunityId(), request); - - MeteringPoint newTargetPoint = meteringPointRepository.findById(request.targetMeteringPointId()) - .orElseThrow(() -> new IllegalArgumentException("Ziel-Zählpunkt nicht gefunden.")); + ValidatedUserTariffPoints validated = validateUserTariffRequest(request.energyCommunityId(), request); tariff.setEnergyCommunityId(request.energyCommunityId()); tariff.setSourceMeteringPointId(request.sourceMeteringPointId()); @@ -152,7 +135,7 @@ public class TariffService { tariffId, request.pricePerKwhCents()); eventPublisher.publishEvent(new UserTariffChangedEvent( - request.energyCommunityId(), sourcePoint.getUserId(), newTargetPoint.getUserId(), "UPDATED")); + request.energyCommunityId(), sourcePoint.getUserId(), validated.target().getUserId(), "UPDATED")); return toUserTariffResponse(saved); } @@ -166,7 +149,7 @@ public class TariffService { .orElseThrow(() -> new IllegalArgumentException("Quell-Zählpunkt nicht gefunden.")); if (!sourcePoint.getUserId().equals(userId)) { - throw new org.springframework.security.access.AccessDeniedException( + throw new AccessDeniedException( "Keine Berechtigung zum Löschen dieses Tarifs."); } @@ -214,7 +197,13 @@ public class TariffService { ); } - private void validateUserTariffRequest(UUID communityId, UserTariffRequest request) { + record ValidatedUserTariffPoints(MeteringPoint source, MeteringPoint target) {} + + private ValidatedUserTariffPoints validateUserTariffRequest(UUID communityId, UserTariffRequest request) { + if (request.sourceMeteringPointId().equals(request.targetMeteringPointId())) { + throw new IllegalStateException("Quell- und Ziel-Zählpunkt müssen unterschiedlich sein."); + } + MeteringPoint sourcePoint = meteringPointRepository.findById(request.sourceMeteringPointId()) .orElseThrow(() -> new IllegalArgumentException( "Quell-Zählpunkt nicht gefunden: " + request.sourceMeteringPointId())); @@ -248,5 +237,7 @@ public class TariffService { if (!membershipRepository.isActiveMemberOfCommunity(targetUserId, communityId)) { throw new IllegalStateException("Ziel-Benutzer ist kein Mitglied der Energiegemeinschaft."); } + + return new ValidatedUserTariffPoints(sourcePoint, targetPoint); } }