billing frontend for mariadb. setup as otb_billing for outsidethebox.top accounting. also involved with outsidethedb
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

167 lines
5.9 KiB

<!doctype html>
<html>
<head>
<title>Invoices</title>
<style>
.status-badge {
display: inline-block;
padding: 3px 8px;
border-radius: 999px;
font-size: 12px;
font-weight: bold;
text-transform: uppercase;
letter-spacing: 0.03em;
}
.status-draft { background: #e5e7eb; color: #111827; }
.status-pending { background: #dbeafe; color: #1d4ed8; }
.status-partial { background: #fef3c7; color: #92400e; }
.status-paid { background: #dcfce7; color: #166534; }
.status-overdue { background: #fee2e2; color: #991b1b; }
.status-cancelled { background: #e5e7eb; color: #4b5563; }
.locked-note {
color: #92400e;
font-weight: bold;
}
.filter-box {
border: 1px solid #ccc;
padding: 12px;
margin: 14px 0;
max-width: 1100px;
}
.filter-row {
display: flex;
gap: 14px;
align-items: end;
flex-wrap: wrap;
}
.filter-row div {
display: flex;
flex-direction: column;
}
input[type="date"],
input[type="number"],
select {
padding: 6px;
min-width: 150px;
}
.action-links {
margin-top: 12px;
display: flex;
gap: 18px;
flex-wrap: wrap;
}
</style>
<link rel="icon" type="image/png" href="/static/favicon.png">
</head>
<body>
<h1>Invoices</h1>
<p><a href="/">Home</a></p>
<p><a href="/invoices/new">Create Invoice</a></p>
<div class="filter-box">
<form method="get" action="/invoices">
<div class="filter-row">
<div>
<label for="start_date">Issued From</label>
<input type="date" id="start_date" name="start_date" value="{{ filters.start_date if filters is defined else '' }}">
</div>
<div>
<label for="end_date">Issued To</label>
<input type="date" id="end_date" name="end_date" value="{{ filters.end_date if filters is defined else '' }}">
</div>
<div>
<label for="status">Status</label>
<select id="status" name="status">
<option value="" {% if not filters.status %}selected{% endif %}>All</option>
<option value="draft" {% if filters.status == 'draft' %}selected{% endif %}>draft</option>
<option value="pending" {% if filters.status == 'pending' %}selected{% endif %}>pending</option>
<option value="partial" {% if filters.status == 'partial' %}selected{% endif %}>partial</option>
<option value="paid" {% if filters.status == 'paid' %}selected{% endif %}>paid</option>
<option value="overdue" {% if filters.status == 'overdue' %}selected{% endif %}>overdue</option>
<option value="cancelled" {% if filters.status == 'cancelled' %}selected{% endif %}>cancelled</option>
</select>
</div>
<div>
<label for="client_id">Client</label>
<select id="client_id" name="client_id">
<option value="" {% if not filters.client_id %}selected{% endif %}>All Clients</option>
{% for c in clients %}
<option value="{{ c.id }}" {% if filters.client_id == (c.id|string) %}selected{% endif %}>
{{ c.client_code }} - {{ c.company_name }}
</option>
{% endfor %}
</select>
</div>
<div>
<label for="limit">Limit</label>
<input type="number" id="limit" name="limit" min="1" step="1" value="{{ filters.limit if filters is defined else '' }}">
</div>
<div>
<button type="submit">Apply Filters</button>
</div>
</div>
<div class="action-links">
<a href="/invoices">Clear Filters</a>
<a href="/invoices/export.csv?start_date={{ filters.start_date if filters is defined else '' }}&end_date={{ filters.end_date if filters is defined else '' }}&status={{ filters.status if filters is defined else '' }}&client_id={{ filters.client_id if filters is defined else '' }}&limit={{ filters.limit if filters is defined else '' }}">Export Filtered CSV</a>
<a href="/invoices/export-pdf.zip?start_date={{ filters.start_date if filters is defined else '' }}&end_date={{ filters.end_date if filters is defined else '' }}&status={{ filters.status if filters is defined else '' }}&client_id={{ filters.client_id if filters is defined else '' }}&limit={{ filters.limit if filters is defined else '' }}">Export Filtered PDF ZIP</a>
<a href="/invoices/print?start_date={{ filters.start_date if filters is defined else '' }}&end_date={{ filters.end_date if filters is defined else '' }}&status={{ filters.status if filters is defined else '' }}&client_id={{ filters.client_id if filters is defined else '' }}&limit={{ filters.limit if filters is defined else '' }}">Batch Print</a>
</div>
</form>
</div>
<table border="1" cellpadding="6">
<tr>
<th>ID</th>
<th>Invoice</th>
<th>Client</th>
<th>Currency</th>
<th>Total</th>
<th>Paid</th>
<th>Remaining</th>
<th>Status</th>
<th>Issued</th>
<th>Due</th>
<th>Actions</th>
</tr>
{% for i in invoices %}
<tr>
<td>{{ i.id }}</td>
<td>{{ i.invoice_number }}</td>
<td>{{ i.client_code }} - {{ i.company_name }}</td>
<td>{{ i.currency_code }}</td>
<td>{{ i.total_amount|money(i.currency_code) }}</td>
<td>{{ i.amount_paid|money(i.currency_code) }}</td>
<td>{{ (i.total_amount - i.amount_paid)|money(i.currency_code) }}</td>
<td>
<span class="status-badge status-{{ i.status }}">{{ i.status }}</span>
</td>
<td>{{ i.issued_at|localtime }}</td>
<td>{{ i.due_at|localtime }}</td>
<td>
<a href="/invoices/view/{{ i.id }}">View</a> |
<a href="/invoices/pdf/{{ i.id }}">PDF</a> |
<a href="/invoices/edit/{{ i.id }}">Edit</a>
{% if i.payment_count > 0 %}
<span class="locked-note">(Locked)</span>
{% endif %}
</td>
</tr>
{% endfor %}
</table>
{% include "footer.html" %}
</body>
</html>