Files
PackControl/pirp/public/belegarchiv.php

193 lines
9.0 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?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>