| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788 |
- """Decode legacy dashboard links into the regular editable list filters."""
- from datetime import date
- import json
- 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()}
|