소스 검색

Einen Großteil der Anforderungen umgesetzt

gc-server3 4 주 전
부모
커밋
a807d32e63
6개의 변경된 파일257개의 추가작업 그리고 135개의 파일을 삭제
  1. 76 34
      app/routes.py
  2. 29 60
      templates/base/base.html
  3. 55 0
      templates/base/select.html
  4. 28 7
      templates/forderungen/details.html
  5. 68 34
      templates/forderungen/liste.html
  6. 1 0
      templates/forderungen/queries/forderungen_liste.sql

+ 76 - 34
app/routes.py

@@ -1,11 +1,18 @@
 import io
 from datetime import datetime
+from pathlib import Path
+from urllib.parse import unquote, urlencode
 
 import pandas as pd
 from docx import Document
 from docxtpl import DocxTemplate
 from fastapi import APIRouter, Depends, Form, HTTPException, Request, Response
-from fastapi.responses import HTMLResponse, RedirectResponse, StreamingResponse
+from fastapi.responses import (
+    FileResponse,
+    HTMLResponse,
+    RedirectResponse,
+    StreamingResponse,
+)
 from fastapi.templating import Jinja2Templates
 from sqlalchemy import text
 from sqlalchemy.orm import Session
@@ -21,12 +28,17 @@ templates = Jinja2Templates(directory="templates")
 
 @router.get("/", response_class=HTMLResponse)
 def index(request: Request):
-    return RedirectResponse(url="/forderungen")
+    return RedirectResponse(url="/login")
 
 
 @router.get("/login", response_class=HTMLResponse)
 def login_get(request: Request):
-    return templates.TemplateResponse("base/login.html", {"request": request})
+    return templates.TemplateResponse(request, "base/login.html", {"request": request})
+
+
+@router.get("/select", response_class=HTMLResponse)
+def select_get(request: Request):
+    return templates.TemplateResponse(request, "base/select.html", {"request": request})
 
 
 @router.post("/login")
@@ -51,6 +63,8 @@ def number_format(input: float) -> str:
 
 
 def date_format(input: datetime) -> str:
+    if input is None:
+        return ""
     return input.strftime("%d.%m.%Y")
 
 
@@ -58,21 +72,28 @@ templates.env.filters["number_format"] = number_format
 templates.env.filters["date_format"] = date_format
 
 
