Initial commit
This commit is contained in:
186
skrift-configurator/includes/admin-orders.php
Normal file
186
skrift-configurator/includes/admin-orders.php
Normal file
@@ -0,0 +1,186 @@
|
||||
<?php
|
||||
/**
|
||||
* Bestellnummer-Verwaltung für Skrift Konfigurator
|
||||
* Generiert fortlaufende Bestellnummern im Format: S-JAHR-MONAT-TAG-XXX
|
||||
*/
|
||||
|
||||
if (!defined('ABSPATH')) { exit; }
|
||||
|
||||
final class Skrift_Konfigurator_Orders {
|
||||
|
||||
const COUNTER_OPTION_KEY = 'skrift_konfigurator_order_counter';
|
||||
const ORDERS_OPTION_KEY = 'skrift_konfigurator_orders';
|
||||
|
||||
public function __construct() {
|
||||
add_action('rest_api_init', [$this, 'register_rest_routes']);
|
||||
}
|
||||
|
||||
/**
|
||||
* REST API Routen registrieren
|
||||
*/
|
||||
public function register_rest_routes() {
|
||||
// Neue Bestellnummer generieren
|
||||
register_rest_route('skrift/v1', '/order/generate-number', [
|
||||
'methods' => 'POST',
|
||||
'callback' => [$this, 'rest_generate_order_number'],
|
||||
'permission_callback' => ['Skrift_Konfigurator_Admin_Settings', 'rest_api_key_permission'],
|
||||
]);
|
||||
|
||||
// Bestellung registrieren (nach erfolgreicher Zahlung)
|
||||
register_rest_route('skrift/v1', '/order/register', [
|
||||
'methods' => 'POST',
|
||||
'callback' => [$this, 'rest_register_order'],
|
||||
'permission_callback' => ['Skrift_Konfigurator_Admin_Settings', 'rest_api_key_permission'],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generiert die nächste fortlaufende Bestellnummer
|
||||
* Format: S-YYYY-MM-DD-XXX (z.B. S-2026-01-12-001)
|
||||
* Verwendet Transient-Lock um Race Conditions zu vermeiden
|
||||
*/
|
||||
public static function generate_order_number() {
|
||||
$lock_key = 'skrift_order_number_lock';
|
||||
$max_attempts = 10;
|
||||
$attempt = 0;
|
||||
|
||||
// Versuche Lock zu bekommen (einfaches Locking mit Transients)
|
||||
while ($attempt < $max_attempts) {
|
||||
// Prüfe ob Lock existiert
|
||||
if (get_transient($lock_key) === false) {
|
||||
// Setze Lock (5 Sekunden Timeout)
|
||||
set_transient($lock_key, time(), 5);
|
||||
|
||||
// Aktuellen Counter holen
|
||||
$counter_data = get_option(self::COUNTER_OPTION_KEY, [
|
||||
'date' => '',
|
||||
'counter' => 0
|
||||
]);
|
||||
|
||||
$today = date('Y-m-d');
|
||||
|
||||
// Counter zurücksetzen wenn neuer Tag
|
||||
if ($counter_data['date'] !== $today) {
|
||||
$counter_data = [
|
||||
'date' => $today,
|
||||
'counter' => 0
|
||||
];
|
||||
}
|
||||
|
||||
// Counter erhöhen
|
||||
$counter_data['counter']++;
|
||||
|
||||
// Speichern
|
||||
update_option(self::COUNTER_OPTION_KEY, $counter_data);
|
||||
|
||||
// Lock freigeben
|
||||
delete_transient($lock_key);
|
||||
|
||||
// Format: S-YYYY-MM-DD-XXX
|
||||
$year = date('Y');
|
||||
$month = date('m');
|
||||
$day = date('d');
|
||||
$number = str_pad($counter_data['counter'], 3, '0', STR_PAD_LEFT);
|
||||
|
||||
return "S-{$year}-{$month}-{$day}-{$number}";
|
||||
}
|
||||
|
||||
// Warte kurz und versuche erneut
|
||||
usleep(100000); // 100ms
|
||||
$attempt++;
|
||||
}
|
||||
|
||||
// Fallback wenn Lock nicht bekommen werden konnte
|
||||
// Verwende Microtime für Eindeutigkeit
|
||||
$year = date('Y');
|
||||
$month = date('m');
|
||||
$day = date('d');
|
||||
$micro = substr(str_replace('.', '', microtime(true)), -6);
|
||||
|
||||
return "S-{$year}-{$month}-{$day}-{$micro}";
|
||||
}
|
||||
|
||||
/**
|
||||
* REST API Endpoint: Neue Bestellnummer generieren
|
||||
*/
|
||||
public function rest_generate_order_number($request) {
|
||||
$order_number = self::generate_order_number();
|
||||
|
||||
return [
|
||||
'success' => true,
|
||||
'orderNumber' => $order_number
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* REST API Endpoint: Bestellung registrieren
|
||||
*/
|
||||
public function rest_register_order($request) {
|
||||
$order_number = $request->get_param('orderNumber');
|
||||
$customer = $request->get_param('customer');
|
||||
$quote = $request->get_param('quote');
|
||||
$payment_method = $request->get_param('paymentMethod');
|
||||
$payment_id = $request->get_param('paymentId');
|
||||
|
||||
if (empty($order_number)) {
|
||||
return new WP_Error('missing_order_number', 'Bestellnummer fehlt', ['status' => 400]);
|
||||
}
|
||||
|
||||
// Bestellung speichern
|
||||
$orders = get_option(self::ORDERS_OPTION_KEY, []);
|
||||
|
||||
$orders[$order_number] = [
|
||||
'orderNumber' => $order_number,
|
||||
'customer' => $customer,
|
||||
'quote' => $quote,
|
||||
'paymentMethod' => $payment_method,
|
||||
'paymentId' => $payment_id,
|
||||
'createdAt' => current_time('mysql'),
|
||||
'status' => 'pending'
|
||||
];
|
||||
|
||||
update_option(self::ORDERS_OPTION_KEY, $orders);
|
||||
|
||||
return [
|
||||
'success' => true,
|
||||
'orderNumber' => $order_number,
|
||||
'message' => 'Bestellung erfolgreich registriert'
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Bestellung als bezahlt markieren
|
||||
*/
|
||||
public static function mark_order_paid($order_number, $payment_id = null) {
|
||||
$orders = get_option(self::ORDERS_OPTION_KEY, []);
|
||||
|
||||
if (isset($orders[$order_number])) {
|
||||
$orders[$order_number]['status'] = 'paid';
|
||||
$orders[$order_number]['paidAt'] = current_time('mysql');
|
||||
if ($payment_id) {
|
||||
$orders[$order_number]['paymentId'] = $payment_id;
|
||||
}
|
||||
update_option(self::ORDERS_OPTION_KEY, $orders);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Alle Bestellungen abrufen
|
||||
*/
|
||||
public static function get_orders() {
|
||||
return get_option(self::ORDERS_OPTION_KEY, []);
|
||||
}
|
||||
|
||||
/**
|
||||
* Einzelne Bestellung abrufen
|
||||
*/
|
||||
public static function get_order($order_number) {
|
||||
$orders = self::get_orders();
|
||||
return $orders[$order_number] ?? null;
|
||||
}
|
||||
}
|
||||
|
||||
new Skrift_Konfigurator_Orders();
|
||||
Reference in New Issue
Block a user