Files
BlackMarkandClaude Opus 5.5 45424e6fd6 Vermietungs-Tool
A local web app for a small room-rental business in Austria: guest register,
room ledger, occupancy plan, invoices, the monthly tourist-tax report and the
quarterly VAT list. Application code only; it ships no data.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-02 16:52:27 +01:00

55 lines
3.1 KiB
HTML

{% extends "base.html" %}
{% block main_class %}grid-page{% endblock %}
{% block content %}
{% set unit_opts = rows|map(attribute='unit')|select|unique|sort %}
<h1>{{ t('invoices_title') }}</h1>
<div class="toolbar">
<input class="search live-search" data-grid="inv" type="text" placeholder="{{ t('search_placeholder') }}">
<select class="live-filter" data-grid="inv" data-col="{{ t('col_unit') }}"><option value="">{{ t('filter_all', col=t('col_unit')) }}</option>
{% for u in unit_opts %}<option>{{ u }}</option>{% endfor %}</select>
<select class="live-filter" data-grid="inv" data-col="{{ t('col_payment') }}"><option value="">{{ t('filter_all', col=t('col_payment')) }}</option>
<option>{{ t('payment_paid') }}</option><option>{{ t('payment_open') }}</option>
<option value="{{ t('payment_unknown') }}">{{ t('payment_unknown_label') }}</option></select>
<span class="count"><span class="grid-count" data-grid="inv">{{ rows|length }}</span> {{ t('showing_count', count='')|trim }}</span>
<span class="count">{{ t('sum_label') }}: <span class="grid-sum" data-grid="inv" data-col="{{ t('col_invoice_total') }}"></span> €</span>
<span class="spacer"></span>
<button class="btn secondary" type="button" onclick="gridPrint('inv')">{{ t('btn_print') }}</button>
<a class="btn" href="{{ url_for('invoice_new') }}">+ {{ t('btn_new_invoice') }}</a>
</div>
<p class="printinfo" data-grid="inv"></p>
<div class="tablewrap">
<table id="inv" class="grid">
<thead><tr>
<th>{{ t('col_invoice') }}</th><th>{{ t('col_date') }}</th><th>{{ t('col_unit') }}</th>
<th>{{ t('col_client') }}</th><th class="num">{{ t('col_invoice_total') }}</th>
<th>{{ t('col_payment') }}</th><th>{{ t('col_paid_date') }}</th>
<th class="nosort actions"></th>
</tr></thead>
<tbody>
{# rows ship inside an inert <template>: grids.js renders only the visible window (see freezeLayout) #}
<template>
{% for r in rows %}
<tr>
<td data-k="{{ '%04d.%04d'|format(r.number_key[0], r.number_key[1]) }}">{{ r.number }}</td><td>{{ r.date|date }}</td>
<td>{% if r.unit %}<span class="pill unit">{{ r.unit }}</span>{% endif %}</td>
<td>{{ r.client or '' }}</td>
<td class="num">{{ r.gross|euro if r.gross else '' }}</td>
<td>{% if r.payment_state == 'paid' %}<span class="pill paid">{{ t('payment_paid') }}</span>
{% elif r.payment_state == 'open' %}<span class="pill open">{{ t('payment_open') }}</span>
{% else %}{{ t('payment_unknown') }}{% endif %}</td>
<td>{{ r.paid_on|date }}</td>
<td class="actions">
<a class="btn secondary small" href="{{ url_for('invoice_view', invoice_id=r.id) }}">{{ t('btn_open') }}</a>
<a class="btn secondary small" href="{{ url_for('invoice_edit', invoice_id=r.id) }}">{{ t('btn_edit') }}</a>
</td>
</tr>
{% endfor %}
</template>
{% if not rows %}
<tr data-empty="1"><td class="empty" colspan="8">{{ t('no_results') }}</td></tr>
{% endif %}
</tbody>
</table>
</div>
{% endblock %}