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

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")
     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:
 def checked(input: str) -> str:
     if input in ("J", "1", 1, True):
     if input in ("J", "1", 1, True):
         return "checked"
         return "checked"
@@ -41,6 +49,7 @@ def show(input: str) -> str:
 
 
 templates.env.filters["number_format"] = number_format
 templates.env.filters["number_format"] = number_format
 templates.env.filters["date_format"] = date_format
 templates.env.filters["date_format"] = date_format
+templates.env.filters["date_format2"] = date_format2
 templates.env.filters["checked"] = checked
 templates.env.filters["checked"] = checked
 templates.env.filters["selected"] = selected
 templates.env.filters["selected"] = selected
 templates.env.filters["truefalse"] = truefalse
 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 io
 import re
 import re
-from dataclasses import dataclass
 from datetime import datetime, timedelta
 from datetime import datetime, timedelta
 from pathlib import Path
 from pathlib import Path
 from urllib.parse import unquote, urlencode
 from urllib.parse import unquote, urlencode
@@ -18,6 +17,8 @@ from fastapi.responses import (
 from sqlalchemy import text
 from sqlalchemy import text
 from sqlalchemy.orm import Session
 from sqlalchemy.orm import Session
 
 
+from app.query_filter import filter_type_option, import_filter_config
+
 from .db import get_session
 from .db import get_session
 from .jinja_templates import templates
 from .jinja_templates import templates
 from .ldap import ldap_authenticate
 from .ldap import ldap_authenticate
@@ -63,77 +64,7 @@ def single_quote(text: str):
     return "'" + unquote(text) + "'"
     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)
 @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(
     query = templates.TemplateResponse(request, "forderungen/liste/queries/forderungen_liste.sql", context).body.decode(
         "utf-8"
         "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 = db.execute(text("SELECT * FROM [dbo].[Forderungen]"))
     q_res = db.execute(text(query))
     q_res = db.execute(text(query))
     col_names = list(q_res.keys())
     col_names = list(q_res.keys())
@@ -161,7 +98,7 @@ def forderungen_liste(request: Request, db: Session = Depends(get_session), limi
 
 
     filters = {}
     filters = {}
     for f in forderung_filter_config:
     for f in forderung_filter_config:
-        if f.key_column == "":
+        if f.key_column not in col_names:
             continue
             continue
         filters[f.name] = {row[col_names.index(f.key_column)]: row[col_names.index(f.value_column)] for row in q}
         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]
         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 %}
       {% endfor %}
     </select>
     </select>
     {% elif f.filter_type == 'date' %}
     {% 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 %}
     {% else %}
     <input type="text" class="form-control" id="{{ f.name }}" name="{{ f.name }}" value="{{ f.current_value }}">
     <input type="text" class="form-control" id="{{ f.name }}" name="{{ f.name }}" value="{{ f.current_value }}">
     {% endif %}
     {% 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].[Forderungsart]
      --, [F].[Abwarten]
      --, [F].[Abwarten]
      , [F].[Verursacher_Benutzer_ID]
      , [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_Fibu], ''), 50) AS [Kommentar_Fibu]
      , left(isnull([FK].[Kommentar_Abteilung], ''), 50) AS [Kommentar_Abteilung]
      , left(isnull([FK].[Kommentar_Abteilung], ''), 50) AS [Kommentar_Abteilung]
      , [K].[Kunde_Email] AS [Kunde_Email]
      , [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])
 AND ([BR].[Rolle] = 'Buchhaltung' OR [BR].[Benutzer_ID] = [F].[Verursacher_Benutzer_ID])
 
 
 WHERE 1 = 1
 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
 ORDER BY F.[Wiedervorlage] ASC, F.[Tage] DESC