187 lines
5.1 KiB
PHP
187 lines
5.1 KiB
PHP
<?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();
|