|
|
@@ -1301,6 +1301,7 @@ function getDefaultSystemSettings()
|
|
|
? (bool) ATTACH_ORDER_PDF_TO_ADMIN_EMAIL
|
|
|
: true,
|
|
|
"startpage_intro_text" => $startpageIntroText,
|
|
|
+ "nametag_product_name" => "Namensschild",
|
|
|
];
|
|
|
}
|
|
|
|
|
|
@@ -1323,12 +1324,20 @@ function normalizeSystemSettings($settings)
|
|
|
(string) ($settings["startpage_intro_text"] ?? $defaults["startpage_intro_text"]),
|
|
|
);
|
|
|
|
|
|
+ $nametagProductName = trim(
|
|
|
+ (string) ($settings["nametag_product_name"] ?? $defaults["nametag_product_name"]),
|
|
|
+ );
|
|
|
+ if ($nametagProductName === "") {
|
|
|
+ $nametagProductName = $defaults["nametag_product_name"];
|
|
|
+ }
|
|
|
+
|
|
|
return [
|
|
|
"order_recipient_email" => $recipientEmail,
|
|
|
"attach_order_pdf_to_admin_email" => !empty(
|
|
|
$settings["attach_order_pdf_to_admin_email"]
|
|
|
),
|
|
|
"startpage_intro_text" => $startpageIntroText,
|
|
|
+ "nametag_product_name" => $nametagProductName,
|
|
|
];
|
|
|
}
|
|
|
|
|
|
@@ -1357,6 +1366,12 @@ function shouldAttachOrderPdfToAdminEmail()
|
|
|
return !empty($settings["attach_order_pdf_to_admin_email"]);
|
|
|
}
|
|
|
|
|
|
+function getNametagProductName()
|
|
|
+{
|
|
|
+ $settings = getSystemSettings();
|
|
|
+ return $settings["nametag_product_name"];
|
|
|
+}
|
|
|
+
|
|
|
function getStartpageIntroLines()
|
|
|
{
|
|
|
$settings = getSystemSettings();
|
|
|
@@ -2389,249 +2404,174 @@ function markBackorderItemsDelivered($productId, $size, $quantity)
|
|
|
return applyBackorderBulkUpdate($productId, $size, "ordered", "", $quantity);
|
|
|
}
|
|
|
|
|
|
-function nametagStatusOpen(): string
|
|
|
-{
|
|
|
- return "open";
|
|
|
-}
|
|
|
-
|
|
|
-function nametagStatusOrdered(): string
|
|
|
-{
|
|
|
- return "ordered";
|
|
|
-}
|
|
|
-
|
|
|
-function getNametagOrders()
|
|
|
+function collectNametagOrderItemRefs()
|
|
|
{
|
|
|
- $data = readJsonFile(NAMETAGS_FILE);
|
|
|
- $entries =
|
|
|
- isset($data["entries"]) && is_array($data["entries"])
|
|
|
- ? $data["entries"]
|
|
|
- : [];
|
|
|
- $normalized = [];
|
|
|
+ $nametagProductName = getNametagProductName();
|
|
|
+ $refs = [];
|
|
|
|
|
|
- foreach ($entries as $entry) {
|
|
|
- if (!is_array($entry)) {
|
|
|
+ foreach (getOrders() as $order) {
|
|
|
+ if (($order["status"] ?? "") === "cancelled") {
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
- $id = trim((string) ($entry["id"] ?? ""));
|
|
|
- $personName = trim((string) ($entry["person_name"] ?? ""));
|
|
|
- $status = trim((string) ($entry["status"] ?? ""));
|
|
|
- if (
|
|
|
- $id === "" ||
|
|
|
- $personName === "" ||
|
|
|
- !in_array($status, [nametagStatusOpen(), nametagStatusOrdered()], true)
|
|
|
- ) {
|
|
|
- continue;
|
|
|
- }
|
|
|
+ foreach ($order["items"] as $itemIndex => $item) {
|
|
|
+ if (!empty($item["is_processed"])) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ if (
|
|
|
+ trim((string) ($item["product_name"] ?? "")) !==
|
|
|
+ $nametagProductName
|
|
|
+ ) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
|
|
|
- $normalized[] = [
|
|
|
- "id" => $id,
|
|
|
- "person_name" => $personName,
|
|
|
- "organization_id" => trim((string) ($entry["organization_id"] ?? "")),
|
|
|
- "organization_label" => trim(
|
|
|
- (string) ($entry["organization_label"] ?? ""),
|
|
|
- ),
|
|
|
- "quantity" => max(1, (int) ($entry["quantity"] ?? 1)),
|
|
|
- "note" => trim((string) ($entry["note"] ?? "")),
|
|
|
- "status" => $status,
|
|
|
- "created_at" => trim((string) ($entry["created_at"] ?? "")),
|
|
|
- "ordered_at" => trim((string) ($entry["ordered_at"] ?? "")),
|
|
|
- ];
|
|
|
+ $refs[] = [
|
|
|
+ "order_id" => $order["id"],
|
|
|
+ "item_index" => (int) $itemIndex,
|
|
|
+ "person_name" => $order["customer_name"],
|
|
|
+ "organization_label" => $order["organization_label"],
|
|
|
+ "size" => $item["size"],
|
|
|
+ "availability_label" => $item["availability_label"],
|
|
|
+ "backorder_status" => trim(
|
|
|
+ (string) ($item["backorder_status"] ?? ""),
|
|
|
+ ),
|
|
|
+ "created_at" => $order["created_at"],
|
|
|
+ "ordered_at" => trim((string) ($item["ordered_at"] ?? "")),
|
|
|
+ ];
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- return $normalized;
|
|
|
+ return $refs;
|
|
|
}
|
|
|
|
|
|
-function saveNametagOrders($entries)
|
|
|
+function getOutstandingNametagOrderItems()
|
|
|
{
|
|
|
- return writeJsonFile(NAMETAGS_FILE, [
|
|
|
- "entries" => array_values($entries),
|
|
|
- ]);
|
|
|
+ $refs = array_values(
|
|
|
+ array_filter(collectNametagOrderItemRefs(), function ($ref) {
|
|
|
+ return $ref["backorder_status"] === "" ||
|
|
|
+ $ref["backorder_status"] === backorderStatusToBeBackordered();
|
|
|
+ }),
|
|
|
+ );
|
|
|
+ usort($refs, function ($left, $right) {
|
|
|
+ return strcmp($left["created_at"], $right["created_at"]);
|
|
|
+ });
|
|
|
+ return $refs;
|
|
|
}
|
|
|
|
|
|
-function generateNametagOrderId()
|
|
|
+function getOrderedNametagOrderItems()
|
|
|
{
|
|
|
- return "nt-" . date("YmdHis") . "-" . bin2hex(random_bytes(4));
|
|
|
+ $refs = array_values(
|
|
|
+ array_filter(collectNametagOrderItemRefs(), function ($ref) {
|
|
|
+ return $ref["backorder_status"] === backorderStatusOrdered();
|
|
|
+ }),
|
|
|
+ );
|
|
|
+ usort($refs, function ($left, $right) {
|
|
|
+ return strcmp($left["ordered_at"], $right["ordered_at"]);
|
|
|
+ });
|
|
|
+ return $refs;
|
|
|
}
|
|
|
|
|
|
-function addNametagOrder($personName, $organizationId, $quantity, $note)
|
|
|
+function markNametagOrderItemOrdered($orderId, $itemIndex)
|
|
|
{
|
|
|
- $personName = trim((string) $personName);
|
|
|
- $organizationId = trim((string) $organizationId);
|
|
|
- $quantity = (int) $quantity;
|
|
|
- $note = trim((string) $note);
|
|
|
-
|
|
|
- if ($personName === "") {
|
|
|
- return ["success" => false, "message" => "Bitte einen Namen eingeben."];
|
|
|
- }
|
|
|
-
|
|
|
- if ($quantity <= 0) {
|
|
|
- $quantity = 1;
|
|
|
- }
|
|
|
- if ($quantity > 20) {
|
|
|
- return [
|
|
|
- "success" => false,
|
|
|
- "message" => "Maximal 20 Namensschilder pro Position.",
|
|
|
- ];
|
|
|
- }
|
|
|
+ $nametagProductName = getNametagProductName();
|
|
|
+ $orders = getOrders();
|
|
|
+ $now = date("Y-m-d H:i:s");
|
|
|
|
|
|
- $organizationLabel = "";
|
|
|
- if ($organizationId !== "") {
|
|
|
- $organization = getOrganizationById($organizationId);
|
|
|
- if ($organization === null) {
|
|
|
- return ["success" => false, "message" => "Ungültige Organisation."];
|
|
|
+ foreach ($orders as &$order) {
|
|
|
+ if ($order["id"] !== $orderId) {
|
|
|
+ continue;
|
|
|
}
|
|
|
- $organizationLabel = $organization["label"];
|
|
|
- }
|
|
|
|
|
|
- $entries = getNametagOrders();
|
|
|
- $entries[] = [
|
|
|
- "id" => generateNametagOrderId(),
|
|
|
- "person_name" => $personName,
|
|
|
- "organization_id" => $organizationId,
|
|
|
- "organization_label" => $organizationLabel,
|
|
|
- "quantity" => $quantity,
|
|
|
- "note" => $note,
|
|
|
- "status" => nametagStatusOpen(),
|
|
|
- "created_at" => date("Y-m-d H:i:s"),
|
|
|
- "ordered_at" => "",
|
|
|
- ];
|
|
|
-
|
|
|
- if (!saveNametagOrders($entries)) {
|
|
|
- return [
|
|
|
- "success" => false,
|
|
|
- "message" => "Namensschild-Bestellung konnte nicht gespeichert werden.",
|
|
|
- ];
|
|
|
- }
|
|
|
-
|
|
|
- return ["success" => true];
|
|
|
-}
|
|
|
+ $guard = orderItemCanBeManaged($order);
|
|
|
+ if (!$guard["success"]) {
|
|
|
+ return $guard;
|
|
|
+ }
|
|
|
|
|
|
-function markNametagOrdered($id)
|
|
|
-{
|
|
|
- $id = trim((string) $id);
|
|
|
- $entries = getNametagOrders();
|
|
|
- $now = date("Y-m-d H:i:s");
|
|
|
- $found = false;
|
|
|
+ if (!isset($order["items"][$itemIndex])) {
|
|
|
+ return ["success" => false, "message" => "Position nicht gefunden."];
|
|
|
+ }
|
|
|
|
|
|
- foreach ($entries as &$entry) {
|
|
|
- if ($entry["id"] !== $id) {
|
|
|
- continue;
|
|
|
+ $item = $order["items"][$itemIndex];
|
|
|
+ if (
|
|
|
+ trim((string) ($item["product_name"] ?? "")) !== $nametagProductName
|
|
|
+ ) {
|
|
|
+ return [
|
|
|
+ "success" => false,
|
|
|
+ "message" => "Position ist kein Namensschild.",
|
|
|
+ ];
|
|
|
}
|
|
|
- if ($entry["status"] !== nametagStatusOpen()) {
|
|
|
+ if (!empty($item["is_processed"])) {
|
|
|
+ return [
|
|
|
+ "success" => false,
|
|
|
+ "message" =>
|
|
|
+ "Bearbeitete Positionen können nicht als bestellt markiert werden.",
|
|
|
+ ];
|
|
|
+ }
|
|
|
+ $currentBackorderStatus = trim(
|
|
|
+ (string) ($item["backorder_status"] ?? ""),
|
|
|
+ );
|
|
|
+ if (
|
|
|
+ $currentBackorderStatus !== "" &&
|
|
|
+ $currentBackorderStatus !== backorderStatusToBeBackordered()
|
|
|
+ ) {
|
|
|
return [
|
|
|
"success" => false,
|
|
|
"message" => "Position wurde bereits bestellt.",
|
|
|
];
|
|
|
}
|
|
|
- $entry["status"] = nametagStatusOrdered();
|
|
|
- $entry["ordered_at"] = $now;
|
|
|
- $found = true;
|
|
|
- break;
|
|
|
- }
|
|
|
- unset($entry);
|
|
|
|
|
|
- if (!$found) {
|
|
|
- return ["success" => false, "message" => "Position nicht gefunden."];
|
|
|
- }
|
|
|
+ $order["items"][$itemIndex]["backorder_status"] = backorderStatusOrdered();
|
|
|
+ $order["items"][$itemIndex]["ordered_at"] = $now;
|
|
|
+ $order["updated_at"] = $now;
|
|
|
+ saveOrders($orders);
|
|
|
|
|
|
- if (!saveNametagOrders($entries)) {
|
|
|
- return [
|
|
|
- "success" => false,
|
|
|
- "message" => "Namensschild-Bestellung konnte nicht gespeichert werden.",
|
|
|
- ];
|
|
|
+ return ["success" => true];
|
|
|
}
|
|
|
+ unset($order);
|
|
|
|
|
|
- return ["success" => true];
|
|
|
+ return ["success" => false, "message" => "Bestellung nicht gefunden."];
|
|
|
}
|
|
|
|
|
|
-function markNametagDelivered($id)
|
|
|
+function markNametagOrderItemDelivered($orderId, $itemIndex)
|
|
|
{
|
|
|
- $id = trim((string) $id);
|
|
|
- $entries = getNametagOrders();
|
|
|
- $target = null;
|
|
|
+ $orders = getOrders();
|
|
|
+ $now = date("Y-m-d H:i:s");
|
|
|
|
|
|
- foreach ($entries as $entry) {
|
|
|
- if ($entry["id"] === $id) {
|
|
|
- $target = $entry;
|
|
|
- break;
|
|
|
+ foreach ($orders as &$order) {
|
|
|
+ if ($order["id"] !== $orderId) {
|
|
|
+ continue;
|
|
|
}
|
|
|
- }
|
|
|
-
|
|
|
- if ($target === null) {
|
|
|
- return ["success" => false, "message" => "Position nicht gefunden."];
|
|
|
- }
|
|
|
- if ($target["status"] !== nametagStatusOrdered()) {
|
|
|
- return [
|
|
|
- "success" => false,
|
|
|
- "message" => "Position wartet nicht auf Lieferung.",
|
|
|
- ];
|
|
|
- }
|
|
|
-
|
|
|
- $remaining = array_values(
|
|
|
- array_filter($entries, function ($entry) use ($id) {
|
|
|
- return $entry["id"] !== $id;
|
|
|
- }),
|
|
|
- );
|
|
|
|
|
|
- if (!saveNametagOrders($remaining)) {
|
|
|
- return [
|
|
|
- "success" => false,
|
|
|
- "message" => "Namensschild-Bestellung konnte nicht gespeichert werden.",
|
|
|
- ];
|
|
|
- }
|
|
|
+ $guard = orderItemCanBeManaged($order);
|
|
|
+ if (!$guard["success"]) {
|
|
|
+ return $guard;
|
|
|
+ }
|
|
|
|
|
|
- return ["success" => true];
|
|
|
-}
|
|
|
+ if (!isset($order["items"][$itemIndex])) {
|
|
|
+ return ["success" => false, "message" => "Position nicht gefunden."];
|
|
|
+ }
|
|
|
|
|
|
-function deleteNametagOrder($id)
|
|
|
-{
|
|
|
- $id = trim((string) $id);
|
|
|
- $entries = getNametagOrders();
|
|
|
- $filtered = array_values(
|
|
|
- array_filter($entries, function ($entry) use ($id) {
|
|
|
- return $entry["id"] !== $id;
|
|
|
- }),
|
|
|
- );
|
|
|
+ $item = $order["items"][$itemIndex];
|
|
|
+ if (
|
|
|
+ trim((string) ($item["backorder_status"] ?? "")) !==
|
|
|
+ backorderStatusOrdered()
|
|
|
+ ) {
|
|
|
+ return [
|
|
|
+ "success" => false,
|
|
|
+ "message" => "Position wartet nicht auf Lieferung.",
|
|
|
+ ];
|
|
|
+ }
|
|
|
|
|
|
- if (count($filtered) === count($entries)) {
|
|
|
- return ["success" => false, "message" => "Position nicht gefunden."];
|
|
|
- }
|
|
|
+ $order["items"][$itemIndex]["backorder_status"] = backorderStatusEmpty();
|
|
|
+ $order["items"][$itemIndex]["ordered_at"] = "";
|
|
|
+ $order["updated_at"] = $now;
|
|
|
+ saveOrders($orders);
|
|
|
|
|
|
- if (!saveNametagOrders($filtered)) {
|
|
|
- return [
|
|
|
- "success" => false,
|
|
|
- "message" => "Namensschild-Bestellung konnte nicht gelöscht werden.",
|
|
|
- ];
|
|
|
+ return ["success" => true];
|
|
|
}
|
|
|
+ unset($order);
|
|
|
|
|
|
- return ["success" => true];
|
|
|
-}
|
|
|
-
|
|
|
-function getOpenNametagOrders()
|
|
|
-{
|
|
|
- $entries = array_values(
|
|
|
- array_filter(getNametagOrders(), function ($entry) {
|
|
|
- return $entry["status"] === nametagStatusOpen();
|
|
|
- }),
|
|
|
- );
|
|
|
- usort($entries, function ($left, $right) {
|
|
|
- return strcmp($left["created_at"], $right["created_at"]);
|
|
|
- });
|
|
|
- return $entries;
|
|
|
-}
|
|
|
-
|
|
|
-function getOrderedNametagOrders()
|
|
|
-{
|
|
|
- $entries = array_values(
|
|
|
- array_filter(getNametagOrders(), function ($entry) {
|
|
|
- return $entry["status"] === nametagStatusOrdered();
|
|
|
- }),
|
|
|
- );
|
|
|
- usort($entries, function ($left, $right) {
|
|
|
- return strcmp($left["ordered_at"], $right["ordered_at"]);
|
|
|
- });
|
|
|
- return $entries;
|
|
|
+ return ["success" => false, "message" => "Bestellung nicht gefunden."];
|
|
|
}
|
|
|
|
|
|
function orderHasBackorder($order)
|