Löschschutz für Ausleiher, Geräte und Reservierungen #8

Open
thiel wants to merge 1 commit from fix/loeschschutz into main
Owner

Behebt die Befunde 1 und 2 des externen Checks.

Ausleiher sind nur noch löschbar, wenn nichts mehr offen ist: keine ausgegebenen Geräte, kein ausgegebenes Zubehör, keine offene Reservierung. Die Prüfung sitzt im Modell (Holder::deleteBlockReason() + deleting-Hook), greift also auch bei Sammelauswahl und auf der Kommandozeile. Die Sammelaktion überspringt betroffene Ausleiher mit Begründung, statt abzubrechen.

Der Verlauf hält den Namen des Ausleihers jetzt selbst fest (asset_activities.holder_name), damit er nach einem späteren Löschen lesbar bleibt. Vorhandene Einträge werden in der Migration nachgetragen.

Geräte sind nicht mehr löschbar, solange sie ausgegeben sind. Beim Löschen werden offene Reservierungen storniert.

Die Reservierungsliste bricht nicht mehr ab: Die Beziehung schließt gelöschte Geräte ein (withTrashed), und die Erfüllbarkeit wird an einer Stelle im Modell geprüft (Reservation::isFulfillable()). Ursache war nicht ein fehlgeschlagenes Cascade, sondern dass Asset SoftDeletes nutzt und die Kaskade deshalb nie feuert.

8 neue Tests in tests/Feature/LoeschschutzTest.php. Volle Suite grün (158 Tests), Pint sauber.

Dieser Branch ist die Grundlage für die folgenden Blöcke und sollte zuerst gemergt werden.

🤖 Generated with Claude Code

https://claude.ai/code/session_01QKiq6LV8Lk1vst5CQW15ar

Behebt die Befunde 1 und 2 des externen Checks. **Ausleiher** sind nur noch löschbar, wenn nichts mehr offen ist: keine ausgegebenen Geräte, kein ausgegebenes Zubehör, keine offene Reservierung. Die Prüfung sitzt im Modell (`Holder::deleteBlockReason()` + `deleting`-Hook), greift also auch bei Sammelauswahl und auf der Kommandozeile. Die Sammelaktion überspringt betroffene Ausleiher mit Begründung, statt abzubrechen. **Der Verlauf** hält den Namen des Ausleihers jetzt selbst fest (`asset_activities.holder_name`), damit er nach einem späteren Löschen lesbar bleibt. Vorhandene Einträge werden in der Migration nachgetragen. **Geräte** sind nicht mehr löschbar, solange sie ausgegeben sind. Beim Löschen werden offene Reservierungen storniert. **Die Reservierungsliste** bricht nicht mehr ab: Die Beziehung schließt gelöschte Geräte ein (`withTrashed`), und die Erfüllbarkeit wird an einer Stelle im Modell geprüft (`Reservation::isFulfillable()`). Ursache war nicht ein fehlgeschlagenes Cascade, sondern dass `Asset` SoftDeletes nutzt und die Kaskade deshalb nie feuert. 8 neue Tests in `tests/Feature/LoeschschutzTest.php`. Volle Suite grün (158 Tests), Pint sauber. Dieser Branch ist die Grundlage für die folgenden Blöcke und sollte zuerst gemergt werden. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01QKiq6LV8Lk1vst5CQW15ar
Löschschutz für Ausleiher, Geräte und Reservierungen
All checks were successful
Tests / phpunit (pull_request) Successful in 1m36s
341a2fa5fa
Ein Ausleiher war jederzeit löschbar. Die Fremdschlüssel stehen auf
nullOnDelete, holders hat kein SoftDeletes - ein weiterhin verliehenes
Gerät stand danach wieder als verfügbar da, und im Verlauf war die
Personenzuordnung endgültig weg.

Gelöscht werden kann jetzt nur, wer nichts mehr offen hat. Die Prüfung
sitzt im Modell und greift damit auch bei Sammelauswahl und auf der
Kommandozeile; die Sammelaktion überspringt die betroffenen Ausleiher
mit Begründung statt abzubrechen.

asset_activities hält den Namen des Ausleihers jetzt selbst fest, damit
der Verlauf auch nach einem späteren Löschen lesbar bleibt. Vorhandene
Einträge werden nachgetragen.

Ausgegebene Geräte sind ebenfalls nicht mehr löschbar; beim Löschen
eines Geräts werden offene Reservierungen storniert. Die Beziehung
Reservierung -> Gerät schließt gelöschte Geräte ein, sonst brach die
Reservierungsliste mit einem Fehler ab.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QKiq6LV8Lk1vst5CQW15ar
All checks were successful
Tests / phpunit (pull_request) Successful in 1m36s
This pull request has changes conflicting with the target branch.
  • CHANGELOG.md
  • config/inventar.php
View command line instructions

Manual merge helper

Use this merge commit message when completing the merge manually.

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin fix/loeschschutz:fix/loeschschutz
git switch fix/loeschschutz

Merge

Merge the changes and update on Forgejo.

Warning: The "Autodetect manual merge" setting is not enabled for this repository, you will have to mark this pull request as manually merged afterwards.

git switch main
git merge --no-ff fix/loeschschutz
git switch fix/loeschschutz
git rebase main
git switch main
git merge --ff-only fix/loeschschutz
git switch fix/loeschschutz
git rebase main
git switch main
git merge --no-ff fix/loeschschutz
git switch main
git merge --squash fix/loeschschutz
git switch main
git merge --ff-only fix/loeschschutz
git switch main
git merge fix/loeschschutz
git push origin main
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
thiel/natec-inventar!8
No description provided.