-@router.get("/forderungen/liste", response_class=HTMLResponse)
-def forderungen_liste(request: Request, db: Session = Depends(get_session), limit: int = 100):
+def single_quote(text: str):
+    return "'" + unquote(text) + "'"
+
+
+@router.get("/app/forderungen/liste", response_class=HTMLResponse)
+def forderungen_liste(request: Request, db: Session = Depends(get_session), limit: int = 100, page: int = 0):
+    params = {k: v for k, v in request.query_params.items() if v != ""}
+    if len(params) < len(request.query_params):
+        return RedirectResponse(url="/app/forderungen/liste?" + urlencode(params))
     context = {
-        "RechnungsdatumVon": {"selectedDate": "'2000-01-01T00:00:00'"},
-        "RechnungsdatumBis": {"selectedDate": "'2027-01-01T00:00:00'"},
-        "Hauptbetrieb": {"selectedOptionValue": "''"},
-        "Standort": {"selectedOptionValue": "''"},
-        "Rechnungsnummer": {"text": "''"},
-        "Kunde": {"selectedOptionValue": "''"},
-        "Verursacher": {"selectedOptionValue": "''"},
-        "Fahrzeug": {"selectedOptionValue": "''"},
-        "Staffel": {"selectedOptionValue": "''"},
-        "Mahnstufe": {"selectedOptionValue": "''"},
-        "WiedervorlageVon": {"selectedDate": "'2000-01-01T00:00:00'"},
-        "WiedervorlageBis": {"selectedDate": "'2027-01-01T00:00:00'"},
+        "RechnungsdatumVon": {"selectedDate": single_quote(params.get("RechnungsdatumVon", "2000-01-01T00:00:00"))},
+        "RechnungsdatumBis": {"selectedDate": single_quote(params.get("RechnungsdatumBis", "2027-01-01T00:00:00"))},
+        "Hauptbetrieb": {"selectedOptionValue": single_quote(params.get("Hauptbetrieb", ""))},
+        "Standort": {"selectedOptionValue": single_quote(params.get("Standort", ""))},
+        "Rechnungsnummer": {"text": single_quote(params.get("Rechnungsnummer", ""))},
+        "Kunde": {"selectedOptionValue": single_quote(params.get("Kunde", ""))},
+        "Verursacher": {"selectedOptionValue": single_quote(params.get("Verursacher", ""))},
+        "Fahrzeug": {"selectedOptionValue": single_quote(params.get("Fahrzeug", ""))},
+        "Staffel": {"selectedOptionValue": single_quote(params.get("Staffel", ""))},
+        "Mahnstufe": {"selectedOptionValue": single_quote(params.get("Mahnstufe", ""))},
+        "WiedervorlageVon": {"selectedDate": single_quote(params.get("WiedervorlageVon", "2000-01-01T00:00:00"))},
+        "WiedervorlageBis": {"selectedDate": single_quote(params.get("WiedervorlageBis", "2027-01-01T00:00:00"))},
         "BenutzerSelect": {"selectedOptionValue": "winter"},
     }
     query = templates.TemplateResponse(request, "forderungen/queries/forderungen_liste.sql", context).body.decode(
@@ -104,14 +125,21 @@ def forderungen_liste(request: Request, db: Session = Depends(get_session), limi
     for filter_name, (key, value) in config.items():
         filters[filter_name] = {row[col_names.index(key)]: row[col_names.index(value)] for row in q}
 
+    q_limit = q[page * limit : (page + 1) * limit]
+
+    defaults = {}
+    for filter_name in config.keys():
+        defaults[filter_name] = unquote(request.query_params.get(filter_name, ""))
     # print(filters["Standort"])
 
     return templates.TemplateResponse(
-        request, "forderungen/liste.html", {"request": request, "forderungen_liste": q, "filter": filters}
+        request,
+        "forderungen/liste.html",
+        {"request": request, "forderungen_liste": q_limit, "filter": filters, "defaults": defaults},
     )
 
 
-@router.get("/forderungen/details/{client_db}_{document_no}", response_class=HTMLResponse)
+@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
 ):
@@ -145,6 +173,8 @@ def forderungen_details(
         "betrag": "120,00",
         "faelligkeit": "23.12.1983",
     }
+    template_context["files"] = list(Path(f"C:\\Projekte\\Reisacher-Fileserver\\{client_db}\\{document_no}").glob("*"))
+
     return templates.TemplateResponse(request, "forderungen/details.html", template_context)
 
 
@@ -244,28 +274,40 @@ def export_docx(id: int, db: Session = Depends(get_session)):
     )
 
 
-@router.get("/export/docx")
-def export_docx2(id: int, db: Session = Depends(get_session)):
+@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 = {
+        "appsmith": {
+            "URL": {
+                "queryParams": {
+                    "Client_DB": "'" + client_db + "'",
+                    "Document_No": "'" + document_no + "'",
+                }
+            }
+        },
+    }
+    query = templates.TemplateResponse(request, "forderungen/queries/forderung_kopf.sql", context).body.decode("utf-8")
+    q = db.execute(text(query)).fetchone()
+
     doc = DocxTemplate("templates\\forderungen\\docs\\Mahnung_AHR.docx")
