PlatformPrice::query() ->where('is_active', true) ->ordered() ->get(), ]); } /** * Display platform prices in a card grid with administration actions. */ public function index(): View { return view('platform::prices.index', [ 'prices' => PlatformPrice::ordered()->get(), ]); } /** * Show the create price form. */ public function create(): View { return view('platform::prices.create', [ 'price' => new PlatformPrice([ 'currency' => 'gbp', 'sort_order' => 40, 'is_active' => true, 'features' => [], ]), ]); } /** * Store a new platform price. */ public function store(Request $request): RedirectResponse { PlatformPrice::create($this->validatedPriceData($request)); return redirect()->route('platform.prices.index')->with('status', 'Price created.'); } /** * Show the edit price form. */ public function edit(PlatformPrice $price): View { return view('platform::prices.edit', [ 'price' => $price, ]); } /** * Update an existing platform price. */ public function update(Request $request, PlatformPrice $price): RedirectResponse { $price->update($this->validatedPriceData($request, $price)); return redirect()->route('platform.prices.index')->with('status', 'Price updated.'); } /** * Delete a platform price. */ public function destroy(PlatformPrice $price): RedirectResponse { $price->delete(); return redirect()->route('platform.prices.index')->with('status', 'Price deleted.'); } /** * Validate and normalise price request data. * * @return array */ private function validatedPriceData(Request $request, ?PlatformPrice $price = null): array { $data = $request->validate([ 'code' => ['nullable', 'string', 'max:40', 'unique:platform_prices,code,' . ($price?->id ?? 'NULL')], 'name' => ['required', 'string', 'max:255'], 'strapline' => ['nullable', 'string', 'max:255'], 'description' => ['nullable', 'string', 'max:2000'], 'monthly_amount' => ['required', 'numeric', self::MIN_ZERO, 'max:999999.99'], 'annual_amount' => ['nullable', 'numeric', self::MIN_ZERO, 'max:999999.99'], 'currency' => ['required', 'string', 'size:3'], 'badge_label' => ['nullable', 'string', 'max:60'], 'features' => ['nullable', 'string', 'max:4000'], 'sort_order' => ['required', 'integer', self::MIN_ZERO, 'max:65535'], 'is_featured' => ['nullable', 'boolean'], 'is_active' => ['nullable', 'boolean'], ]); $data['code'] = Str::slug($data['code'] ?: $data['name']); $data['monthly_amount'] = (int) round(((float) $data['monthly_amount']) * 100); $data['annual_amount'] = $data['annual_amount'] === null || $data['annual_amount'] === '' ? null : (int) round(((float) $data['annual_amount']) * 100); $data['currency'] = strtolower($data['currency']); $data['features'] = collect(preg_split('/\r\n|\r|\n/', (string) ($data['features'] ?? ''))) ->map(fn (string $feature): string => trim($feature)) ->filter() ->values() ->all(); $data['is_featured'] = $request->boolean('is_featured'); $data['is_active'] = $request->boolean('is_active'); return $data; } }