Add edge gateway broker configurations and session management routes
- Add broker-related configuration classes (`broker_url`, `public_broker_url`, `auth_mode`, `shared_secret`) to support edge gateway functionality. - Enhance `SelfserveRoute` with routes for managing self-serve wash sessions, including session listing, detail retrieval, and forced lane stop. - Update unit tests to validate new configuration handling, session routes, and OpenAPI endpoint coverage. - Include default environment variables for broker settings in `docker-compose.example.yml`.
This commit is contained in:
@@ -5,7 +5,9 @@ namespace modules\selfserve\classes;
|
||||
require_once WD . '/classes/selfserve.php';
|
||||
require_once WD . '/classes/selfserve_schema_bootstrap.php';
|
||||
require_once WD . '/modules/selfserve/classes/selfserve_condition_evaluator.php';
|
||||
require_once WD . '/modules/selfserve/classes/selfserve_lane_command_arguments.php';
|
||||
require_once WD . '/modules/selfserve/classes/selfserve_config_versioning.php';
|
||||
require_once WD . '/modules/selfserve/helpers/selfserve_lane_command.php';
|
||||
require_once WD . '/modules/selfserve/helpers/selfserve_lane_relay.php';
|
||||
require_once WD . '/modules/selfserve/helpers/selfserve_lane_services.php';
|
||||
require_once WD . '/modules/selfserve/helpers/selfserve_lane_state.php';
|
||||
@@ -30,6 +32,8 @@ require_once WD . '/objects/selfserve_wash_sessions_o.php';
|
||||
|
||||
use classes\selfserve;
|
||||
use classes\selfserve_schema_bootstrap;
|
||||
use modules\selfserve\classes\selfserve_lane_command_arguments;
|
||||
use modules\selfserve\helpers\selfserve_lane_command;
|
||||
use modules\selfserve\classes\selfserve_config_versioning;
|
||||
use modules\selfserve\helpers\selfserve_task_gate_type;
|
||||
use modules\selfserve\helpers\selfserve_lane_relay;
|
||||
@@ -313,6 +317,56 @@ class selfserve_wash_flow implements selfserve_wash_flow_i
|
||||
return $this->getSessionSummary((int)$session->id);
|
||||
}
|
||||
|
||||
public function forceStopLane(int $laneId, ?int $sessionId = null, bool $bill = false, ?string $reason = null, ?int $userId = null): array
|
||||
{
|
||||
$lane = (new selfserve())->lane($laneId);
|
||||
$session = $this->resolveForceStopSession($laneId, $sessionId);
|
||||
$runtimeSnapshot = $this->buildForceStopRuntimeSnapshot($lane);
|
||||
$hasRuntime = $this->laneRuntimeLooksActive($runtimeSnapshot);
|
||||
if (!$session->exists() && !$hasRuntime) {
|
||||
throw new \RuntimeException('No active self-serve wash session or lane runtime found.');
|
||||
}
|
||||
|
||||
$orderId = null;
|
||||
if ($bill) {
|
||||
try {
|
||||
if ($lane->invoice() !== true) {
|
||||
throw new \RuntimeException('Elapsed-minute invoice was not created.');
|
||||
}
|
||||
$orderId = method_exists($lane, 'getLastInvoiceOrderId') ? $lane->getLastInvoiceOrderId() : null;
|
||||
} catch (\Throwable $e) {
|
||||
throw new \RuntimeException('Failed to bill elapsed minutes before force stop: ' . $e->getMessage(), 409, $e);
|
||||
}
|
||||
}
|
||||
|
||||
$summary = null;
|
||||
if ($session->exists()) {
|
||||
$eventPayload = [
|
||||
'lane_id' => $laneId,
|
||||
'reason' => $reason,
|
||||
'user_id' => $userId,
|
||||
'bill' => $bill,
|
||||
'order_id' => $orderId,
|
||||
'runtime_before_reset' => $runtimeSnapshot,
|
||||
'forced_at' => date('Y-m-d H:i:s'),
|
||||
];
|
||||
$session->markForceStopped($orderId, $eventPayload);
|
||||
$this->logSessionEvent((int)$session->id, selfserve_wash_event_type::SESSION_FORCE_STOPPED, $eventPayload);
|
||||
$summary = $this->getSessionSummary((int)$session->id);
|
||||
}
|
||||
|
||||
$lane->execute(selfserve_lane_command::RESET, new selfserve_lane_command_arguments());
|
||||
|
||||
return [
|
||||
'lane_id' => $laneId,
|
||||
'forced' => true,
|
||||
'bill' => $bill,
|
||||
'order_id' => $orderId,
|
||||
'session' => $summary,
|
||||
'runtime_before_reset' => $runtimeSnapshot,
|
||||
];
|
||||
}
|
||||
|
||||
protected function buildEligibilitySnapshot(int $laneId, string $reg, ?int $customerNumber = null, ?int $vehicleTypeIdOverride = null): array
|
||||
{
|
||||
$normalizedReg = selfserve::standardize_registration($reg);
|
||||
@@ -932,6 +986,48 @@ class selfserve_wash_flow implements selfserve_wash_flow_i
|
||||
return (new selfserve_wash_sessions_o())->select((int)$rows[0]['id']);
|
||||
}
|
||||
|
||||
protected function resolveForceStopSession(int $laneId, ?int $sessionId = null): selfserve_wash_sessions_o
|
||||
{
|
||||
if ($sessionId === null) {
|
||||
return (new selfserve_wash_sessions_o())->selectLatestOpenByLane($laneId);
|
||||
}
|
||||
|
||||
$session = (new selfserve_wash_sessions_o())->select($sessionId);
|
||||
if (!$session->exists()) {
|
||||
throw new \RuntimeException('Self-serve wash session not found.');
|
||||
}
|
||||
if ((int)$session->lane_id->value() !== $laneId) {
|
||||
throw new \RuntimeException('Self-serve wash session does not belong to the requested lane.');
|
||||
}
|
||||
if ($session->completed_at->value() !== null) {
|
||||
throw new \RuntimeException('Self-serve wash session is already closed.');
|
||||
}
|
||||
|
||||
return $session;
|
||||
}
|
||||
|
||||
protected function buildForceStopRuntimeSnapshot(selfserve_lane $lane): array
|
||||
{
|
||||
return [
|
||||
'status' => $lane->getLaneStatus()->name,
|
||||
'mode' => $lane->getLaneMode()->name,
|
||||
'state' => $lane->getLaneState()->name,
|
||||
'wash_start_time' => $lane->getWashStartTime(),
|
||||
'elapsed_wash_time' => $lane->getElapsedWashTime(),
|
||||
'license_plate' => $lane->getLicensePlate(),
|
||||
'customer_number' => $lane->getCustomerNumber(),
|
||||
];
|
||||
}
|
||||
|
||||
protected function laneRuntimeLooksActive(array $snapshot): bool
|
||||
{
|
||||
return $snapshot['status'] === selfserve_lane_status::OCCUPIED->name
|
||||
|| $snapshot['state'] === selfserve_lane_state::IN_WASH->name
|
||||
|| (int)($snapshot['wash_start_time'] ?? 0) > 0
|
||||
|| trim((string)($snapshot['license_plate'] ?? '')) !== ''
|
||||
|| (int)($snapshot['customer_number'] ?? 0) > 0;
|
||||
}
|
||||
|
||||
protected function nullableInt(mixed $value): ?int
|
||||
{
|
||||
if ($value === null || $value === '' || $value === 0 || $value === '0') {
|
||||
|
||||
Reference in New Issue
Block a user