""" Geschäftslogik für die Entität Projekt. Diese Funktionen kapseln den DB-Zugriff und die fachlichen Validierungen. Aufgerufen werden sie aus crm/routes.py; die Autorisierungsprüfung erfolgt dort über den Decorator authorisation_required. :author: Mistral Vibe :date: 2026-09-04 :version: 1.0 """ from db import dbapp from crm.model import Projekt, Kunde from auth.model.errors import ApplicationError, HtmlStatusCode session = dbapp.session def get_projekte(): """ Liefert alle Projekte, sortiert nach projektname. """ return Projekt.query.order_by(Projekt.projektname).all() def get_projekt(projekt_id: int) -> Projekt: """ Liefert ein einzelnes Projekt anhand seiner ID. Wirft ApplicationError (404), falls das Projekt nicht existiert. """ projekt = Projekt.query.get(projekt_id) if projekt is None: raise ApplicationError( "Projekt mit der ID {} wurde nicht gefunden.".format(projekt_id), htmlstatus=HtmlStatusCode.Not_Found, ) return projekt def create_projekt(data: dict) -> Projekt: """ Legt ein neues Projekt an. Die vom Client übergebene ID wird ignoriert; die ID wird serverseitig per Auto-Increment vergeben. - data: dict mit den Feldern kunden_id, projektname, zweck, verantwortlicher, startdatum """ kunden_id = data.get("kunden_id") if kunden_id is None: raise ApplicationError( "Es muss ein Kunde ausgewählt werden.", htmlstatus=HtmlStatusCode.Bad_Request, ) kunde = Kunde.query.get(int(kunden_id)) if kunde is None: raise ApplicationError( "Der ausgewählte Kunde existiert nicht.", htmlstatus=HtmlStatusCode.Bad_Request, ) if not data.get("projektname") or not str(data["projektname"]).strip(): raise ApplicationError( "Der Projektname darf nicht leer sein.", htmlstatus=HtmlStatusCode.Bad_Request, ) projekt = Projekt() projekt.kunden_id = int(kunden_id) projekt.projektname = data["projektname"].strip() projekt.zweck = (data.get("zweck") or "").strip() or None projekt.verantwortlicher = (data.get("verantwortlicher") or "").strip() or None projekt.startdatum = (data.get("startdatum") or "").strip() or None session.add(projekt) session.commit() return projekt def update_projekt(data: dict) -> Projekt: """ Aktualisiert ein bestehendes Projekt. Die ID im data-Dict bestimmt den zu ändernden Datensatz. """ projekt = get_projekt(data["id"]) kunden_id = data.get("kunden_id") if kunden_id is None: raise ApplicationError( "Es muss ein Kunde ausgewählt werden.", htmlstatus=HtmlStatusCode.Bad_Request, ) kunde = Kunde.query.get(int(kunden_id)) if kunde is None: raise ApplicationError( "Der ausgewählte Kunde existiert nicht.", htmlstatus=HtmlStatusCode.Bad_Request, ) if not data.get("projektname") or not str(data["projektname"]).strip(): raise ApplicationError( "Der Projektname darf nicht leer sein.", htmlstatus=HtmlStatusCode.Bad_Request, ) projekt.kunden_id = int(kunden_id) projekt.projektname = data["projektname"].strip() projekt.zweck = (data.get("zweck") or "").strip() or None projekt.verantwortlicher = (data.get("verantwortlicher") or "").strip() or None projekt.startdatum = (data.get("startdatum") or "").strip() or None session.commit() return projekt def delete_projekt(projekt_id: int): """ Löscht ein Projekt anhand seiner ID. Wirft ApplicationError (404), falls das Projekt nicht existiert. """ projekt = get_projekt(projekt_id) session.delete(projekt) session.commit()