Sync self-serve machine relay session state

This commit is contained in:
Jeppe Bundgaard
2026-06-03 20:35:50 +02:00
parent 33b7c3e51a
commit 1d43221b4d
3 changed files with 105 additions and 1 deletions
@@ -12,6 +12,7 @@ use modules\selfserve\helpers\selfserve_lane_relay;
use modules\selfserve\helpers\selfserve_lane_services;
use modules\selfserve\helpers\selfserve_lane_status;
use modules\shelly\helpers\shelly_request_body_get_states;
use objects\selfserve_wash_sessions_o;
trait selfserve_lane_relay_controller_t
{
@@ -917,7 +918,38 @@ trait selfserve_lane_relay_controller_t
}
}
return $this->sendRelaySwitchCommand($relay, true, $duration);
$result = $this->sendRelaySwitchCommand($relay, true, $duration);
if ($result && $relay === selfserve_lane_relay::MACHINE) {
$this->markLatestSelfServeSessionRelayEnabledForLane();
}
return $result;
}
protected function markLatestSelfServeSessionRelayEnabledForLane(): void
{
try {
$customerNumber = (int)$this->getCustomerNumber();
$session = (new selfserve_wash_sessions_o())->selectLatestOpenByLane(
(int)$this->id,
$customerNumber > 0 ? $customerNumber : null
);
if (!$session->exists() && $customerNumber > 0) {
$session = (new selfserve_wash_sessions_o())->selectLatestOpenByLane((int)$this->id);
}
if (!$session->exists() || (bool)$session->machine_relay_enabled->value() === true) {
return;
}
$session->markRelayEnabled();
} catch (\Throwable $e) {
error_log(
'Failed to synchronize self-serve machine relay session state for lane '
. (int)$this->id
. ': '
. $e->getMessage()
);
}
}
/**
@@ -86,6 +86,73 @@ it('allows the customer self-serve start sequence without department access', fu
->toBe((int)$scenario['customer']['customer_number']);
});
it('marks the active customer session relay-enabled after machine relay enable', function (): void {
$group = api_fixtures()->createGroup([], [
'list_own_department_selfserve_vehicle_conditions',
'modules_selfserve_lane_relay_enable_machine',
]);
$scenario = api_fixtures()->createSelfServeScenario([
'customer' => ['group_id' => $group['id']],
'department_selfserve_enabled' => true,
'lane_selfserve_enabled' => true,
'session' => [
'status' => 'READY_FOR_MACHINE_START',
'machine_relay_enabled' => 0,
'machine_relay_enabled_at' => null,
'machine_start_triggered' => 0,
'machine_start_triggered_at' => null,
'wash_started_at' => null,
],
]);
$headers = api_fixtures()->bearerHeaders(
api_fixtures()->createAuthToken((int)$scenario['customer']['id'])
);
$laneId = (int)$scenario['lane']['id'];
$reg = (string)$scenario['vehicle']['reg'];
$machineTaskId = (int)$scenario['tasks'][1]['id'];
selfserve_customer_start_make_available($laneId);
api_client()
->get('/department/selfserve/vehicle/allowed?lane_id=' . $laneId . '&reg=' . urlencode($reg), $headers)
->assertStatus(200)
->assertSuccess(true);
api_client()
->post('/modules/self-serve/lane/services/allowed', [
'lane_id' => $laneId,
'task_ids' => [$machineTaskId],
], $headers)
->assertStatus(200)
->assertSuccess(true);
api_client()
->post('/modules/self-serve/lane/command', [
'lane_id' => $laneId,
'command' => 'START',
'license_plate' => $reg,
'defer_relay_side_effects' => true,
], $headers)
->assertStatus(200)
->assertSuccess(true);
api_client()
->post('/modules/self-serve/lane/relay/machine/enable', [
'lane_id' => $laneId,
], $headers)
->assertStatus(200)
->assertSuccess(true);
$activeResponse = api_client()
->get('/modules/self-serve/lane/wash/my-active-wash', $headers)
->assertStatus(200)
->assertSuccess(true);
expect($activeResponse->data()['session']['status'] ?? null)->toBe('MACHINE_RELAY_ENABLED')
->and($activeResponse->data()['session']['machine_relay_enabled'] ?? null)->toBeTrue()
->and($activeResponse->data()['session']['machine_start_triggered'] ?? null)->toBeFalse();
});
it('derives allowed services from v2 session task snapshots when task rows are not legacy records', function (): void {
$group = api_fixtures()->createGroup([], [
'list_own_department_selfserve_vehicle_conditions',
@@ -181,8 +181,10 @@ it('keeps legacy self-serve CRUD routes syncing canonical drafts', function ():
it('wires machine relay status get and set endpoints', function (): void {
$moduleSelfServeRoute = file_get_contents(app_path('routes/moduleSelfServeRoute.php'));
$relayController = file_get_contents(app_path('modules/selfserve/traits/selfserve_lane_relay_controller_t.php'));
expect($moduleSelfServeRoute)->not->toBeFalse();
expect($relayController)->not->toBeFalse();
expect($moduleSelfServeRoute)->toContain('/modules/self-serve/lane/relay/machine/status');
expect($moduleSelfServeRoute)->toContain('/modules/self-serve/lane/relay/machine/set');
expect($moduleSelfServeRoute)->toContain('/modules/self-serve/lane/relay/machine_program_picker/status');
@@ -196,6 +198,9 @@ it('wires machine relay status get and set endpoints', function (): void {
expect($moduleSelfServeRoute)->toContain('getMachineCleanerRelayStatus');
expect($moduleSelfServeRoute)->toContain('setMachineCleanerRelayStatus');
expect($moduleSelfServeRoute)->toContain('setMachineCleanerRelayStatusHard(true)');
expect($relayController)->toContain('markLatestSelfServeSessionRelayEnabledForLane');
expect($relayController)->toContain('selectLatestOpenByLane(');
expect($relayController)->toContain('$session->markRelayEnabled();');
expect($moduleSelfServeRoute)->toContain('applyShellyTransportOverride($lane)');
expect($moduleSelfServeRoute)->toContain("'transport' => \$this->requestedShellyTransportOverride()");
expect($moduleSelfServeRoute)->toContain('buildRelayStatusResponse');