{% extends "base.html" %} {% block title %}Movements — BILLS{% endblock %} {% block content %} {# ── Filter chips ─────────────────────────────────────────────────── #} {% set base_args = {} %} {% if q %}{% set _ = base_args.update({'q': q}) %}{% endif %} {% if per_page != 50 %}{% set _ = base_args.update({'per_page': per_page}) %}{% endif %} {% if sort_by != 'pdf_number' %}{% set _ = base_args.update({'sort': sort_by}) %}{% endif %} {% if sort_dir != 'desc' %}{% set _ = base_args.update({'dir': sort_dir}) %}{% endif %}
{# Search #} {# Filter chips #} {% macro chip(key, label, icon='', tooltip='') %} {% set is_on = flt[key] %} {% set new_args = dict(base_args) %} {% for k, v in flt.items() if v and k != key %} {% set _ = new_args.update({k: '1'}) %} {% endfor %} {% if not is_on %} {% set _ = new_args.update({key: '1'}) %} {% endif %} {% if icon.endswith('.png') or icon.endswith('.svg') or icon.endswith('.jpg') %} {% else %} {{ icon }} {% endif %} {{ label }} {% endmacro %}
{{ chip('has_pdf', 'Has PDF', 'pdf_icon.png', 'Movements with an attached invoice PDF') }} {{ chip('has_bank_row', 'Has Bank Row', '🏦', 'Movements backed by a bank statement entry') }} {{ chip('missing_pdf', 'Missing Invoice', 'upload_icon.png', 'Bank rows still needing an invoice PDF') }} {{ chip('needs_review', 'Needs Review', '⚠', 'Low-confidence extractions or missing required fields') }} {{ chip('excluded', 'Show Excluded', '🚫', 'Include manually-excluded movements') }}
{# ── Movements table ───────────────────────────────────────────────── #}
{% for m in movements.items %} {% else %} {% endfor %}
# Origin Date Company / Reason Direction Amount (€) Source
{{ m.display_id }} {% if m.has_pdf and m.has_bank_row %} ⚭ Fused {% elif m.has_pdf %} 📄 PDF {% elif m.has_bank_row %} 🏦 Bank {% endif %} {% set d = m.invoice_date or m.value_date or m.transaction_date %} {{ d.strftime('%d/%m/%Y') if d else '—' }} {% if m.company_name %} {{ m.company_name }} {% elif m.reason %} {{ m.reason }} {% else %} {% endif %} {% if m.invoice_number %} {{ m.invoice_number }} {% endif %} {% if m.direction == 'emitted' %} 📤 Emitted {% else %} 📥 Received {% endif %} {{ '%.2f'|format(m.amount|float) if m.amount is not none else '—' }} {% if m.extraction_source %} {{ m.extraction_source }} {% endif %} {% if m.has_pdf %} {% endif %} {% if m.has_bank_row and not m.has_pdf and not m.manually_excluded %} {% endif %} {% if m.fusion_status == 'ambiguous' %} {% endif %}
{% if flt.missing_pdf %} 🎉 No bank rows missing an invoice. Either everything is reconciled, or you haven't imported a bank statement yet. {% elif q or flt.has_pdf or flt.has_bank_row or flt.needs_review or flt.excluded %} No movements match the current filters. {% else %} No movements yet. Drop a PDF or bank statement on the Import page to get started. {% endif %}
{# ── Pagination ───────────────────────────────────────────────────── #} {% if movements.pages > 1 %} {# Merge base_args + active filter chips into a single dict for url_for #} {% set page_args = dict(base_args) %} {% for k, v in flt.items() if v %} {% set _ = page_args.update({k: '1'}) %} {% endfor %} {% endif %} {# ── Right-click context menu (delete) ───────────────────────────── #} {# ── Delete confirmation modal ──────────────────────────────────── #}
{% endblock %}