Added support for Streamdeck Pedal and updated UI to better fit the Packed UI style
This commit is contained in:
192
pirp/public/belegarchiv.php
Normal file
192
pirp/public/belegarchiv.php
Normal file
@@ -0,0 +1,192 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../src/config.php';
|
||||
require_once __DIR__ . '/../src/auth.php';
|
||||
require_once __DIR__ . '/../src/db.php';
|
||||
require_once __DIR__ . '/../src/icons.php';
|
||||
require_login();
|
||||
|
||||
$pdo = get_db();
|
||||
|
||||
$filter_type = $_GET['type'] ?? 'all'; // all | rechnung | ausgabe | mahnung
|
||||
$filter_from = trim($_GET['from'] ?? '');
|
||||
$filter_to = trim($_GET['to'] ?? '');
|
||||
$filter_q = trim($_GET['q'] ?? '');
|
||||
$invoice_id = isset($_GET['invoice_id']) ? (int)$_GET['invoice_id'] : 0;
|
||||
|
||||
$belege = [];
|
||||
|
||||
// ---- Rechnungs-PDFs ----
|
||||
if ($filter_type === 'all' || $filter_type === 'rechnung') {
|
||||
$base = "FROM invoices i JOIN customers c ON c.id = i.customer_id WHERE i.pdf_path IS NOT NULL";
|
||||
$params = [];
|
||||
if ($filter_from) { $base .= " AND i.invoice_date >= :from"; $params[':from'] = $filter_from; }
|
||||
if ($filter_to) { $base .= " AND i.invoice_date <= :to"; $params[':to'] = $filter_to; }
|
||||
if ($filter_q) { $base .= " AND (i.invoice_number ILIKE :q OR c.name ILIKE :q2)";
|
||||
$params[':q'] = '%' . $filter_q . '%'; $params[':q2'] = '%' . $filter_q . '%'; }
|
||||
try {
|
||||
$sql = "SELECT i.id, i.invoice_date AS beleg_date, i.invoice_number AS beleg_ref,
|
||||
c.name AS kunde, i.total_gross AS betrag, i.pdf_path,
|
||||
'rechnung' AS beleg_type, COALESCE(i.is_storno, FALSE) AS is_storno $base";
|
||||
$stmt = $pdo->prepare($sql);
|
||||
$stmt->execute($params);
|
||||
} catch (\PDOException $e) {
|
||||
// is_storno Spalte noch nicht migriert — Fallback ohne die Spalte
|
||||
$sql = "SELECT i.id, i.invoice_date AS beleg_date, i.invoice_number AS beleg_ref,
|
||||
c.name AS kunde, i.total_gross AS betrag, i.pdf_path,
|
||||
'rechnung' AS beleg_type, FALSE AS is_storno $base";
|
||||
$stmt = $pdo->prepare($sql);
|
||||
$stmt->execute($params);
|
||||
}
|
||||
$belege = array_merge($belege, $stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||
}
|
||||
|
||||
// ---- Ausgaben-Belege ----
|
||||
if ($filter_type === 'all' || $filter_type === 'ausgabe') {
|
||||
$sql = "SELECT e.id, e.expense_date AS beleg_date, e.description AS beleg_ref,
|
||||
'' AS kunde, e.amount AS betrag, e.attachment_path AS pdf_path,
|
||||
'ausgabe' AS beleg_type, FALSE AS is_storno
|
||||
FROM expenses e
|
||||
WHERE e.attachment_path IS NOT NULL";
|
||||
$params = [];
|
||||
if ($filter_from) { $sql .= " AND e.expense_date >= :from"; $params[':from'] = $filter_from; }
|
||||
if ($filter_to) { $sql .= " AND e.expense_date <= :to"; $params[':to'] = $filter_to; }
|
||||
if ($filter_q) { $sql .= " AND e.description ILIKE :q"; $params[':q'] = '%' . $filter_q . '%'; }
|
||||
$stmt = $pdo->prepare($sql);
|
||||
$stmt->execute($params);
|
||||
$belege = array_merge($belege, $stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||
}
|
||||
|
||||
// ---- Mahnungen ----
|
||||
$show_mahnungen = ($filter_type === 'all' || $filter_type === 'mahnung');
|
||||
if ($show_mahnungen) {
|
||||
$sql = "SELECT m.id, m.mahnung_date AS beleg_date,
|
||||
'MAHNUNG L' || m.level || ' – ' || i.invoice_number AS beleg_ref,
|
||||
c.name AS kunde, i.total_gross + m.fee_amount AS betrag,
|
||||
m.pdf_path, 'mahnung' AS beleg_type, FALSE AS is_storno,
|
||||
m.invoice_id
|
||||
FROM mahnungen m
|
||||
JOIN invoices i ON i.id = m.invoice_id
|
||||
JOIN customers c ON c.id = i.customer_id
|
||||
WHERE m.pdf_path IS NOT NULL";
|
||||
$params = [];
|
||||
if ($invoice_id) { $sql .= " AND m.invoice_id = :iid"; $params[':iid'] = $invoice_id; }
|
||||
if ($filter_from) { $sql .= " AND m.mahnung_date >= :from"; $params[':from'] = $filter_from; }
|
||||
if ($filter_to) { $sql .= " AND m.mahnung_date <= :to"; $params[':to'] = $filter_to; }
|
||||
if ($filter_q) { $sql .= " AND (i.invoice_number ILIKE :q OR c.name ILIKE :q2)";
|
||||
$params[':q'] = '%' . $filter_q . '%'; $params[':q2'] = '%' . $filter_q . '%'; }
|
||||
try {
|
||||
$stmt = $pdo->prepare($sql);
|
||||
$stmt->execute($params);
|
||||
$belege = array_merge($belege, $stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||
} catch (\PDOException $e) {
|
||||
// Tabelle noch nicht migriert
|
||||
}
|
||||
}
|
||||
|
||||
// Sortieren: neueste zuerst
|
||||
usort($belege, fn($a, $b) => strcmp($b['beleg_date'], $a['beleg_date']));
|
||||
|
||||
$type_labels = ['rechnung' => 'Rechnung', 'ausgabe' => 'Ausgabe', 'mahnung' => 'Mahnung'];
|
||||
$type_colors = ['rechnung' => 'var(--accent)', 'ausgabe' => 'var(--info)', 'mahnung' => 'var(--warning)'];
|
||||
?>
|
||||
<!doctype html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Belegarchiv</title>
|
||||
<link rel="stylesheet" href="assets/style.css">
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<h1>PIRP</h1>
|
||||
<nav>
|
||||
<a href="<?= url_for('index.php') ?>"><?= icon_dashboard() ?>Dashboard</a>
|
||||
<a href="<?= url_for('invoices.php') ?>"><?= icon_invoices() ?>Rechnungen</a>
|
||||
<a href="<?= url_for('customers.php') ?>"><?= icon_customers() ?>Kunden</a>
|
||||
<a href="<?= url_for('expenses.php') ?>"><?= icon_expenses() ?>Ausgaben</a>
|
||||
<a href="<?= url_for('belegarchiv.php') ?>" class="active"><?= icon_archive() ?>Belege</a>
|
||||
<a href="<?= url_for('journal.php') ?>"><?= icon_journal() ?>Journal</a>
|
||||
<a href="<?= url_for('euer.php') ?>"><?= icon_euer() ?>EÜR</a>
|
||||
<a href="<?= url_for('settings.php') ?>"><?= icon_settings() ?>Einstellungen</a>
|
||||
<a href="<?= url_for('logout.php') ?>"><?= icon_logout() ?>Logout (<?= htmlspecialchars($_SESSION['username'] ?? '') ?>)</a>
|
||||
<span class="cmd-k-hint" onclick="document.dispatchEvent(new KeyboardEvent('keydown',{key:'k',ctrlKey:true}))"><kbd>Ctrl+K</kbd></span>
|
||||
</nav>
|
||||
</header>
|
||||
<main>
|
||||
<form method="get" class="filters">
|
||||
<label>Typ:
|
||||
<select name="type">
|
||||
<option value="all" <?= $filter_type === 'all' ? 'selected' : '' ?>>Alle</option>
|
||||
<option value="rechnung" <?= $filter_type === 'rechnung' ? 'selected' : '' ?>>Rechnungen</option>
|
||||
<option value="ausgabe" <?= $filter_type === 'ausgabe' ? 'selected' : '' ?>>Ausgaben</option>
|
||||
<option value="mahnung" <?= $filter_type === 'mahnung' ? 'selected' : '' ?>>Mahnungen</option>
|
||||
</select>
|
||||
</label>
|
||||
<label>Suche:
|
||||
<input type="text" name="q" value="<?= htmlspecialchars($filter_q) ?>" placeholder="Nr., Beschreibung, Kunde...">
|
||||
</label>
|
||||
<label>Von:
|
||||
<input type="date" name="from" value="<?= htmlspecialchars($filter_from) ?>">
|
||||
</label>
|
||||
<label>Bis:
|
||||
<input type="date" name="to" value="<?= htmlspecialchars($filter_to) ?>">
|
||||
</label>
|
||||
<button type="submit">Filtern</button>
|
||||
<a href="<?= url_for('belegarchiv.php') ?>">Zurücksetzen</a>
|
||||
</form>
|
||||
|
||||
<section>
|
||||
<h2>Belegarchiv
|
||||
<span style="font-weight:normal;font-size:12px;color:var(--text-muted);"><?= count($belege) ?> Dokument(e)</span>
|
||||
</h2>
|
||||
|
||||
<?php if (empty($belege)): ?>
|
||||
<p style="color:var(--text-muted);">Keine Belege gefunden.</p>
|
||||
<?php else: ?>
|
||||
<table class="list">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Datum</th>
|
||||
<th>Typ</th>
|
||||
<th>Referenz / Beschreibung</th>
|
||||
<th>Kunde</th>
|
||||
<th style="text-align:right;">Betrag</th>
|
||||
<th>PDF</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($belege as $b): ?>
|
||||
<tr>
|
||||
<td><?= date('d.m.Y', strtotime($b['beleg_date'])) ?></td>
|
||||
<td>
|
||||
<span style="font-size:10px;color:<?= $type_colors[$b['beleg_type']] ?? 'var(--text)' ?>;">
|
||||
<?= $type_labels[$b['beleg_type']] ?? $b['beleg_type'] ?>
|
||||
<?php if (!empty($b['is_storno'])): ?>
|
||||
<span style="color:var(--error);"> · STORNO</span>
|
||||
<?php endif; ?>
|
||||
</span>
|
||||
</td>
|
||||
<td><?= htmlspecialchars($b['beleg_ref']) ?></td>
|
||||
<td style="color:var(--text-muted);"><?= htmlspecialchars($b['kunde']) ?></td>
|
||||
<td style="text-align:right;font-family:var(--font-mono);font-size:12px;">
|
||||
<?= number_format((float)$b['betrag'], 2, ',', '.') ?> €
|
||||
</td>
|
||||
<td>
|
||||
<?php if ($b['beleg_type'] === 'rechnung'): ?>
|
||||
<a href="<?= url_for('invoice_pdf.php?id=' . $b['id']) ?>" target="_blank">PDF</a>
|
||||
<?php elseif ($b['beleg_type'] === 'ausgabe'): ?>
|
||||
<a href="<?= url_for('expense_file.php?id=' . $b['id']) ?>" target="_blank">PDF</a>
|
||||
<?php elseif ($b['beleg_type'] === 'mahnung'): ?>
|
||||
<a href="<?= url_for('mahnung_pdf.php?id=' . $b['id']) ?>" target="_blank">PDF</a>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
<?php endif; ?>
|
||||
</section>
|
||||
</main>
|
||||
<script src="assets/command-palette.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user