{% extends "base.html" %} {% from "_macros.html" import app_pill, item_type_badge, action_badge, avatar, money %} {% block title %}Dashboard{% endblock %} {% block breadcrumb %}

Übersicht

{% endblock %} {% block heading %}Dashboard{% endblock %} {% block topbar_actions %} + Auftrag + Angebot Mindestbestand {% endblock %} {% block content %}
{# v1.12.0: "Heute" — was muss erledigt werden #} {% if today_block and today_block.total_count > 0 %}

Heute zu erledigen {{ today_block.total_count }}

Tagesplan für {{ today_block.offene_anfragen|length + today_block.auftraege_kw|length }} Vorgänge. Klick auf einen Eintrag öffnet das Detail.

{% if today_block.offene_anfragen %}
Offene Anfragen ({{ today_block.offene_anfragen|length }})
{% for inq in today_block.offene_anfragen[:5] %}
{{ (inq.subject or inq.inquiry_no)[:40] }}
{{ inq.customer_name or '(unbekannt)' }} {% if inq.days_ago and inq.days_ago >= 2 %} · seit {{ inq.days_ago|int }} Tagen {% endif %}
{% endfor %}
{% endif %} {% if today_block.auftraege_kw %}
Aufträge diese Woche ({{ today_block.auftraege_kw|length }})
{% for so in today_block.auftraege_kw[:5] %}
{{ so.order_no }}
{{ so.customer_name or '?' }} · Liefer: {{ (so.due_date or '')[:10] }}
{% endfor %}
{% endif %} {% if today_block.ueberfaellige_rechnungen %}
Überfällige Rechnungen ({{ today_block.ueberfaellige_rechnungen|length }})
{% for inv in today_block.ueberfaellige_rechnungen[:5] %}
{{ inv.invoice_no }}
{{ inv.customer_name or '?' }} · {{ inv.days_over }} T überfällig {% if inv.dunning_level %} · Mahnstufe {{ inv.dunning_level }}{% endif %}
{% endfor %}
{% endif %} {% if today_block.wartungen_woche or today_block.werkzeug_nachbestellen %}
Werkstatt-Pflege ({{ today_block.wartungen_woche|length + today_block.werkzeug_nachbestellen|length }})
{% for w in today_block.wartungen_woche[:3] %}
{{ w.task_name }}
Wartung · fällig {{ (w.due_date or '')[:10] }}
{% endfor %} {% if today_block.werkzeug_nachbestellen %}
{{ today_block.werkzeug_nachbestellen|length }} Werkzeuge nachbestellen
→ Bestellvorschläge anzeigen
{% endif %}
{% endif %}
{% endif %} {% set b = budget %} {% set bar_color = '#10b981' if b.status == 'ok' else ('#f59e0b' if b.status == 'warning' else '#ef4444') %} {% set bar_width = (b.percent | round(0, 'common')) | int %} {% set bar_width_clamped = bar_width if bar_width < 100 else 100 %} {# Reihenfolge + Sichtbarkeit kommt aus dashboard_widgets — über /settings/dashboard konfigurierbar. #} {% if 'sales_kpis' in dashboard_widgets %} {# ---------- VERKAUFS-KPIs als VERTIKALES KARUSSELL ---------- #} {% endif %} {% if quality_kpis is defined and (quality_kpis.overdue_followups or quality_kpis.stale_inquiries or quality_kpis.unconfirmed_pos or dms_expiring_count or maintenance_due_count or tool_reorder_count) %} {# ---------- ACTION-CENTER: Was wartet auf dich? ---------- #}
⚠ Action-Center {% if maintenance_due_count %} 🔧 {{ maintenance_due_count }} Wartung{% if maintenance_due_count != 1 %}en{% endif %} {% if maintenance_due_overdue %}({{ maintenance_due_overdue }} überfällig){% else %}bald fällig{% endif %} {% endif %} {% if tool_reorder_count %} 🔩 {{ tool_reorder_count }} Werkzeug-Bestellvorschlag{% if tool_reorder_count != 1 %}{% endif %} {% endif %} {% if dms_expiring_count %} 📜 {{ dms_expiring_count }} Zertifikate/Dokumente laufen ab {% endif %} {% if quality_kpis.overdue_followups %} {{ quality_kpis.overdue_followups }} überfällige Follow-ups {% endif %} {% if quality_kpis.stale_inquiries %} {{ quality_kpis.stale_inquiries }} Anfragen seit 7 T unbeantwortet {% endif %} {# v1.12.2: Wartende Angebote — Follow-up-Kandidaten #} {% if overdue_quotes_count %} 💬 {{ overdue_quotes_count }} Angebot{% if overdue_quotes_count != 1 %}e{% endif %} warten auf Antwort {% endif %} {# v1.12.2: Auto-Lieferschein-Entwürfe (wenn Feature an) #} {% if auto_dn_draft_count %} 📦 {{ auto_dn_draft_count }} Auto-Lieferschein{% if auto_dn_draft_count != 1 %}e{% endif %} bereit {% endif %} {# v1.12.2: Demo-Passwort-Warnung — extrem prominent wenn Default-Passwörter aktiv #} {% if demo_pwd_count is defined and demo_pwd_count > 0 %} 🔓 {{ demo_pwd_count }} User mit Demo-Passwort — JETZT ÄNDERN {% endif %} {# v1.12.2: Backup-Reminder — kein Backup seit >14 Tagen ist rot #} {% if days_since_backup is defined and days_since_backup >= 7 %} 💾 {% if days_since_backup == 999 %}Noch kein Backup erstellt{% else %}Backup seit {{ days_since_backup }} Tagen{% endif %} {% endif %} {% if quality_kpis.unconfirmed_pos %} {{ quality_kpis.unconfirmed_pos }} POs ohne Bestätigung {% endif %}
{% endif %} {% if quality_kpis is defined and ('quality_kpis' in dashboard_widgets or dashboard_widgets is none) %} {# ---------- QUALITÄTS-/PRODUKTIONS-KPIs ---------- #}

Qualität & Compliance

Reklamationen · Material · Zertifikate · Liefertreue · Ausschuss

{% endif %} {% if 'funnel' in dashboard_widgets or 'recent_invoices' in dashboard_widgets %} {# ---------- Conversion-Funnel + neueste Rechnungen ---------- #}
{% if 'funnel' in dashboard_widgets %}

Conversion · 90 Tage

{% set f = sales.funnel %}
Anfragen{{ f.inq }}
Angebote {{ f.q }}{% if f.inq %} ({{ "%.0f"|format(f.q * 100 / f.inq) }} %){% endif %}
Angebote angenommen {{ f.q_won }}{% if f.q %} ({{ "%.0f"|format(f.q_won * 100 / f.q) }} %){% endif %}
Aufträge gesamt{{ f.so }}
{% endif %} {% if 'recent_invoices' in dashboard_widgets %}

Aktuelle Rechnungen

Alle →
{% if sales.recent_invoices %}
{% for inv in sales.recent_invoices %} {% set open_amt = (inv.total_gross or 0) - (inv.paid_amount or 0) %} {% set overdue = inv.due_date and inv.due_date < '2026-04-29' and open_amt > 0 %}
{{ inv.invoice_no }}
{{ inv.customer }}
{{ money(inv.total_gross) }} {{ inv.currency }}
{% if open_amt > 0 %}
{{ money(open_amt) }} offen{% if overdue %} · überfällig{% endif %}
{% else %}
bezahlt
{% endif %}
{{ INV_STATUS_LABELS.get(inv.status, inv.status) }}
{% endfor %}
{% else %}
Noch keine Rechnungen.
{% endif %}
{% endif %}
{% endif %} {% if 'operative_kpis' in dashboard_widgets %} {# ---------- OPERATIVE KPIs (Werkstatt) ---------- #}

Operativer Stand

Lager · Verleih · Einkauf · Prüfung · Wochenbudget

{% endif %} {% if 'weekly_budget' in dashboard_widgets %} {# ---------- 1-Zeiler Budget mit Progress ---------- #}

Werkzeug-Budget · KW {{ b.week_start[5:7] }}/{{ b.week_start[8:10] }}

{{ money(b.spent) }} / {{ money(b.budget) }} {% if b.status == 'over' %}· überschritten{% endif %}
{% endif %} {% if 'open_rentals' in dashboard_widgets or 'activity_feed' in dashboard_widgets %} {# ---------- Hauptbereich: Verleihe + Aktivität nebeneinander ---------- #}
{% if 'open_rentals' in dashboard_widgets %}

Aktive Ausleihen · {{ open_rentals|length }}

Alle →
{% if open_rentals %}
{% for r in open_rentals[:6] %}
{{ avatar(r.first_name, r.last_name) }}
{{ r.first_name }} {{ r.last_name }}
{{ r.machine_name or 'Werkbank' }} · {{ r.rented_at[11:16] }}
{{ r.ident }}
{{ r.description }}
{% endfor %}
{% else %}
Keine offenen Ausleihen
{% endif %}
{% endif %} {% if 'activity_feed' in dashboard_widgets %}

Aktivität

Alle →
{% for h in recent_history[:10] %}
{{ avatar(h.first_name, h.last_name) }}
{{ h.first_name or '—' }} · {{ h.action_name or h.action_code }}
{{ h.item_ident or '' }} {% if h.quantity %}· {{ h.quantity }}×{% endif %}
{{ h.created_at[11:16] }}
{% else %}
Keine Aktivität
{% endfor %}
{% endif %}
{% endif %} {# ---------- Untere Mini-Listen: Prüfmittel + Mindestbestand ---------- #} {% if ('inspections' in dashboard_widgets and insp_upcoming and insp_upcoming|length) or ('low_stock' in dashboard_widgets and low_stock) %}
{% if 'inspections' in dashboard_widgets and insp_upcoming and insp_upcoming|length %} {% endif %} {% if 'low_stock' in dashboard_widgets and low_stock %}

Mindestbestand · {{ kpis.low_stock_count }}

Alle →
{% endif %}
{% endif %}
{# /.dashboard-stack #} {% endblock %}