filled('search')) { $search = $request->search; $query->where(function ($q) use ($search) { $q->where('codice_articolo', 'like', "%{$search}%") ->orWhere('descrizione', 'like', "%{$search}%") ->orWhere('ciclo', 'like', "%{$search}%"); }); } $articoli = $query->orderBy('created_at', 'desc')->paginate(15); return view('admin.articoli.index', compact('articoli')); } public function create() { return view('admin.articoli.create'); } public function store(Request $request) { $validated = $request->validate([ 'codice_articolo' => 'required|string|max:255|unique:articoli', 'ciclo' => 'nullable|string|max:255', 'diametro' => 'nullable|string|max:255', 'descrizione' => 'nullable|string', 'posizione' => 'nullable|string|max:255', 'quantita' => 'nullable|integer|min:0', 'tipo_lavorazione' => 'nullable|string|max:255', 'materiale_lavorare' => 'nullable|string|max:255', 'maximum_thickness' => 'nullable|string|max:255', 'speed_rpm' => 'nullable|integer|min:0', 'feed' => 'nullable|numeric|min:0', 'max_thrust_a' => 'nullable|string|max:255', 'min_torque_a' => 'nullable|string|max:255', 'quantita_fori' => 'nullable|integer|min:0', ]); $articolo = Articolo::create($validated); return redirect()->route('admin.articoli.show', $articolo) ->with('success', 'Articolo creato con successo.'); } public function show(Articolo $articolo) { return view('admin.articoli.show', compact('articolo')); } public function edit(Articolo $articolo) { return view('admin.articoli.edit', compact('articolo')); } public function update(Request $request, Articolo $articolo) { $validated = $request->validate([ 'codice_articolo' => 'required|string|max:255|unique:articoli,codice_articolo,' . $articolo->id, 'ciclo' => 'nullable|string|max:255', 'diametro' => 'nullable|string|max:255', 'descrizione' => 'nullable|string', 'posizione' => 'nullable|string|max:255', 'quantita' => 'nullable|integer|min:0', 'tipo_lavorazione' => 'nullable|string|max:255', 'materiale_lavorare' => 'nullable|string|max:255', 'maximum_thickness' => 'nullable|string|max:255', 'speed_rpm' => 'nullable|integer|min:0', 'feed' => 'nullable|numeric|min:0', 'max_thrust_a' => 'nullable|string|max:255', 'min_torque_a' => 'nullable|string|max:255', 'quantita_fori' => 'nullable|integer|min:0', ]); $articolo->update($validated); return redirect()->route('admin.articoli.show', $articolo) ->with('success', 'Articolo aggiornato con successo.'); } public function destroy(Articolo $articolo) { $articolo->delete(); return redirect()->route('admin.articoli.index') ->with('success', 'Articolo eliminato con successo.'); } public function qrCode(Articolo $articolo) { $qrCode = QrCode::format('svg') ->size(300) ->errorCorrection('H') ->generate($articolo->qr_url); return response($qrCode) ->header('Content-Type', 'image/svg+xml'); } public function downloadQrCode(Articolo $articolo) { $qrCode = QrCode::format('png') ->size(300) ->errorCorrection('H') ->generate($articolo->qr_url); return response($qrCode) ->header('Content-Type', 'image/png') ->header('Content-Disposition', 'attachment; filename="qr-' . $articolo->codice_articolo . '.png"'); } public function printQrCodes(Request $request) { $ids = explode(',', $request->get('ids', '')); $ids = array_filter($ids, fn($id) => is_numeric($id)); if (empty($ids)) { return redirect()->route('admin.articoli.index') ->with('error', 'Nessun articolo selezionato.'); } $articoli = Articolo::whereIn('id', $ids)->get(); // Generate QR codes as base64 for each article $articoliWithQr = $articoli->map(function ($articolo) { $qrCode = QrCode::format('png') ->size(100) // 100px ~ 10mm at 254 DPI ->errorCorrection('H') ->margin(0) ->generate($articolo->qr_url); return [ 'articolo' => $articolo, 'qr_base64' => base64_encode($qrCode), ]; }); $pdf = Pdf::loadView('admin.articoli.pdf-qrcodes', [ 'articoliWithQr' => $articoliWithQr, ]); $pdf->setPaper('a4', 'portrait'); return $pdf->stream('qrcodes.pdf'); } public function import(Request $request) { $request->validate([ 'file' => 'required|file|mimes:xlsx,xls', 'clean_import' => 'nullable|boolean', ]); $file = $request->file('file'); $cleanImport = $request->boolean('clean_import', false); try { $seeder = new ArticoloSeeder(); $result = $this->importFromExcel($file->getPathname(), $cleanImport); $message = "Import completato! "; $message .= "Articoli importati: {$result['imported']}, "; $message .= "Articoli aggiornati: {$result['updated']}, "; $message .= "Totale articoli: {$result['total']}"; if (!empty($result['errors'])) { $message .= ". Errori: " . count($result['errors']); } return response()->json([ 'success' => true, 'message' => $message, 'data' => $result, ]); } catch (\Exception $e) { return response()->json([ 'success' => false, 'message' => 'Errore durante l\'importazione: ' . $e->getMessage(), ], 500); } } /** * Import articoli from Excel file. */ public function importFromExcel(string $filePath, bool $cleanImport = false): array { $spreadsheet = IOFactory::load($filePath); $worksheet = $spreadsheet->getActiveSheet(); $rows = $worksheet->toArray(); $imported = 0; $updated = 0; $errors = []; // If clean import, delete all existing records if ($cleanImport) { Articolo::truncate(); } // Skip header rows (first 2 rows) foreach (array_slice($rows, 2) as $index => $row) { // Skip empty rows if (empty($row[0])) { continue; } try { $exists = Articolo::where('codice_articolo', $row[0])->exists(); Articolo::updateOrCreate( ['codice_articolo' => $row[0]], [ 'ciclo' => $row[1] ?? null, 'diametro' => $row[2] ?? null, 'descrizione' => $row[3] ?? null, 'posizione' => $row[4] ?? null, 'quantita' => is_numeric($row[5]) ? (int) $row[5] : 0, 'tipo_lavorazione' => $row[6] ?? null, 'materiale_lavorare' => $row[7] ?? null, 'maximum_thickness' => $row[8] ?? null, 'speed_rpm' => is_numeric($row[9]) ? (int) $row[9] : null, 'feed' => is_numeric($row[10]) ? (float) $row[10] : null, 'max_thrust_a' => $row[11] ?? null, 'min_torque_a' => $row[12] ?? null, 'quantita_fori' => is_numeric($row[13]) ? (int) $row[13] : null, ] ); if ($exists && !$cleanImport) { $updated++; } else { $imported++; } if (isset($this->command)) { $this->command->info('Importato articolo: ' . $row[0]); } } catch (\Exception $e) { $errors[] = "Riga " . ($index + 3) . ": " . $e->getMessage(); } } if (isset($this->command)) { $this->command->info('Import completato! Totale articoli: ' . Articolo::count()); } return [ 'imported' => $imported, 'updated' => $updated, 'errors' => $errors, 'total' => Articolo::count(), ]; } }