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>
55 lines
3.1 KiB
HTML
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 %}
|