+    filename = Path(
+        f"C:\\Projekte\\Reisacher-Fileserver\\{client_db}\\{document_no}\\Mahnung_{client_db}_{document_no}.docx"
+    )
+    filename.parent.mkdir(parents=True, exist_ok=True)
+
     context = {
-        "Kunde_Name": "Robert Burghard",
+        "Kunde_Name": q.Kunde,
         "Kunde_Adresse": "Im Waldhof 14a",
         "Kunde_PLZ": "61476",
         "Kunde_Ort": "Kronberg",
-        "Datum_heute": "25.03.2026",
-        "Kunde_Nr": "23121983",
+        "Datum_heute": datetime.now().strftime("%d.%m.%Y"),
+        "Kunde_Nr": q.Kunde.split("-")[-1].strip(),
         "Fahrzeug_Kennzeichen": "OF-RB 512",
-        "Rechnung_Nr": "2600007",
+        "Rechnung_Nr": q.Document_No,
         "Betrag_SB": "250,00",
         "Betrag_USt": "380,00",
     }
     doc.render(context)
-    # doc.save("export\\Mahnung_AHR_Burghard.docx")
-    buf = io.BytesIO()
-    doc.save(buf)
-    buf.seek(0)
-    return StreamingResponse(
-        buf,
-        media_type="application/vnd.openxmlformats-officedocument.wordprocessingml.document",
-        headers={"Content-Disposition": "attachment; filename=Mahnung_Burghard.docx"},
-    )
+    doc.save(filename)
+
+    return FileResponse(filename, media_type="application/octet-stream", filename=filename.name)

+ 29 - 60
templates/base/base.html

@@ -16,10 +16,11 @@
   
   <script src="https://cdn.jsdelivr.net/npm/@coreui/coreui@5.6.1/dist/js/coreui.bundle.min.js"></script>
   <script src="https://cdn.jsdelivr.net/npm/@coreui/icons@3.0.1/dist/cjs/index.min.js"></script>
-
+  <!-- Favicon icon -->
+	<link rel="icon" href="/static/assets/images/favicon.ico" type="image/x-icon">
 </head>
 
-<body class="container py-3">
+<body class="container py-3" hx-boost="true">
   <!--<nav class="navbar navbar-expand-lg bg-primary">
     <div class="container-fluid">
         <a class="navbar-brand" href="#">Navbar</a>
@@ -50,28 +51,20 @@
         <button class="header-toggler" type="button"
           onclick="coreui.Sidebar.getInstance(document.querySelector('#sidebar')).toggle()"
           style="margin-inline-start: -14px;">
-          <svg class="icon icon-lg">
-            <use xlink:href="vendors/@coreui/icons/svg/free.svg#cil-menu"></use>
-          </svg>
+          <i class="icon icon-lg cil-menu"></i>
         </button>
         <ul class="header-nav d-none d-lg-flex">
-          <li class="nav-item"><a class="nav-link" href="#">Dashboard</a></li>
-          <li class="nav-item"><a class="nav-link" href="#">Users</a></li>
-          <li class="nav-item"><a class="nav-link" href="#">Settings</a></li>
+          <li class="nav-item"><a class="nav-link" href="/select">Übersicht</a></li>
+          <li class="nav-item"><a class="nav-link" href="/app/forderungen/liste">Liste</a></li>
+          <li class="nav-item"><a class="nav-link" href="#">Einstellungen</a></li>
         </ul>
         <ul class="header-nav ms-auto">
           <li class="nav-item"><a class="nav-link" href="#">
-              <svg class="icon icon-lg">
-                <use xlink:href="vendors/@coreui/icons/svg/free.svg#cil-bell"></use>
-              </svg></a></li>
+              <i class="icon icon-lg cil-bell"></i></a></li>
           <li class="nav-item"><a class="nav-link" href="#">
-              <svg class="icon icon-lg">
-                <use xlink:href="vendors/@coreui/icons/svg/free.svg#cil-list-rich"></use>
-              </svg></a></li>
+              <i class="icon icon-lg cil-list-rich"></i></a></li>
           <li class="nav-item"><a class="nav-link" href="#">
-              <svg class="icon icon-lg">
-                <use xlink:href="vendors/@coreui/icons/svg/free.svg#cil-envelope-open"></use>
-              </svg></a></li>
+              <i class="icon icon-lg cil-envelope-open"></i></a></li>
         </ul>
         <ul class="header-nav">
           <li class="nav-item py-1">
