Ver Fonte

Verschiedene Verbesserungen an der Dokumentation und den SQL-Modellen

- README.md: Formatierung der Befehle verbessert
- auth.py: Entfernen von nicht benötigten Importen
- models.py: Hinzufügen von Beziehungen zwischen Modellen und Anpassung der Spaltendefinitionen
- routes.py: Bereinigung von Importen
- schemas.py: Anpassung der Konfiguration für Pydantic-Modelle
- specs.md: Kleinere Formatierungsänderungen
- base.html: Titel und Überschrift aktualisiert
gc-server3 há 3 meses atrás
pai
commit
2fac46b3d9
7 ficheiros alterados com 41 adições e 36 exclusões
  1. 20 19
      README.md
  2. 1 1
      app/auth.py
  3. 12 6
      app/models.py
  4. 2 4
      app/routes.py
  5. 3 3
      app/schemas.py
  6. 1 1
      specs.md
  7. 2 2
      templates/base.html

+ 20 - 19
README.md

@@ -1,31 +1,32 @@
-GCOutline - Minimal prototype
+# GCOutline - Minimal prototype
 
 Quickstart (local development):
 
 1. Create a virtual environment and install dependencies:
 
-```powershell
-python -m venv .venv
-.\.venv\Scripts\Activate.ps1
-pip install -e .
-pip install -r <(python -c "import tomllib,sys;print('\n'.join([]))")
-```
+    ```powershell
+    python -m venv .venv
+    .\.venv\Scripts\Activate.ps1
+    pip install -e .
+    pip install -r <(python -c "import tomllib,sys;print('\n'.join([]))")
+    ```
 
-Alternatively install directly:
+    Alternatively install directly:
 
-```powershell
-pip install fastapi uvicorn Jinja2 SQLAlchemy alembic ldap3 python-docx openpyxl pandas python-multipart pyodbc aiofiles
-```
+    ```powershell
+    pip install fastapi uvicorn Jinja2 SQLAlchemy alembic ldap3 python-docx openpyxl pandas python-multipart pyodbc aiofiles
+    ```
 
 2. Run the app:
 
-```powershell
-uvicorn app.main:app --reload
-```
+    ```powershell
+    uvicorn app.main:app --reload
+    ```
 
-3. Open http://127.0.0.1:8000 in your browser.
+3. Open <http://127.0.0.1:8000> in your browser.
 
-Notes:
-- The project uses SQLite by default for local development (`DATABASE_URL` env var can point to MS SQL Server).
-- LDAP authentication will fall back to a local mock where the password `password` is accepted for any username.
-- Exports are available on the list and detail pages.
+    Notes:
+
+    - The project uses SQLite by default for local development (`DATABASE_URL` env var can point to MS SQL Server).
+    - LDAP authentication will fall back to a local mock where the password `password` is accepted for any username.
+    - Exports are available on the list and detail pages.

+ 1 - 1
app/auth.py

@@ -2,7 +2,7 @@ import os
 from typing import Optional
 
 from dotenv import load_dotenv
-from ldap3 import ALL, NTLM, Connection, Server
+from ldap3 import ALL, Connection, Server
 
 load_dotenv()
 

+ 12 - 6
app/models.py

@@ -1,4 +1,4 @@
-from datetime import datetime
+from datetime import datetime, timezone
 
 from sqlalchemy import (
     Column,
@@ -11,6 +11,7 @@ from sqlalchemy import (
     Text,
 )
 from sqlalchemy.orm import relationship
+from sqlalchemy.orm.relationships import _RelationshipDeclared
 
 from .db import Base
 
@@ -20,6 +21,7 @@ class Kunde(Base):
     id = Column(Integer, primary_key=True, index=True)
     name = Column(String, nullable=False)
     historie = Column(Text, default="")
+    forderungen = relationship("Forderung", back_populates="kunde")
 
 
 class Forderung(Base):
@@ -29,14 +31,14 @@ class Forderung(Base):
     verkaeufer_id = Column(Integer, index=True)
     fahrzeug = Column(String, nullable=True)
     fahrgestellnummer = Column(String, nullable=True)
-    rechnungsnummer = Column(String, unique=True, nullable=False, index=True)
+    rechnungsnummer: Column[str] = Column(String, nullable=False)
     betrag = Column(Numeric(12, 2), nullable=False)
     faelligkeit = Column(Date, nullable=True)
     status = Column(String, default="offen")
 
-    kunde = relationship("Kunde", backref="forderungen")
-    zahlungen = relationship("Zahlung", backref="forderung")
-    bemerkungen = relationship("Bemerkung", backref="forderung")
+    kunde = relationship("Kunde", back_populates="forderungen")
+    zahlungen = relationship("Zahlung", back_populates="forderung")
+    bemerkungen = relationship("Bemerkung", back_populates="forderung")
 
 
 class Zahlung(Base):
@@ -46,6 +48,8 @@ class Zahlung(Base):
     betrag = Column(Numeric(12, 2), nullable=False)
     datum = Column(Date, nullable=False)
 
+    forderung = relationship("Forderung", back_populates="zahlungen")
+
 
 class Bemerkung(Base):
     __tablename__ = "bemerkungen"
@@ -54,4 +58,6 @@ class Bemerkung(Base):
     benutzer = Column(String, nullable=False)
     bemerkung = Column(Text, nullable=True)
     wiedervorlage_datum = Column(Date, nullable=True)
-    zeitstempel = Column(DateTime, default=datetime.utcnow)
+    zeitstempel = Column(DateTime, default=datetime.now(timezone.utc))
+
+    forderung = relationship("Forderung", back_populates="bemerkungen")

+ 2 - 4
app/routes.py

@@ -1,6 +1,4 @@
 import io
-import os
-from datetime import datetime
 
 import pandas as pd
 from docx import Document
@@ -10,8 +8,8 @@ from fastapi.templating import Jinja2Templates
 from sqlalchemy.orm import Session
 
 from .auth import ldap_authenticate
-from .db import engine, get_session
-from .models import Bemerkung, Forderung, Kunde, Zahlung
+from .db import get_session
+from .models import Bemerkung, Forderung
 from .schemas import BemerkungIn
 
 router = APIRouter()

+ 3 - 3
app/schemas.py

@@ -1,5 +1,5 @@
 from datetime import date
-from typing import List, Optional
+from typing import Optional
 
 from pydantic import BaseModel
 
@@ -9,7 +9,7 @@ class KundeOut(BaseModel):
     name: str
 
     class Config:
-        orm_mode = True
+        from_attributes = True
 
 
 class ZahlungOut(BaseModel):
@@ -18,7 +18,7 @@ class ZahlungOut(BaseModel):
     datum: date
 
     class Config:
-        orm_mode = True
+        from_attributes = True
 
 
 class BemerkungIn(BaseModel):

+ 1 - 1
specs.md

@@ -85,7 +85,7 @@
 
 ## **Datenbank-Design (vereinfacht)**
 
-### Tabellen:
+### Tabellen
 
 - **Forderungen**
   - ID (PK)

+ 2 - 2
templates/base.html

@@ -3,13 +3,13 @@
   <head>
     <meta charset="utf-8">
     <meta name="viewport" content="width=device-width, initial-scale=1">
-    <title>GCOutline</title>
+    <title>Forderungen</title>
     <script src="https://unpkg.com/htmx.org@1.9.3"></script>
     <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css">
   </head>
   <body class="container py-3">
     <header class="mb-3">
-      <h1>GCOutline</h1>
+      <h1>Forderungen</h1>
     </header>
     <main>
       {% block content %}{% endblock %}