initial commit
This commit is contained in:
@@ -0,0 +1,114 @@
|
||||
<?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']);
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user