@@ -80,31 +73,23 @@
           <li class="nav-item dropdown">
             <button class="btn btn-link nav-link py-2 px-2 d-flex align-items-center" type="button"
               aria-expanded="false" data-coreui-toggle="dropdown">
-              <svg class="icon icon-lg theme-icon-active">
-                <use xlink:href="vendors/@coreui/icons/svg/free.svg#cil-contrast"></use>
-              </svg>
+              <i class="icon icon-lg theme-icon-active cil-contrast"></i>
             </button>
             <ul class="dropdown-menu dropdown-menu-end" style="--cui-dropdown-min-width: 8rem;">
               <li>
                 <button class="dropdown-item d-flex align-items-center" type="button" data-coreui-theme-value="light">
-                  <svg class="icon icon-lg me-3">
-                    <use xlink:href="vendors/@coreui/icons/svg/free.svg#cil-sun"></use>
-                  </svg>Light
+                  <i class="icon icon-lg me-3 cil-sun"></i> Light
                 </button>
               </li>
               <li>
                 <button class="dropdown-item d-flex align-items-center" type="button" data-coreui-theme-value="dark">
-                  <svg class="icon icon-lg me-3">
-                    <use xlink:href="vendors/@coreui/icons/svg/free.svg#cil-moon"></use>
-                  </svg>Dark
+                  <i class="icon icon-lg me-3 cil-moon"></i> Dark
                 </button>
               </li>
               <li>
                 <button class="dropdown-item d-flex align-items-center active" type="button"
                   data-coreui-theme-value="auto">
-                  <svg class="icon icon-lg me-3">
-                    <use xlink:href="vendors/@coreui/icons/svg/free.svg#cil-contrast"></use>
-                  </svg>Auto
+                  <i class="icon icon-lg me-3 cil-contrast"></i> Auto
                 </button>
               </li>
             </ul>
@@ -114,52 +99,36 @@
           </li>
           <li class="nav-item dropdown"><a class="nav-link py-0 pe-0" data-coreui-toggle="dropdown" href="#"
               role="button" aria-haspopup="true" aria-expanded="false">
-              <div class="avatar avatar-md"><img class="avatar-img" src="assets/img/avatars/8.jpg" alt="user@email.com">
+              <div class="avatar avatar-md"><img class="avatar-img" src="/static/assets/img/avatars/winter.jpg" alt="winter@global-cube.de">
               </div>
             </a>
             <div class="dropdown-menu dropdown-menu-end pt-0">
               <div class="dropdown-header bg-body-tertiary text-body-secondary fw-semibold rounded-top mb-2">Account
               </div><a class="dropdown-item" href="#">
-                <svg class="icon me-2">
-                  <use xlink:href="vendors/@coreui/icons/svg/free.svg#cil-bell"></use>
-                </svg> Updates<span class="badge badge-sm bg-info ms-2">42</span></a><a class="dropdown-item" href="#">
-                <svg class="icon me-2">
-                  <use xlink:href="vendors/@coreui/icons/svg/free.svg#cil-envelope-open"></use>
-                </svg> Messages<span class="badge badge-sm bg-success ms-2">42</span></a><a class="dropdown-item"
+                <i class="icon me-2 cil-bell"></i> Updates<span class="badge badge-sm bg-info ms-2">42</span></a><a class="dropdown-item" href="#">
+                <i class="icon me-2 cil-envelope-open"></i> Messages<span class="badge badge-sm bg-success ms-2">42</span></a><a class="dropdown-item"
                 href="#">
-                <svg class="icon me-2">
-                  <use xlink:href="vendors/@coreui/icons/svg/free.svg#cil-task"></use>
-                </svg> Tasks<span class="badge badge-sm bg-danger ms-2">42</span></a><a class="dropdown-item" href="#">
-                <svg class="icon me-2">
-                  <use xlink:href="vendors/@coreui/icons/svg/free.svg#cil-comment-square"></use>
-                </svg> Comments<span class="badge badge-sm bg-warning ms-2">42</span></a>
+                <i class="icon me-2 cil-task"></i> Tasks<span class="badge badge-sm bg-danger ms-2">42</span></a><a class="dropdown-item" href="#">
+                <i class="icon me-2 cil-comment-square"></i> Comments<span class="badge badge-sm bg-warning ms-2">42</span></a>
               <div class="dropdown-header bg-body-tertiary text-body-secondary fw-semibold my-2">
                 <div class="fw-semibold">Settings</div>
               </div><a class="dropdown-item" href="#">
