Files
PackControl/pirp/public/recurring_edit.php

278 lines
12 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/customer_functions.php';
require_once __DIR__ . '/../src/recurring_functions.php';
require_once __DIR__ . '/../src/icons.php';
require_login();
$settings = get_settings();
$customers = get_customers();
$error = '';
$msg = '';
$id = isset($_GET['id']) ? (int)$_GET['id'] : null;
$template = null;
$items = [];
if ($id) {
$template = get_recurring_template($id);
if (!$template) {
header('Location: ' . url_for('recurring.php'));
exit;
}
$items = get_recurring_template_items($id);
}
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$data = [
'template_name' => trim($_POST['template_name'] ?? ''),
'customer_id' => (int)($_POST['customer_id'] ?? 0),
'interval_type' => $_POST['interval_type'] ?? 'monthly',
'start_date' => $_POST['start_date'] ?? date('Y-m-d'),
'end_date' => $_POST['end_date'] ?: null,
'next_due_date' => $_POST['next_due_date'] ?? date('Y-m-d'),
'vat_mode' => $settings['vat_mode'] ?? 'klein',
'vat_rate' => (float)($settings['default_vat_rate'] ?? 19.0),
'is_active' => !empty($_POST['is_active']),
'notes_internal' => $_POST['notes_internal'] ?? ''
];
// Validierung
if (empty($data['template_name'])) {
$error = 'Bitte einen Namen eingeben.';
} elseif ($data['customer_id'] <= 0) {
$error = 'Bitte einen Kunden auswählen.';
} else {
// Positionen sammeln
$newItems = [];
$count = isset($_POST['item_desc']) ? count($_POST['item_desc']) : 0;
for ($i = 0; $i < $count; $i++) {
$desc = trim($_POST['item_desc'][$i] ?? '');
$qty = (float)($_POST['item_qty'][$i] ?? 0);
$price = (float)($_POST['item_price'][$i] ?? 0);
if ($desc !== '' && $qty > 0) {
$newItems[] = [
'position_no' => count($newItems) + 1,
'description' => $desc,
'quantity' => $qty,
'unit_price' => $price
];
}
}
if (empty($newItems)) {
$error = 'Bitte mindestens eine Position ausfüllen.';
} else {
$template_id = save_recurring_template($id, $data);
save_recurring_template_items($template_id, $newItems);
header('Location: ' . url_for('recurring.php'));
exit;
}
}
}
?>
<!doctype html>
<html lang="de">
<head>
<meta charset="utf-8">
<title><?= $id ? 'Abo-Vorlage bearbeiten' : 'Neue Abo-Vorlage' ?></title>
<link rel="stylesheet" href="assets/style.css">
<script>
function addRow() {
const tbody = document.getElementById('items-body');
const index = tbody.children.length;
const tr = document.createElement('tr');
tr.innerHTML = `
<td>${index+1}</td>
<td><input type="text" name="item_desc[${index}]" size="40"></td>
<td><input type="number" step="0.01" name="item_qty[${index}]" value="1"></td>
<td><input type="number" step="0.01" name="item_price[${index}]" value="0.00"></td>
<td><button type="button" onclick="this.closest('tr').remove()">X</button></td>
`;
tbody.appendChild(tr);
}
</script>
</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') ?>">Übersicht</a>
<a href="<?= url_for('invoice_new.php') ?>">Neue Rechnung</a>
<a href="<?= url_for('recurring.php') ?>" class="active">Abo-Rechnungen</a>
</div>
<?php if ($error): ?><p class="error"><?= htmlspecialchars($error) ?></p><?php endif; ?>
<form method="post">
<section>
<h2>Abo-Details</h2>
<div>
<label>Name der Vorlage:
<input type="text" name="template_name"
value="<?= htmlspecialchars($template['template_name'] ?? '') ?>" required>
</label>
<label>Kunde:
<select name="customer_id" required>
<option value="">-- wählen --</option>
<?php foreach ($customers as $c): ?>
<option value="<?= $c['id'] ?>"
<?= ($template['customer_id'] ?? 0) == $c['id'] ? 'selected' : '' ?>>
<?= htmlspecialchars($c['name']) ?>
</option>
<?php endforeach; ?>
</select>
</label>
<label>Intervall:
<select name="interval_type" required>
<option value="monthly" <?= ($template['interval_type'] ?? '') === 'monthly' ? 'selected' : '' ?>>
Monatlich
</option>
<option value="quarterly" <?= ($template['interval_type'] ?? '') === 'quarterly' ? 'selected' : '' ?>>
Quartalsweise (alle 3 Monate)
</option>
<option value="yearly" <?= ($template['interval_type'] ?? '') === 'yearly' ? 'selected' : '' ?>>
Jährlich
</option>
</select>
</label>
<div class="flex-row">
<label>Startdatum:
<input type="date" name="start_date"
value="<?= htmlspecialchars($template['start_date'] ?? date('Y-m-d')) ?>" required>
</label>
<label>Enddatum (optional):
<input type="date" name="end_date"
value="<?= htmlspecialchars($template['end_date'] ?? '') ?>">
</label>
<label>Nächste Fälligkeit:
<input type="date" name="next_due_date"
value="<?= htmlspecialchars($template['next_due_date'] ?? date('Y-m-d')) ?>" required>
</label>
</div>
<label>
<input type="checkbox" name="is_active" value="1"
<?= ($template['is_active'] ?? true) ? 'checked' : '' ?>>
Aktiv (Rechnungen werden generiert)
</label>
<label>Interne Notizen:
<textarea name="notes_internal" rows="2"><?= htmlspecialchars($template['notes_internal'] ?? '') ?></textarea>
</label>
</div>
</section>
<section>
<h2>Positionen</h2>
<div>
<table class="list" id="items-table">
<thead>
<tr>
<th style="width:5%">Pos.</th>
<th>Beschreibung</th>
<th style="width:12%">Menge</th>
<th style="width:15%">Einzelpreis (netto)</th>
<th style="width:5%"></th>
</tr>
</thead>
<tbody id="items-body">
<?php
// Bestehende Positionen oder leere Zeilen
$displayItems = !empty($items) ? $items : [
['description' => '', 'quantity' => 1, 'unit_price' => 0],
['description' => '', 'quantity' => 1, 'unit_price' => 0],
['description' => '', 'quantity' => 1, 'unit_price' => 0]
];
foreach ($displayItems as $i => $item):
?>
<tr>
<td><?= $i + 1 ?></td>
<td><input type="text" name="item_desc[<?= $i ?>]"
value="<?= htmlspecialchars($item['description']) ?>" size="40"></td>
<td><input type="number" step="0.01" name="item_qty[<?= $i ?>]"
value="<?= number_format($item['quantity'], 2, '.', '') ?>"></td>
<td><input type="number" step="0.01" name="item_price[<?= $i ?>]"
value="<?= number_format($item['unit_price'], 2, '.', '') ?>"></td>
<td><button type="button" onclick="this.closest('tr').remove()">X</button></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<p>
<button type="button" onclick="addRow()" class="button-secondary">Position hinzufügen</button>
</p>
</div>
</section>
<p>
<button type="submit">Speichern</button>
<a href="<?= url_for('recurring.php') ?>" class="button-secondary">Abbrechen</a>
</p>
</form>
<?php if ($id): ?>
<section>
<h2>Generierte Rechnungen</h2>
<div>
<?php $log = get_recurring_log($id); ?>
<?php if (empty($log)): ?>
<p>Noch keine Rechnungen generiert.</p>
<?php else: ?>
<table class="list">
<thead>
<tr>
<th>Datum</th>
<th>Fälligkeit</th>
<th>Rechnungsnr.</th>
<th>Betrag</th>
<th>Aktion</th>
</tr>
</thead>
<tbody>
<?php foreach ($log as $entry): ?>
<tr>
<td><?= date('d.m.Y H:i', strtotime($entry['generated_at'])) ?></td>
<td><?= date('d.m.Y', strtotime($entry['due_date'])) ?></td>
<td><?= htmlspecialchars($entry['invoice_number'] ?? '-') ?></td>
<td><?= $entry['total_gross'] ? number_format($entry['total_gross'], 2, ',', '.') . ' €' : '-' ?></td>
<td>
<?php if ($entry['invoice_id']): ?>
<a href="<?= url_for('invoice_pdf.php?id=' . $entry['invoice_id']) ?>" target="_blank">PDF</a>
<?php endif; ?>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php endif; ?>
</div>
</section>
<?php endif; ?>
</main>
<script src="assets/command-palette.js"></script>
</body>
</html>