| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100 |
- """Decode legacy dashboard links into the regular editable list filters."""
- import json
- from datetime import date
- from .query_filter import EMPTY_FILTER_VALUE, encode_filter_values
- VIEWS = ("Altersstaffel", "Standort", "Verursacher", "Wiedervorlage")
- DASHBOARD_VIEWS = VIEWS[:-1] # Old Wiedervorlage list selections remain valid.
- def _date_key(key):
- if key is None:
- return
- if not isinstance(key, dict) or set(key) != {"from", "to"} or not any(key.values()):
- raise ValueError("Ungültiger Datumsfilter")
- for value in key.values():
- if value is not None and (not isinstance(value, str) or date.fromisoformat(value).isoformat() != value):
- raise ValueError("Ungültiges Datum")
- if key["from"] and key["to"] and key["from"] > key["to"]:
- raise ValueError("Ungültiger Zeitraum")
- if key["to"] == "9999-12-31":
- raise ValueError("Zeitraum außerhalb des unterstützten Bereichs")
- def _value(value):
- if value is not None and (
- not isinstance(value, str)
- or len(value) > 500
- or any(ord(char) < 32 or ord(char) == 127 or 0xD800 <= ord(char) <= 0xDFFF for char in value)
- ):
- raise ValueError("Ungültiger Gruppenschlüssel")
- def parse_segment(raw):
- if not raw:
- return None
- if not isinstance(raw, str) or len(raw) > 4096:
- raise ValueError("Ungültiger Dashboardfilter")
- try:
- segment = json.loads(raw)
- except (ValueError, TypeError, RecursionError) as error:
- raise ValueError("Ungültiger Dashboardfilter") from error
- if (
- not isinstance(segment, dict)
- or set(segment) - {"view", "key", "department", "only_invoices", "follow_up"}
- or not {"view", "key"} <= set(segment)
- or segment["view"] not in VIEWS
- ):
- raise ValueError("Ungültiger Dashboardfilter")
- key, view = segment["key"], segment["view"]
- if "only_invoices" in segment and type(segment["only_invoices"]) is not bool:
- raise ValueError("Ungültiger Rechnungsfilter")
- if "department" in segment:
- _value(segment["department"])
- if "follow_up" in segment:
- _date_key(segment["follow_up"])
- if view == "Altersstaffel":
- _value(key)
- elif view == "Standort":
- if not isinstance(key, dict) or set(key) != {"client", "site"} or not key["client"]:
- raise ValueError("Ungültiger Standortfilter")
- _value(key["client"])
- _value(key["site"])
- elif view == "Verursacher":
- if not isinstance(key, dict) or set(key) not in ({"id"}, {"text"}):
- raise ValueError("Ungültiger Verursacherfilter")
- _value(next(iter(key.values())))
- if "id" in key and not key["id"]:
- raise ValueError("Benutzer-ID fehlt")
- else:
- _date_key(key)
- return segment
- def pack_segment(segment):
- return json.dumps(segment, ensure_ascii=False, sort_keys=True, separators=(",", ":"))
- def segment_filters(segment, person_values=None):
- """Translate old dashboard URLs into editable list filters, never hidden predicates."""
- if not segment:
- return {}
- values = {}
- key, view = segment["key"], segment["view"]
- if view == "Standort":
- values.update(Mandant=[key["client"]], Filiale=[key["site"]])
- elif view == "Altersstaffel":
- values["Staffel"] = [key]
- elif view == "Verursacher":
- values["Verursacher"] = person_values if person_values is not None else [key.get("text", key.get("id"))]
- if "department" in segment:
- values["Abteilung"] = [segment["department"]]
- if segment.get("only_invoices"):
- values["RechnungGutschrift"] = ["Rechnung"]
- # Both the old Wiedervorlage rubric and follow_up stacks are deliberately ignored.
- return {
- name: encode_filter_values([EMPTY_FILTER_VALUE if value in (None, "") else value for value in items])
- for name, items in values.items()
- }
|