-                <svg class="icon me-2">
-                  <use xlink:href="vendors/@coreui/icons/svg/free.svg#cil-user"></use>
-                </svg> Profile</a><a class="dropdown-item" href="#">
-                <svg class="icon me-2">
-                  <use xlink:href="vendors/@coreui/icons/svg/free.svg#cil-settings"></use>
-                </svg> Settings</a><a class="dropdown-item" href="#">
-                <svg class="icon me-2">
-                  <use xlink:href="vendors/@coreui/icons/svg/free.svg#cil-credit-card"></use>
-                </svg> Payments<span class="badge badge-sm bg-secondary ms-2">42</span></a><a class="dropdown-item"
+                <i class="icon me-2 cil-user"></i> Profile</a><a class="dropdown-item" href="#">
+                <i class="icon me-2 cil-settings"></i> Settings</a><a class="dropdown-item" href="#">
+                <i class="icon me-2 cil-credit-card"></i> Payments<span class="badge badge-sm bg-secondary ms-2">42</span></a><a class="dropdown-item"
                 href="#">
-                <svg class="icon me-2">
-                  <use xlink:href="vendors/@coreui/icons/svg/free.svg#cil-file"></use>
-                </svg> Projects<span class="badge badge-sm bg-primary ms-2">42</span></a>
+                <i class="icon me-2 cil-file"></i> Projects<span class="badge badge-sm bg-primary ms-2">42</span></a>
               <div class="dropdown-divider"></div><a class="dropdown-item" href="#">
-                <svg class="icon me-2">
-                  <use xlink:href="vendors/@coreui/icons/svg/free.svg#cil-lock-locked"></use>
-                </svg> Lock Account</a><a class="dropdown-item" href="#">
-                <svg class="icon me-2">
-                  <use xlink:href="vendors/@coreui/icons/svg/free.svg#cil-account-logout"></use>
-                </svg> Logout</a>
+                <i class="icon me-2 cil-lock-locked"></i> Lock Account</a><a class="dropdown-item" href="#">
+                <i class="icon me-2 cil-account-logout"></i> Logout</a>
             </div>
           </li>
         </ul>
       </div>
+      <div class="container-fluid px-6">
+        <img src="/static/assets/images/Reisacher.png">
+        <h2>Forderungsmanagement</h2>
+      </div>
       <div class="container-fluid px-6">
         {% block content %}{% endblock %}
       </div>

+ 55 - 0
templates/base/select.html

@@ -0,0 +1,55 @@
+{% extends "base/base.html" %}
+{% block content %}
+
+<br/>
+<br/>
+<br/>
+
+<div class="row row-cols-1 row-cols-md-4 g-4">
+  <div class="col">
+    <div class="card">
+      <img src="/static/assets/images/auth/forderung.jpg" class="card-img-top" alt="Forderungen">
+
+      <div class="card-body">
+        <h5 class="card-title">Forderungen</h5>
+        <p class="card-text">Alle offenen Posten im Überblick</p>
+        <a href="/app/forderungen/liste" class="btn btn-secondary">Öffnen</a>
+      </div>
+    </div>
+  </div>
+  <div class="col">
+    <div class="card">
+      <img src="/static/assets/images/auth/werkstatt.jpg" class="card-img-top" alt="Offene Aufträge">
+
+      <div class="card-body">
+        <h5 class="card-title">Offene Aufträge</h5>
+        <p class="card-text">Warum geht es nicht weiter?</p>
+        <a href="/app/forderungen/liste" class="btn btn-secondary">Öffnen</a>
+      </div>
+    </div>
+  </div>
+  <div class="col">
+    <div class="card">
+      <img src="/static/assets/images/auth/auftragseingang.jpg" class="card-img-top" alt="Fahrzeug-Auftragseingang">
+
+      <div class="card-body">
+        <h5 class="card-title">Fahrzeug-Auftragseingang</h5>
+        <p class="card-text">Mein Baby heißt WBABT31060...</p>
+        <a href="/app/forderungen/liste" class="btn btn-secondary">Öffnen</a>
+      </div>
+    </div>
+  </div>
+  <div class="col">
+    <div class="card">
+      <img src="/static/assets/images/auth/planung.jpg" class="card-img-top" alt="Planung">
+
+      <div class="card-body">
+        <h5 class="card-title">Planung</h5>
+        <p class="card-text">Höher, schneller, weiter!</p>
+        <a href="/app/forderungen/liste" class="btn btn-secondary">Öffnen</a>
+      </div>
+    </div>
+  </div>
+</div>
+
+{% endblock %}

