{% extends "client_portal/base.html" %} {% from "components/ui.html" import page_header %} {% block title %}{{ _('Reports') }} - {{ _('Client Portal') }}{% endblock %} {% block content %} {% set breadcrumbs = [ {'text': _('Client Portal'), 'url': url_for('client_portal.dashboard')}, {'text': _('Reports')} ] %} {{ page_header( icon_class='fas fa-chart-bar', title_text=_('Reports'), subtitle_text=_('Project and invoice summaries') + (' — ' + (_('Last %(days)s days') % {'days': date_range_days}) if (date_range_days is defined and date_range_days) else ''), breadcrumbs=breadcrumbs ) }}

{{ _('Total Hours') }}

{{ "%.1f"|format(total_hours) }}

{{ _('Hours tracked') }}

{{ _('Total Invoiced') }}

{{ "%.2f"|format(invoice_summary.total) }}

EUR

{{ _('Paid') }}

{{ "%.2f"|format(invoice_summary.paid) }}

EUR

{{ _('Outstanding') }}

{{ "%.2f"|format(invoice_summary.unpaid) }}

EUR

{{ _('Project progress') }}

{% if project_hours %}
{% for ph in project_hours %} {% endfor %}
{{ _('Project') }} {{ _('Status') }} {{ _('Total Hours') }} {{ _('Billable Hours') }} {{ _('Est. / Budget') }}
{{ ph.project.name if ph.project else _('N/A') }}
{{ (ph.project.status if ph.project else 'active')|capitalize }} {{ "%.2f"|format(ph.hours) }}h {{ "%.2f"|format(ph.billable_hours) }}h {% if ph.get('estimated_hours') %}{{ "%.1f"|format(ph.estimated_hours) }}h{% endif %} {% if ph.get('estimated_hours') and ph.get('budget_amount') %} / {% endif %} {% if ph.get('budget_amount') %}{{ "%.2f"|format(ph.budget_amount) }} EUR{% endif %} {% if not ph.get('estimated_hours') and not ph.get('budget_amount') %}—{% endif %}
{% else %}

{{ _('No project hours data available.') }}

{% endif %}
{% if task_summary and (task_summary.total > 0 or task_summary.by_status) %}

{{ _('Task summary') }}

{{ _('Total tasks: %(count)s', count=task_summary.total) }}

{% if task_summary.by_status %}
{% for status, count in task_summary.by_status.items() %} {{ status|replace('_', ' ')|title }} ({{ count }}) {% endfor %}
{% else %}

{{ _('No tasks yet.') }}

{% endif %}
{% endif %} {% if time_by_date is defined and time_by_date %}

{{ _('Time by date (last 30 days)') }}

{% for row in time_by_date[:31] %} {% endfor %}
{{ _('Date') }} {{ _('Hours') }}
{{ row.date }} {{ "%.2f"|format(row.hours) }}h
{% endif %}

{{ _('Recent Time Entries (Last 30 Days)') }}

{% if recent_entries %}
{% for entry in recent_entries[:20] %} {% endfor %}
{{ _('Date') }} {{ _('Project') }} {{ _('Duration') }} {{ _('User') }}
{{ entry.start_time|user_date if entry.start_time else _('N/A') }}
{{ entry.project.name if entry.project else _('N/A') }}
{{ "%.2f"|format(entry.duration_hours) }}h
{{ entry.user.display_name if entry.user else _('N/A') }}
{% else %}

{{ _('No recent time entries.') }}

{% endif %}
{% endblock %}