3
0

12 Commits b3a46dcaaf ... 94b7c2d3e9

Autor SHA1 Nachricht Datum
  gc-server3 94b7c2d3e9 Detailsanpassungen Matthias vor 2 Wochen
  gc-server3 ec40881626 Viele kleine Änderungen vor Abstimmung mit Matthias vor 3 Wochen
  gc-server3 58657b8644 mcp vor 3 Wochen
  gc-server3 10923cce5f Tabellenüberschriften und Filter angepasst vor 3 Wochen
  gc-server3 968abbf834 Reihenfolge der Tabellenfelder angepasst vor 3 Wochen
  gc-server3 5a81b02b24 Abfrage angepasst, neue Schriftart, Modal für PDF vor 3 Wochen
  gc-server3 2c348804b9 IMAP Credentials vor 3 Wochen
  gc-server3 bdd362ca1b Kommentare bereinigen vor 3 Wochen
  gc-server3 4dd99ad9b3 Datenbank umstrukturiert, Queries und Templates entsprechend angepasst vor 3 Wochen
  gc-server3 28f8d01bc9 Tabellennamen angepasst vor 3 Wochen
  gc-server3 d734ee9377 HTML formatiert vor 3 Wochen
  gc-server3 91eb5dc6f1 Kommentare speichern vor 3 Wochen
37 geänderte Dateien mit 753 neuen und 547 gelöschten Zeilen
  1. 9 0
      .vscode/mcp.json
  2. 43 3
      app/cleanup_comments.py
  3. 22 0
      app/file_storage.py
  4. 9 3
      app/imap.py
  5. 7 9
      app/query_filter.py
  6. 100 83
      app/routes.py
  7. 1 1
      pyproject.toml
  8. 128 78
      static/assets/css/main.css
  9. 52 50
      static/assets/css/redesign.css
  10. BIN
      static/assets/pdf/invoice.pdf
  11. 6 2
      templates/base/base.html
  12. 28 14
      templates/base/chat_container.html
  13. 22 0
      templates/base/liste.html
  14. 1 0
      templates/forderungen/config/primary_key.txt
  15. 26 35
      templates/forderungen/details/details.html
  16. 11 9
      templates/forderungen/details/details_buchungen.html
  17. 61 45
      templates/forderungen/details/details_formular.html
  18. 1 1
      templates/forderungen/details/details_kommentare.html
  19. 12 12
      templates/forderungen/details/details_mahnungen.html
  20. 2 2
      templates/forderungen/details/details_positionen.html
  21. 3 3
      templates/forderungen/details/details_rohdaten.html
  22. 56 55
      templates/forderungen/details/details_uebersicht.html
  23. 2 2
      templates/forderungen/details/queries/auftraege_positionen.sql
  24. 0 30
      templates/forderungen/details/queries/forderung_belege.sql
  25. 0 9
      templates/forderungen/details/queries/forderung_kommentar.sql
  26. 0 15
      templates/forderungen/details/queries/forderung_mahnung.sql
  27. 25 0
      templates/forderungen/details/queries/forderungen_buchungen.sql
  28. 6 6
      templates/forderungen/details/queries/forderungen_details.sql
  29. 9 0
      templates/forderungen/details/queries/forderungen_kommentare.sql
  30. 15 0
      templates/forderungen/details/queries/forderungen_mahnungen.sql
  31. 0 2
      templates/forderungen/details/queries/post/insert_kommentar.sql
  32. 2 0
      templates/forderungen/details/queries/post/post_comments.sql
  33. 0 0
      templates/forderungen/details/queries/post/post_details.sql
  34. 16 12
      templates/forderungen/liste/config/liste_filter.csv
  35. 5 6
      templates/forderungen/liste/liste_kopfzeile.html
  36. 37 34
      templates/forderungen/liste/liste_zeile.html
  37. 36 26
      templates/forderungen/liste/queries/forderungen_liste.sql

+ 9 - 0
.vscode/mcp.json

@@ -0,0 +1,9 @@
+{
+  "servers": {
+    "coreui-docs": {
+      "type": "stdio",
+      "command": "npx",
+      "args": ["-y", "@coreui/docs-mcp", "--framework", "bootstrap"]
+    }
+  }
+}

+ 43 - 3
app/cleanup_comments.py

@@ -1,7 +1,7 @@
-from datetime import timedelta, date
+import re
+from datetime import date, timedelta
 
 from db import get_session
-import re
 from sqlalchemy import text
 
 
@@ -25,6 +25,46 @@ def main():
     db.commit()
 
 
+def get_details_from_comments():
+    db = next(get_session())
+    q = db.execute(text("SELECT * FROM dbo.Forderungen_Kommentar_Rohdaten"))
+
+    for row in q.fetchall():
+        data = {}
+
+        az = re.search(r"^AZ\:?\s(\d+\/\d+)", row.Kommentar)
+        if az:
+            data["Rechtsanwalt_Aktenzeichen"] = az[1]
+
+        if "HP Schaden" in row.Kommentar:
+            data["Versicherung_Typ"] = "Haftpflicht"
+        if "Haftpflicht" in row.Kommentar:
+            data["Versicherung_Typ"] = "Haftpflicht"
+        if "VK Schaden" in row.Kommentar:
+            data["Versicherung_Typ"] = "Vollkasko"
+        if "VK-Schaden" in row.Kommentar:
+            data["Versicherung_Typ"] = "Vollkasko"
+        if "TK Schaden" in row.Kommentar:
+            data["Versicherung_Typ"] = "Teilkasko"
+        if "TK-Schaden" in row.Kommentar:
+            data["Versicherung_Typ"] = "Teilkasko"
+
+        s = re.search(r"Schaden (.*) bei (.*) eingereicht", row.Kommentar)
+        if s:
+            data["Schadennummer"] = s[1]
+            data["Vers_Adresse_ID"] = s[2].replace("'", "").lower()[:25]
+
+        if data:
+            db.execute(
+                text(
+                    "UPDATE dbo.Forderungen_Details SET "
+                    + ", ".join([f"{k} = '{v}'" for k, v in data.items()])
+                    + f" WHERE Client_DB = '{row.Client_DB}' AND Beleg_Nr = '{row.Beleg_Nr}'"
+                )
+            )
+    db.commit()
+
+
 def get_date_and_user_from_comment(r: str) -> tuple[date, str]:
     m = re.search(r"(\d\d\.\d\d?)\.?[\/\s](\w+)", r)
     if m:
@@ -41,4 +81,4 @@ def get_date_and_user_from_comment(r: str) -> tuple[date, str]:
 
 
 if __name__ == "__main__":
-    main()
+    get_details_from_comments()

+ 22 - 0
app/file_storage.py

@@ -0,0 +1,22 @@
+import os
+from pathlib import Path
+from urllib.parse import unquote
+
+from dotenv import load_dotenv
+
+load_dotenv()
+
+
+def get_files(primary_key: dict[str, str]):
+    fileserver = os.environ.get("LOCAL_STORAGE")
+    files = [
+        f.relative_to(fileserver)
+        for f in Path(f"{fileserver}\\{primary_key['Client_DB']}\\{primary_key['Beleg_Nr']}").glob("*")
+    ]
+    return files
+
+
+def get_file(name: str):
+    fileserver = os.environ.get("LOCAL_STORAGE")
+    filename = Path(f"{fileserver}\\{unquote(name)}")
+    return filename

+ 9 - 3
app/imap.py

@@ -1,11 +1,15 @@
+import os
 import re
 from dataclasses import dataclass
 from pathlib import Path
 
 from db import get_session
+from dotenv import load_dotenv
 from imap_tools import MailBox
 from sqlalchemy import text
 
+load_dotenv()
+
 
 @dataclass
 class ImapCredentials:
@@ -14,13 +18,15 @@ class ImapCredentials:
     password: str
 
 
-creds = ImapCredentials("mail.global-cube.com", "forderung", "Navision2013!")
-fileserver = Path("C:\\Projekte\\Reisacher-Fileserver")
+creds = ImapCredentials(
+    server=os.getenv("IMAP_SERVER"), username=os.getenv("IMAP_USERNAME"), password=os.getenv("IMAP_PASSWORD")
+)
+fileserver = Path(os.environ.get("LOCAL_STORAGE"))
 
 
 def main():
     db = next(get_session())
-    q = db.execute(text("SELECT Client_DB, Document_No FROM dbo.Forderungen")).fetchall()
+    q = db.execute(text("SELECT [Client_DB], [Beleg_Nr] FROM [dbo].[Forderungen_Kopf]")).fetchall()
     lookup = {row[1]: row[0] for row in q}
 
     with MailBox(creds.server).login(creds.username, creds.password) as mb:

+ 7 - 9
app/query_filter.py

@@ -1,5 +1,5 @@
 import csv
-from dataclasses import dataclass
+from dataclasses import dataclass, field
 
 
 @dataclass
@@ -13,7 +13,7 @@ class FilterConfig:
     sort_column: str
     visible: bool = True
     default_value: str = ""
-    options: list[dict[str, str]] | None = None
+    options: dict[str, str] | None = field(default_factory=dict)
     current_value: str | None = None
 
     @property
@@ -25,11 +25,11 @@ class FilterConfig:
 
         if self.filter_type == "date":
             if "bis" in self.name.lower():
-                return f" [{self.key_column}] <= '{self.current_value}' "
-            return f" [{self.key_column}] >= '{self.current_value}' "
+                return f" F.[{self.key_column}] <= '{self.current_value}' "
+            return f" F.[{self.key_column}] >= '{self.current_value}' "
         # if self.filter_type == "select":
         #     return f"{self.key_column} IN ({self.current_value})"