+ 28 - 7
templates/forderungen/details.html

@@ -1,8 +1,7 @@
 {% extends "base/base.html" %}
 {% block content %}
 
-
-<h2>Kommentare</h2>
+<h3>Kommentare</h3>
 
 <table class="table table-striped table-bordered">
   <thead>
@@ -30,7 +29,26 @@
 </table>
 
 
-<h2>Eingabemaske</h2>
+<h3>Dateien</h3>
+
+<table class="table table-striped table-bordered">
+  <thead>
+    <tr>
+        <th>Datum</th>
+        <th>Dateiname</th>
+    </tr>
+  </thead>
+  <tbody>
+    {% for row in files %}
+    <tr>
+      <td></td>
+      <td>{{ row }}</td>
+    </tr>
+    {% endfor %}
+  </tbody>
+</table>
+
+<h3>Eingabemaske</h3>
 
 <form class="row g-3">
   <div class="col-md-6">
@@ -73,12 +91,15 @@
     </div>
   </div>
   <div class="col-12">
-    <button type="submit" class="btn btn-primary">Sign in</button>
+    <a class="btn btn-secondary" href="/app/forderungen/export/{{forderung_kopf[0].Client_DB}}_{{forderung_kopf[0].Document_No}}">Mahnung erstellen</a>
   </div>
 </form>
 
 
-<h2>Forderung Details</h2>
+
+
+
+<h3>Forderung Details</h3>
 
 <table class="table table-striped table-bordered">
   <tbody>
@@ -95,7 +116,7 @@
 </table>
 
 
-<h2>Mahnungen</h2>
+<h3>Mahnungen</h3>
 
 <table class="table table-striped table-bordered">
   <thead>
@@ -127,7 +148,7 @@
 
 
 
-<h2>Auftragspositionen</h2>
+<h3>Auftragspositionen</h3>
 
 <table class="table table-striped table-bordered">
   <thead>

+ 68 - 34
templates/forderungen/liste.html

@@ -1,41 +1,50 @@
 {% extends "base/base.html" %}
 {% block content %}
 <div class="d-flex mb-3">
-  <a class="btn btn-secondary me-2" href="/export/csv">Export CSV</a>
   <a class="btn btn-secondary" href="/export/xlsx">Export XLSX</a>
 </div>
 
-<form class="row g-3">
+<form class="row g-3" id="liste-filter"
+      hx-get=""
+      hx-params="*"
+      hx-trigger="change"
+      hx-push-url="true" 
+      hx-swap="innerHTML" 
+      hx-target="body">
   <div class="col-md-2">
     <label for="Hauptbetrieb" class="form-label">Hauptbetrieb</label>
-    <select id="Hauptbetrieb" class="form-select">
-        <option name="">-</option>
+    <select id="Hauptbetrieb" name="Hauptbetrieb" class="form-select">
+        <option value="">-</option>
       {% for key, value in filter.Hauptbetrieb.items() %}
