initial commit

This commit is contained in:
bastien
2026-06-28 12:29:53 +02:00
parent 03e85d2f9d
commit b2443b654c
220 changed files with 24969 additions and 1 deletions
@@ -0,0 +1,167 @@
<?php
namespace App\Http\Controllers\Supervisor;
use App\Http\Controllers\Controller;
use App\Http\Controllers\Supervisor\Concerns\ScopesSupervisorResources;
use App\Models\Establishment;
use App\Models\Promotion;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Inertia\Inertia;
use Inertia\Response;
class PromotionPageController extends Controller
{
use ScopesSupervisorResources;
public function index(): Response
{
$query = Promotion::query()->with('establishment:id,name');
$this->scopeEstablishmentQuery($query);
$promotions = $query
->orderByDesc('starts_at')
->get()
->map(fn (Promotion $promotion) => $this->formatPromotion($promotion));
return Inertia::render('Supervisor/Promotions/Index', [
'promotions' => $promotions,
'establishments' => $this->establishmentOptions(),
'machineTypes' => $this->machineTypeOptions(),
'discountTypes' => $this->discountTypeOptions(),
]);
}
public function store(Request $request): RedirectResponse
{
$validated = $this->validatePromotion($request);
$this->assertEstablishmentAccessible((int) $validated['establishment_id']);
Promotion::query()->create($validated);
return redirect()->route('supervisor.promotions.index')
->with('success', 'Promotion créée.');
}
public function update(Request $request, int $id): RedirectResponse
{
$promotion = $this->findAccessiblePromotion($id);
$validated = $this->validatePromotion($request);
$this->assertEstablishmentAccessible((int) $validated['establishment_id']);
$promotion->update($validated);
return redirect()->route('supervisor.promotions.index')
->with('success', 'Promotion mise à jour.');
}
public function destroy(int $id): RedirectResponse
{
$promotion = $this->findAccessiblePromotion($id);
$promotion->delete();
return redirect()->route('supervisor.promotions.index')
->with('success', 'Promotion supprimée.');
}
/**
* @return array<string, mixed>
*/
private function validatePromotion(Request $request): array
{
return $request->validate([
'establishment_id' => ['required', 'integer', 'exists:establishments,id'],
'machine_type' => ['required', 'in:washer_small,washer_large,dryer_small,dryer_large,all'],
'discount_type' => ['required', 'in:percent,fixed'],
'discount_value' => ['required', 'numeric', 'min:0'],
'starts_at' => ['required', 'date'],
'ends_at' => ['required', 'date', 'after:starts_at'],
'description' => ['nullable', 'string', 'max:500'],
'is_active' => ['boolean'],
]);
}
private function findAccessiblePromotion(int $id): Promotion
{
$query = Promotion::query()->where('id', $id);
$this->scopeEstablishmentQuery($query);
return $query->firstOrFail();
}
private function assertEstablishmentAccessible(int $establishmentId): void
{
$supervisor = $this->supervisor();
$exists = Establishment::query()
->where('id', $establishmentId)
->where('organization_id', $supervisor->organization_id)
->when($supervisor->establishment_id, fn ($q) => $q->where('id', $supervisor->establishment_id))
->exists();
abort_unless($exists, 403);
}
/**
* @return array<string, mixed>
*/
private function formatPromotion(Promotion $promotion): array
{
return [
'id' => $promotion->id,
'establishment_id' => $promotion->establishment_id,
'establishment_name' => $promotion->establishment?->name,
'machine_type' => $promotion->machine_type,
'machine_type_label' => $this->machineTypeOptions()[$promotion->machine_type] ?? $promotion->machine_type,
'discount_type' => $promotion->discount_type,
'discount_type_label' => $this->discountTypeOptions()[$promotion->discount_type] ?? $promotion->discount_type,
'discount_value' => (float) $promotion->discount_value,
'starts_at' => $promotion->starts_at?->format('Y-m-d\TH:i'),
'ends_at' => $promotion->ends_at?->format('Y-m-d\TH:i'),
'description' => $promotion->description,
'is_active' => $promotion->is_active,
];
}
/**
* @return array<int, array{id: int, name: string}>
*/
private function establishmentOptions(): array
{
$supervisor = $this->supervisor();
return Establishment::query()
->where('organization_id', $supervisor->organization_id)
->when($supervisor->establishment_id, fn ($q) => $q->where('id', $supervisor->establishment_id))
->orderBy('name')
->get(['id', 'name'])
->map(fn (Establishment $e) => ['id' => $e->id, 'name' => $e->name])
->all();
}
/**
* @return array<string, string>
*/
private function machineTypeOptions(): array
{
return [
'all' => 'Toutes les machines',
'washer_small' => 'Lave-linge petit',
'washer_large' => 'Lave-linge grand',
'dryer_small' => 'Sèche-linge petit',
'dryer_large' => 'Sèche-linge grand',
];
}
/**
* @return array<string, string>
*/
private function discountTypeOptions(): array
{
return [
'percent' => 'Pourcentage',
'fixed' => 'Montant fixe',
];
}
}