130 lines
5.1 KiB
PHP
130 lines
5.1 KiB
PHP
<?php
|
||
require_once __DIR__ . '/../src/config.php';
|
||
require_once __DIR__ . '/../src/auth.php';
|
||
require_once __DIR__ . '/../src/db.php';
|
||
require_once __DIR__ . '/../src/invoice_functions.php';
|
||
require_once __DIR__ . '/../src/pdf_functions.php';
|
||
require_once __DIR__ . '/../src/journal_functions.php';
|
||
require_once __DIR__ . '/../src/icons.php';
|
||
require_login();
|
||
|
||
$id = isset($_GET['id']) ? (int)$_GET['id'] : 0;
|
||
if (!$id) {
|
||
header('Location: ' . url_for('invoices.php'));
|
||
exit;
|
||
}
|
||
|
||
$inv = get_invoice_with_customer($id);
|
||
if (!$inv) {
|
||
header('Location: ' . url_for('invoices.php?msg=' . urlencode('Rechnung nicht gefunden.')));
|
||
exit;
|
||
}
|
||
|
||
// Bereits storniert?
|
||
if (!empty($inv['is_storno'])) {
|
||
header('Location: ' . url_for('invoices.php?msg=' . urlencode('Diese Rechnung ist selbst eine Stornorechnung.')));
|
||
exit;
|
||
}
|
||
|
||
// Prüfe ob schon Storno existiert
|
||
$pdo = get_db();
|
||
try {
|
||
$stmt = $pdo->prepare("SELECT id FROM invoices WHERE storno_of = :id LIMIT 1");
|
||
$stmt->execute([':id' => $id]);
|
||
$existing_storno = $stmt->fetchColumn();
|
||
} catch (\PDOException $e) {
|
||
$existing_storno = false;
|
||
}
|
||
|
||
if ($existing_storno) {
|
||
header('Location: ' . url_for('invoices.php?msg=' . urlencode('Für diese Rechnung existiert bereits eine Stornorechnung.')));
|
||
exit;
|
||
}
|
||
|
||
$error = '';
|
||
|
||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||
try {
|
||
$storno_id = create_storno_invoice($id);
|
||
archive_invoice_pdf($storno_id);
|
||
|
||
// Journalbuchung stornieren falls vorhanden
|
||
$original_entry = get_journal_entry_for_invoice($id);
|
||
if ($original_entry) {
|
||
create_storno_journal_entry($id, $storno_id);
|
||
}
|
||
|
||
$stmt = $pdo->prepare("SELECT invoice_number FROM invoices WHERE id = :id");
|
||
$stmt->execute([':id' => $storno_id]);
|
||
$storno_number = $stmt->fetchColumn();
|
||
|
||
header('Location: ' . url_for('invoices.php?msg=' . urlencode('Stornorechnung ' . $storno_number . ' erstellt.')));
|
||
exit;
|
||
} catch (\Exception $e) {
|
||
$error = $e->getMessage();
|
||
}
|
||
}
|
||
?>
|
||
<!doctype html>
|
||
<html lang="de">
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<title>Storno – <?= htmlspecialchars($inv['invoice_number']) ?></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') ?>" class="active"><?= 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') ?>"><?= 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>
|
||
<div class="module-subnav">
|
||
<a href="<?= url_for('invoices.php') ?>">← Zurück zu Rechnungen</a>
|
||
</div>
|
||
|
||
<?php if ($error): ?>
|
||
<p class="error"><?= htmlspecialchars($error) ?></p>
|
||
<?php endif; ?>
|
||
|
||
<section>
|
||
<h2>Stornorechnung erstellen</h2>
|
||
<div style="max-width:520px;">
|
||
<table class="list" style="margin-bottom:16px;">
|
||
<tr><td style="color:var(--text-muted);width:140px;">Rechnungsnummer</td><td><strong><?= htmlspecialchars($inv['invoice_number']) ?></strong></td></tr>
|
||
<tr><td style="color:var(--text-muted);">Kunde</td><td><?= htmlspecialchars($inv['customer_name']) ?></td></tr>
|
||
<tr><td style="color:var(--text-muted);">Datum</td><td><?= date('d.m.Y', strtotime($inv['invoice_date'])) ?></td></tr>
|
||
<tr><td style="color:var(--text-muted);">Betrag</td><td><?= number_format($inv['total_gross'], 2, ',', '.') ?> €</td></tr>
|
||
<tr><td style="color:var(--text-muted);">Status</td><td><?= $inv['paid'] ? 'bezahlt' : 'offen' ?></td></tr>
|
||
</table>
|
||
|
||
<div class="gobd-warning" style="margin-bottom:16px;">
|
||
<strong>Achtung:</strong> Es wird eine neue Rechnung mit negativen Beträgen (Stornorechnung) erstellt.
|
||
<?php if ($inv['paid']): ?>
|
||
Die bestehende Journalbuchung wird automatisch storniert (Gegenbuchung).
|
||
<?php else: ?>
|
||
Die Rechnung ist noch nicht bezahlt – es wird keine Journalbuchung storniert.
|
||
<?php endif; ?>
|
||
</div>
|
||
|
||
<form method="post">
|
||
<button type="submit" class="button-danger">Stornorechnung erstellen</button>
|
||
<a href="<?= url_for('invoices.php') ?>" style="margin-left:12px;">Abbrechen</a>
|
||
</form>
|
||
</div>
|
||
</section>
|
||
</main>
|
||
<script src="assets/command-palette.js"></script>
|
||
</body>
|
||
</html>
|