settings->get('items_per_page', 15); // Costruisce la query con filtri opzionali dalla URL // Es: /customers?search=mario&type=privato&status=attivo $query = Customer::query(); if ($search = $request->input('search')) { $query->search($search); // Usa lo scope definito nel Model } if ($type = $request->input('type')) { $query->byType($type); } if ($status = $request->input('status')) { $query->where('status', $status); } // paginate() divide i risultati in pagine e genera automaticamente // i link prev/next, passati alla view come $customers->links() $customers = $query->latest()->paginate($perPage)->withQueryString(); return view('customers.index', compact('customers')); } // ─── Form nuovo cliente ──────────────────────────────────────────────── public function create() { return view('customers.create'); } // ─── Salva nuovo cliente ─────────────────────────────────────────────── public function store(Request $request) { // Validazione: se fallisce, Laravel reindirizza automaticamente // al form precedente con gli errori e i valori inseriti. $validated = $request->validate([ 'name' => 'required|string|max:255', 'email' => 'required|email|unique:customers,email', 'phone' => 'nullable|string|max:50', 'city' => 'nullable|string|max:100', 'address' => 'nullable|string|max:255', 'vat_number' => 'nullable|string|max:20', 'fiscal_code' => 'nullable|string|max:20', 'type' => 'required|in:privato,azienda', 'status' => 'required|in:attivo,inattivo,prospect', 'notes' => 'nullable|string', 'contract_value' => 'nullable|numeric|min:0', ]); $customer = Customer::create($validated); // redirect() rimanda il browser a un'altra pagina // with('success', ...) aggiunge un messaggio flash (mostrato una volta) return redirect() ->route('customers.show', $customer) ->with('success', "Cliente \"{$customer->name}\" creato con successo."); } // ─── Dettaglio cliente ───────────────────────────────────────────────── // Route Model Binding: Laravel trova automaticamente il Customer dall'URL // Non serve scrivere: $customer = Customer::findOrFail($id); public function show(Customer $customer) { return view('customers.show', compact('customer')); } // ─── Form modifica cliente ───────────────────────────────────────────── public function edit(Customer $customer) { return view('customers.edit', compact('customer')); } // ─── Aggiorna cliente ───────────────────────────────────────────────── public function update(Request $request, Customer $customer) { $validated = $request->validate([ 'name' => 'required|string|max:255', // unique: ignora il record corrente (altrimenti failerebbe sempre) 'email' => "required|email|unique:customers,email,{$customer->id}", 'phone' => 'nullable|string|max:50', 'city' => 'nullable|string|max:100', 'address' => 'nullable|string|max:255', 'vat_number' => 'nullable|string|max:20', 'fiscal_code' => 'nullable|string|max:20', 'type' => 'required|in:privato,azienda', 'status' => 'required|in:attivo,inattivo,prospect', 'notes' => 'nullable|string', 'contract_value' => 'nullable|numeric|min:0', ]); $customer->update($validated); return redirect() ->route('customers.show', $customer) ->with('success', "Cliente \"{$customer->name}\" aggiornato."); } // ─── Elimina cliente (soft delete) ──────────────────────────────────── // Grazie a SoftDeletes nel Model, il record non viene cancellato: // viene impostato `deleted_at` e non compare più nelle query normali. public function destroy(Customer $customer) { $name = $customer->name; $customer->delete(); return redirect() ->route('customers.index') ->with('success', "Cliente \"{$name}\" eliminato."); } }