Files
backend/app/Services/WashService.php
T
2026-06-28 12:29:53 +02:00

115 lines
3.7 KiB
PHP

<?php
namespace App\Services;
use App\Exceptions\MachineNotAvailableException;
use App\Models\Booking;
use App\Models\Machine;
use App\Models\User;
use App\Models\Wash;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
class WashService
{
public function __construct(
private readonly WalletService $walletService,
private readonly PricingService $pricingService,
private readonly MachineIntegrationService $machineIntegrationService,
private readonly AuditService $auditService,
) {}
public function startWash(
User $user,
Machine $machine,
string $triggerMethod,
?int $bookingId = null,
?string $program = null,
): Wash {
return DB::transaction(function () use ($user, $machine, $triggerMethod, $bookingId, $program) {
$machine = Machine::query()->whereKey($machine->id)->lockForUpdate()->firstOrFail();
if (! in_array($machine->status, ['available', 'reserved'], true)) {
throw new MachineNotAvailableException("Statut actuel : {$machine->status}");
}
$booking = null;
if ($bookingId !== null) {
$booking = Booking::query()
->whereKey($bookingId)
->where('user_id', $user->id)
->where('machine_id', $machine->id)
->lockForUpdate()
->firstOrFail();
if (! in_array($booking->status, ['confirmed', 'active'], true)) {
throw new \RuntimeException('La réservation n\'est pas valide pour démarrer un lavage.');
}
}
$cost = $booking !== null
? (float) $booking->reserved_amount
: $this->pricingService->getActivePrice($machine);
if ($booking === null) {
$this->walletService->debit(
$user,
$cost,
Wash::class,
null,
'wash-debit:'.Str::uuid(),
['machine_id' => $machine->id],
);
}
$wash = Wash::query()->create([
'uuid' => (string) Str::uuid(),
'user_id' => $user->id,
'machine_id' => $machine->id,
'booking_id' => $booking?->id,
'trigger_method' => $triggerMethod,
'status' => 'pending_start',
'program' => $program,
'cost' => $cost,
]);
$result = $this->machineIntegrationService->startCycle($machine, [
'wash_id' => $wash->id,
'wash_uuid' => $wash->uuid,
'program' => $program,
'requested_by_user_id' => $user->id,
], $user);
if (! $result->success) {
throw new \RuntimeException('Échec du démarrage du cycle machine.');
}
$command = $machine->commands()->latest('id')->first();
$wash->update([
'status' => 'running',
'machine_command_id' => $command?->id,
'started_at' => now(),
]);
if ($booking !== null) {
$booking->update(['status' => 'active']);
}
$machine->update(['current_user_id' => $user->id]);
$this->auditService->log(
$user,
'wash.started',
$wash,
null,
$wash->fresh()->toArray(),
$machine->establishment?->organization_id,
$machine->establishment_id,
);
return $wash->fresh(['machine', 'booking']);
});
}
}