beginTransaction();
try {
$stmt = $pdo->prepare('UPDATE expenses SET paid = TRUE, payment_date = :pd WHERE id = :id');
$stmt->execute([':id' => $pay_id, ':pd' => $payment_date]);
// Journal-Eintrag erstellen
$existing = get_journal_entry_for_expense($pay_id);
if (!$existing) {
$entry_id = create_journal_entry_from_expense($pay_id);
$msg = 'Ausgabe als bezahlt markiert. Journalbuchung #' . $entry_id . ' erstellt.';
} else {
$msg = 'Ausgabe als bezahlt markiert (Journalbuchung existierte bereits).';
}
$pdo->commit();
} catch (Exception $e) {
$pdo->rollBack();
$error = 'Fehler: ' . $e->getMessage();
}
}
// Normale Ausgabe speichern (neu oder Update)
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['expense_date']) && !isset($_POST['mark_paid_id'])) {
$idPost = isset($_POST['id']) && $_POST['id'] !== '' ? (int)$_POST['id'] : null;
$data = [
'expense_date' => $_POST['expense_date'] ?? '',
'description' => $_POST['description'] ?? '',
'category' => $_POST['category'] ?? '',
'amount' => (float)($_POST['amount'] ?? 0),
'vat_rate' => (float)($_POST['vat_rate'] ?? 0),
'expense_category_id' => !empty($_POST['expense_category_id']) ? (int)$_POST['expense_category_id'] : null,
'paid' => !empty($_POST['paid']) ? 1 : 0,
'payment_date' => $_POST['payment_date'] ?? '',
];
if (!$data['expense_date'] || !$data['description'] || $data['amount'] <= 0) {
$error = 'Datum, Beschreibung und Betrag sind Pflichtfelder.';
} elseif (!empty($data['paid']) && empty($data['expense_category_id'])) {
$error = 'Bei bezahlten Ausgaben ist eine Aufwandskategorie für die Journalbuchung Pflicht.';
} else {
$pdo->beginTransaction();
try {
// War vorher schon bezahlt? (für Update-Check)
$was_paid = false;
$had_journal = false;
if ($idPost) {
$old_exp = get_expense($idPost);
$was_paid = $old_exp && $old_exp['paid'];
$had_journal = $old_exp ? (bool)get_journal_entry_for_expense($idPost) : false;
}
// Ausgabe speichern
$expense_id = save_expense($idPost, $data);
// Datei-Upload (PDF) verarbeiten
if (!empty($_FILES['attachment']['tmp_name'])) {
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mime = finfo_file($finfo, $_FILES['attachment']['tmp_name']);
finfo_close($finfo);
if ($mime === 'application/pdf') {
$uploadDir = __DIR__ . '/uploads/expenses';
if (!is_dir($uploadDir)) {
mkdir($uploadDir, 0775, true);
}
$targetFile = $uploadDir . '/expense_' . $expense_id . '.pdf';
if (move_uploaded_file($_FILES['attachment']['tmp_name'], $targetFile)) {
$relPath = 'uploads/expenses/expense_' . $expense_id . '.pdf';
$stmt = $pdo->prepare("UPDATE expenses SET attachment_path = :p WHERE id = :id");
$stmt->execute([':p' => $relPath, ':id' => $expense_id]);
} else {
$error = 'Ausgabe gespeichert, aber Datei konnte nicht verschoben werden.';
}
} else {
$error = 'Bitte nur PDF-Dateien als Beleg hochladen.';
}
}
// Journal-Integration
if (!empty($data['paid']) && !$had_journal) {
// Neu bezahlt → Journal-Eintrag erstellen
$existing = get_journal_entry_for_expense($expense_id);
if (!$existing) {
$entry_id = create_journal_entry_from_expense($expense_id);
$msg = 'Ausgabe gespeichert. Journalbuchung #' . $entry_id . ' erstellt.';
} else {
$msg = 'Ausgabe gespeichert.';
}
} elseif (empty($data['paid']) && $had_journal) {
// War bezahlt, jetzt offen → Journal-Eintrag entfernen
delete_journal_entry_for_expense($expense_id);
$msg = 'Ausgabe gespeichert. Journalbuchung entfernt (Status: offen).';
} else {
$msg = $msg ?: 'Ausgabe gespeichert.';
}
$pdo->commit();
$action = '';
$id = null;
} catch (Exception $e) {
$pdo->rollBack();
$error = 'Fehler: ' . $e->getMessage();
}
}
}
if ($action === 'delete' && $id) {
$exp = get_expense($id);
if ($exp) {
// Verknüpften Journal-Eintrag löschen
delete_journal_entry_for_expense($id);
if (!empty($exp['attachment_path'])) {
$fsPath = __DIR__ . '/' . $exp['attachment_path'];
if (is_file($fsPath)) {
@unlink($fsPath);
}
}
delete_expense($id);
$msg = 'Ausgabe und zugehörige Journalbuchung gelöscht.';
}
$action = '';
$id = null;
}
$editExpense = null;
if ($action === 'edit' && $id) {
$editExpense = get_expense($id);
}
$filters = [
'from' => $_GET['from'] ?? '',
'to' => $_GET['to'] ?? '',
'paid' => $_GET['paid'] ?? '',
'search' => $_GET['search'] ?? '',
];
$expenses = get_expenses($filters);
// Journal-Verknüpfungen laden
$journal_linked_expenses = [];
try {
$stmt_jl = $pdo->query("SELECT expense_id, id FROM journal_entries WHERE expense_id IS NOT NULL");
foreach ($stmt_jl->fetchAll(PDO::FETCH_ASSOC) as $jl) {
$journal_linked_expenses[(int)$jl['expense_id']] = (int)$jl['id'];
}
} catch (PDOException $e) {
// Spalte existiert noch nicht
}
?>
Ausgaben
= htmlspecialchars($msg) ?>
= htmlspecialchars($error) ?>
= $editExpense ? 'Ausgabe bearbeiten' : 'Neue Ausgabe' ?>
Übersicht Ausgaben
| Datum |
Beschreibung |
Kategorie |
Betrag |
Status |
Beleg |
Aktion |
| = htmlspecialchars(date('d.m.Y', strtotime($e['expense_date']))) ?> |
= htmlspecialchars($e['description']) ?> |
= htmlspecialchars($e['category']) ?> |
= number_format($e['amount'], 2, ',', '.') ?> € |
= $e['paid'] ? 'bezahlt' : 'offen' ?> |
PDF
-
|
Bearbeiten
| Löschen
| als bezahlt
| Journal
|
|
|
| Keine Ausgaben gefunden. |
| Summe |
= number_format($total, 2, ',', '.') ?> € |
|