-        <option name="{{ key }}">{{ value }}</option>
+        <option value="{{ key }}">{{ value }}</option>
       {% endfor %}
     </select>
   </div>
   <div class="col-md-3">
     <label for="Standort" class="form-label">Standort</label>
-    <select id="Standort" class="form-select">
-        <option name="">-</option>
+    <select id="Standort" name="Standort" class="form-select">
+        <option value="">-</option>
       {% for key, value in filter.Standort.items() %}
-        <option name="{{ key }}">{{ value }}</option>
+        <option value="{{ key }}">{{ value }}</option>
       {% endfor %}
     </select>
   </div>
   <div class="col-md-3">
     <label for="Bereich" class="form-label">Bereich</label>
-    <select id="Bereich" class="form-select">
-        <option name="">-</option>
+    <select id="Bereich" name="Bereich" class="form-select">
+        <option value="">-</option>
     </select>
   </div>
   <div class="col-md-4">
     <label for="Verursacher" class="form-label">Verursacher</label>
-    <select id="Verursacher" class="form-select">
-        <option name="">-</option>
+    <select id="Verursacher" name="Verursacher" class="form-select">
+        <option value="">-</option>
       {% for key, value in filter.Verursacher.items() %}
-        <option name="{{ key }}">{{ value }}</option>
+        {% if key == defaults.Verursacher %}
+        <option value="{{ key }}" selected>{{ value }}</option>
+        {% else %}
+        <option value="{{ key }}">{{ value }}</option>
+        {% endif %}
       {% endfor %}
     </select>
   </div>
@@ -43,22 +52,26 @@
 
   <div class="col-md-3">
     <label for="Rechnungsnummer" class="form-label">Rechnungsnummer</label>
-    <input type="email" class="form-control" id="Rechnungsnummer">
+    <input type="email" class="form-control" id="Rechnungsnummer" name="Rechnungsnummer">
   </div>
   <div class="col-md-2">
     <label for="RechnungsdatumVon" class="form-label">Rechnungsdatum von</label>
-    <input type="date" class="form-control" id="RechnungsdatumVon">
+    <input type="date" class="form-control" id="RechnungsdatumVon" name="RechnungsdatumVon">
   </div>
   <div class="col-md-2">
     <label for="RechnungsdatumBis" class="form-label">Rechnungsdatum bis</label>
-    <input type="date" class="form-control" id="RechnungsdatumBis">
+    <input type="date" class="form-control" id="RechnungsdatumBis" name="RechnungsdatumBis">
   </div>
   <div class="col-md-5">
     <label for="Kunde" class="form-label">Kunde</label>
-    <select id="Kunde" class="form-select">
-        <option name="">-</option>
+    <select id="Kunde" name="Kunde" class="form-select">
+        <option value="">-</option>
       {% for key, value in filter.Kunde.items() %}
-        <option name="{{ key }}">{{ value }}</option>
+        {% if key == defaults.Kunde %}
+        <option value="{{ key }}" selected>{{ value }}</option>
+        {% else %}
+        <option value="{{ key }}">{{ value }}</option>
+        {% endif %}
       {% endfor %}
     </select>
   </div>
@@ -66,37 +79,41 @@
 
   <div class="col-md-2">
     <label for="WiedervorlageVon" class="form-label">Wiedervorlage von</label>
-    <input type="date" class="form-control" id="WiedervorlageVon">
+    <input type="date" class="form-control" id="WiedervorlageVon" name="WiedervorlageVon">
   </div>
   <div class="col-md-2">
     <label for="WiedervorlageBis" class="form-label">Wiedervorlage bis</label>
-    <input type="date" class="form-control" id="WiedervorlageBis">
+    <input type="date" class="form-control" id="WiedervorlageBis" name="WiedervorlageBis">
   </div>
 
   <div class="col-md-4">
     <label for="Fahrzeug" class="form-label">Fahrzeug</label>
-    <select id="Fahrzeug" class="form-select">
-        <option name="">-</option>
+    <select id="Fahrzeug" name="Fahrzeug" class="form-select">
+        <option value="">-</option>
       {% for key, value in filter.Fahrzeug.items() %}