-        return f" [{self.key_column}] LIKE '%{self.current_value}%' "
+        return f" F.[{self.key_column}] LIKE '%{self.current_value}%' "
 
     @staticmethod
     def from_dict(
@@ -77,11 +77,9 @@ filter_type_option = {
 }
 
 
-def import_filter_config() -> list[FilterConfig]:
+def import_filter_config(area: str) -> list[FilterConfig]:
     res = []
-    with open(
-        "templates\\forderungen\\liste\\config\\liste_filter.csv", "r", newline="", encoding="latin-1"
-    ) as csvfile:
+    with open(f"templates\\{area}\\liste\\config\\liste_filter.csv", "r", newline="", encoding="latin-1") as csvfile:
         reader = csv.DictReader(csvfile, delimiter=";")
         for row in reader:
             config = FilterConfig.from_dict(*row.values())

+ 100 - 83
app/routes.py

@@ -2,6 +2,7 @@ import io
 import re
 from datetime import datetime, timedelta
 from pathlib import Path
+from typing import Annotated
 from urllib.parse import unquote, urlencode
 
 import pandas as pd
@@ -17,13 +18,13 @@ from fastapi.responses import (
 from sqlalchemy import text
 from sqlalchemy.orm import Session
 
+from app.file_storage import get_file, get_files
 from app.query_filter import filter_type_option, import_filter_config
 
 from .db import get_session
 from .jinja_templates import templates
 from .ldap import ldap_authenticate
-from .models import Bemerkung, Forderung
-from .schemas import BemerkungIn
+from .models import Forderung
 
 router = APIRouter()
 
@@ -54,21 +55,14 @@ def login_post(username: str = Form(...), password: str = Form(...)):
     return response
 
 
-@router.get("/forderungen", response_class=HTMLResponse)
-def forderungsliste(request: Request, db: Session = Depends(get_session), limit: int = 100):
-    q = db.query(Forderung).order_by(Forderung.faelligkeit.asc()).limit(limit).all()
-    return templates.TemplateResponse(request, "base/list.html", {"request": request, "forderungen": q})
-
-
 def single_quote(text: str):
     return "'" + unquote(text) + "'"
 
 
-forderung_filter_config = import_filter_config()
-
-
 @router.get("/app/forderungen/liste", response_class=HTMLResponse)
 def forderungen_liste(request: Request, db: Session = Depends(get_session), limit: int = 100, page: int = 0):
+    forderung_filter_config = import_filter_config("forderungen")
+
     params = {
         f.name: request.query_params[f.name]
         for f in forderung_filter_config
@@ -80,6 +74,8 @@ def forderungen_liste(request: Request, db: Session = Depends(get_session), limi
     context = {}
     for f in forderung_filter_config:
         context[f.name] = {filter_type_option[f.filter_type]: single_quote(params.get(f.name, f.default_value))}
+        if f.name in params:
+            f.current_value = params[f.name]
 
     query = templates.TemplateResponse(request, "forderungen/liste/queries/forderungen_liste.sql", context).body.decode(
         "utf-8"
@@ -100,11 +96,24 @@ def forderungen_liste(request: Request, db: Session = Depends(get_session), limi
     for f in forderung_filter_config:
         if f.key_column not in col_names:
             continue
-        filters[f.name] = {row[col_names.index(f.key_column)]: row[col_names.index(f.value_column)] for row in q}
+        filter_temp = [
+            (
+                row[col_names.index(f.sort_column)] or "",
+                row[col_names.index(f.key_column)],
+                row[col_names.index(f.value_column)],
+            )
+            for row in q
+        ]
+        if filter_temp:
+            print(filter_temp[0])
+            filters[f.name] = {item[1]: item[2] for item in sorted(list(set(filter_temp)))}
+        else:
+            print(f"Filter {f.name} has no options, skipping")
+            filters[f.name] = {}
         f.options = filters[f.name]
 
     summary = {
-        "offen": sum([r[col_names.index("offen")] for r in q]),
+        "Beleg_offen": sum([r[col_names.index("Beleg_offen")] for r in q]),
         "Anzahl": len(q),
     }
 
@@ -137,16 +146,22 @@ def forderungen_liste(request: Request, db: Session = Depends(get_session), limi
     )
 
 
-@router.get("/app/forderungen/details/{client_db}_{document_no}", response_class=HTMLResponse)
-def forderungen_details(
-    request: Request, client_db: str, document_no: str, db: Session = Depends(get_session), limit: int = 100
-):
+@router.get("/app/forderungen/details/{primary_key}", response_class=HTMLResponse)
+def forderungen_details(request: Request, primary_key: str, db: Session = Depends(get_session)):
+
+    pkey = convert_primary_key("forderungen", primary_key)
+
+    template_context = get_template_context(request, pkey, db)
+    return templates.TemplateResponse(request, "forderungen/details/details.html", template_context)
+
+
+def get_template_context(request: Request, pkey: dict[str, str], db: Session) -> dict:
     context = {
         "appsmith": {
             "URL": {
                 "queryParams": {
-                    "Client_DB": "'" + client_db + "'",
-                    "Document_No": "'" + document_no + "'",
+                    "Client_DB": "'" + pkey["Client_DB"] + "'",
+                    "Beleg_Nr": "'" + pkey["Beleg_Nr"] + "'",
                 }
             }
         },
@@ -156,11 +171,11 @@ def forderungen_details(
 
     template_context = {}
     for filename in [
-        "auftrag_positionen",
-        "forderung_belege",
-        "forderung_kommentar",
-        "forderung_kopf",
-        "forderung_mahnung",
+        "auftraege_positionen",
+        "forderungen_buchungen",
+        "forderungen_kommentare",
+        "forderungen_details",
+        "forderungen_mahnungen",
         "versicherungen",
     ]:
         query = templates.TemplateResponse(request, f"forderungen/details/queries/{filename}.sql", context).body.decode(
@@ -174,39 +189,52 @@ def forderungen_details(
         "betrag": "120,00",
         "faelligkeit": "23.12.1983",
     }
-    fileserver = "C:\\Projekte\\Reisacher-Fileserver"
-    files = [f.relative_to(fileserver) for f in Path(f"{fileserver}\\{client_db}\\{document_no}").glob("*")]
-    template_context["files"] = files
-    template_context["add7days"] = datetime.now() + timedelta(days=7)
-
-    return templates.TemplateResponse(request, "forderungen/details/details.html", template_context)
+    template_context["files"] = get_files(pkey)
+    template_context["add7days"] = (datetime.now() + timedelta(days=7)).strftime("%Y-%m-%d")
+    return template_context
 
 
-@router.post("/app/forderungen/details/{client_db}_{document_no}", response_class=HTMLResponse)
+@router.post("/app/forderungen/details/{primary_key}", response_class=HTMLResponse)
 async def post_forderungen_details(
-    request: Request, client_db: str, document_no: str, db: Session = Depends(get_session)
+    request: Request,
+    primary_key: str,
+    source: Annotated[str, Form()],
+    redirect: Annotated[str, Form()],
+    db: Session = Depends(get_session),
 ):
-    data = {
-        "Client_DB": client_db,
-        "Beleg_Nr": document_no,
-        "Bearbeitet": "J",
-        "Versicherung": "N",
-        "Rechtsanwalt": "N",
-        "Reklamation": "N",
-        "Mahnen_aussetzen": "N",
-        "Selbstbeteiligung": "",
-        "Selbstbeteiligung_Betrag": "0.0",
-        "Mwst": "",
-        "Mwst_Betrag": "0.0",
-        "Wiedervorlage": "",
-        "Vers_Adresse_ID": "",
-        "Versicherung_Typ": "",
-        "Reklamation_Begruendung": "",
-        "Rechtsanwalt_Begruendung": "",
-        "Rechtsanwalt_Aktenzeichen": "",
-        "Rechtsanwalt_Stand": "",
-        "Mahnen_Begruendung": "",
-    }
+    pkey = convert_primary_key("forderungen", primary_key)
+
+    if source == "comments":
+        data = {
+            "Client_DB": "",
+            "Beleg_Nr": "",
+            "Timestamp": datetime.now().strftime("%Y-%m-%dT%H:%M:%S"),
+            "Benutzer_ID": "winter",
+            "Kommentar": "",
+        }
+    else:
+        data = {
+            "Client_DB": "",
+            "Beleg_Nr": "",
+            "Bearbeitet": "J",
+            "Versicherung": "N",
+            "Rechtsanwalt": "N",
+            "Reklamation": "N",
+            "Mahnen_aussetzen": "N",
+            "Selbstbeteiligung": "",
+            "Selbstbeteiligung_Betrag": "0.0",
+            "Mwst": "",
+            "Mwst_Betrag": "0.0",
+            "Wiedervorlage": "",
+            "Vers_Adresse_ID": "",
+            "Versicherung_Typ": "",
+            "Reklamation_Begruendung": "",
+            "Rechtsanwalt_Begruendung": "",
+            "Rechtsanwalt_Aktenzeichen": "",
+            "Rechtsanwalt_Stand": "",
+            "Mahnen_Begruendung": "",
+        }
+    data.update(pkey)
 
     async with request.form() as form:
         for k, v in form.items():
@@ -216,14 +244,29 @@ async def post_forderungen_details(
                 if re.match(r"\d+,?\d*", v):
                     v = v.replace(",", ".")
                 data[k] = v
+
     query = templates.TemplateResponse(
-        request, "forderungen/details/queries/post/update_details.sql", context={"data": data}
+        request, f"forderungen/details/queries/post/post_{source}.sql", context={"data": data}
     ).body.decode("utf-8")
     print(query)
     for subquery in query.split(";"):
         q = db.execute(text(subquery))
         print(q.rowcount)
     db.commit()
+    template_context = get_template_context(request, pkey, db)
+
+    if redirect:
+        return RedirectResponse(url=redirect, status_code=302)
+    if source == "comments":
+        return templates.TemplateResponse(request, "base/chat_container.html", template_context)
+    return templates.TemplateResponse(request, "forderungen/details/details_formular.html", template_context)
+
+
+def convert_primary_key(area: str, primary_key: str) -> dict[str, str]:
+    if area == "forderungen":
+        pkey = ["Client_DB", "Beleg_Nr"]
+    pkey_values = primary_key.split("_")
+    return dict(zip(pkey, pkey_values))
 
 
 @router.get("/app/forderungen/dashboard", response_class=HTMLResponse)
@@ -232,12 +275,6 @@ def forderungen_dashboard(request: Request, db: Session = Depends(get_session)):
     return templates.TemplateResponse(request, "forderungen/dashboard/dashboard.html", context)
 
 
-@router.get("/chat", response_class=HTMLResponse)
-def chat(request: Request):
-    # q = db.query(Forderung).order_by(Forderung.faelligkeit.asc()).limit(limit).all()
-    return templates.TemplateResponse(request, "base/chat.html")
-
-
 @router.get("/export/csv")
 def export_csv(db: Session = Depends(get_session)):
     q = db.query(Forderung).all()
@@ -289,25 +326,6 @@ def export_xlsx(db: Session = Depends(get_session)):
     )
 
 
-@router.get("/detail/{id}", response_class=HTMLResponse)
-def detail(request: Request, id: int, db: Session = Depends(get_session)):
-    f = db.query(Forderung).filter(Forderung.id == id).first()
-    if not f:
-        raise HTTPException(status_code=404)
-    return templates.TemplateResponse(request, "base/detail.html", {"request": request, "forderung": f})
-
-
-@router.post("/detail/{id}/bemerkung")
-def save_bemerkung(id: int, data: BemerkungIn, request: Request, db: Session = Depends(get_session)):
-    user = request.cookies.get("user") or "anonymous"
-    b = Bemerkung(
-        forderung_id=id, benutzer=user, bemerkung=data.bemerkung, wiedervorlage_datum=data.wiedervorlage_datum
-    )
-    db.add(b)
-    db.commit()
-    return RedirectResponse(url=f"/detail/{id}", status_code=302)
-
-
 @router.get("/detail/{id}/export/docx")
 def export_docx(id: int, db: Session = Depends(get_session)):
     f = db.query(Forderung).filter(Forderung.id == id).first()
@@ -328,6 +346,7 @@ def export_docx(id: int, db: Session = Depends(get_session)):
     )
 
 
+# TODO
 @router.get("/app/forderungen/export/{client_db}_{document_no}/")
 def export_docx2(request: Request, client_db: str, document_no: str, db: Session = Depends(get_session)):
     context = {
@@ -370,8 +389,6 @@ def export_docx2(request: Request, client_db: str, document_no: str, db: Session
 
 
 @router.get("/files/")
-def get_files(request: Request):
-    name = request.query_params.get("name")
-    filename = Path(f"C:\\Projekte\\Reisacher-Fileserver\\{unquote(name)}")
-
+def get_files2(request: Request):
+    filename = get_file(request.query_params.get("name"))
     return FileResponse(filename, media_type="application/octet-stream", filename=filename.name)

+ 1 - 1
pyproject.toml

@@ -1,7 +1,7 @@
 [project]
 name = "gcepic"
 version = "0.2.0"
-description = "GlobalCube Enterprise Planning, Information & Controlling"
+description = "GlobalCube Enterprise Processing, Information & Controlling"
 readme = "README.md"
 requires-python = ">=3.13"
 dependencies = [

+ 128 - 78
static/assets/css/main.css

@@ -1,3 +1,12 @@
+.inter-gc {
+    font-family: "Inter", sans-serif;
+    font-optical-sizing: auto;
+    font-weight: 400;
+    font-style: normal;
+}
+
+
+
 :root {
     --primary: #5468FF;
     --primary-light: #8590FF;
@@ -463,6 +472,10 @@ body {
     margin-bottom: 12px;
 }
 
+.toolbar form {
+    width: 100%;
+}
+
 .tool-button {
     background: none;
     border: none;
@@ -503,6 +516,7 @@ body {
     resize: none;
     transition: var(--transition);
     height: 50px;
+    width: 80%;
     outline: none;
 }
 
@@ -786,7 +800,13 @@ body {
 
 
 @media (min-width: 1400px) {
-    .container, .container-lg, .container-md, .container-sm, .container-xl, .container-xxl {
+
+    .container,
+    .container-lg,
+    .container-md,
+    .container-sm,
+    .container-xl,
+    .container-xxl {
         max-width: 1750px;
     }
 }
@@ -809,80 +829,110 @@ a {
 }
 
 .footer {
-        --cui-footer-bg: #B1BCC7;
-}
-
-.table thead {
-  position: sticky;
-  top: 40px;
-  background: white;
-}
-
-
-      .chat-input {
-            padding: 15px 20px;
-            border-top: 1px solid var(--border);
-            display: flex;
-            align-items: center;
-            background-color: white;
-            position: relative;
-            z-index: 10;
-        }
-
-        .input-container {
-            flex: 1;
-            display: flex;
-            align-items: center;
-            background-color: var(--secondary);
-            border-radius: 20px;
-            padding: 0 15px;
-            position: relative;
-        }
-
-        .input-container input {
-            flex: 1;
-            border: none;
-            outline: none;
-            height: 40px;
-            background-color: transparent;
-            padding: 0 10px;
-            font-size: 15px;
-        }
-
-        .input-actions {
-            display: flex;
-            gap: 10px;
-        }
-
-        .input-btn {
-            background: none;
-            border: none;
-            color: #888;
-            cursor: pointer;
-            transition: var(--transition);
-            font-size: 18px;
-        }
-
-        .input-btn:hover {
-            color: var(--primary);
-        }
-
-        .send-btn {
-            background-color: var(--primary);
-            color: white;
-            width: 40px;
-            height: 40px;
-            border-radius: 50%;
-            border: none;
-            cursor: pointer;
-            margin-left: 10px;
-            transition: var(--transition);
-            display: flex;
-            align-items: center;
-            justify-content: center;
-        }
-
-        .send-btn:hover {
-            background-color: var(--primary-light);
-            transform: scale(1.05);
-        }
+    --cui-footer-bg: #B1BCC7;
+}
+
+.table thead
+{
+    position: sticky;
+    top: 40px;
+    background: white;
+}
+
+
+.chat-input {
+    padding: 15px 20px;
+    border-top: 1px solid var(--border);
+    display: flex;
+    align-items: center;
+    background-color: white;
+    position: relative;
+    z-index: 10;
+}
+
+.input-container {
+    flex: 1;
+    display: flex;
+    align-items: center;
+    background-color: var(--secondary);
+    border-radius: 20px;
+    padding: 0 15px;
+    position: relative;
+}
+
+.input-container input {
+    flex: 1;
+    border: none;
+    outline: none;
+    height: 40px;
+    background-color: transparent;
+    padding: 0 10px;
+    font-size: 15px;
+}
+
+.input-actions {
+    display: flex;
+    gap: 10px;
+}
+
+.input-btn {
+    background: none;
+    border: none;
+    color: #888;
+    cursor: pointer;
+    transition: var(--transition);
+    font-size: 18px;
+}
+
+.input-btn:hover {
+    color: var(--primary);
+}
+
+.send-btn {
+    background-color: var(--primary);
+    color: white;
+    width: 40px;
+    height: 40px;
+    border-radius: 50%;
+    border: none;
+    cursor: pointer;
+    margin-left: 10px;
+    transition: var(--transition);
+    display: flex;
+    align-items: center;
+    justify-content: center;
+}
+
+.send-btn:hover {
+    background-color: var(--primary-light);
+    transform: scale(1.05);
+}
+
+.modal {
+    --cui-modal-width: 80%;
+}
+
+.beleg-M1 td {
+    color: #cc8800
+}
+
+.beleg-M2 td {
+    color: #cc2200
+}
+
+.beleg-M3 td {
+    color: #882200
+}
+
+::-webkit-datetime-edit-year-field:not([aria-valuenow]),
+::-webkit-datetime-edit-month-field:not([aria-valuenow]),
+::-webkit-datetime-edit-day-field:not([aria-valuenow]) {
+    color: #eee;
+}
+
+input[type="date"]:in-range::-webkit-datetime-edit-year-field,
+input[type="date"]:in-range::-webkit-datetime-edit-month-field,
+input[type="date"]:in-range::-webkit-datetime-edit-day-field,
+input[type="date"]:in-range::-webkit-datetime-edit-text {
+    color: #eee;
+}

+ 52 - 50
static/assets/css/redesign.css

@@ -31,7 +31,7 @@
   body {
     overflow-y: auto;
     overflow-x: auto;
-    font-family: Inter, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
+    font-family: "Inter", system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
   }
   
   /* App Shell */
@@ -218,7 +218,7 @@
   /* Tabellenlinks neutral/grau */
   
   .gc-table a {
-    color: #4b5563 !important;
+    color: #008 !important;
     text-decoration: none;
     font-weight: 600;
   }
@@ -296,19 +296,19 @@
     border-color: #dbe3ee;
   }
   
-  .gc-badge-warning {
+  .gc-badge-warning, .gc-badge-1 {
     background: #f6ecd2;
     color: #8a6a1f;
     border-color: #ead9a7;
   }
   
-  .gc-badge-danger {
+  .gc-badge-danger, .gc-badge-2 {
     background: #fee2e2;
     color: #991b1b;
     border-color: #fecaca;
   }
   
-  .gc-badge-success {
+  .gc-badge-success, .gc-badge-0 {
     background: #dcfce7;
     color: #166534;
     border-color: #bbf7d0;
@@ -734,91 +734,85 @@
   }
   
   /* Aktion */
-  .gc-table th:nth-child(1),
-  .gc-table td:nth-child(1) {
+  .gc-table th:nth-child(12),
+  .gc-table td:nth-child(12) {
     width: 54px;
   }
   
   /* Filiale / Bereich */
-  .gc-table th:nth-child(2),
-  .gc-table td:nth-child(2) {
+  .gc-table th:nth-child(1),
+  .gc-table td:nth-child(1) {
     width: 115px;
     max-width: 115px;
     white-space: normal !important;
   }
   
-  /* Kunde */
-  .gc-table th:nth-child(3),
-  .gc-table td:nth-child(3) {
-    width: 230px;
-    min-width: 230px;
-    padding-left: 8px !important;
-  }
-  
   /* Verursacher */
-  .gc-table th:nth-child(4),
-  .gc-table td:nth-child(4) {
+  .gc-table th:nth-child(2),
+  .gc-table td:nth-child(2) {
     width: 145px;
     min-width: 145px;
     padding-left: 6px !important;
   }
   
   /* RG-Nr. */
-  .gc-table th:nth-child(5),
-  .gc-table td:nth-child(5) {
+  .gc-table th:nth-child(3),
+  .gc-table td:nth-child(3) {
     width: 118px;
   }
   
   /* RG-Datum / Fällig */
-  .gc-table th:nth-child(6),
-  .gc-table td:nth-child(6) {
+  .gc-table th:nth-child(4),
+  .gc-table td:nth-child(4) {
     width: 120px;
   }
   
-  /* RG-Betrag */
-  .gc-table th:nth-child(7),
-  .gc-table td:nth-child(7) {
-    width: 105px;
-  }
-  
+  /* Kunde */
+  .gc-table th:nth-child(5),
+  .gc-table td:nth-child(5) {
+    width: 230px;
+    min-width: 230px;
+    padding-left: 8px !important;
+  }  
+
   /* offen / Kunde ges. */
-  .gc-table th:nth-child(8),
-  .gc-table td:nth-child(8) {
+  .gc-table th:nth-child(6),
+  .gc-table td:nth-child(6) {
     width: 155px;
   }
   
   /* Mahnstufe / Staffel */
-  .gc-table th:nth-child(9),
-  .gc-table td:nth-child(9) {
+  .gc-table th:nth-child(7),
+  .gc-table td:nth-child(7) {
     width: 125px;
   }
   
   /* Abw. */
-  .gc-table th:nth-child(10),
-  .gc-table td:nth-child(10) {
+  .gc-table th:nth-child(8),
+  .gc-table td:nth-child(8) {
     width: 80px;
   }
   
   /* Kommentar Fibu */
-  .gc-table th:nth-child(11),
-  .gc-table td:nth-child(11) {
+  .gc-table th:nth-child(9),
+  .gc-table td:nth-child(9) {
     width: 165px;
   }
   
   /* Kommentar Abteilung */
-  .gc-table th:nth-child(12),
-  .gc-table td:nth-child(12) {
+  .gc-table th:nth-child(10),
+  .gc-table td:nth-child(10) {
     width: 165px;
   }
   
   /* Wiedervorlage */
-  .gc-table th:nth-child(13),
-  .gc-table td:nth-child(13) {
+  .gc-table th:nth-child(11),
+  .gc-table td:nth-child(11) {
     width: 120px;
   }
   
   /* Abw. wieder im alten Gelb */
-  .gc-table td:nth-child(10) .gc-badge-warning {
+  .gc-table td:nth-child(8) .gc-badge-warning {
     background: #fef3c7 !important;
     color: #92400e !important;
     border-color: #fde68a !important;
@@ -828,9 +822,9 @@
    EDIT BUTTON LINKS HELLER
 ========================================================= */
 
-.gc-table td:first-child button,
-.gc-table td:first-child .btn,
-.gc-table td:first-child a {
+.gc-table td:nth-child(12) button,
+.gc-table td:nth-child(12) .btn,
+.gc-table td:nth-child(12) a {
   width: 34px;
   height: 34px;
   border-radius: 12px !important;
@@ -852,9 +846,9 @@
 }
 
 /* Hover */
-.gc-table td:first-child button:hover,
-.gc-table td:first-child .btn:hover,
-.gc-table td:first-child a:hover {
+.gc-table td:nth-child(12) button:hover,
+.gc-table td:nth-child(12) .btn:hover,
+.gc-table td:nth-child(12) a:hover {
   background: linear-gradient(
     180deg,
     #a8b9c9 0%,
@@ -865,8 +859,8 @@
 }
 
 /* Icon */
-.gc-table td:first-child i,
-.gc-table td:first-child svg {
+.gc-table td:nth-child(12) i,
+.gc-table td:nth-child(12) svg {
   color: #ffffff !important;
   font-size: .9rem;
 }
@@ -1069,6 +1063,10 @@
   transform: translateY(-1px);
 }
 
+.btn-warning {
+  background-color: #e80;
+}
+
 /* =========================================================
    DETAILSEITE: SEITE BEI AUFGEKLAPPTEN BOXEN SCROLLBAR
 ========================================================= */
@@ -1178,4 +1176,8 @@ body {
 
 .gc-detail-main .accordion-body::-webkit-scrollbar-thumb:hover {
   background: #94a3b8;
+}
+
+.gc-link {
+  color: #008;
 }

BIN
static/assets/pdf/invoice.pdf


+ 6 - 2
templates/base/base.html

@@ -18,6 +18,10 @@
   <script src="https://cdn.jsdelivr.net/npm/@coreui/icons@3.0.1/dist/cjs/index.min.js"></script>
   <script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.8/dist/umd/popper.min.js"></script>
 
+  <link rel="preconnect" href="https://fonts.googleapis.com">
+  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
+  <link href="https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&display=swap" rel="stylesheet">
+
   <link href="/static/assets/css/main.css" rel="stylesheet">
   <link href="/static/assets/css/redesign.css" rel="stylesheet">
 
@@ -25,7 +29,7 @@
   <link rel="icon" href="/static/assets/images/favicon.ico" type="image/x-icon">
 </head>
 
-<body class="container py-3" hx-boost="true">
+<body class="container" hx-boost="true">
   <!--<nav class="navbar navbar-expand-lg bg-primary">
     <div class="container-fluid">
         <a class="navbar-brand" href="#">Navbar</a>
@@ -165,7 +169,7 @@
           {% endfor %}
         </div>
         <div class="col-sm-3 text-end">
-          Gesamt: <strong>{{ summary.offen|number_format }}</strong>
+          Gesamt: <strong>{{ summary.Beleg_offen|number_format }}</strong>
         </div>
       </div>
     </div>

+ 28 - 14
templates/base/chat_container.html

@@ -1,4 +1,4 @@
-<div class="chat-container">
+<div class="chat-container" id="chat">
     <div class="header">
         <div class="header-left">
             <div class="avatar" style="background-color: #5468FF;">
@@ -10,7 +10,7 @@
                 </svg>
             </div>
             <div class="course-info">
-                <div class="course-title">{{ forderung_kopf[0].Kunde }} / {{ forderung_kopf[0].Document_No }}</div>
+                <div class="course-title">{{ forderungen_details[0].Kunde_Text }} / {{ forderungen_details[0].Beleg_Nr }}</div>
                 <div class="course-participants">4 Mitarbeiter involviert</div>
             </div>
         </div>
@@ -49,7 +49,7 @@
     <div class="chat-content" id="chatContent">
         <div class="date-divider">
             <div class="divider-line"></div>
-            <div class="divider-text">{{ forderung_kopf[0].Invoice_Date|date_format }}</div>
+            <div class="divider-text">{{ forderungen_details[0].Beleg_Datum|date_format }}</div>
             <div class="divider-line"></div>
         </div>
         <!--
@@ -96,7 +96,7 @@
                 AZ 3120/24 HP Schaden Rep RE kann nicht eingereicht werden. ESW Zusatzprodukte fehlen
             </div>
         </div>-->
-        {% for row in forderung_kommentar %}
+        {% for row in forderungen_kommentare %}
         <div class="message teacher {{ row.Rolle }}">
             <div class="message-header">
                 <div class="avatar">{{ row.Benutzer_ID }}</div>
@@ -108,6 +108,11 @@
             </div>
         </div>
         {% endfor %}
+
+        <div id="chat-end">
+            &nbsp;
+        </div>
+
         <!--
         <div class="message student">
             <div class="message-header">
@@ -415,15 +420,17 @@
     </div>
     <div class="input-area">
         <div class="toolbar">
-            
-            <button class="btn btn-primary">
-                <i class="icon icon-lg cil-paperclip"></i>
-            </button>
-            <input type="text" class="message-input" id="comment" name="comment" placeholder="Kommentieren ..." autofocus="autofocus"></textarea>
-            <button class="btn btn-primary">
-                <i class="icon icon-lg cil-chevron-right"></i>
-            </button>
-
+            <form>
+                <button class="btn btn-primary">
+                    <i class="icon icon-lg cil-paperclip"></i>
+                </button>
+                <input type="hidden" name="source" value="comments" />
+                <input type="text" class="message-input" id="comment" name="Kommentar" placeholder="Kommentieren ..."
+                    autofocus="autofocus" />
+                <button class="btn btn-primary" hx-post="" hx-trigger="click" hx-swap="outerHTML" hx-target="#chat" hx-push-url="false">
+                    <i class="icon icon-lg cil-chevron-right"></i>
+                </button>
+            </form>
 
 
 
@@ -461,4 +468,11 @@
             </div>
         </div>
     </div>
-</div>
+</div>
+
+<script>
+    window.setTimeout(function() {
+        let element = document.getElementById("chat-end");
+        element.scrollIntoView({ behavior: "smooth", block: "end" });
+    }, 1000);
+</script>

+ 22 - 0
templates/base/liste.html

@@ -61,4 +61,26 @@ Klassen:
   </table>
 </div>
 
+<!-- Modal -->
+<div class="modal fade" id="exampleModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
+  <div class="modal-dialog">
+    <div class="modal-content">
+      <div class="modal-header">
+        <h5 class="modal-title" id="exampleModalLabel">Invoice</h5>
+        <button type="button" class="btn-close" data-coreui-dismiss="modal" aria-label="Close"></button>
+      </div>
+      <div class="modal-body">
+        <iframe src="/static/assets/pdf/invoice.pdf" style="width: 100%; height: 800px;" frameborder="0">
+          Ihr Browser kann leider keine eingebetteten Frames anzeigen.
+        </iframe>
+      </div>
+      <!--
+      <div class="modal-footer">
+        <button type="button" class="btn btn-secondary" data-coreui-dismiss="modal">Schließen</button>
+      </div>
+      -->
+    </div>
+  </div>
+</div>
+
 {% endblock %}

+ 1 - 0
templates/forderungen/config/primary_key.txt

@@ -0,0 +1 @@
+Client_DB;Beleg_Nr

+ 26 - 35
templates/forderungen/details/details.html

@@ -2,65 +2,56 @@
 {% block content %}
 
 <br>
-<h2>{{forderung_kopf[0].Beleg }}</h2>
+<h2>{{ forderungen_details[0].Beleg_Text }}</h2>
 <br>
+<div class="col-1">
+<button class="btn btn-warning" hx-get="{{ request.headers.referer }}" hx-trigger="click" hx-push-url="true"
+  hx-swap="innerHTML" hx-target="body">Zurück</button>
+</div>
 
 <div class="row g-3">
 
-<div class="col-3">
+  <div class="col-3">
 
-  {%include 'forderungen/details/details_uebersicht.html' %}
+    {%include 'forderungen/details/details_uebersicht.html' %}
 
-</div>
+  </div>
 
 
-<div class="col-5">
+  <div class="col-5">
 
-  {%include 'base/chat_container.html' %}
+    {%include 'base/chat_container.html' %}
 
-  <br>
-  <br>
+    <br>
+    <br>
 
-  <h3>Dateien</h3>
+    <h3>Dateien</h3>
 
-  {%include 'forderungen/details/details_dateien.html' %}
+    {%include 'forderungen/details/details_dateien.html' %}
 
-</div>
+  </div>
 
-<div class="col-4">
+  <div class="col-4">
 
-{%include 'forderungen/details/details_formular.html' %}
+    {%include 'forderungen/details/details_formular.html' %}
 
-<br>
-<br>
+    <br>
+    <br>
 
-<h3>Auftragspositionen</h3>
+    <h3>Auftragspositionen</h3>
 
-{%include 'forderungen/details/details_positionen.html' %}
+    {%include 'forderungen/details/details_positionen.html' %}
 
+  </div>
 </div>
-</div>
-<br>
-<br>
 
-{%include 'forderungen/details/details_kommentare.html' %}
-
-<br>
 <br>
 
-
-<h3>Mahnungen</h3>
-
-{%include 'forderungen/details/details_mahnungen.html' %}
-
-<br>
-<br>
-
-
 <h3>Buchungsbelege</h3>
+<p class="lead">
+  Debitorenkonto {{ forderungen_details[0].Kunde_Nr }} - {{ forderungen_details[0].Kunde_Name }}
+</p>
 
-        {%include 'forderungen/details/details_buchungen.html' %}
-
-
+{%include 'forderungen/details/details_buchungen.html' %}
 
 {% endblock %}

+ 11 - 9
templates/forderungen/details/details_buchungen.html

@@ -1,6 +1,6 @@
 <div class="tabs">
     <div class="tab">Diese Rechnung</div>
-    <div class="tab">Alle offenen Rechnungen</div>
+    <div class="tab">Alle offenen Belege</div>
     <div class="tab">Dieses Fahrzeug</div>
     <div class="tab active">Debitor Historie</div>
 </div>
@@ -9,24 +9,26 @@
     <thead>
         <tr>
             <th>Fahrzeug</th>
-            <th>Rechnungsnr.</th>
-            <th>Rechnungsdatum</th>
+            <th>Belegart</th>
+            <th>Belegnr.</th>
+            <th>Belegdatum</th>
             <th>Beschreibung</th>
-            <th>Betrag</th>
-            <th>Offen</th>
             <th>Benutzer</th>
+            <th>Betrag</th>
+            <th>Bezahlt</th>
         </tr>
     </thead>
     <tbody>
-        {% for row in forderung_belege %}
-        <tr>
+        {% for row in forderungen_buchungen %}
+        <tr class="beleg-{{ row.Beleg_Art }}">
             <td>{{ row.Fahrzeug_Nr }}</td>
+            <td>{{ row.Beleg_Art }}</td>
             <td>{{ row.Beleg_Nr }}</td>
             <td>{{ row.Beleg_Datum|date_format }}</td>
             <td>{{ row.Beleg_Beschreibung }}</td>
-            <td class="text-end">{{ row.Betrag|number_format }}</td>
-            <td>{{ row.Status }}</td>
             <td>{{ row.Benutzer }}</td>
+            <td class="text-end">{{ row.Betrag|number_format }}</td>
+            <td>{{ row.Bezahlt }}</td>
         </tr>
         {% endfor %}
     </tbody>

+ 61 - 45
templates/forderungen/details/details_formular.html

@@ -1,15 +1,19 @@
-<form class="row g-3">
+{% set row = forderungen_details[0] %}
+
+<form class="row g-3" id="formular">
+  <input type="hidden" name="source" value="details" />
   <div class="col-12">
     <div class="form-check" data-coreui-toggle="collapse" data-coreui-target="#VersicherungCollapse"
-      aria-expanded="{{ forderung_kopf[0].Versicherung|truefalse }}" aria-controls="VersicherungCollapse">
-      <input class="form-check-input" type="checkbox" name="Versicherung" id="Versicherung" {{ forderung_kopf[0].Versicherung|checked }}>
+      aria-expanded="{{ row.Versicherung|truefalse }}" aria-controls="VersicherungCollapse">
+      <input class="form-check-input" type="checkbox" name="Versicherung" id="Versicherung" {{
+        row.Versicherung|checked }}>
       <label class="form-check-label" for="Versicherung">
         <strong>Versicherungsfall</strong>
       </label>
     </div>
   </div>
 
-  <div class="collapse {{ forderung_kopf[0].Versicherung|show }}" id="VersicherungCollapse">
+  <div class="collapse {{ row.Versicherung|show }}" id="VersicherungCollapse">
     <div class="card card-body">
       <div class="row mb-3">
         <label for="Versicherung_Name" class="col-sm-3 col-form-label">Versicherung</label>
@@ -17,7 +21,7 @@
           <select id="Versicherung_Name" name="Vers_Adresse_ID" class="form-select">
             <option value="" selected>-</option>
             {% for v in versicherungen %}
-            {% if v.Vers_Adresse_ID == forderung_kopf[0].Vers_Adresse_ID %}
+            {% if v.Vers_Adresse_ID == row.Vers_Adresse_ID %}
             <option value="{{ v.Vers_Adresse_ID }}" selected>{{ v.Vers_Name }}</option>
             {% else %}
             <option value="{{ v.Vers_Adresse_ID }}">{{ v.Vers_Name }}</option>
@@ -29,7 +33,7 @@
           <select id="Versicherung_Typ" name="Versicherung_Typ" class="form-select">
             <option value="" selected>-</option>
             {% for v in ('Haftpflicht', 'Teilkasko', 'Vollkasko', 'Ausländisch') %}
-            {% if v == forderung_kopf[0].Versicherung_Typ %}
+            {% if v == row.Versicherung_Typ %}
             <option value="{{ v }}" selected>{{ v }}</option>
             {% else %}
             <option value="{{ v }}">{{ v }}</option>
@@ -42,46 +46,49 @@
       <div class="row mb-3">
         <label for="Versicherung_Schadennummer" class="col-sm-3 col-form-label">Schadennummer</label>
         <div class="col-sm-5">
-          <input type="text" class="form-control" id="Versicherung_Schadennummer" name="Versicherung_Schadennummer" value="{{ forderung_kopf[0].Versicherung_Schadennummer }}">
+          <input type="text" class="form-control" id="Versicherung_Schadennummer" name="Versicherung_Schadennummer"
+            value="{{ row.Versicherung_Schadennummer }}">
         </div>
       </div>
       <div class="row mb-3">
         <label for="Selbstbeteiligung" class="col-sm-3 col-form-label">Selbstbeteiligung</label>
         <div class="col-sm-3">
           <select id="Selbstbeteiligung" name="Selbstbeteiligung" class="form-select">
-            <option value="" {{ (forderung_kopf[0].Selbstbeteiligung=="" )|selected }}>-</option>
-            <option {{ (forderung_kopf[0].Selbstbeteiligung=="Versicherung" )|selected }}>Versicherung</option>
-            <option {{ (forderung_kopf[0].Selbstbeteiligung=="Kunde" )|selected }}>Kunde</option>
-            <option {{ (forderung_kopf[0].Selbstbeteiligung=="Autohaus" )|selected }}>Autohaus</option>
+            <option value="" {{ (row.Selbstbeteiligung=="" )|selected }}>-</option>
+            <option {{ (row.Selbstbeteiligung=="Versicherung" )|selected }}>Versicherung</option>
+            <option {{ (row.Selbstbeteiligung=="Kunde" )|selected }}>Kunde</option>
+            <option {{ (row.Selbstbeteiligung=="Autohaus" )|selected }}>Autohaus</option>
           </select>
         </div>
         <div class="col-sm-3">
-          <input type="text" class="form-control" id="Selbstbeteiligung_Betrag" name="Selbstbeteiligung_Betrag" placeholder="Betrag" value="{{ forderung_kopf[0].Selbstbeteiligung_Betrag }}">
+          <input type="text" class="form-control" id="Selbstbeteiligung_Betrag" name="Selbstbeteiligung_Betrag"
+            placeholder="Betrag" value="{{ row.Selbstbeteiligung_Betrag }}">
         </div>
       </div>
       <div class="row mb-3">
         <label for="MwSt" class="col-sm-3 col-form-label">MwSt</label>
         <div class="col-sm-3">
           <select id="MwSt" name="Mwst" class="form-select">
-            <option value="" {{ (forderung_kopf[0].MwSt=="" )|selected }}>-</option>
-            <option {{ (forderung_kopf[0].Mwst=="Versicherung" )|selected }}>Versicherung</option>
-            <option {{ (forderung_kopf[0].Mwst=="Kunde" )|selected }}>Kunde</option>
-            <option {{ (forderung_kopf[0].Mwst=="Autohaus" )|selected }}>Autohaus</option>
+            <option value="" {{ (row.MwSt=="" )|selected }}>-</option>
+            <option {{ (row.Mwst=="Versicherung" )|selected }}>Versicherung</option>
+            <option {{ (row.Mwst=="Kunde" )|selected }}>Kunde</option>
+            <option {{ (row.Mwst=="Autohaus" )|selected }}>Autohaus</option>
           </select>
         </div>
         <div class="col-sm-3">
-          <input type="text" class="form-control" id="Mwst_Betrag" name="Mwst_Betrag" placeholder="Betrag" value="{{ forderung_kopf[0].Mwst_Betrag|number_format }}">
+          <input type="text" class="form-control" id="Mwst_Betrag" name="Mwst_Betrag" placeholder="Betrag"
+            value="{{ row.Mwst_Betrag|number_format }}">
         </div>
         <div class="col-sm-3">
           <a class="btn btn-primary" hx-disable="true"
-            onclick="document.getElementById('Mwst_Betrag').value='{{ forderung_kopf[0].Mwst_Betrag_berechnet|number_format }}';">
+            onclick="document.getElementById('Mwst_Betrag').value='{{ row.Mwst_Betrag_berechnet|number_format }}';">
             <i class="cil-arrow-thick-left"></i>
-            {{ forderung_kopf[0].Mwst_Betrag_berechnet|number_format }}</a>
+            {{ row.Mwst_Betrag_berechnet|number_format }}</a>
         </div>
       </div>
       <div class="col-3">
         <a class="btn btn-secondary" hx-disable="true"
-          href="/app/forderungen/export/{{forderung_kopf[0].Client_DB}}_{{forderung_kopf[0].Document_No}}">Mahnung
+          href="/app/forderungen/export/{{row.Client_DB}}_{{row.Beleg_Nr}}">Mahnung
           erstellen</a>
       </div>
 
@@ -90,20 +97,22 @@
 
   <div class="col-12">
     <div class="form-check" data-coreui-toggle="collapse" data-coreui-target="#ReklamationCollapse"
-      aria-expanded="{{ forderung_kopf[0].Reklamation|truefalse }}" aria-controls="ReklamationCollapse">
-      <input class="form-check-input" type="checkbox" id="Reklamation" name="Reklamation" {{ forderung_kopf[0].Reklamation|checked }}>
+      aria-expanded="{{ row.Reklamation|truefalse }}" aria-controls="ReklamationCollapse">
+      <input class="form-check-input" type="checkbox" id="Reklamation" name="Reklamation" {{
+        row.Reklamation|checked }}>
       <label class="form-check-label" for="Reklamation">
         <strong>Reklamation</strong>
       </label>
     </div>
   </div>
 
-  <div class="collapse {{ forderung_kopf[0].Reklamation|show }}" id="ReklamationCollapse">
+  <div class="collapse {{ row.Reklamation|show }}" id="ReklamationCollapse">
     <div class="card card-body">
       <div class="row mb-3">
         <label for="Reklamation_Begruendung" class="col-sm-3 col-form-label">Begründung</label>
         <div class="col-sm-5">
-          <input type="text" class="form-control" id="Reklamation_Begruendung" name="Reklamation_Begruendung" value="{{ forderung_kopf[0].Reklamation_Begruendung }}">
+          <input type="text" class="form-control" id="Reklamation_Begruendung" name="Reklamation_Begruendung"
+            value="{{ row.Reklamation_Begruendung }}">
         </div>
       </div>
     </div>
@@ -111,8 +120,9 @@
 
   <div class="col-12">
     <div class="form-check" data-coreui-toggle="collapse" data-coreui-target="#RechtsanwaltCollapse"
-      aria-expanded="{{ forderung_kopf[0].Rechtsanwalt|truefalse }}" aria-controls="RechtsanwaltCollapse">
-      <input class="form-check-input" type="checkbox" id="Rechtsanwalt" name="Rechtsanwalt" {{ forderung_kopf[0].Rechtsanwalt|checked }}>
+      aria-expanded="{{ row.Rechtsanwalt|truefalse }}" aria-controls="RechtsanwaltCollapse">
+      <input class="form-check-input" type="checkbox" id="Rechtsanwalt" name="Rechtsanwalt" {{
+        row.Rechtsanwalt|checked }}>
       <label class="form-check-label" for="Rechtsanwalt">
         <strong>Rechtsanwalt</strong>
       </label>
@@ -121,29 +131,32 @@
 
 
 
-  <div class="collapse {{ forderung_kopf[0].Rechtsanwalt|show }}" id="RechtsanwaltCollapse">
+  <div class="collapse {{ row.Rechtsanwalt|show }}" id="RechtsanwaltCollapse">
     <div class="card card-body">
       <div class="row mb-3">
         <label for="Rechtsanwalt_Begruendung" class="col-sm-3 col-form-label">Begründung</label>
         <div class="col-sm-5">
-          <input type="text" class="form-control" id="Rechtsanwalt_Begruendung" name="Rechtsanwalt_Begruendung" value="{{ forderung_kopf[0].Rechtsanwalt_Begruendung }}">
+          <input type="text" class="form-control" id="Rechtsanwalt_Begruendung" name="Rechtsanwalt_Begruendung"
+            value="{{ row.Rechtsanwalt_Begruendung }}">
         </div>
       </div>
       <div class="row mb-3">
         <label for="Rechtsanwalt_Aktenzeichen" class="col-sm-3 col-form-label">Aktenzeichen</label>
         <div class="col-sm-5">
-          <input type="text" class="form-control" id="Rechtsanwalt_Aktenzeichen" name="Rechtsanwalt_Aktenzeichen" value="{{ forderung_kopf[0].Rechtsanwalt_Aktenzeichen }}">
+          <input type="text" class="form-control" id="Rechtsanwalt_Aktenzeichen" name="Rechtsanwalt_Aktenzeichen"
+            value="{{ row.Rechtsanwalt_Aktenzeichen }}">
         </div>
       </div>
       <div class="row mb-3">
         <label for="Rechtsanwalt_Stand" class="col-sm-3 col-form-label">Aktueller Stand</label>
         <div class="col-sm-5">
-          <input type="text" class="form-control" id="Rechtsanwalt_Stand" name="Rechtsanwalt_Stand" value="{{ forderung_kopf[0].Rechtsanwalt_Stand }}">
+          <input type="text" class="form-control" id="Rechtsanwalt_Stand" name="Rechtsanwalt_Stand"
+            value="{{ row.Rechtsanwalt_Stand }}">
         </div>
       </div>
       <div class="col-3">
         <a class="btn btn-secondary" hx-disable="true"
-          href="/app/forderungen/export/{{forderung_kopf[0].Client_DB}}_{{forderung_kopf[0].Document_No}}">Beitreibungsauftrag</a>
+          href="/app/forderungen/export/{{row.Client_DB}}_{{row.Beleg_Nr}}">Beitreibungsauftrag</a>
       </div>
     </div>
   </div>
@@ -151,15 +164,16 @@
 
   <div class="col-12">
     <div class="form-check" data-coreui-toggle="collapse" data-coreui-target="#MahnenCollapse"
-      aria-expanded="{{ forderung_kopf[0].Mahnen_aussetzen|truefalse }}" aria-controls="MahnenCollapse">
-      <input class="form-check-input" type="checkbox" id="Mahnen" name="Mahnen_aussetzen" {{ forderung_kopf[0].Mahnen_aussetzen|checked }}>
+      aria-expanded="{{ row.Mahnen_aussetzen|truefalse }}" aria-controls="MahnenCollapse">
+      <input class="form-check-input" type="checkbox" id="Mahnen" name="Mahnen_aussetzen" {{
+        row.Mahnen_aussetzen|checked }}>
       <label class="form-check-label" for="Mahnen">
         <strong>Mahnlauf aussetzen</strong>
       </label>
     </div>
   </div>
 
-  <div class="collapse {{ forderung_kopf[0].Mahnen_aussetzen|show }}" id="MahnenCollapse">
+  <div class="collapse {{ row.Mahnen_aussetzen|show }}" id="MahnenCollapse">
     <div class="card card-body">
       <div class="row mb-3">
         <p>
@@ -169,7 +183,8 @@
         <label for="Mahnen_Begründung" class="col-sm-3 col-form-label">Begründung</label>
         <div class="col-sm-5">
 
-          <input type="text" class="form-control" id="Mahnen_Begruendung" name="Mahnen_Begruendung" value="{{ forderung_kopf[0].Mahnen_Begruendung }}">
+          <input type="text" class="form-control" id="Mahnen_Begruendung" name="Mahnen_Begruendung"
+            value="{{ row.Mahnen_Begruendung }}">
         </div>
       </div>
     </div>
@@ -179,23 +194,24 @@
   </div>
 
   <div class="col-12">
-  <div class="row mb-3">
-    <label for="Wiedervorlage" class="col-sm-3 col-form-label">Wiedervorlage</label>
-    <div class="col-sm-5">
+    <div class="row mb-3">
+      <label for="Wiedervorlage" class="col-sm-3 col-form-label">Wiedervorlage</label>
+      <div class="col-sm-5">
         <input type="date" class="form-control" id="Wiedervorlage" name="Wiedervorlage"
-      value="{{ forderung_kopf[0].Wiedervorlage.strftime("%Y-%m-%d") }}">
+          value="{{ row.Wiedervorlage.strftime("%Y-%m-%d") }}">
       </div>
       <div class="col-3">
-        <a class="btn btn-primary" 
-              onclick="document.getElementById('Wiedervorlage').value='{{ add7days.strftime("%Y-%m-%d") }}';" hx-disable="true">
-      +7 Tage
-      </a>
+        <a class="btn btn-primary" onclick="document.getElementById('Wiedervorlage').value='{{ add7days }}';" hx-disable="true">
+          +7 Tage
+        </a>
+      </div>
     </div>
   </div>
-  </div>  
 
   <div class="col-12">
-    <button class="btn btn-primary" hx-post=""    hx-trigger="click"    hx-swap="none" hx-push-url="false"  >Speichern</button>
+    <button class="btn btn-warning" hx-post="" hx-trigger="click" hx-swap="outerHTML" hx-target="#formular" hx-push-url="false">Speichern</button>
+    <button class="btn btn-warning" hx-post="" hx-trigger="click" hx-swap="innerHTML" hx-target="body" hx-push-url="true" hx-vals='{"redirect": "{{ request.headers.referer }}"}'">Speichern &amp; Zurück</button>
+    <button class="btn btn-warning" hx-get="{{ request.headers.referer }}" hx-trigger="click" hx-swap="innerHTML" hx-target="body" hx-push-url="true">Zurück</button>
   </div>
 
 

+ 1 - 1
templates/forderungen/details/details_kommentare.html

@@ -13,7 +13,7 @@
     </tr>
   </thead>
   <tbody>
-    {% for row in forderung_kommentar %}
+    {% for row in forderungen_kommentare %}
     <tr>
       <td>{{ row.Timestamp|date_format }}</td>
       <td>{{ row.Name }}</td>

+ 12 - 12
templates/forderungen/details/details_mahnungen.html

@@ -1,6 +1,6 @@
 <div class="tabs">
     <div class="tab">Diese Rechnung</div>
-    <div class="tab">Alle offenen Rechnungen</div>
+    <div class="tab">Alle offenen Belege</div>
     <div class="tab">Dieses Fahrzeug</div>
     <div class="tab active">Debitor Historie</div>
 </div>
@@ -8,27 +8,27 @@
 <table class="table table-striped table-bordered">
     <thead>
         <tr>
-            <th>Kunde_Nr</th>
-            <th>Mahnung_Nr</th>
+            <th>Fahrzeug</th>
+            <th>Mahnung Nr.</th>
             <th>Mahndatum</th>
             <th>Mahnstufe</th>
-            <th>Rechnung_Nr</th>
-            <th>Rechnung_Datum</th>
+            <th>Belegnr.</th>
+            <th>Belegdatum</th>
             <th>Betrag</th>
-            <th>Offen</th>
+            <th>Bezahlt</th>
         </tr>
     </thead>
     <tbody>
-        {% for row in forderung_mahnung %}
+        {% for row in forderungen_mahnungen %}
         <tr>
-            <td>{{ row.Kunde_Nr }}</td>
+            <td></td>
             <td>{{ row.Mahnung_Nr }}</td>
-            <td>{{ row.Mahndatum|date_format }}</td>
+            <td>{{ row.Mahnung_Datum|date_format }}</td>
             <td>{{ row.Mahnstufe }}</td>
-            <td>{{ row.Rechnung_Nr }}</td>
-            <td>{{ row.Rechnung_Datum|date_format }}</td>
+            <td>{{ row.Beleg_Nr }}</td>
+            <td>{{ row.Beleg_Datum|date_format }}</td>
             <td class="text-end">{{ row.Betrag|number_format }}</td>
-            <td class="text-end">{{ row.Offen|number_format }}</td>
+            <td>J</td>
         </tr>
         {% endfor %}
     </tbody>

+ 2 - 2
templates/forderungen/details/details_positionen.html

@@ -1,12 +1,12 @@
 <table class="table table-bordered">
     <thead>
         <tr>
-            <th>Auftrag_Position</th>
+            <th>Position</th>
             <th>Betrag</th>
         </tr>
     </thead>
     <tbody>
-        {% for row in auftrag_positionen %}
+        {% for row in auftraege_positionen %}
         <tr>
             <td>{{ row.Auftrag_Position }}</td>
             <td class="text-end">{{ row.Betrag|number_format }}</td>

+ 3 - 3
templates/forderungen/details/details_rohdaten.html

@@ -1,19 +1,19 @@
 <table class="table table-striped table-bordered">
     <div>
         <!--
-          {% for row in forderung_kopf %}
+          {% for row in forderungen_details %}
 
             {% for key, value in row._asdict().items() %}
             <tr>
               <td><strong>{{ key }}:</strong></td>
-              <td>{{ '{{' }}forderung_kopf[0].{{ key }} {{ '}}' }}</td>
+              <td>{{ '{{' }}forderungen_details[0].{{ key }} {{ '}}' }}</td>
             </tr>
             {% endfor %}
             {% endfor %}
           -->
     </div>
     <tbody>
-        {% for row in forderung_kopf %}
+        {% for row in forderungen_details %}
 
         {% for key, value in row._asdict().items() %}
         <tr>

+ 56 - 55
templates/forderungen/details/details_uebersicht.html

@@ -1,3 +1,4 @@
+{% set row = forderungen_details[0] %}
 
 <div class="row mb-3">
   <div>
@@ -7,26 +8,26 @@
       </tr>
       <tr>
         <td><strong>Hauptbetrieb:</strong></td>
-        <td>{{forderung_kopf[0].Hauptbetrieb_Name }}</td>
+        <td>{{row.Hauptbetrieb_Name }}</td>
       </tr>
 
       <tr>
         <td><strong>Standort:</strong></td>
-        <td>{{forderung_kopf[0].Standort_Name }}</td>
+        <td>{{row.Standort_Name }}</td>
       </tr>
       <tr>
         <td><strong>Benutzer:</strong></td>
-        <td>{{forderung_kopf[0].User_ID }}</td>
+        <td>{{row.Benutzer_ID }}</td>
       </tr>
 
       <tr>
         <td><strong>Verursacher:</strong></td>
-        <td>{{forderung_kopf[0].Verursacher }}</td>
+        <td>{{row.Verursacher_Text }}</td>
       </tr>
 
       <tr>
-        <td><strong>Bereich:</strong></td>
-        <td>{{forderung_kopf[0].Bereich }}</td>
+        <td><strong>Abteilung:</strong></td>
+        <td>{{row.Abteilung }}</td>
       </tr>
 
     </table>
@@ -38,27 +39,27 @@
       </tr>
       <tr>
         <td><strong>Belegart:</strong></td>
-        <td>{{forderung_kopf[0].Rechnung_Gutschrift }}</td>
+        <td>{{row.Rechnung_Gutschrift }}</td>
       </tr>
       <tr>
         <td><strong>Beleg-Nr:</strong></td>
-        <td>{{forderung_kopf[0].Document_No }}</td>
+        <td>{{row.Beleg_Nr }}</td>
       </tr>
       <tr>
         <td><strong>Betrag:</strong></td>
-        <td>{{forderung_kopf[0].offen|number_format }} &euro;</td>
+        <td>{{row.Beleg_offen|number_format }} &euro;</td>
       </tr>
       <tr>
         <td><strong>Rechnungsdatum:</strong></td>
-        <td>{{forderung_kopf[0].Invoice_Date|date_format }}</td>
+        <td>{{row.Beleg_Datum|date_format }}</td>
       </tr>            
       <tr>
         <td><strong>Lieferdatum:</strong></td>
-        <td>{{forderung_kopf[0].Invoice_Date|date_format }}</td>
+        <td>{{row.Beleg_Datum|date_format }}</td>
       </tr>
       <tr>
         <td><strong>Fälligkeitsdatum:</strong></td>
-        <td>{{forderung_kopf[0].Invoice_Date|date_format }}</td>
+        <td>{{row.Beleg_Datum|date_format }}</td>
       </tr>
 
 
@@ -72,27 +73,27 @@
       </tr>
       <tr>
         <td><strong>offen:</strong></td>
-        <td>{{forderung_kopf[0].offen|number_format }} &euro;</td>
+        <td>{{row.Beleg_offen|number_format }} &euro;</td>
       </tr>
 
       <tr>
         <td><strong>offen (Kunde gesamt):</strong></td>
-        <td>{{forderung_kopf[0].offen_Kunde_gesamt|number_format }} &euro;</td>
+        <td>{{row.Kunde_offen_gesamt|number_format }} &euro;</td>
       </tr>
 
       <tr>
         <td><strong>Tage:</strong></td>
-        <td>{{forderung_kopf[0].Tage }}</td>
+        <td>{{row.Beleg_Tage_offen }}</td>
       </tr>
 
       <tr>
         <td><strong>Staffel:</strong></td>
-        <td>{{forderung_kopf[0].Staffel }}</td>
+        <td>{{row.Staffel_Text }}</td>
       </tr>
 
       <tr>
         <td><strong>Mahnstufe:</strong></td>
-        <td>{{forderung_kopf[0].Mahnstufe }}</td>
+        <td>{{row.Mahnstufe }}</td>
       </tr>
     </table>
   </div>
@@ -106,52 +107,52 @@
 
       <tr>
         <td><strong>Kunden-Nr:</strong></td>
-        <td>{{forderung_kopf[0].Kunde_Nr }}</td>
+        <td>{{row.Kunde_Nr }}</td>
       </tr>
 
       <tr>
         <td><strong>Name:</strong></td>
-        <td>{{forderung_kopf[0].Kunde_Name }}</td>
+        <td>{{row.Kunde_Name }}</td>
       </tr>
 
       <tr>
         <td><strong>Adresse:</strong></td>
-        <td>{{forderung_kopf[0].Kunde_Adresse }}</td>
+        <td>{{row.Kunde_Adresse }}</td>
       </tr>
 
       <tr>
         <td><strong>PLZ / Ort:</strong></td>
-        <td>{{forderung_kopf[0].Kunde_PLZ }} {{forderung_kopf[0].Kunde_Ort }}</td>
+        <td>{{row.Kunde_PLZ }} {{row.Kunde_Ort }}</td>
       </tr>
 
       <tr>
         <td><strong>Land:</strong></td>
-        <td>{{forderung_kopf[0].Kunde_Land }}</td>
+        <td>{{row.Kunde_Land }}</td>
       </tr>
 
       <tr>
         <td><strong>Telefon:</strong></td>
-        <td>{{forderung_kopf[0].Kunde_Telefon }}</td>
+        <td>{{row.Kunde_Telefon }}</td>
       </tr>
 
       <tr>
         <td><strong>E-Mail:</strong></td>
-        <td><a href="mailto:{{forderung_kopf[0].Kunde_Email }}?subject={{forderung_kopf[0].Document_No }}" hx-disable="true">{{forderung_kopf[0].Kunde_Email }}</a></td>
+        <td><a href="mailto:{{row.Kunde_Email }}?subject={{row.Beleg_Nr }}" hx-disable="true">{{row.Kunde_Email }}</a></td>
       </tr>
 
       <tr>
         <td><strong>Payment_Terms_Code:</strong></td>
-        <td>{{forderung_kopf[0].Payment_Terms_Code }}</td>
+        <td>{{row.Payment_Terms_Code }}</td>
       </tr>
 
       <tr>
         <td><strong>Kundengruppe:</strong></td>
-        <td>{{forderung_kopf[0].Customer_Group_Description }}</td>
+        <td>{{row.Customer_Group_Description }}</td>
       </tr>
 
     </table>
   </div>
-{% if forderung_kopf[0].Fahrzeug_Leasing == 'J' %}
+{% if row.Fahrzeug_Leasing == 'J' %}
 <div>
     <table class="table table-sm">
       <tr>
@@ -160,44 +161,44 @@
 
       <tr>
         <td><strong>Kunden-Nr:</strong></td>
-        <td>{{forderung_kopf[0].Leasing_Kunde_Nr }}</td>
+        <td>{{row.Leasing_Kunde_Nr }}</td>
       </tr>
 
       <tr>
         <td><strong>Name:</strong></td>
-        <td>{{forderung_kopf[0].Leasing_Kunde_Name }}</td>
+        <td>{{row.Leasing_Kunde_Name }}</td>
       </tr>
 
       <tr>
         <td><strong>Adresse:</strong></td>
-        <td>{{forderung_kopf[0].Leasing_Kunde_Adresse }}</td>
+        <td>{{row.Leasing_Kunde_Adresse }}</td>
       </tr>
 
       <tr>
         <td><strong>PLZ / Ort:</strong></td>
-        <td>{{forderung_kopf[0].Leasing_Kunde_PLZ }} {{forderung_kopf[0].Leasing_Kunde_Ort }}</td>
+        <td>{{row.Leasing_Kunde_PLZ }} {{row.Leasing_Kunde_Ort }}</td>
       </tr>
 
       <tr>
         <td><strong>Land:</strong></td>
-        <td>{{forderung_kopf[0].Leasing_Kunde_Land }}</td>
+        <td>{{row.Leasing_Kunde_Land }}</td>
       </tr>
 
       <tr>
         <td><strong>Telefon:</strong></td>
-        <td>{{forderung_kopf[0].Leasing_Kunde_Telefon }}</td>
+        <td>{{row.Leasing_Kunde_Telefon }}</td>
       </tr>
 
       <tr>
         <td><strong>E-Mail:</strong></td>
-        <td><a href="mailto:{{forderung_kopf[0].Leasing_Kunde_Email }}?subject={{forderung_kopf[0].Document_No }}" hx-disable="true">{{forderung_kopf[0].Leasing_Kunde_Email }}</a></td>
+        <td><a href="mailto:{{row.Leasing_Kunde_Email }}?subject={{row.Beleg_Nr }}" hx-disable="true">{{row.Leasing_Kunde_Email }}</a></td>
       </tr>
     </table>
   </div>
 {% endif %}
 
 
-{% if forderung_kopf[0].Versicherung == 'J' and forderung_kopf[0].Vers_Adresse_ID != '' %}
+{% if row.Versicherung == 'J' and row.Vers_Adresse_ID != '' %}
   <div>
     <table class="table table-sm">
       <tr>
@@ -205,37 +206,37 @@
       </tr>
       <tr>
         <td><strong>Name:</strong></td>
-        <td>{{forderung_kopf[0].Vers_Name }}</td>
+        <td>{{row.Vers_Name }}</td>
       </tr>
 
       <tr>
         <td><strong>Adresse:</strong></td>
-        <td>{{forderung_kopf[0].Vers_Adresse }}</td>
+        <td>{{row.Vers_Adresse }}</td>
       </tr>
 
       <tr>
         <td><strong>PLZ / Ort:</strong></td>
-        <td>{{forderung_kopf[0].Vers_PLZ }} {{forderung_kopf[0].Vers_Ort }}</td>
+        <td>{{row.Vers_PLZ }} {{row.Vers_Ort }}</td>
       </tr>
 
       <tr>
         <td><strong>Telefon:</strong></td>
-        <td>{{forderung_kopf[0].Vers_Telefon }}</td>
+        <td>{{row.Vers_Telefon }}</td>
       </tr>
 
       <tr>
         <td><strong>Telefax:</strong></td>
-        <td>{{forderung_kopf[0].Vers_Telefax }}</td>
+        <td>{{row.Vers_Telefax }}</td>
       </tr>
 
       <tr>
         <td><strong>Webseite:</strong></td>
-        <td><a href="{{forderung_kopf[0].Vers_Web }}" hx-disable="true" target="_blank">{{forderung_kopf[0].Vers_Web }}</a></td>
+        <td><a href="{{row.Vers_Web }}" hx-disable="true" target="_blank">{{row.Vers_Web }}</a></td>
       </tr>
 
       <tr>
         <td><strong>Vers_Email:</strong></td>
-        <td><a href="mailto:{{forderung_kopf[0].Vers_Email }}?subject={{forderung_kopf[0].Document_No }}" hx-disable="true">{{forderung_kopf[0].Vers_Email }}</a></td>
+        <td><a href="mailto:{{row.Vers_Email }}?subject={{row.Beleg_Nr }}" hx-disable="true">{{row.Vers_Email }}</a></td>
       </tr>
     </table>
   </div>
@@ -249,67 +250,67 @@
       </tr>
       <tr>
         <td><strong>VIN:</strong></td>
-        <td>{{forderung_kopf[0].Fahrzeug_VIN }}</td>
+        <td>{{row.Fahrzeug_VIN }}</td>
       </tr>
 
       <tr>
         <td><strong>Marke:</strong></td>
-        <td>{{forderung_kopf[0].Fahrzeug_Marke_Nr }}</td>
+        <td>{{row.Fahrzeug_Marke_Nr }}</td>
       </tr>
 
       <tr>
         <td><strong>Modell:</strong></td>
-        <td>{{forderung_kopf[0].Fahrzeug_Modell_Nr }}</td>
+        <td>{{row.Fahrzeug_Modell_Nr }}</td>
       </tr>
 
       <tr>
         <td><strong>Modell Name:</strong></td>
-        <td>{{forderung_kopf[0].Fahrzeug_Modell_Name }}</td>
+        <td>{{row.Fahrzeug_Modell_Name }}</td>
       </tr>
 
       <tr>
         <td><strong>Kategoriecode:</strong></td>
-        <td>{{forderung_kopf[0].Fahrzeug_Kategoriecode }}</td>
+        <td>{{row.Fahrzeug_Kategoriecode }}</td>
       </tr>
 
       <tr>
         <td><strong>Halter:</strong></td>
-        <td>{{forderung_kopf[0].Fahrzeug_Kunde_Nr }}</td>
+        <td>{{row.Fahrzeug_Kunde_Nr }}</td>
       </tr>
 
       <tr>
         <td><strong>Kennzeichen:</strong></td>
-        <td>{{forderung_kopf[0].Fahrzeug_Kennzeichen }}</td>
+        <td>{{row.Fahrzeug_Kennzeichen }}</td>
       </tr>
 
       <tr>
         <td><strong>KM-Stand:</strong></td>
-        <td>{{forderung_kopf[0].Fahrzeug_Kmstand }}</td>
+        <td>{{row.Fahrzeug_Kmstand }}</td>
       </tr>
 
       <tr>
         <td><strong>Antriebsart:</strong></td>
-        <td>{{forderung_kopf[0].Fahrzeug_Antriebsart }}</td>
+        <td>{{row.Fahrzeug_Antriebsart }}</td>
       </tr>
 
       <tr>
         <td><strong>Erstzulassung:</strong></td>
-        <td>{{forderung_kopf[0].Fahrzeug_Erstzulassung|date_format }}</td>
+        <td>{{row.Fahrzeug_Erstzulassung|date_format }}</td>
       </tr>
 
       <tr>
         <td><strong>Kaufdatum:</strong></td>
-        <td>{{forderung_kopf[0].Fahrzeug_Kaufdatum|date_format }}</td>
+        <td>{{row.Fahrzeug_Kaufdatum|date_format }}</td>
       </tr>
 
       <tr>
         <td><strong>Anzahl Vorbesitzer:</strong></td>
-        <td>{{forderung_kopf[0].Fahrzeug_Vorbesitzer_Anzahl }}</td>
+        <td>{{row.Fahrzeug_Vorbesitzer_Anzahl }}</td>
       </tr>
 
       <tr>
         <td><strong>Vorbesitzer:</strong></td>
-        <td>{{forderung_kopf[0].Fahrzeug_Vorbesitzer_Kunde_Nr }}</td>
+        <td>{{row.Fahrzeug_Vorbesitzer_Kunde_Nr }}</td>
       </tr>
     </table>
   </div>

+ 2 - 2
templates/forderungen/details/queries/auftrag_positionen.sql → templates/forderungen/details/queries/auftraege_positionen.sql

@@ -1,8 +1,8 @@
 SELECT TOP 100 [Auftrag_Nr]
      , [Auftrag_Position]
      , [Betrag]
-FROM [dbo].[Auftrag_Positionen]
+FROM [dbo].[Auftraege_Positionen]
 WHERE (
 	Client_DB = {{ appsmith.URL.queryParams.Client_DB }}
-AND [Rechnung_Nr] = {{ appsmith.URL.queryParams.Document_No }}
+AND [Beleg_Nr] = {{ appsmith.URL.queryParams.Beleg_Nr }}
 ) OR 1 != 1

+ 0 - 30
templates/forderungen/details/queries/forderung_belege.sql

@@ -1,30 +0,0 @@
-SELECT TOP 1000 [Client_DB]
-     , [Kunde_Nr]
-     , [Fahrzeug_Nr]
-     , [Beleg_Nr]
-     , [Bezug_Beleg_Nr]
-     , [Beleg_Datum]
-     , [Beleg_Beschreibung]
-     , [Betrag]
-     , [Benutzer]
-     , iif([Open] = '0', 'N', 'J') as [Status]
-     , CASE
-           WHEN [Document Type] = '2' THEN 'R'
-           WHEN [Document Type] = '3' THEN 'R'
-           WHEN [Document Type] = '1' THEN 'Z'
-           WHEN [Document Type] = '0' THEN 'K'
-           ELSE 'X' END AS [Beleg_Art]
-FROM [dbo].[Forderung_Belege]
-WHERE (
-	[Client_DB] = {{ appsmith.URL.queryParams.Client_DB }}
-AND [Kunde_Nr] IN (SELECT [Kunde_Nr] FROM [dbo].[Forderung_Mahnung] WHERE [Rechnung_Nr] = {{ appsmith.URL.queryParams.Document_No }} )
-AND (
-	('D' = '{{ BelegeFilter.selectedOptionValue }}')
-	OR
-	('F' = '{{ BelegeFilter.selectedOptionValue }}' AND [Fahrzeug_Nr] IN (SELECT [Fahrzeug_Nr] FROM [dbo].[Forderung_Mahnung] WHERE [Rechnung_Nr] = {{ appsmith.URL.queryParams.Document_No }} )) 
-
-)
-	
-) OR 1 != 1
-
-ORDER BY Beleg_Datum

+ 0 - 9
templates/forderungen/details/queries/forderung_kommentar.sql

@@ -1,9 +0,0 @@
-SELECT [Timestamp],
- [Benutzer_ID],
- [Name],
- [Rolle],
- [Kommentar]
- 
-FROM dbo.Forderungen_Kommentar_Benutzer
-WHERE Client_DB = {{ appsmith.URL.queryParams.Client_DB }}
-AND Beleg_Nr = {{ appsmith.URL.queryParams.Document_No }}

+ 0 - 15
templates/forderungen/details/queries/forderung_mahnung.sql

@@ -1,15 +0,0 @@
-SELECT TOP 100 [Client_DB]
-     , [Kunde_Nr]
-     , [Mahnung_Nr]
-     , [Mahndatum]
-     , [Mahnstufe]
-     , [Rechnung_Nr]
-     , [Rechnung_Datum]
-     , [Betrag]
-     , [Offen]
-FROM [dbo].[Forderung_Mahnung]
-WHERE (
-	Client_DB = {{ appsmith.URL.queryParams.Client_DB }}
-AND [Kunde_Nr] IN (SELECT [Kunde_Nr] FROM [dbo].[Forderung_Mahnung] WHERE [Rechnung_Nr] = {{ appsmith.URL.queryParams.Document_No }} )
-) OR 1 != 1
-ORDER BY Mahndatum

+ 25 - 0
templates/forderungen/details/queries/forderungen_buchungen.sql

@@ -0,0 +1,25 @@
+SELECT TOP 1000 [Client_DB]
+     , [Kunde_Nr]
+     , [Fahrzeug_Nr]
+     , [Beleg_Nr]
+     , [Bezug_Beleg_Nr]
+     , [Beleg_Datum]
+     , [Beleg_Beschreibung]
+     , [Betrag]
+     , [Benutzer_ID]
+     , [Bezahlt]
+     , [Beleg_Art]
+FROM [dbo].[Forderungen_Buchungen]
+WHERE (
+	[Client_DB] = {{ appsmith.URL.queryParams.Client_DB }}
+AND [Kunde_Nr] IN (SELECT [Kunde_Nr] FROM [dbo].[Forderungen_Mahnungen] WHERE [Beleg_Nr] = {{ appsmith.URL.queryParams.Beleg_Nr }} )
+AND (
+	('D' = '{{ BelegeFilter.selectedOptionValue }}')
+	OR
+	('F' = '{{ BelegeFilter.selectedOptionValue }}' AND [Fahrzeug_Nr] IN (SELECT [Fahrzeug_Nr] FROM [dbo].[Forderungen_Mahnungen] WHERE [Beleg_Nr] = {{ appsmith.URL.queryParams.Beleg_Nr }} )) 
+
+)
+	
+) OR 1 != 1
+
+ORDER BY [Beleg_Datum], [Beleg_Art], [Beleg_Nr]

+ 6 - 6
templates/forderungen/details/queries/forderung_kopf.sql → templates/forderungen/details/queries/forderungen_details.sql

@@ -1,5 +1,5 @@
 SELECT [F].*
-     , round([offen] * 0.19, 2) AS [Mwst_Betrag_berechnet]
+     , round([Beleg_offen] * 0.19, 2) AS [Mwst_Betrag_berechnet]
      , [K].[Kunde_Name]
      , [K].[Kunde_Nachname]
      , [K].[Kunde_Vorname]
@@ -30,7 +30,7 @@ SELECT [F].*
      , isnull([FD].[Rechtsanwalt_Aktenzeichen], '') AS [Rechtsanwalt_Aktenzeichen]
      , isnull([FD].[Rechtsanwalt_Stand], '') AS [Rechtsanwalt_Stand]
      , isnull([FD].[Mahnen_Begruendung], '') AS [Mahnen_Begruendung]
-     , isnull([FD].[Wiedervorlage], coalesce([FD].[Wiedervorlage], dateadd(DAY, 14, [F].[Invoice_Date]))) AS [Wiedervorlage]
+     , isnull([FD].[Wiedervorlage], coalesce([FD].[Wiedervorlage], dateadd(DAY, 14, [F].[Beleg_Datum]))) AS [Wiedervorlage]
      , [V].[Vers_Name]
      , [V].[Vers_Adresse]
      , [V].[Vers_PLZ]
@@ -64,11 +64,11 @@ SELECT [F].*
      , [K2].[Kunde_Land] AS [Leasing_Kunde_Land]
      , [K2].[Kunde_Telefon] AS [Leasing_Kunde_Telefon]
      , [K2].[Kunde_Email] AS [Leasing_Kunde_Email]     
-FROM [dbo].[Forderungen] [F]
+FROM [dbo].[Forderungen_Kopf] [F]
          LEFT JOIN [dbo].[Kunden] [K] ON [F].[Kunde_Nr] = [K].[Kunde_Nr] AND [F].[Client_DB] = [K].[Client_DB]
-         LEFT JOIN [dbo].[Fahrzeuge] FZ ON F.VIN = FZ.Fahrzeug_Nr AND [F].[Client_DB] = [FZ].[Client_DB]
+         LEFT JOIN [dbo].[Fahrzeuge] FZ ON F.[Fahrzeug_Nr] = FZ.[Fahrzeug_Nr] AND [F].[Client_DB] = [FZ].[Client_DB]
          LEFT JOIN [dbo].[Kunden] [K2] ON [FZ].[Fahrzeug_Kunde_Nr] = [K2].[Kunde_Nr] AND [FZ].[Client_DB] = [K2].[Client_DB]
-         LEFT JOIN [dbo].[Forderungen_Details] [FD] ON [F].[Client_DB] = [FD].[Client_DB] AND [F].[Document_No] = [FD].[Beleg_Nr]
+         LEFT JOIN [dbo].[Forderungen_Details] [FD] ON [F].[Beleg_Nr] = [FD].[Beleg_Nr] AND [F].[Client_DB] = [FD].[Client_DB] 
          LEFT JOIN [dbo].[Versicherungen] [V] ON [FD].[Vers_Adresse_ID] = [V].[Vers_Adresse_ID]
 WHERE [F].[Client_DB] = {{ appsmith.URL.queryParams.Client_DB }}
-AND [F].[Document_No] = {{ appsmith.URL.queryParams.Document_No }}
+AND [F].[Beleg_Nr] = {{ appsmith.URL.queryParams.Beleg_Nr }}

+ 9 - 0
templates/forderungen/details/queries/forderungen_kommentare.sql

@@ -0,0 +1,9 @@
+SELECT [Timestamp],
+ [Benutzer_ID],
+ [Name],
+ [Rolle],
+ [Kommentar]
+ 
+FROM [dbo].[Forderungen_Kommentar_Benutzer]
+WHERE [Client_DB] = {{ appsmith.URL.queryParams.Client_DB }}
+AND [Beleg_Nr] = {{ appsmith.URL.queryParams.Beleg_Nr }}

+ 15 - 0
templates/forderungen/details/queries/forderungen_mahnungen.sql

@@ -0,0 +1,15 @@
+SELECT TOP 100 [Client_DB]
+     , [Kunde_Nr]
+     , [Mahnung_Nr]
+     , [Mahnung_Datum]
+     , [Mahnstufe]
+     , [Beleg_Nr]
+     , [Beleg_Datum]
+     , [Betrag]
+     , 'N' as [Bezahlt]
+FROM [dbo].[Forderungen_Mahnungen]
+WHERE (
+	[Client_DB] = {{ appsmith.URL.queryParams.Client_DB }}
+AND [Kunde_Nr] IN (SELECT [Kunde_Nr] FROM [dbo].[Forderungen_Mahnungen] WHERE [Beleg_Nr] = {{ appsmith.URL.queryParams.Beleg_Nr }} )
+) OR 1 != 1
+ORDER BY [Mahnung_Datum], [Beleg_Nr]

+ 0 - 2
templates/forderungen/details/queries/post/insert_kommentar.sql

@@ -1,2 +0,0 @@
-INSERT INTO [dbo].[Forderungen_Kommentar] ([Client_DB], [Beleg_Nr], [Timestamp], [Benutzer_ID], [Kommentar])
-VALUES ('{{data.Client_DB}}', '{{data.Beleg_Nr}}', getdate(), '{{data.Benutzer_ID}}', '{{data.Kommentar}}')

+ 2 - 0
templates/forderungen/details/queries/post/post_comments.sql

@@ -0,0 +1,2 @@
+INSERT INTO [dbo].[Forderungen_Kommentar] ([Client_DB], [Beleg_Nr], [Timestamp], [Benutzer_ID], [Kommentar])
+VALUES ('{{data.Client_DB}}', '{{data.Beleg_Nr}}', '{{data.Timestamp}}', '{{data.Benutzer_ID}}', '{{data.Kommentar}}')

+ 0 - 0
templates/forderungen/details/queries/post/update_details.sql → templates/forderungen/details/queries/post/post_details.sql


+ 16 - 12
templates/forderungen/liste/config/liste_filter.csv

@@ -1,17 +1,21 @@
 Name;Filter_Typ;Breite;Beschriftung;Tabellenfeld;Anzeigewert;Sortierung;Standardwert
-Hauptbetrieb;select;2;;Client_DB;Hauptbetrieb_Name;;
-Standort;select;3;;Standort_ID;Standort_Name;;
-Bereich;select;3;;;;;
-Verursacher;select;4;;;;;
-Rechnungsnummer;text;2;;Document_No;;;
-RechnungsdatumVon;date;2;Rechnungsdatum von;Invoice_Date;;;
-RechnungsdatumBis;date;2;Rechnungsdatum bis;Invoice_Date;;;
-Kunde;text;4;;;;;
+Mandant;select;2;;Client_DB;Hauptbetrieb_Name;;
+Filiale;select;2;;Standort_ID;Standort_Name;;
+Abteilung;select;2;;;;;
+Verursacher;select;4;;Verursacher_Text;;;
+RechnungGutschrift;select;2;R/G;Rechnung_Gutschrift;;;
+
+Fahrzeug;text;2;;Fahrzeug_Nr;;;
+Kunde;text;4;;Kunde_Text;;;
+Rechnungsnummer;text;2;;Beleg_Nr;;;
+RechnungsdatumVon;date;2;RG-Datum von;Beleg_Datum;;;
+RechnungsdatumBis;date;2;RG-Datum bis;Beleg_Datum;;;
+
+Staffel;select;2;;Staffel_Text;;;
+Mahnstufe;select;2;;;;;
+Bearbeitet;select;2;;;;;
 Abwarten;select;2;;;;;
 WiedervorlageVon;date;2;Wiedervorlage von;Wiedervorlage;;;
 WiedervorlageBis;date;2;Wiedervorlage bis;Wiedervorlage;;;
-Fahrzeug;select;2;;VIN;;;
-Staffel;select;2;;;;;
-Mahnstufe;select;2;;;;;
-Bearbeitet;select;2;;;;;
+
 BenutzerSelect;hidden;2;Benutzer;;;;winter

+ 5 - 6
templates/forderungen/liste/liste_kopfzeile.html

@@ -1,15 +1,14 @@
     <tr>
-        <th></th>
-        <th>Filiale / Bereich</th>
-        <th>Kunde</th>
+        <th>Filiale / Abteilung</th>
         <th>Verursacher</th>
-        <th>RG-Nr.</th>
+        <th>RG-Betrag<br>/ RG-Nr.</th>
         <th>RG-Datum<br>/ Fällig</th>
-        <th>RG-Betrag</th>
+        <th>Kunde</th>
         <th>offen /<br>Kunde ges.</th>
-        <th>Mahnstufe<br>/ Staffel</th>
+        <th>Mahnstufe<br>/ Tage offen</th>
         <th>Abw.</th>
         <th>Kommentar<br>Fibu</th>
         <th>Kommentar<br>Abteilung</th>
         <th>Wieder-<br>vorlage</th>
+        <th></th>
     </tr>

+ 37 - 34
templates/forderungen/liste/liste_zeile.html

@@ -1,65 +1,57 @@
 <tr>
-  <td>
-    <a href="/app/forderungen/details/{{ row.Client_DB }}_{{ row.Document_No }}"
-      class="btn btn-sm btn-primary gc-action-btn">
-      <i class="icon cil-pencil"></i>
-    </a>
-  </td>
-
   <td>
     <div class="gc-title">{{ row.Standort_Name }}</div>
-    <div class="gc-subtitle">{{ row.Bereich }}</div>
-  </td>
-
-  <td class="gc-main-cell">
-    <a class="gc-title text-decoration-none" href="/app/forderungen/liste?Kunde={{ row.Kunde|urlencode }}">
-      {{ row.Kunde }}
-    </a>
-    <div class="gc-subtitle">
-      {{ row.Kunde2 or '' }}
-      {% if row.Kunde_Email %}
-      · <a href="mailto:{{ row.Kunde_Email }}?subject={{ row.Document_No }}" hx-disable="true">E-Mail</a>
-      {% endif %}
-    </div>
+    <div class="gc-subtitle">{{ row.Abteilung }}</div>
   </td>
 
   <td>
-    <a href="/app/forderungen/liste?Verursacher={{ row.Verursacher|urlencode }}"
-      class="text-decoration-none fw-semibold">
-      {{ row.Verursacher }}
+    <a href="/app/forderungen/liste?Verursacher={{ row.Verursacher_Text|urlencode }}"
+      class="fw-semibold gc-link">
+      {{ row.Verursacher_Text }}
     </a>
-    {% if row.Verursacher == 'N.N.' %}
+    {% if row.Verursacher_Text == '--N.N.' %}
     <span class="gc-badge gc-badge-warning ms-1">offen</span>
     {% endif %}
   </td>
 
-  <td>
-    <span class="gc-badge gc-badge-info">{{ row.Document_No }}</span>
+  <td class="text-end align-top">
+    <div class="gc-money">{{ row.Beleg_Betrag|number_format }} €</div>
+    <a href="#" data-coreui-toggle="modal" data-coreui-target="#exampleModal">
+      <span class="gc-badge gc-badge-info">{{ row.Beleg_Nr }}</span>
+    </a>
   </td>
 
   <td>
-    <div>{{ row.Invoice_Date|date_format }}</div>
+    <div>{{ row.Beleg_Datum|date_format }}</div>
     <div class="gc-subtitle">fällig {{ row.Fällig_Datum|date_format }}</div>
   </td>
 
-  <td class="text-end align-top">
-    <div class="gc-money">{{ row.Beleg_Betrag|number_format }} €</div>
+  <td class="gc-main-cell">
+    <a class="gc-title" href="/app/forderungen/liste?Kunde={{ row.Kunde_Text|urlencode }}">
+      {{ row.Kunde_Text }}
+    </a>
+    <div class="gc-subtitle">
+      {{ row.Besitzer_Kunde_Text or '' }}
+      {% if row.Kunde_Email %}
+      · <a href="mailto:{{ row.Kunde_Email }}?subject={{ row.Beleg_Nr }}" hx-disable="true">E-Mail</a>
+      {% endif %}
+    </div>
   </td>
 
   <td class="text-end">
-    <div class="gc-money">{{ row.offen|number_format }} €</div>
-    <div class="gc-subtitle">{{ row.Kunde_gesamt_Bezug }} {{ row.offen_Kunde_gesamt|number_format }} €</div>
+    <div class="gc-money">{{ row.Beleg_offen|number_format }} €</div>
+    <div class="gc-subtitle">{{ row.Kunde_gesamt_Bezug }} {{ row.Kunde_offen_gesamt|number_format }} €</div>
   </td>
 
   <td class="text-end">
-    {% set mahnstufe = row.Mahnstufe or row.Stufe %}
+    {% set mahnstufe = row.Mahnstufe or '0' %}
 
     {% if mahnstufe and mahnstufe|string != '0' %}
     <span class="gc-badge gc-badge-danger gc-mahnstufe-{{ mahnstufe }}">
       M{{ mahnstufe }}
     </span>
     {% endif %}
-    <div class="gc-subtitle">{{ row.Tage }} Tage</div>
+    <div class="gc-subtitle">{{ row.Beleg_Tage_offen }} Tage</div>
   </td>
 
   <td class="text-end">
@@ -73,12 +65,23 @@
   </td>
 
   <td>
+    {% if row.Antrag_Nr %}
+    <div class="gc-subtitle">{{ row.Antrag_Art }} {{ row.Antrag_Nr }} vom {{ row.Antrag_Datum|date_format }}<br>{{ row.Antrag_Benutzer_ID }}, Status: {{ row.Antrag_Status }}</div>
+    {% else %}
     <div class="gc-subtitle">{{ row.Kommentar_Abteilung or '' }}</div>
+    {% endif %}
   </td>
 
   <td class="text-end">
     {% if row.Wiedervorlage %}
-    <span class="gc-badge gc-badge-success">{{ row.Wiedervorlage|date_format }}</span>
+    <span class="gc-badge gc-badge-{{ row.Wiedervorlage_Stufe }}">{{ row.Wiedervorlage|date_format }}</span>
     {% endif %}
   </td>
+
+  <td>
+    <a href="/app/forderungen/details/{{ row.Client_DB }}_{{ row.Beleg_Nr }}"
+      class="btn btn-sm btn-primary gc-action-btn">
+      <i class="icon cil-pencil"></i>
+    </a>
+  </td>
 </tr>

+ 36 - 26
templates/forderungen/liste/queries/forderungen_liste.sql

@@ -5,38 +5,42 @@ SELECT [F].[Client_DB]
      , [F].[Hauptbetrieb_Name]
      , [F].[Standort_ID]
      , [F].[Standort_Name]
-     , [F].[Document_No]
+     , [F].[Beleg_Nr]
      , [F].[Rechnung_Gutschrift]
-     , [F].[User_ID]
-     , [F].[VIN]
-     , [F].[Comment]
-     , [F].[offen]
-     , [F].[offen_Kunde_gesamt]
-     , [F].[Invoice_Date]
-     , [F].[Verursacher]
-     , [F].[Kunde]
-     , [F].[Beleg]
-     , [F].[Bereich]
-     , [F].[Tage]
+     , [F].[Benutzer_ID]
+     , [F].[Fahrzeug_Nr]
+     , [F].[Beleg_Kommentar]
+     , [F].[Beleg_offen]
+     , [F].[Kunde_offen_gesamt]
+     , [F].[Beleg_Datum]
+     , [F].[Verursacher_Text]
+     , [F].[Kunde_Text]
+     , [F].[Beleg_Text]
+     , [F].[Abteilung]
+     , [F].[Beleg_Tage_offen]
      , CASE
-           WHEN [F].[Tage] > 90 THEN 3
-           WHEN [F].[Tage] > 60 THEN 2
-           WHEN [F].[Tage] > 30 THEN 1
+           WHEN [F].[Beleg_Tage_offen] > 90 THEN 3
+           WHEN [F].[Beleg_Tage_offen] > 60 THEN 2
+           WHEN [F].[Beleg_Tage_offen] > 30 THEN 1
            ELSE 0
        END AS [Stufe]
-     , replace([F].[Staffel], 'Wochen', 'W.') AS [Staffel]
+     , replace([F].[Staffel_Text], 'Wochen', 'W.') AS [Staffel_Text]
      , [F].[Mahnstufe]
      , [F].[Forderungsart]
      --, [F].[Abwarten]
      , [F].[Verursacher_Benutzer_ID]
-     , F.Kunde2
-     , F.Beleg_Betrag
-     , F.Kunde_gesamt_Bezug
+     , F.[Besitzer_Kunde_Text]
+     , F.[Beleg_Betrag]
+     , F.[Kunde_gesamt_Bezug]
 
      , left(isnull([FK].[Kommentar_Fibu], ''), 50) AS [Kommentar_Fibu]
      , left(isnull([FK].[Kommentar_Abteilung], ''), 50) AS [Kommentar_Abteilung]
      , [K].[Kunde_Email] AS [Kunde_Email]
-     , coalesce([FD].[Wiedervorlage], dateadd(DAY, 14, [F].[Invoice_Date])) AS [Wiedervorlage]
+     , coalesce([FD].[Wiedervorlage], dateadd(DAY, 14, [F].[Beleg_Datum])) AS [Wiedervorlage]
+     , case 
+        when coalesce([FD].[Wiedervorlage], dateadd(DAY, 14, [F].[Beleg_Datum])) < getdate() then '2'
+        when coalesce([FD].[Wiedervorlage], dateadd(DAY, 14, [F].[Beleg_Datum])) < dateadd(day, 4, getdate()) then '1'
+      else '0' end AS [Wiedervorlage_Stufe]
      , CASE
            WHEN [FD].[Reklamation] = 'J' THEN 'Rekl.'
            WHEN [FD].[Versicherung] = 'J' THEN 'Vers.'
@@ -46,13 +50,19 @@ SELECT [F].[Client_DB]
        END AS [Abwarten]
      , isnull([FK].[Begründung], '') AS [Begründung]
      , isnull([FD].[Bearbeitet], 'N') AS [Bearbeitet]
-     , dateadd(DAY, 14, [F].[Invoice_Date]) AS [Fällig_Datum]
+     , dateadd(DAY, 14, [F].[Beleg_Datum]) AS [Fällig_Datum]
 
-FROM [dbo].[Forderungen] [F]
+     , [G].[Antrag_Art]
+     , [G].[Antrag_Nr]
+     , [G].[Antrag_Datum]
+     , [G].[Antrag_Benutzer_ID]
+     , [G].[Antrag_Status]
+     , [G].[Letzte_Beantragung]
+FROM [dbo].[Forderungen_Kopf] [F]
          LEFT JOIN [dbo].[Kunden] [K] ON [F].[Kunde_Nr] = [K].[Kunde_Nr] AND [F].[Client_DB] = [K].[Client_DB]
-         LEFT JOIN [dbo].[Forderungen_Details] [FD] ON [F].[Client_DB] = [FD].[Client_DB] AND [F].[Document_No] = [FD].[Beleg_Nr]
-         LEFT JOIN [dbo].[Forderungen_Kommentar_letzte] [FK] ON [F].[Client_DB] = [FK].[Client_DB] AND [F].[Document_No] = [FK].[Beleg_Nr]
-
+         LEFT JOIN [dbo].[Forderungen_Details] [FD] ON [F].[Client_DB] = [FD].[Client_DB] AND [F].[Beleg_Nr] = [FD].[Beleg_Nr]
+         LEFT JOIN [dbo].[Forderungen_Kommentar_letzte] [FK] ON [F].[Client_DB] = [FK].[Client_DB] AND [F].[Beleg_Nr] = [FK].[Beleg_Nr]
+         LEFT JOIN [Garantie2] [G] ON [F].[Client_DB] = [G].[Client_DB] AND [F].[Beleg_Nr] = [G].[Beleg_Nr]
 ) AS F
 INNER JOIN [dbo].[Benutzer_Rechte] [BR] ON ([BR].[Benutzer_ID] = {{ BenutzerSelect.selectedOptionValue }} OR BR.Benutzer_ID = '')
 AND [F].[Hauptbetrieb_ID] = [BR].[Hauptbetrieb_ID] 
@@ -60,4 +70,4 @@ AND [F].[Standort_ID] = [BR].[Standort_ID]
 AND ([BR].[Rolle] = 'Buchhaltung' OR [BR].[Benutzer_ID] = [F].[Verursacher_Benutzer_ID])
 
 WHERE 1 = 1
-ORDER BY F.[Wiedervorlage] ASC, F.[Tage] DESC
+ORDER BY F.[Wiedervorlage] ASC, F.[Beleg_Tage_offen] DESC