implemented delete of energy community
This commit is contained in:
parent
7d485f4079
commit
caf05d3103
11 changed files with 83 additions and 25 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -35,3 +35,4 @@ build/
|
||||||
/eeg_backend/eegportal.mv.db
|
/eeg_backend/eegportal.mv.db
|
||||||
/eegportal.mv.db
|
/eegportal.mv.db
|
||||||
/eegportal.trace.db
|
/eegportal.trace.db
|
||||||
|
/projekt_kontext.txt
|
||||||
|
|
|
||||||
31
ai-context.ps1
Normal file
31
ai-context.ps1
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
$OutFile = "projekt_kontext.txt"
|
||||||
|
$Files = @()
|
||||||
|
|
||||||
|
# 1. Konfigurationen und Abhängigkeiten (Das Ökosystem)
|
||||||
|
if (Test-Path ".\pom.xml") { $Files += Get-Item ".\pom.xml" }
|
||||||
|
if (Test-Path ".\eeg_backend\pom.xml") { $Files += Get-Item ".\eeg_backend\pom.xml" }
|
||||||
|
if (Test-Path ".\eeg_frontend\package.json") { $Files += Get-Item ".\eeg_frontend\package.json" }
|
||||||
|
|
||||||
|
# 2. Backend: Java-Klassen (Spring Boot, Hibernate)
|
||||||
|
# Sucht nur im main-Verzeichnis, um Testklassen automatisch auszuschließen
|
||||||
|
if (Test-Path ".\eeg_backend\src\main\java") {
|
||||||
|
$Files += Get-ChildItem -Path ".\eeg_backend\src\main\java" -Filter *.java -Recurse
|
||||||
|
}
|
||||||
|
|
||||||
|
# 3. Frontend: Angular (TypeScript und HTML)
|
||||||
|
if (Test-Path ".\eeg_frontend\src\app") {
|
||||||
|
# Wir holen .ts und .html, filtern aber .spec.ts (Tests) hart heraus
|
||||||
|
$Files += Get-ChildItem -Path ".\eeg_frontend\src\app" -Include *.ts, *.html -Recurse | Where-Object { $_.Name -notmatch "\.spec\.ts$" }
|
||||||
|
}
|
||||||
|
|
||||||
|
# Ausgabe schreiben (UTF8 ist extrem wichtig!)
|
||||||
|
Clear-Content -Path $OutFile -ErrorAction SilentlyContinue
|
||||||
|
foreach ($f in $Files) {
|
||||||
|
"========================================" | Out-File -Append $OutFile -Encoding UTF8
|
||||||
|
"Datei: $($f.FullName)" | Out-File -Append $OutFile -Encoding UTF8
|
||||||
|
"========================================" | Out-File -Append $OutFile -Encoding UTF8
|
||||||
|
Get-Content $f.FullName -Encoding UTF8 | Out-File -Append $OutFile -Encoding UTF8
|
||||||
|
"`n" | Out-File -Append $OutFile -Encoding UTF8
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host "Erfolgreich! Der Kontext für Backend und Frontend wurde in '$OutFile' gespeichert."
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
package at.mueller.eeg.backend.common.event;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public record UserRejectedEvent(UUID userId) {}
|
||||||
|
|
@ -1,9 +1,6 @@
|
||||||
package at.mueller.eeg.backend.community.event.listener;
|
package at.mueller.eeg.backend.community.event.listener;
|
||||||
|
|
||||||
import at.mueller.eeg.backend.common.event.EdaTopologyCompletedEvent;
|
import at.mueller.eeg.backend.common.event.*;
|
||||||
import at.mueller.eeg.backend.common.event.EdaTopologyFailedEvent;
|
|
||||||
import at.mueller.eeg.backend.common.event.InitiateMakoConsentEvent;
|
|
||||||
import at.mueller.eeg.backend.common.event.UserRegisteredEvent;
|
|
||||||
import at.mueller.eeg.backend.common.exception.AtNumberAlreadyExistsException;
|
import at.mueller.eeg.backend.common.exception.AtNumberAlreadyExistsException;
|
||||||
import at.mueller.eeg.backend.community.domain.MeteringPoint;
|
import at.mueller.eeg.backend.community.domain.MeteringPoint;
|
||||||
import at.mueller.eeg.backend.community.domain.PointType;
|
import at.mueller.eeg.backend.community.domain.PointType;
|
||||||
|
|
@ -77,4 +74,9 @@ public class MeteringPointEventListener {
|
||||||
meteringPointRepository.save(point);
|
meteringPointRepository.save(point);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@EventListener
|
||||||
|
public void handleUserRejected(UserRejectedEvent event) {
|
||||||
|
meteringPointRepository.deleteByUserId(event.userId());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,4 +11,6 @@ public interface MeteringPointRepository extends JpaRepository<MeteringPoint, UU
|
||||||
List<MeteringPoint> findAllByUserId(UUID userId);
|
List<MeteringPoint> findAllByUserId(UUID userId);
|
||||||
|
|
||||||
boolean existsByAtNumber(String atNumber);
|
boolean existsByAtNumber(String atNumber);
|
||||||
|
|
||||||
|
void deleteByUserId(UUID userId);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -66,6 +66,9 @@ public class EnergyCommunityService {
|
||||||
if (!energyCommunityRepository.existsById(id)) {
|
if (!energyCommunityRepository.existsById(id)) {
|
||||||
throw new IllegalArgumentException("Energy Community mit ID " + id + " existiert nicht.");
|
throw new IllegalArgumentException("Energy Community mit ID " + id + " existiert nicht.");
|
||||||
}
|
}
|
||||||
|
if (membershipRepository.existsByEnergyCommunityId(id)) {
|
||||||
|
throw new ResponseStatusException(HttpStatus.CONFLICT, "Die Energiegemeinschaft kann nicht gelöscht werden, da noch Zählpunkte zugeordnet sind.");
|
||||||
|
}
|
||||||
energyCommunityRepository.deleteById(id);
|
energyCommunityRepository.deleteById(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -67,10 +67,7 @@ public class AdminIamController {
|
||||||
@Operation(summary = "User ablehnen",
|
@Operation(summary = "User ablehnen",
|
||||||
description = "Lehnt den Antrag ab (z.B. weil Zählpunkt nicht ins Netz passt).")
|
description = "Lehnt den Antrag ab (z.B. weil Zählpunkt nicht ins Netz passt).")
|
||||||
public ResponseEntity<Void> rejectUser(@PathVariable UUID userId) {
|
public ResponseEntity<Void> rejectUser(@PathVariable UUID userId) {
|
||||||
// Logik: status auf REJECTED setzen oder User hard-löschen, je nach Datenschutz-Konzept
|
|
||||||
// Event feuern: UserRejectedEvent
|
|
||||||
|
|
||||||
adminIamService.rejectUser(userId);
|
adminIamService.rejectUser(userId);
|
||||||
return ResponseEntity.noContent().build();
|
return ResponseEntity.ok().build();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,13 +1,16 @@
|
||||||
package at.mueller.eeg.backend.iam.service;
|
package at.mueller.eeg.backend.iam.service;
|
||||||
|
|
||||||
import at.mueller.eeg.backend.common.event.UserApprovedEvent;
|
import at.mueller.eeg.backend.common.event.UserApprovedEvent;
|
||||||
|
import at.mueller.eeg.backend.common.event.UserRejectedEvent;
|
||||||
import at.mueller.eeg.backend.iam.domain.RegistrationStatus;
|
import at.mueller.eeg.backend.iam.domain.RegistrationStatus;
|
||||||
import at.mueller.eeg.backend.iam.domain.User;
|
import at.mueller.eeg.backend.iam.domain.User;
|
||||||
import at.mueller.eeg.backend.iam.repository.UserRepository;
|
import at.mueller.eeg.backend.iam.repository.UserRepository;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.context.ApplicationEventPublisher;
|
import org.springframework.context.ApplicationEventPublisher;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
import org.springframework.web.server.ResponseStatusException;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
@ -44,6 +47,16 @@ public class AdminIamService {
|
||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
public void rejectUser(UUID userId) {
|
public void rejectUser(UUID userId) {
|
||||||
// Hier folgt später die Logik für das Ablehnen
|
User user = userRepository.findById(userId)
|
||||||
|
.orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "User nicht gefunden"));
|
||||||
|
|
||||||
|
if (user.getStatus() != RegistrationStatus.PENDING) {
|
||||||
|
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Nur User im Status PENDING können abgelehnt werden.");
|
||||||
|
}
|
||||||
|
|
||||||
|
user.setStatus(RegistrationStatus.REJECTED);
|
||||||
|
userRepository.save(user);
|
||||||
|
|
||||||
|
eventPublisher.publishEvent(new UserRejectedEvent(user.getId()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -97,19 +97,22 @@ export class AdminEnergyCommunity implements OnInit {
|
||||||
}
|
}
|
||||||
|
|
||||||
canDelete(ec: EnergyCommunityDto): boolean {
|
canDelete(ec: EnergyCommunityDto): boolean {
|
||||||
// Wenn dein Backend z.B. die Anzahl der Mitglieder mitliefert:
|
return !ec.memberCount || ec.memberCount === 0;
|
||||||
// return !(ec as any).memberCount || (ec as any).memberCount === 0;
|
|
||||||
return true; // Vorerst true, bis die Relation im DTO steht
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onDelete(id: string | undefined): void {
|
onDelete(id: string | undefined): void {
|
||||||
if (!id) return;
|
if (!id) return;
|
||||||
|
|
||||||
if (confirm('Möchtest du diese Energiegemeinschaft wirklich löschen?')) {
|
if (confirm('Möchtest du diese Energiegemeinschaft wirklich löschen?')) {
|
||||||
this.ecService.deleteEnergyCommunity(id).subscribe({
|
this.ecService.deleteEnergyCommunity(id).subscribe({
|
||||||
next: () => {
|
next: () => {
|
||||||
this.communities = this.communities.filter(c => c.id !== id);
|
this.communities = this.communities.filter(c => c.id !== id);
|
||||||
},
|
},
|
||||||
error: (err) => console.error('Löschen fehlgeschlagen', err)
|
error: (err) => {
|
||||||
|
console.error('Löschen fehlgeschlagen', err);
|
||||||
|
const errorMsg = err.error?.message || 'Die Energiegemeinschaft konnte nicht gelöscht werden.';
|
||||||
|
alert(errorMsg);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,7 @@
|
||||||
Freigeben
|
Freigeben
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button (click)="rejectUser(user.id)"
|
<button (click)="rejectUser(user)"
|
||||||
class="inline-flex items-center justify-center px-4 py-2 border border-gray-300 text-sm font-medium rounded-md text-red-700 bg-white hover:bg-red-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 transition">
|
class="inline-flex items-center justify-center px-4 py-2 border border-gray-300 text-sm font-medium rounded-md text-red-700 bg-white hover:bg-red-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 transition">
|
||||||
Ablehnen
|
Ablehnen
|
||||||
</button>
|
</button>
|
||||||
|
|
|
||||||
|
|
@ -58,21 +58,22 @@ export class AdminUserApprovalComponent implements OnInit {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public rejectUser(userId: string | undefined): void {
|
public rejectUser(user: UserProfileResponse): void {
|
||||||
if (!userId) return;
|
if (!user.id) {
|
||||||
this.errorMessage.set('');
|
console.error('Fehler: UserProfileResponse hat keine ID.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this.adminService.rejectUser(userId)
|
if (confirm(`Möchtest du die Registrierung von ${user.firstName} ${user.lastName} wirklich ablehnen?`)) {
|
||||||
.pipe(takeUntilDestroyed(this.destroyRef))
|
this.adminService.rejectUser(user.id).subscribe({
|
||||||
.subscribe({
|
|
||||||
next: () => {
|
next: () => {
|
||||||
// Den abgelehnten User atomar aus der Liste filtern
|
this.pendingUsers.update(users => users.filter(u => u.id !== user.id));
|
||||||
this.pendingUsers.update(users => users.filter(user => user.id !== userId));
|
|
||||||
},
|
},
|
||||||
error: (error) => {
|
error: (err) => {
|
||||||
console.error(`Failed to reject user with ID ${userId}:`, error);
|
console.error('Fehler beim Ablehnen des Users', err);
|
||||||
this.errorMessage.set('Der User konnte nicht abgelehnt werden.');
|
alert(err.error?.message || 'Der User konnte nicht abgelehnt werden.');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue