|
@@ -1755,6 +1755,38 @@ function cancelOrder($orderId, $adminUsername, $reason = "")
|
|
|
return ["success" => false, "message" => "Bestellung nicht gefunden."];
|
|
return ["success" => false, "message" => "Bestellung nicht gefunden."];
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+function uncancelOrder($orderId)
|
|
|
|
|
+{
|
|
|
|
|
+ $orders = getOrders();
|
|
|
|
|
+ $now = date("Y-m-d H:i:s");
|
|
|
|
|
+
|
|
|
|
|
+ foreach ($orders as &$order) {
|
|
|
|
|
+ if ($order["id"] !== $orderId) {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if ($order["status"] !== "cancelled") {
|
|
|
|
|
+ return [
|
|
|
|
|
+ "success" => false,
|
|
|
|
|
+ "message" => "Die Bestellung ist nicht storniert.",
|
|
|
|
|
+ ];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ $order["cancelled_at"] = "";
|
|
|
|
|
+ $order["cancelled_by"] = "";
|
|
|
|
|
+ $order["cancellation_reason"] = "";
|
|
|
|
|
+ $order["status"] = "open";
|
|
|
|
|
+ $order["updated_at"] = $now;
|
|
|
|
|
+ $order = refreshOrderState($order);
|
|
|
|
|
+ saveOrders($orders);
|
|
|
|
|
+
|
|
|
|
|
+ return ["success" => true, "order" => $order];
|
|
|
|
|
+ }
|
|
|
|
|
+ unset($order);
|
|
|
|
|
+
|
|
|
|
|
+ return ["success" => false, "message" => "Bestellung nicht gefunden."];
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
function orderItemCanBeManaged($order)
|
|
function orderItemCanBeManaged($order)
|
|
|
{
|
|
{
|
|
|
if (($order["status"] ?? "") === "cancelled") {
|
|
if (($order["status"] ?? "") === "cancelled") {
|
|
@@ -1810,6 +1842,13 @@ function setOrderItemBackorderStatus($orderId, $itemIndex, $status)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
if ($status === "to_be_backordered") {
|
|
if ($status === "to_be_backordered") {
|
|
|
|
|
+ if (!empty($order["items"][$itemIndex]["is_processed"])) {
|
|
|
|
|
+ return [
|
|
|
|
|
+ "success" => false,
|
|
|
|
|
+ "message" =>
|
|
|
|
|
+ "Bearbeitete Positionen können nicht als Nachbestellung markiert werden.",
|
|
|
|
|
+ ];
|
|
|
|
|
+ }
|
|
|
$order["items"][$itemIndex]["backorder_status"] = "to_be_backordered";
|
|
$order["items"][$itemIndex]["backorder_status"] = "to_be_backordered";
|
|
|
$order["items"][$itemIndex]["backordered_at"] = $now;
|
|
$order["items"][$itemIndex]["backordered_at"] = $now;
|
|
|
$order["items"][$itemIndex]["ordered_at"] = "";
|
|
$order["items"][$itemIndex]["ordered_at"] = "";
|
|
@@ -1854,10 +1893,146 @@ function toggleOrderItemBackorder($orderId, $itemIndex)
|
|
|
return ["success" => false, "message" => "Bestellung nicht gefunden."];
|
|
return ["success" => false, "message" => "Bestellung nicht gefunden."];
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+function getManualBackorders()
|
|
|
|
|
+{
|
|
|
|
|
+ $data = readJsonFile(MANUAL_BACKORDERS_FILE);
|
|
|
|
|
+ $entries =
|
|
|
|
|
+ isset($data["entries"]) && is_array($data["entries"])
|
|
|
|
|
+ ? $data["entries"]
|
|
|
|
|
+ : [];
|
|
|
|
|
+ $normalized = [];
|
|
|
|
|
+
|
|
|
|
|
+ foreach ($entries as $entry) {
|
|
|
|
|
+ if (!is_array($entry)) {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ $id = trim((string) ($entry["id"] ?? ""));
|
|
|
|
|
+ $productId = (int) ($entry["product_id"] ?? 0);
|
|
|
|
|
+ $productName = trim((string) ($entry["product_name"] ?? ""));
|
|
|
|
|
+ $size = trim((string) ($entry["size"] ?? ""));
|
|
|
|
|
+ $status = trim((string) ($entry["backorder_status"] ?? ""));
|
|
|
|
|
+ if ($id === "" || $productId <= 0 || $productName === "" || $status === "") {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (!in_array($status, ["to_be_backordered", "ordered"], true)) {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ $normalized[] = [
|
|
|
|
|
+ "id" => $id,
|
|
|
|
|
+ "product_id" => $productId,
|
|
|
|
|
+ "product_name" => $productName,
|
|
|
|
|
+ "size" => $size,
|
|
|
|
|
+ "backorder_status" => $status,
|
|
|
|
|
+ "backordered_at" => trim((string) ($entry["backordered_at"] ?? "")),
|
|
|
|
|
+ "ordered_at" => trim((string) ($entry["ordered_at"] ?? "")),
|
|
|
|
|
+ "created_at" => trim((string) ($entry["created_at"] ?? "")),
|
|
|
|
|
+ ];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return $normalized;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+function saveManualBackorders($entries)
|
|
|
|
|
+{
|
|
|
|
|
+ return writeJsonFile(MANUAL_BACKORDERS_FILE, [
|
|
|
|
|
+ "entries" => array_values($entries),
|
|
|
|
|
+ ]);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+function generateManualBackorderId()
|
|
|
|
|
+{
|
|
|
|
|
+ return "mb-" . date("YmdHis") . "-" . bin2hex(random_bytes(4));
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+function addManualBackorderItems($productId, $size, $quantity)
|
|
|
|
|
+{
|
|
|
|
|
+ $productId = (int) $productId;
|
|
|
|
|
+ $size = trim((string) $size);
|
|
|
|
|
+ $quantity = (int) $quantity;
|
|
|
|
|
+
|
|
|
|
|
+ if ($productId <= 0 || $quantity <= 0) {
|
|
|
|
|
+ return [
|
|
|
|
|
+ "success" => false,
|
|
|
|
|
+ "message" => "Ungültige Menge oder Artikel.",
|
|
|
|
|
+ ];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if ($quantity > 100) {
|
|
|
|
|
+ return [
|
|
|
|
|
+ "success" => false,
|
|
|
|
|
+ "message" => "Maximal 100 Positionen auf einmal.",
|
|
|
|
|
+ ];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ $product = getProductById($productId);
|
|
|
|
|
+ if ($product === null) {
|
|
|
|
|
+ return ["success" => false, "message" => "Artikel nicht gefunden."];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ $allowedSizes = getProductSizes($product);
|
|
|
|
|
+ if (empty($allowedSizes)) {
|
|
|
|
|
+ $allowedSizes = ["Standard"];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (!in_array($size, $allowedSizes, true)) {
|
|
|
|
|
+ return ["success" => false, "message" => "Ungültige Größe für diesen Artikel."];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ $entries = getManualBackorders();
|
|
|
|
|
+ $now = date("Y-m-d H:i:s");
|
|
|
|
|
+
|
|
|
|
|
+ for ($i = 0; $i < $quantity; $i++) {
|
|
|
|
|
+ $entries[] = [
|
|
|
|
|
+ "id" => generateManualBackorderId(),
|
|
|
|
|
+ "product_id" => $productId,
|
|
|
|
|
+ "product_name" => $product["name"],
|
|
|
|
|
+ "size" => $size,
|
|
|
|
|
+ "backorder_status" => "to_be_backordered",
|
|
|
|
|
+ "backordered_at" => $now,
|
|
|
|
|
+ "ordered_at" => "",
|
|
|
|
|
+ "created_at" => $now,
|
|
|
|
|
+ ];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (!saveManualBackorders($entries)) {
|
|
|
|
|
+ return [
|
|
|
|
|
+ "success" => false,
|
|
|
|
|
+ "message" => "Nachbestellungen konnten nicht gespeichert werden.",
|
|
|
|
|
+ ];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return ["success" => true, "added" => $quantity];
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
function collectBackorderItemRefs()
|
|
function collectBackorderItemRefs()
|
|
|
{
|
|
{
|
|
|
$refs = [];
|
|
$refs = [];
|
|
|
|
|
|
|
|
|
|
+ foreach (getManualBackorders() as $entry) {
|
|
|
|
|
+ $refs[] = [
|
|
|
|
|
+ "order_id" => "",
|
|
|
|
|
+ "item_index" => 0,
|
|
|
|
|
+ "manual_id" => $entry["id"],
|
|
|
|
|
+ "is_manual" => true,
|
|
|
|
|
+ "product_id" => $entry["product_id"],
|
|
|
|
|
+ "product_name" => $entry["product_name"],
|
|
|
|
|
+ "size" => $entry["size"],
|
|
|
|
|
+ "backorder_status" => $entry["backorder_status"],
|
|
|
|
|
+ "created_at" => $entry["created_at"] !== "" ? $entry["created_at"] : $entry["backordered_at"],
|
|
|
|
|
+ "sort_at" =>
|
|
|
|
|
+ $entry["backorder_status"] === "ordered"
|
|
|
|
|
+ ? ($entry["ordered_at"] !== ""
|
|
|
|
|
+ ? $entry["ordered_at"]
|
|
|
|
|
+ : $entry["created_at"])
|
|
|
|
|
+ : ($entry["backordered_at"] !== ""
|
|
|
|
|
+ ? $entry["backordered_at"]
|
|
|
|
|
+ : $entry["created_at"]),
|
|
|
|
|
+ ];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
foreach (getOrders() as $order) {
|
|
foreach (getOrders() as $order) {
|
|
|
if (($order["status"] ?? "") === "cancelled") {
|
|
if (($order["status"] ?? "") === "cancelled") {
|
|
|
continue;
|
|
continue;
|
|
@@ -2002,10 +2177,35 @@ function applyBackorderBulkUpdate($productId, $size, $fromStatus, $toStatus, $qu
|
|
|
|
|
|
|
|
$targets = array_slice($candidates, 0, $quantity);
|
|
$targets = array_slice($candidates, 0, $quantity);
|
|
|
$orders = getOrders();
|
|
$orders = getOrders();
|
|
|
|
|
+ $manualEntries = getManualBackorders();
|
|
|
|
|
+ $manualChanged = false;
|
|
|
$now = date("Y-m-d H:i:s");
|
|
$now = date("Y-m-d H:i:s");
|
|
|
$updated = 0;
|
|
$updated = 0;
|
|
|
|
|
|
|
|
foreach ($targets as $target) {
|
|
foreach ($targets as $target) {
|
|
|
|
|
+ if (!empty($target["is_manual"])) {
|
|
|
|
|
+ $manualId = (string) ($target["manual_id"] ?? "");
|
|
|
|
|
+ foreach ($manualEntries as &$entry) {
|
|
|
|
|
+ if ($entry["id"] !== $manualId) {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if ($toStatus === "ordered") {
|
|
|
|
|
+ $entry["backorder_status"] = "ordered";
|
|
|
|
|
+ $entry["ordered_at"] = $now;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ $entry["backorder_status"] = "";
|
|
|
|
|
+ $entry["ordered_at"] = "";
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ $manualChanged = true;
|
|
|
|
|
+ $updated++;
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ unset($entry);
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
foreach ($orders as &$order) {
|
|
foreach ($orders as &$order) {
|
|
|
if ($order["id"] !== $target["order_id"]) {
|
|
if ($order["id"] !== $target["order_id"]) {
|
|
|
continue;
|
|
continue;
|
|
@@ -2038,6 +2238,20 @@ function applyBackorderBulkUpdate($productId, $size, $fromStatus, $toStatus, $qu
|
|
|
];
|
|
];
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ if ($manualChanged) {
|
|
|
|
|
+ $manualEntries = array_values(
|
|
|
|
|
+ array_filter($manualEntries, function ($entry) {
|
|
|
|
|
+ return ($entry["backorder_status"] ?? "") !== "";
|
|
|
|
|
+ }),
|
|
|
|
|
+ );
|
|
|
|
|
+ if (!saveManualBackorders($manualEntries)) {
|
|
|
|
|
+ return [
|
|
|
|
|
+ "success" => false,
|
|
|
|
|
+ "message" => "Manuelle Nachbestellungen konnten nicht gespeichert werden.",
|
|
|
|
|
+ ];
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
saveOrders($orders);
|
|
saveOrders($orders);
|
|
|
|
|
|
|
|
return ["success" => true, "updated" => $updated];
|
|
return ["success" => true, "updated" => $updated];
|