Em caso de perda, comunique à secretaria da igreja.
@php use Illuminate\Support\Facades\DB; // ── Parâmetros ──────────────────────────────────────────────────── $rawIds = request('ids', ''); $modelo = request('modelo', 'padrao'); // padrao | obreiro | pastor | congregado | pb $ids = array_values(array_filter(array_map('intval', explode(',', $rawIds)))); // ── Igreja (carregar antes para filtrar membros) ────────────────── $igrejas = session('igrejas', []); // ── IDs permitidos (somente membros das igrejas da sessão) ─────── $igrejasInt = array_map('intval', $igrejas); // Nota: pluck() não aceita nome qualificado (alias.coluna) — usar só o nome da coluna $idsPermitidos = !empty($igrejasInt) ? DB::table('cargoxmembroxigreja as cmi') ->join('departamentosxigreja as di', 'cmi.idDI', '=', 'di.idDI') ->whereIn('cmi.idMembro', $ids) ->whereIn('di.idIgreja', $igrejasInt) ->distinct() ->selectRaw('CAST(cmi.idMembro AS UNSIGNED) as idMembro') ->pluck('idMembro') ->map('intval') ->toArray() : $ids; // ── Buscar membros (somente os permitidos) ──────────────────────── $membros = !empty($idsPermitidos) ? DB::table('membros as m') ->whereIn('m.idMembro', $idsPermitidos) ->select('m.idMembro','m.Nome','m.Imagem','m.dtNascimento','m.Tipo','m.CPF') ->get()->all() : []; $igreja = $igrejas ? DB::table('igrejas')->whereIn('idIgreja', $igrejas)->first() : null; // ── Tipos de membro ─────────────────────────────────────────────── $tipos = ['E'=>'Membro','F'=>'Congregado','C'=>'Criança','V'=>'Visitante']; // Logo URL: usa logo da igreja se disponível, senão fallback do sistema (fundo escuro) $_lotLogoPath = (!empty($igreja->Imagem)) ? storage_path('app/public/logos/'.$igreja->Imagem) : null; $igrejaLogoUrl = ($_lotLogoPath && file_exists($_lotLogoPath)) ? asset('storage/logos/'.$igreja->Imagem) : asset('images/logo-atos-dark.png'); // ── Modelo personalizado (custom_{id}) ─────────────────────────── $modeloCustom = null; $customFields = []; if (str_starts_with($modelo, 'custom_')) { try { if (\Illuminate\Support\Facades\Schema::hasTable('credencial_modelos')) { $customId = (int) str_replace('custom_', '', $modelo); $modeloCustom = DB::table('credencial_modelos') ->where('idModelo', $customId) ->where('Ativo', 1) ->first(); if ($modeloCustom && $modeloCustom->ConfigJson) { $customFields = json_decode($modeloCustom->ConfigJson, true) ?? []; } } } catch (\Exception $e) { /* tabela ainda não criada */ } } // ── Helper: estilo inline para campos do modelo personalizado ──── $fStyle = function(array $f, bool $isFoto = false): string { $s = 'position:absolute;'; $s .= 'top:' . ($f['top'] ?? 0) . '%;'; $s .= 'left:' . ($f['left'] ?? 0) . '%;'; $s .= 'z-index:2;'; if ($isFoto) { $s .= 'width:' . ($f['w'] ?? 25) . '%;'; $s .= 'height:' . ($f['h'] ?? 55) . '%;'; $s .= 'overflow:hidden;border-radius:2px;'; } else { $s .= 'color:' . ($f['color'] ?? '#ffffff') . ';'; $s .= 'font-size:' . ($f['size'] ?? 2) . 'mm;'; $s .= 'font-weight:' . (!empty($f['bold']) ? 'bold' : 'normal') . ';'; $s .= 'white-space:nowrap;line-height:1.2;'; if (!empty($f['align'])) { $s .= 'text-align:' . $f['align'] . ';'; } } return $s; }; // ── Modelos visuais padrão ──────────────────────────────────────── $modelos = [ 'padrao' => [ 'label' => 'Padrão Azul', 'bg' => 'linear-gradient(135deg, #1e3a8a 0%, #3b82f6 100%)', 'bgDark' => '#1e3a8a', 'accent' => 'rgba(255,255,255,0.28)', 'bar' => 'rgba(255,255,255,0.35)', ], 'obreiro' => [ 'label' => 'Obreiro / Líder', 'bg' => 'linear-gradient(135deg, #0f172a 0%, #1e293b 60%, #334155 100%)', 'bgDark' => '#0f172a', 'accent' => '#d4af37', 'bar' => '#d4af37', ], 'pastor' => [ 'label' => 'Pastor / Presbitério', 'bg' => 'linear-gradient(135deg, #3b0764 0%, #7e22ce 60%, #a855f7 100%)', 'bgDark' => '#3b0764', 'accent' => '#fde68a', 'bar' => '#fde68a', ], 'congregado' => [ 'label' => 'Congregado', 'bg' => 'linear-gradient(135deg, #052e16 0%, #166534 60%, #22c55e 100%)', 'bgDark' => '#052e16', 'accent' => 'rgba(255,255,255,0.28)', 'bar' => 'rgba(255,255,255,0.4)', ], 'pb' => [ 'label' => 'P&B (Simples)', 'bg' => 'linear-gradient(135deg, #1f2937 0%, #374151 100%)', 'bgDark' => '#1f2937', 'accent' => 'rgba(255,255,255,0.2)', 'bar' => 'rgba(255,255,255,0.3)', ], ]; $mc = $modelos[$modelo] ?? $modelos['padrao']; $mcLabel = $modeloCustom ? $modeloCustom->Nome : $mc['label']; // ── Tokens dos membros para QR Code ────────────────────────────────── $memberTokens = []; try { if (\Illuminate\Support\Facades\Schema::hasTable('membros_tokens')) { $memberIds = array_values(array_filter(array_map(fn($m) => $m ? (int)$m->idMembro : null, $membros))); if (!empty($memberIds)) { $existingTokens = DB::table('membros_tokens') ->whereIn('idMembro', $memberIds) ->pluck('token', 'idMembro') ->toArray(); foreach ($memberIds as $mid) { if (!isset($existingTokens[$mid])) { $newToken = \Illuminate\Support\Str::uuid()->toString(); DB::table('membros_tokens')->insert([ 'idMembro' => $mid, 'token' => $newToken, 'expires_at' => now()->endOfYear()->toDateString(), 'created_at' => now(), ]); $memberTokens[$mid] = $newToken; } else { $memberTokens[$mid] = $existingTokens[$mid]; } } } } } catch (\Exception $e) {} $appUrl = rtrim(config('app.url'), '/'); // ── Montar folhas separadas: TODAS as frentes, depois TODOS os versos ── $cardsPerSheet = 8; $memberChunks = array_chunk($membros, $cardsPerSheet); $frontSheets = []; $backSheets = []; foreach ($memberChunks as $chunk) { while (count($chunk) < $cardsPerSheet) { $chunk[] = null; } // Verso espelhado: [0,1][2,3]... → [1,0][3,2]... (alinhamento duplex borda longa) $verso = []; for ($i = 0; $i < $cardsPerSheet; $i += 2) { $verso[] = $chunk[$i + 1] ?? null; $verso[] = $chunk[$i] ?? null; } $frontSheets[] = $chunk; $backSheets[] = $verso; } if (empty($frontSheets)) { $frontSheets = [array_fill(0, 8, null)]; $backSheets = [array_fill(0, 8, null)]; } $totalMembros = count(array_filter($membros)); $totalFolhas = count($frontSheets); // Verso custom: usa ImagemFundoVerso + campos do verso (cpf, rg, qrcode, etc.) $versoImgUrl = ($modeloCustom && !empty($modeloCustom->ImagemFundoVerso)) ? asset('storage/' . $modeloCustom->ImagemFundoVerso) : null; $versoFields = ['cpf','rg','dtBatismo','dtRecebimento','dtCadastro','endereco','telefone','qrcode','codigoBarras','assinatura']; $fStyleImg = function(array $f): string { $s = 'position:absolute;'; $s .= 'top:' . ($f['top'] ?? 0) . '%;'; $s .= 'left:' . ($f['left'] ?? 0) . '%;'; $s .= 'width:' . ($f['w'] ?? 25) . '%;'; $s .= 'height:' . ($f['h'] ?? 30) . '%;'; $s .= 'z-index:2;overflow:hidden;border-radius:3px;'; return $s; // o div filho com position:absolute;inset:0 cobre 100% deste container }; @endphp