|
|
@@ -0,0 +1,407 @@
|
|
|
+<?php
|
|
|
+require_once __DIR__ . "/../config.php";
|
|
|
+require_once __DIR__ . "/../includes/functions.php";
|
|
|
+
|
|
|
+if (empty($_SESSION['admin_logged_in'])) {
|
|
|
+ header("Location: login.php");
|
|
|
+ exit();
|
|
|
+}
|
|
|
+
|
|
|
+$message = "";
|
|
|
+$messageType = "";
|
|
|
+
|
|
|
+if (
|
|
|
+ $_SERVER['REQUEST_METHOD'] === "POST" &&
|
|
|
+ isset($_POST['toggle_item_backorder'])
|
|
|
+) {
|
|
|
+ if (!validateCsrfToken($_POST['csrf_token'] ?? "")) {
|
|
|
+ $message = "Ungültiges Token. Bitte versuchen Sie es erneut.";
|
|
|
+ $messageType = "error";
|
|
|
+ } else {
|
|
|
+ $result = toggleOrderItemBackorder(
|
|
|
+ $_POST['order_id'] ?? "",
|
|
|
+ (int) ($_POST['item_index'] ?? -1),
|
|
|
+ );
|
|
|
+ $message = $result["success"]
|
|
|
+ ? "Nachbestellstatus wurde aktualisiert."
|
|
|
+ : $result["message"];
|
|
|
+ $messageType = $result["success"] ? "success" : "error";
|
|
|
+
|
|
|
+ if ($result["success"]) {
|
|
|
+ logAccess("Admin toggled order item backorder", [
|
|
|
+ "admin" => $_SESSION['admin_username'] ?? "unknown",
|
|
|
+ "order_id" => $_POST['order_id'] ?? "",
|
|
|
+ "item_index" => $_POST['item_index'] ?? -1,
|
|
|
+ ]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+if (
|
|
|
+ $_SERVER['REQUEST_METHOD'] === "POST" &&
|
|
|
+ isset($_POST['toggle_item_processed'])
|
|
|
+) {
|
|
|
+ if (!validateCsrfToken($_POST['csrf_token'] ?? "")) {
|
|
|
+ $message = "Ungültiges Token. Bitte versuchen Sie es erneut.";
|
|
|
+ $messageType = "error";
|
|
|
+ } else {
|
|
|
+ $result = toggleOrderItemProcessed(
|
|
|
+ $_POST['order_id'] ?? "",
|
|
|
+ (int) ($_POST['item_index'] ?? -1),
|
|
|
+ );
|
|
|
+ $message = $result["success"]
|
|
|
+ ? "Position wurde aktualisiert."
|
|
|
+ : $result["message"];
|
|
|
+ $messageType = $result["success"] ? "success" : "error";
|
|
|
+
|
|
|
+ if ($result["success"]) {
|
|
|
+ logAccess("Admin toggled order item", [
|
|
|
+ "admin" => $_SESSION['admin_username'] ?? "unknown",
|
|
|
+ "order_id" => $_POST['order_id'] ?? "",
|
|
|
+ "item_index" => $_POST['item_index'] ?? -1,
|
|
|
+ ]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+if ($_SERVER['REQUEST_METHOD'] === "POST" && isset($_POST['cancel_order'])) {
|
|
|
+ if (!validateCsrfToken($_POST['csrf_token'] ?? "")) {
|
|
|
+ $message = "Ungültiges Token. Bitte versuchen Sie es erneut.";
|
|
|
+ $messageType = "error";
|
|
|
+ } else {
|
|
|
+ $adminUsername = $_SESSION['admin_username'] ?? "";
|
|
|
+ $result = cancelOrder(
|
|
|
+ $_POST['order_id'] ?? "",
|
|
|
+ $adminUsername,
|
|
|
+ $_POST['cancellation_reason'] ?? "",
|
|
|
+ );
|
|
|
+ $message = $result["success"]
|
|
|
+ ? "Bestellung wurde storniert."
|
|
|
+ : $result["message"];
|
|
|
+ $messageType = $result["success"] ? "success" : "error";
|
|
|
+
|
|
|
+ if ($result["success"]) {
|
|
|
+ logAccess("Admin cancelled order", [
|
|
|
+ "admin" => $adminUsername,
|
|
|
+ "order_id" => $_POST['order_id'] ?? "",
|
|
|
+ ]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+if ($_SERVER['REQUEST_METHOD'] === "POST" && isset($_POST['uncancel_order'])) {
|
|
|
+ if (!validateCsrfToken($_POST['csrf_token'] ?? "")) {
|
|
|
+ $message = "Ungültiges Token. Bitte versuchen Sie es erneut.";
|
|
|
+ $messageType = "error";
|
|
|
+ } else {
|
|
|
+ $adminUsername = $_SESSION['admin_username'] ?? "";
|
|
|
+ $result = uncancelOrder($_POST['order_id'] ?? "");
|
|
|
+ $message = $result["success"]
|
|
|
+ ? "Stornierung wurde aufgehoben."
|
|
|
+ : $result["message"];
|
|
|
+ $messageType = $result["success"] ? "success" : "error";
|
|
|
+
|
|
|
+ if ($result["success"]) {
|
|
|
+ logAccess("Admin uncancelled order", [
|
|
|
+ "admin" => $adminUsername,
|
|
|
+ "order_id" => $_POST['order_id'] ?? "",
|
|
|
+ ]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+$orderId = trim((string) ($_GET['id'] ?? $_POST['order_id'] ?? ""));
|
|
|
+$order = $orderId !== "" ? getOrderById($orderId) : null;
|
|
|
+
|
|
|
+$pageTitle =
|
|
|
+ $order !== null
|
|
|
+ ? "Bestellung " . $order["id"]
|
|
|
+ : ($orderId !== ""
|
|
|
+ ? "Bestellung nicht gefunden"
|
|
|
+ : "Bestellung");
|
|
|
+
|
|
|
+$bodyClass = "admin-page";
|
|
|
+include __DIR__ . "/../includes/header.php";
|
|
|
+?>
|
|
|
+
|
|
|
+<div class="admin-header">
|
|
|
+ <h2><?php echo $order !== null
|
|
|
+ ? "Bestellung " . escape($order["id"])
|
|
|
+ : "Bestellung"; ?></h2>
|
|
|
+ <div class="admin-dashboard-actions">
|
|
|
+ <?php if ($order !== null): ?>
|
|
|
+ <a
|
|
|
+ href="order-pdf.php?id=<?php echo urlencode($order["id"]); ?>"
|
|
|
+ class="btn btn-secondary"
|
|
|
+ target="_blank"
|
|
|
+ rel="noopener noreferrer"
|
|
|
+ >Bestellung drucken</a>
|
|
|
+ <?php endif; ?>
|
|
|
+ <a href="index.php" class="btn btn-secondary">Zurück zum Dashboard</a>
|
|
|
+ <a href="orders.php" class="btn">Zurück zur Bestellliste</a>
|
|
|
+ </div>
|
|
|
+</div>
|
|
|
+
|
|
|
+<?php if ($message !== ""): ?>
|
|
|
+ <div class="alert alert-<?php echo escape($messageType); ?>">
|
|
|
+ <?php echo escape($message); ?>
|
|
|
+ </div>
|
|
|
+<?php endif; ?>
|
|
|
+
|
|
|
+<?php if ($order === null): ?>
|
|
|
+ <div class="alert alert-info">
|
|
|
+ <p><?php echo $orderId !== ""
|
|
|
+ ? "Die Bestellung wurde nicht gefunden."
|
|
|
+ : "Keine Bestellnummer angegeben."; ?></p>
|
|
|
+ </div>
|
|
|
+<?php else: ?>
|
|
|
+ <div class="panel">
|
|
|
+ <p><strong>Status:</strong> <span class="status <?php echo escape(
|
|
|
+ getOrderStatusClass($order),
|
|
|
+ ); ?>"><?php echo escape(
|
|
|
+ getOrderStatusLabel($order),
|
|
|
+); ?></span>
|
|
|
+ <?php if (orderHasBackorder($order)): ?>
|
|
|
+ <span class="status status-backorder">Nachbestellung</span>
|
|
|
+ <?php endif; ?>
|
|
|
+ </p>
|
|
|
+ <p><strong>Name:</strong> <?php echo escape(
|
|
|
+ $order["customer_name"],
|
|
|
+ ); ?></p>
|
|
|
+ <p><strong>E-Mail:</strong> <?php echo escape(
|
|
|
+ $order["customer_email"],
|
|
|
+ ); ?></p>
|
|
|
+ <p><strong>Organisation:</strong> <?php echo escape(
|
|
|
+ $order["organization_label"],
|
|
|
+ ); ?></p>
|
|
|
+ <p><strong>Erstellt:</strong> <?php echo escape(
|
|
|
+ formatDate($order["created_at"]),
|
|
|
+ ); ?></p>
|
|
|
+ <?php if ($order["admin_notified_at"] !== ""): ?>
|
|
|
+ <p><strong>Intern weitergeleitet:</strong> <?php echo escape(
|
|
|
+ formatDate($order["admin_notified_at"]),
|
|
|
+ ); ?></p>
|
|
|
+ <?php endif; ?>
|
|
|
+ <p><strong>Kommentar:</strong><br><?php echo $order[
|
|
|
+ "comment"
|
|
|
+ ] !== ""
|
|
|
+ ? nl2br(escape($order["comment"]))
|
|
|
+ : "Kein Kommentar"; ?></p>
|
|
|
+
|
|
|
+ <?php if ($order["status"] === "cancelled"): ?>
|
|
|
+ <div class="alert alert-warning">
|
|
|
+ <p><strong>Storniert am:</strong> <?php echo escape(
|
|
|
+ formatDate($order["cancelled_at"]),
|
|
|
+ ); ?></p>
|
|
|
+ <p><strong>Storniert durch:</strong> <?php echo escape(
|
|
|
+ $order["cancelled_by"],
|
|
|
+ ); ?></p>
|
|
|
+ <p><strong>Stornogrund:</strong><br><?php echo $order[
|
|
|
+ "cancellation_reason"
|
|
|
+ ] !== ""
|
|
|
+ ? nl2br(escape($order["cancellation_reason"]))
|
|
|
+ : "Kein Grund angegeben"; ?></p>
|
|
|
+ </div>
|
|
|
+ <form
|
|
|
+ method="POST"
|
|
|
+ class="inline-form"
|
|
|
+ onsubmit="return confirm('Stornierung wirklich aufheben? Die Bestellung kann danach wieder bearbeitet werden.');"
|
|
|
+ >
|
|
|
+ <?php echo csrfField(); ?>
|
|
|
+ <input type="hidden" name="order_id" value="<?php echo escape(
|
|
|
+ $order["id"],
|
|
|
+ ); ?>">
|
|
|
+ <button type="submit" name="uncancel_order" class="btn btn-small">
|
|
|
+ Stornierung aufheben
|
|
|
+ </button>
|
|
|
+ </form>
|
|
|
+ <?php endif; ?>
|
|
|
+
|
|
|
+ <h4>Positionen</h4>
|
|
|
+ <div class="table-responsive">
|
|
|
+ <table class="responsive-table table-compact">
|
|
|
+ <thead>
|
|
|
+ <tr>
|
|
|
+ <th>Artikel</th>
|
|
|
+ <th>Größe</th>
|
|
|
+ <th>Lieferhinweis</th>
|
|
|
+ <th>Bearbeitet</th>
|
|
|
+ <th>Nachbestellung</th>
|
|
|
+ <th>Aktion</th>
|
|
|
+ </tr>
|
|
|
+ </thead>
|
|
|
+ <tbody>
|
|
|
+ <?php foreach ($order["items"] as $index => $item): ?>
|
|
|
+ <tr>
|
|
|
+ <td data-label="Artikel"><?php echo escape(
|
|
|
+ $item["product_name"],
|
|
|
+ ); ?></td>
|
|
|
+ <td data-label="Größe"><?php echo $item["size"] !==
|
|
|
+ ""
|
|
|
+ ? escape($item["size"])
|
|
|
+ : "-"; ?></td>
|
|
|
+ <td data-label="Lieferhinweis"><?php echo $item[
|
|
|
+ "availability_label"
|
|
|
+ ] !== ""
|
|
|
+ ? escape($item["availability_label"])
|
|
|
+ : "-"; ?></td>
|
|
|
+ <td data-label="Bearbeitet">
|
|
|
+ <span class="status <?php echo !empty(
|
|
|
+ $item["is_processed"]
|
|
|
+ )
|
|
|
+ ? "status-processed"
|
|
|
+ : "status-open"; ?>">
|
|
|
+ <?php echo !empty($item["is_processed"])
|
|
|
+ ? "Ja"
|
|
|
+ : "Nein"; ?>
|
|
|
+ </span>
|
|
|
+ </td>
|
|
|
+ <td data-label="Nachbestellung">
|
|
|
+ <?php
|
|
|
+ $backorderStatus = (string) ($item["backorder_status"] ?? "");
|
|
|
+ if ($backorderStatus !== ""): ?>
|
|
|
+ <span class="status <?php echo escape(
|
|
|
+ getBackorderStatusClass($backorderStatus),
|
|
|
+ ); ?>"><?php echo escape(
|
|
|
+ getBackorderStatusLabel($backorderStatus),
|
|
|
+); ?></span>
|
|
|
+ <?php else: ?>
|
|
|
+ -
|
|
|
+ <?php endif; ?>
|
|
|
+ </td>
|
|
|
+ <td data-label="Aktionen">
|
|
|
+ <?php if ($order["status"] !== "cancelled"): ?>
|
|
|
+ <form method="POST" class="inline-form">
|
|
|
+ <?php echo csrfField(); ?>
|
|
|
+ <input type="hidden" name="order_id" value="<?php echo escape(
|
|
|
+ $order["id"],
|
|
|
+ ); ?>">
|
|
|
+ <input type="hidden" name="item_index" value="<?php echo (int) $index; ?>">
|
|
|
+ <button type="submit" name="toggle_item_processed" class="btn btn-small">
|
|
|
+ <?php echo !empty(
|
|
|
+ $item["is_processed"]
|
|
|
+ )
|
|
|
+ ? "Als offen markieren"
|
|
|
+ : "Als bearbeitet markieren"; ?>
|
|
|
+ </button>
|
|
|
+ </form>
|
|
|
+ <?php
|
|
|
+ $canToggleBackorder =
|
|
|
+ $backorderStatus === "to_be_backordered" ||
|
|
|
+ ($backorderStatus === "" &&
|
|
|
+ empty($item["is_processed"]));
|
|
|
+ if ($canToggleBackorder): ?>
|
|
|
+ <form method="POST" class="inline-form">
|
|
|
+ <?php echo csrfField(); ?>
|
|
|
+ <input type="hidden" name="order_id" value="<?php echo escape(
|
|
|
+ $order["id"],
|
|
|
+ ); ?>">
|
|
|
+ <input type="hidden" name="item_index" value="<?php echo (int) $index; ?>">
|
|
|
+ <button type="submit" name="toggle_item_backorder" class="btn btn-small btn-secondary">
|
|
|
+ <?php echo $backorderStatus === "to_be_backordered"
|
|
|
+ ? "Nachbestellung aufheben"
|
|
|
+ : "Als Nachbestellung markieren"; ?>
|
|
|
+ </button>
|
|
|
+ </form>
|
|
|
+ <?php endif; ?>
|
|
|
+ <?php else: ?>
|
|
|
+ -
|
|
|
+ <?php endif; ?>
|
|
|
+ </td>
|
|
|
+ </tr>
|
|
|
+ <?php endforeach; ?>
|
|
|
+ </tbody>
|
|
|
+ </table>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <?php if (
|
|
|
+ $order["status"] !== "cancelled" &&
|
|
|
+ $order["status"] !== "processed"
|
|
|
+ ): ?>
|
|
|
+ <button
|
|
|
+ type="button"
|
|
|
+ class="btn btn-secondary btn-small"
|
|
|
+ id="cancel-order-open"
|
|
|
+ >
|
|
|
+ Bestellung stornieren
|
|
|
+ </button>
|
|
|
+
|
|
|
+ <div
|
|
|
+ id="cancel-order-modal"
|
|
|
+ class="modal"
|
|
|
+ role="dialog"
|
|
|
+ aria-labelledby="cancel-order-title"
|
|
|
+ aria-hidden="true"
|
|
|
+ >
|
|
|
+ <div class="modal-content modal-content-compact">
|
|
|
+ <button
|
|
|
+ type="button"
|
|
|
+ class="modal-close btn btn-secondary btn-small"
|
|
|
+ id="cancel-order-close"
|
|
|
+ aria-label="Schließen"
|
|
|
+ >
|
|
|
+ ×
|
|
|
+ </button>
|
|
|
+ <h4 id="cancel-order-title">Bestellung stornieren</h4>
|
|
|
+ <form method="POST" id="cancel-order-form">
|
|
|
+ <?php echo csrfField(); ?>
|
|
|
+ <input type="hidden" name="order_id" value="<?php echo escape(
|
|
|
+ $order["id"],
|
|
|
+ ); ?>">
|
|
|
+ <div class="form-group">
|
|
|
+ <label for="cancellation_reason">Stornogrund</label>
|
|
|
+ <textarea
|
|
|
+ id="cancellation_reason"
|
|
|
+ name="cancellation_reason"
|
|
|
+ rows="3"
|
|
|
+ placeholder="Optionaler Grund"
|
|
|
+ ></textarea>
|
|
|
+ </div>
|
|
|
+ <button type="submit" name="cancel_order" class="btn">
|
|
|
+ Stornierung bestätigen
|
|
|
+ </button>
|
|
|
+ </form>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <script>
|
|
|
+ (function () {
|
|
|
+ const modal = document.getElementById("cancel-order-modal");
|
|
|
+ const openBtn = document.getElementById("cancel-order-open");
|
|
|
+ const closeBtn = document.getElementById("cancel-order-close");
|
|
|
+ if (!modal || !openBtn || !closeBtn) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ function openModal() {
|
|
|
+ modal.classList.add("is-open");
|
|
|
+ modal.setAttribute("aria-hidden", "false");
|
|
|
+ const reason = document.getElementById("cancellation_reason");
|
|
|
+ if (reason) {
|
|
|
+ reason.focus();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ function closeModal() {
|
|
|
+ modal.classList.remove("is-open");
|
|
|
+ modal.setAttribute("aria-hidden", "true");
|
|
|
+ }
|
|
|
+
|
|
|
+ openBtn.addEventListener("click", openModal);
|
|
|
+ closeBtn.addEventListener("click", closeModal);
|
|
|
+ modal.addEventListener("click", function (event) {
|
|
|
+ if (event.target === modal) {
|
|
|
+ closeModal();
|
|
|
+ }
|
|
|
+ });
|
|
|
+ document.addEventListener("keydown", function (event) {
|
|
|
+ if (event.key === "Escape" && modal.classList.contains("is-open")) {
|
|
|
+ closeModal();
|
|
|
+ }
|
|
|
+ });
|
|
|
+ })();
|
|
|
+ </script>
|
|
|
+ <?php endif; ?>
|
|
|
+ </div>
|
|
|
+<?php endif; ?>
|
|
|
+
|
|
|
+<?php include __DIR__ . "/../includes/footer.php"; ?>
|