Просмотр исходного кода

Filter in csv ausgelagert

Co-authored-by: Copilot <copilot@github.com>
gc-server3 3 дней назад
Родитель
Сommit
ada592407d

+ 9 - 0
app/jinja_templates.py

@@ -15,6 +15,14 @@ def date_format(input: datetime) -> str:
     return input.strftime("%d.%m.%Y")
 
 
+def date_format2(input: datetime) -> str:
+    if input is None:
+        return ""
+    if isinstance(input, str):
+        return input[:10]
+    return input.strftime("%Y-%m-%d")
+
+
 def checked(input: str) -> str:
     if input in ("J", "1", 1, True):
         return "checked"
@@ -41,6 +49,7 @@ def show(input: str) -> str:
 
 templates.env.filters["number_format"] = number_format
 templates.env.filters["date_format"] = date_format
+templates.env.filters["date_format2"] = date_format2
 templates.env.filters["checked"] = checked
 templates.env.filters["selected"] = selected
 templates.env.filters["truefalse"] = truefalse

+ 90 - 0
app/query_filter.py

@@ -0,0 +1,90 @@
+import csv
+from dataclasses import dataclass
+
+
+@dataclass
+class FilterConfig:
+    name: str
+    text: str
+    filter_type: str
+    width: str
+    key_column: str
+    value_column: str
+    sort_column: str
+    visible: bool = True
+    default_value: str = ""
+    options: list[dict[str, str]] | None = None
+    current_value: str | None = None
+
+    @property
+    def query_param(self) -> str:
+        if self.current_value is None or self.current_value == "":
+            if self.default_value is None or self.default_value == "":
+                return None
+            self.current_value = self.default_value
+
+        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}' "
+        # if self.filter_type == "select":
+        #     return f"{self.key_column} IN ({self.current_value})"
+        return f" [{self.key_column}] LIKE '%{self.current_value}%' "
+
+    @staticmethod
+    def from_dict(
+        name: str,
+        filter_type: str,
+        width: str,
+        text: str,
+        key_column: str,
+        value_column: str,
+        sort_column: str,
+        default_value: str,
+    ) -> "FilterConfig":
+        if filter_type not in ["text", "select", "date", "hidden"]:
+            filter_type = "text"
+        if width not in ["1", "2", "3", "4"]:
+            width = "2"
+        if not text:
+            text = name
+        if not key_column:
+            key_column = name
+        if not value_column:
+            value_column = key_column
+        if not sort_column:
+            sort_column = key_column
+        if not default_value:
+            default_value = ""
+
+        return FilterConfig(
+            name=name,
+            text=text,
+            filter_type=filter_type,
+            width=width,
+            key_column=key_column,
+            value_column=value_column,
+            sort_column=sort_column,
+            default_value=default_value,
+        )
+
+
+filter_type_option = {
+    "text": "text",
+    "select": "selectedOptionValue",
+    "date": "selectedDate",
+    "hidden": "selectedOptionValue",
+}
+
+
+def import_filter_config() -> list[FilterConfig]:
+    res = []
+    with open(
+        "templates\\forderungen\\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())
+
+            res.append(config)
+    return res

+ 11 - 74
app/routes.py

@@ -1,6 +1,5 @@
 import io
 import re
-from dataclasses import dataclass
 from datetime import datetime, timedelta
 from pathlib import Path
 from urllib.parse import unquote, urlencode
@@ -18,6 +17,8 @@ from fastapi.responses import (
 from sqlalchemy import text
 from sqlalchemy.orm import Session
 
+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
@@ -63,77 +64,7 @@ def single_quote(text: str):
     return "'" + unquote(text) + "'"
 
 
-@dataclass
-class FilterConfig:
-    name: str
-    text: str
-    filter_type: str
-    width: str
-    key_column: str
-    value_column: str
-    visible: bool = True
-    default_value: str = ""
-    options: list[dict[str, str]] | None = None
-    current_value: str | None = None
-
-
-forderung_filter_config = [
-    FilterConfig("Hauptbetrieb", "Hauptbetrieb", "select", "2", "Client_DB", "Hauptbetrieb_Name"),
-    FilterConfig("Standort", "Standort", "select", "3", "Standort_ID", "Standort_Name"),
-    FilterConfig("Bereich", "Bereich", "select", "3", "Bereich", "Bereich"),
-    FilterConfig("Verursacher", "Verursacher", "select", "4", "Verursacher", "Verursacher"),
-    FilterConfig("Rechnungsnummer", "Rechnungsnummer", "text", "2", "Document_No", "Document_No"),
-    FilterConfig(
-        "RechnungsdatumVon",
-        "Rechnungsdatum von",
-        "date",
-        "2",
-        "Invoice_Date",
-        "Invoice_Date",
-        default_value="2000-01-01T00:00:00",
-    ),
-    FilterConfig(
-        "RechnungsdatumBis",
-        "Rechnungsdatum bis",
-        "date",
-        "2",
-        "Invoice_Date",
-        "Invoice_Date",
-        default_value="2027-01-01T00:00:00",
-    ),
-    FilterConfig("Kunde", "Kunde", "text", "4", "Kunde", "Kunde"),
-    FilterConfig("Abwarten", "Abwarten", "select", "2", "Abwarten", "Abwarten"),
-    FilterConfig(
-        "WiedervorlageVon",
-        "Wiedervorlage von",
-        "date",
-        "2",
-        "Wiedervorlage",
-        "Wiedervorlage",
-        default_value="2000-01-01T00:00:00",
-    ),
-    FilterConfig(
-        "WiedervorlageBis",
-        "Wiedervorlage bis",
-        "date",
-        "2",
-        "Wiedervorlage",
-        "Wiedervorlage",
-        default_value="2027-01-01T00:00:00",
-    ),
-    FilterConfig("Fahrzeug", "Fahrzeug", "select", "2", "VIN", "VIN"),
-    FilterConfig("Staffel", "Staffel", "select", "2", "Staffel", "Staffel"),
-    FilterConfig("Mahnstufe", "Mahnstufe", "select", "2", "Mahnstufe", "Mahnstufe"),
-    FilterConfig("Bearbeitet", "Bearbeitet", "select", "2", "Bearbeitet", "Bearbeitet"),
-    FilterConfig("BenutzerSelect", "Benutzer", "hidden", "2", "", "", visible=False, default_value="winter"),
-]
-
-filter_type_option = {
-    "text": "text",
-    "select": "selectedOptionValue",
-    "date": "selectedDate",
-    "hidden": "selectedOptionValue",
-}
+forderung_filter_config = import_filter_config()
 
 
 @router.get("/app/forderungen/liste", response_class=HTMLResponse)
@@ -153,7 +84,13 @@ def forderungen_liste(request: Request, db: Session = Depends(get_session), limi
     query = templates.TemplateResponse(request, "forderungen/liste/queries/forderungen_liste.sql", context).body.decode(
         "utf-8"
     )
-    # print(query)
+    query_params = [
+        f.query_param for f in forderung_filter_config if f.query_param is not None and f.filter_type != "hidden"
+    ]
+    if query_params:
+        query = query.replace("1 = 1", " AND ".join(query_params))
+    print(query)
+    print(query_params)
     # q = db.execute(text("SELECT * FROM [dbo].[Forderungen]"))
     q_res = db.execute(text(query))
     col_names = list(q_res.keys())
@@ -161,7 +98,7 @@ def forderungen_liste(request: Request, db: Session = Depends(get_session), limi
 
     filters = {}
     for f in forderung_filter_config:
-        if f.key_column == "":
+        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}
         f.options = filters[f.name]

+ 27 - 0
filter_export.py

@@ -0,0 +1,27 @@
+import csv
+from dataclasses import asdict
+
+from app.routes import FilterConfig, forderung_filter_config
+
+
+def export_filter_config():
+    with open("filter_config.csv", "w", newline="", encoding="latin-1") as csvfile:
+        writer = csv.DictWriter(csvfile, fieldnames=asdict(forderung_filter_config[0]).keys(), delimiter=";")
+        writer.writeheader()
+        writer.writerows([asdict(config) for config in forderung_filter_config])
+
+
+# name	filter_type	width	text	key_column	value_column	sort_column	default_value
+
+
+def import_filter_config2():
+    with open("forderungen\\liste\\config\\liste_filter.csv", "r", newline="", encoding="latin-1") as csvfile:
+        reader = csv.DictReader(csvfile, delimiter=";")
+        for row in reader:
+            # Convert the row dictionary to a FilterConfig object
+            config = FilterConfig.from_dict(*row.values())
+            print(config)
+
+
+if __name__ == "__main__":
+    import_filter_config2()

+ 1 - 1
templates/base/liste_filter.html

@@ -23,7 +23,7 @@
       {% endfor %}
     </select>
     {% elif f.filter_type == 'date' %}
-    <input type="date" class="form-control" id="{{ f.name }}" name="{{ f.name }}">
+    <input type="date" class="form-control" id="{{ f.name }}" name="{{ f.name }}" value="{{ f.current_value|date_format2 }}">
     {% else %}
     <input type="text" class="form-control" id="{{ f.name }}" name="{{ f.name }}" value="{{ f.current_value }}">
     {% endif %}

+ 17 - 0
templates/forderungen/liste/config/liste_filter.csv

@@ -0,0 +1,17 @@
+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;;;;;
+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

+ 4 - 17
templates/forderungen/liste/queries/forderungen_liste.sql

@@ -29,6 +29,10 @@ SELECT [F].[Client_DB]
      , [F].[Forderungsart]
      --, [F].[Abwarten]
      , [F].[Verursacher_Benutzer_ID]
+     , F.Kunde2
+     , 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]
@@ -56,21 +60,4 @@ AND [F].[Standort_ID] = [BR].[Standort_ID]
 AND ([BR].[Rolle] = 'Buchhaltung' OR [BR].[Benutzer_ID] = [F].[Verursacher_Benutzer_ID])
 
 WHERE 1 = 1
-AND F.[Invoice_Date] >= {{ RechnungsdatumVon.selectedDate }}
-AND F.[Invoice_Date] <= {{ RechnungsdatumBis.selectedDate }}
-AND F.[Client_DB] LIKE '%' + {{ Hauptbetrieb.selectedOptionValue }}
-AND F.[Standort_ID] LIKE '%' + {{ Standort.selectedOptionValue }}
-AND F.[Bereich] LIKE '%' + {{ Bereich.selectedOptionValue }}
-AND F.[Document_No] LIKE '%' + {{ Rechnungsnummer.text }} + '%'
-AND F.[Kunde] LIKE '%' + {{ Kunde.text }} + '%'
-AND F.[Verursacher] LIKE '%' + {{ Verursacher.selectedOptionValue }}
-AND F.[VIN] LIKE '%' + {{ Fahrzeug.selectedOptionValue }}
-AND F.[Staffel] LIKE '%' + {{ Staffel.selectedOptionValue }}
-AND F.[Mahnstufe] LIKE '%' + {{ Mahnstufe.selectedOptionValue }}
-AND F.[Bearbeitet] LIKE '%' + {{ Bearbeitet.selectedOptionValue }}
-AND F.[Abwarten] LIKE '%' + {{ Abwarten.selectedOptionValue }}
-AND (
-	F.Wiedervorlage >= {{ WiedervorlageVon.selectedDate }}
-	AND F.Wiedervorlage <= {{ WiedervorlageBis.selectedDate }}
-)
 ORDER BY F.[Wiedervorlage] ASC, F.[Tage] DESC