latest(); if ($request->filled('plan_id')) { $query->where('plan_id', $request->plan_id); } if ($request->filled('batch')) { $query->where('batch', $request->batch); } match ($request->status) { 'used' => $query->whereNotNull('used_at'), 'unused' => $query->whereNull('used_at'), default => null, }; $codes = $query->paginate(50)->withQueryString(); $plans = MembershipPlan::where('is_active', true)->orderBy('sort_order')->get(); $batches = ActivationCode::select('batch')->whereNotNull('batch') ->distinct()->orderBy('batch', 'desc')->pluck('batch'); $stats = [ 'total' => ActivationCode::count(), 'used' => ActivationCode::whereNotNull('used_at')->count(), 'unused' => ActivationCode::whereNull('used_at')->count(), ]; return view('admin.activation-codes.index', compact('codes', 'plans', 'stats', 'batches')); } public function generate(Request $request) { $request->validate([ 'plan_id' => 'required|exists:membership_plans,id', 'quantity' => 'required|integer|min:1|max:500', 'expires_at' => 'nullable|date|after:today', 'notes' => 'nullable|string|max:500', 'batch' => 'nullable|string|max:64', ]); $batch = $request->batch ?: 'toplu-' . now()->format('Ymd-His'); $generated = []; DB::transaction(function () use ($request, $batch, &$generated) { for ($i = 0; $i < $request->quantity; $i++) { $code = ActivationCode::create([ 'code' => ActivationCode::generateCode(), 'plan_id' => $request->plan_id, 'expires_at' => $request->expires_at ?: null, 'batch' => $batch, 'notes' => $request->notes, 'created_by' => auth()->id(), ]); $generated[] = $code->code; } }); return back() ->with('generated_codes', $generated) ->with('success', count($generated) . ' adet aktivasyon kodu oluşturuldu. (Batch: ' . $batch . ')'); } public function destroy(ActivationCode $activationCode) { if ($activationCode->isUsed()) { return back()->withErrors(['error' => 'Kullanılmış kodlar silinemez.']); } $activationCode->delete(); return back()->with('success', 'Aktivasyon kodu silindi.'); } public function destroyBatch(Request $request) { $request->validate(['batch' => 'required|string|max:64']); $count = ActivationCode::where('batch', $request->batch) ->whereNull('used_at') ->delete(); return back()->with('success', $count . ' adet kullanılmamış kod silindi.'); } public function destroySelected(Request $request) { $request->validate(['ids' => 'required|array|min:1', 'ids.*' => 'integer|exists:activation_codes,id']); $count = ActivationCode::whereIn('id', $request->ids) ->whereNull('used_at') ->delete(); return back()->with('success', $count . ' adet aktivasyon kodu silindi.'); } public function export(Request $request) { $query = ActivationCode::with('plan')->whereNull('used_at'); if ($request->filled('plan_id')) { $query->where('plan_id', $request->plan_id); } if ($request->filled('batch')) { $query->where('batch', $request->batch); } $codes = $query->orderBy('batch')->orderBy('created_at')->get(); $csv = "\xEF\xBB\xBF"; // UTF-8 BOM (Excel için) $csv .= "Kod,Plan,Batch,Son Kullanma,Oluşturulma\n"; foreach ($codes as $code) { $csv .= implode(',', [ $code->code, '"' . str_replace('"', '""', $code->plan->name) . '"', $code->batch ?? '-', $code->expires_at?->format('d.m.Y') ?? '-', $code->created_at->format('d.m.Y H:i'), ]) . "\n"; } return response($csv, 200, [ 'Content-Type' => 'text/csv; charset=UTF-8', 'Content-Disposition' => 'attachment; filename="aktivasyon-kodlari-' . now()->format('Ymd') . '.csv"', ]); } }