initial commit
This commit is contained in:
@@ -0,0 +1,105 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api\V1;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Controllers\Concerns\RespondsWithJson;
|
||||
use App\Http\Resources\MachineResource;
|
||||
use App\Models\Booking;
|
||||
use App\Models\Machine;
|
||||
use App\Services\PricingService;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class MachineController extends Controller
|
||||
{
|
||||
use RespondsWithJson;
|
||||
|
||||
public function __construct(
|
||||
private readonly PricingService $pricingService,
|
||||
) {}
|
||||
|
||||
public function show(string $uuid): JsonResponse
|
||||
{
|
||||
$machine = Machine::query()
|
||||
->where('uuid', $uuid)
|
||||
->with('establishment')
|
||||
->firstOrFail();
|
||||
|
||||
return $this->success([
|
||||
'machine' => new MachineResource($machine),
|
||||
]);
|
||||
}
|
||||
|
||||
public function availability(Request $request, string $uuid): JsonResponse
|
||||
{
|
||||
$machine = Machine::query()
|
||||
->where('uuid', $uuid)
|
||||
->with('establishment')
|
||||
->firstOrFail();
|
||||
|
||||
$date = $request->filled('date')
|
||||
? Carbon::parse($request->string('date')->toString())->startOfDay()
|
||||
: now()->startOfDay();
|
||||
|
||||
$slotDuration = $request->integer('slot_minutes', 60);
|
||||
$dayStart = $date->copy()->setTime(7, 0);
|
||||
$dayEnd = $date->copy()->setTime(22, 0);
|
||||
|
||||
$bookings = Booking::query()
|
||||
->where('machine_id', $machine->id)
|
||||
->whereIn('status', ['pending', 'confirmed', 'active'])
|
||||
->where('slot_start', '<', $dayEnd)
|
||||
->where('slot_end', '>', $dayStart)
|
||||
->get(['slot_start', 'slot_end']);
|
||||
|
||||
$slots = [];
|
||||
$cursor = $dayStart->copy();
|
||||
|
||||
while ($cursor->copy()->addMinutes($slotDuration)->lte($dayEnd)) {
|
||||
$slotEnd = $cursor->copy()->addMinutes($slotDuration);
|
||||
$isAvailable = $cursor->isFuture() && ! in_array($machine->status, ['offline', 'maintenance', 'out_of_order'], true);
|
||||
|
||||
if ($isAvailable) {
|
||||
foreach ($bookings as $booking) {
|
||||
if ($booking->slot_start < $slotEnd && $booking->slot_end > $cursor) {
|
||||
$isAvailable = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($isAvailable) {
|
||||
$slots[] = [
|
||||
'start' => $cursor->toIso8601String(),
|
||||
'end' => $slotEnd->toIso8601String(),
|
||||
];
|
||||
}
|
||||
|
||||
$cursor->addMinutes($slotDuration);
|
||||
}
|
||||
|
||||
return $this->success([
|
||||
'machine_uuid' => $machine->uuid,
|
||||
'date' => $date->toDateString(),
|
||||
'slots' => $slots,
|
||||
]);
|
||||
}
|
||||
|
||||
public function pricing(string $uuid): JsonResponse
|
||||
{
|
||||
$machine = Machine::query()
|
||||
->where('uuid', $uuid)
|
||||
->with('establishment')
|
||||
->firstOrFail();
|
||||
|
||||
$price = $this->pricingService->getActivePrice($machine);
|
||||
|
||||
return $this->success([
|
||||
'machine_uuid' => $machine->uuid,
|
||||
'price' => $price,
|
||||
'currency' => 'EUR',
|
||||
]);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user