-        <option name="{{ key }}">{{ value }}</option>
+        <option value="{{ key }}">{{ value }}</option>
       {% endfor %}
     </select>
   </div>
   <div class="col-md-2">
     <label for="Staffel" class="form-label">Staffel</label>
-    <select id="Staffel" class="form-select">
-        <option name="">-</option>
+    <select id="Staffel" name="Staffel" class="form-select">
+        <option value="">-</option>
       {% for key, value in filter.Staffel.items() %}
-        <option name="{{ key }}">{{ value }}</option>
+        <option value="{{ key }}">{{ value }}</option>
       {% endfor %}
     </select>
   </div>
   <div class="col-md-2">
     <label for="Mahnstufe" class="form-label">Mahnstufe</label>
-    <select id="Mahnstufe" class="form-select">
-        <option name="">-</option>
+    <select id="Mahnstufe" name="Mahnstufe" class="form-select">
+        <option value="">-</option>
       {% for key, value in filter.Mahnstufe.items() %}
-        <option name="{{ key }}">{{ value }}</option>
+        {% if value == defaults[key] %}
+        <option value="{{ key }}" selected>{{ value }}</option>
+        {% else %}
+        <option value="{{ key }}">{{ value }}</option>
+        {% endif %}
       {% endfor %}
     </select>
   </div>
@@ -110,7 +127,7 @@
   </div>
 </form>
 
-
+<div  id="liste-content">
 <table class="table table-striped table-bordered">
   <thead>
     <tr>
@@ -131,11 +148,27 @@
   <tbody>
     {% for row in forderungen_liste %}
     <tr>
-      <td><a href="/forderungen/details/{{ row.Client_DB }}_{{ row.Document_No }}" class="btn btn-sm btn-primary"><i class="icon cil-pencil"></i></a></td>
+      <td>
+        <a href="/app/forderungen/details/{{ row.Client_DB }}_{{ row.Document_No }}" class="btn btn-sm btn-primary"><i class="icon cil-pencil"></i></a>
+      </td>
       <td>{{ row.Standort_Name }}</td>
-      <td>{{ row.Kunde }}</td>
+      <td>
+        <a href="/app/forderungen/liste?Kunde={{ row.Kunde|urlencode }}">{{ row.Kunde }}</a>
+        {% if row.Kunde.startswith("K") %}
+        <a href="mailto:dummy@xyz.de?subject={{ row.Document_No }}" class="btn btn-sm btn-outline-secondary">
+            <i class="cil-at"></i>
+        </a>
+        {% endif %}
+      </td>
       <td>{{ row.Bereich }}</td>
-      <td>{{ row.Verursacher }}</td>
+      <td>
+        <a href="/app/forderungen/liste?Verursacher={{ row.Verursacher|urlencode }}">{{ row.Verursacher }}</a>
+        {% if row.Verursacher == 'N.N.' %}
+        <a class="btn btn-sm btn-outline-secondary">
+            <i class="cil-user-follow"></i>
+        </a>
+        {% endif %}
+      </td>
       <td>{{ row.Document_No }}</td>
       <td>{{ row.Invoice_Date|date_format }}</td>
       <td class="text-end">{{ row.Tage }}</td>
@@ -147,4 +180,5 @@
     {% endfor %}
   </tbody>
 </table>
+</div>
 {% endblock %}

+ 1 - 0
templates/forderungen/queries/forderungen_liste.sql

@@ -29,6 +29,7 @@ SELECT [T1].[Client_DB]
      , T3.[Kommentar_Abteilung] 
 		 , T3.[Wiedervorlage]
 		 , T3.[Begründung]
+     , iif([T1].[Kunde] like 'k%', 'kunde@xyz.de', '') as Kunde_Email
 
 FROM [dbo].[Forderungen] T1
 INNER JOIN [dbo].[Benutzer_Rechte] T2 ON (T2.Benutzer_ID = '{{ BenutzerSelect.selectedOptionValue }}' OR T2.Benutzer_ID = '')