Objekt bleibt der Materialträger (Rucksack/Gerät/Fahrzeug, Karte 11) -
"Material verschieben" heißt: das Objekt bekommt einen neuen Standort, jede
Bewegung wird append-only protokolliert (Wer/Wann/Von/Nach/Grund, Nutzer-
Vorgabe Modul 5).
POST /objekte/{id}/lagerbewegungen setzt Standort + protokolliert in einem
Zug, GET /lagerbewegungen (Filter objekt_id/standort_id) für die Historie.
Rollen wie beim Mangel-Modul: Materialverantwortliche+Leitung+Admin dürfen
verschieben, alle Eingeloggten dürfen lesen.
Frontend: "Verschieben"-Aktion in ObjektSection, neuer Admin-Tab
"Lagerbewegungen" (reine Anzeige, analog HistorieSection).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KC8HYvv6UkCVYheYiTw9DD
41 lines
1.5 KiB
Python
41 lines
1.5 KiB
Python
"""Lagerbewegung (Roadmap Phase 4, Modul Lager): protokolliert Standortwechsel
|
|
eines Objekts. Objekt bleibt der Materialträger (Rucksack/Gerät/Fahrzeug,
|
|
Karte 11) - "Material verschieben" heißt hier: das Objekt, das es enthält,
|
|
bekommt einen neuen Standort, die Bewegung wird mit Wer/Wann/Von/Nach/Grund
|
|
protokolliert (Nutzer-Vorgabe Modul 5 "Lagerverwaltung").
|
|
|
|
Revision ID: 0015_lagerbewegung
|
|
Revises: 0014_fahrzeugdetails
|
|
Create Date: 2026-09-05
|
|
"""
|
|
from typing import Sequence, Union
|
|
|
|
from alembic import op
|
|
|
|
revision: str = "0015_lagerbewegung"
|
|
down_revision: Union[str, None] = "0014_fahrzeugdetails"
|
|
branch_labels: Union[str, Sequence[str], None] = None
|
|
depends_on: Union[str, Sequence[str], None] = None
|
|
|
|
|
|
def upgrade() -> None:
|
|
op.execute(
|
|
"""
|
|
CREATE TABLE lagerbewegung (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
objekt_id INTEGER NOT NULL REFERENCES objekt(id),
|
|
von_standort_id INTEGER REFERENCES standort(id),
|
|
nach_standort_id INTEGER NOT NULL REFERENCES standort(id),
|
|
benutzer_id INTEGER NOT NULL REFERENCES benutzer(id),
|
|
zeitpunkt TIMESTAMPTZ NOT NULL,
|
|
grund TEXT
|
|
)
|
|
"""
|
|
)
|
|
op.execute("CREATE INDEX idx_lagerbewegung_objekt ON lagerbewegung (objekt_id)")
|
|
op.execute("CREATE INDEX idx_lagerbewegung_standorte ON lagerbewegung (von_standort_id, nach_standort_id)")
|
|
|
|
|
|
def downgrade() -> None:
|
|
op.execute("DROP TABLE lagerbewegung")
|