@extends('layouts.app') @section('content') {{-- Alerts --}} @if(session('success'))
{{ session('success') }}
@endif @if(session('error'))
{{ session('error') }}
@endif @if($errors->any())
No se pudo guardar:
    @foreach($errors->all() as $error)
  • {{ $error }}
  • @endforeach
@endif {{-- ═══ TABS compactos ═══ --}}
@php $tabs = [ ['id'=>'empresa', 'icon'=>'bi-building', 'label'=>'Empresa'], ['id'=>'sunat', 'icon'=>'bi-receipt-cutoff', 'label'=>'SUNAT / PSE'], ['id'=>'ticket', 'icon'=>'bi-printer', 'label'=>'Ticket'], ['id'=>'impresoras','icon'=>'bi-hdd-network-fill', 'label'=>'Impresoras'], ['id'=>'api', 'icon'=>'bi-cpu', 'label'=>'API DNI/RUC'], ['id'=>'backup', 'icon'=>'bi-cloud-download', 'label'=>'Backup'], ['id'=>'reinicio', 'icon'=>'bi-arrow-counterclockwise','label'=>'Reinicio'], ]; @endphp @foreach($tabs as $i => $tab) @endforeach
@csrf
{{-- ══════════════════════ EMPRESA ══════════════════════ --}}
@csrf
Datos del negocio
PIN de acceso a Configuración

@if(!empty($settings['config_pin'])) PIN activado — escribe uno nuevo abajo solo si quieres cambiarlo. @else Sin PIN configurado — cualquier Administrador puede entrar aquí libremente. @endif

Pantalla de inicio de sesión
@if(!empty($settings['login_cover_image'])) @endif
{{-- ══════════════════════ SUNAT + PSE (fusionado) ══════════════════════ --}}
@csrf
@php $ambiente = $settings['sunat_environment'] ?? 'beta'; $tieneCert = !empty($settings['sunat_cert_path']); $pseProveedor = $settings['sunat_pse_proveedor'] ?? ''; $pseEntorno = $settings['sunat_pse_entorno'] ?? 'test'; $pseUsuarioClave = ['gior', 'qpse', 'validapse', 'sendfact']; $pseActivo = in_array($pseProveedor, ['nubefact','gior','qpse','validapse','sendfact'], true); @endphp
Ambiente: {{ $ambiente==='produccion'?'PRODUCCIÓN':'BETA (pruebas)' }} @if(!$tieneCert) · cert. demo@endif
Identificación del emisor
Ambiente
Enviar a SUNAT automáticamente
Activado: cada boleta/factura se envía a SUNAT apenas se genera. Desactivado: queda "Pendiente" en Comprobantes → SUNAT hasta que le des clic a enviar.
Régimen de Selva (exonerado de IGV)
Actívalo solo si este negocio está domiciliado y opera dentro de la zona de Selva (Ley N° 27037). Todas las ventas se calculan sin IGV. Verifica con tu contador antes de activarlo.
¿Cómo vas a firmar y enviar tus comprobantes a SUNAT?
{{-- ═══ Bloque PSE: solo visible si el modo elegido es "pse" ═══ --}}
Datos del proveedor PSE
{{-- Info del proveedor seleccionado --}}
@if($pseProveedor==='nubefact') 🟢 Nubefact — Obtén tu token en nubefact.com → Panel → Token API. @elseif($pseProveedor==='qpse') 🟢 QPSE — Usa el usuario y contraseña de tu cuenta en qpse.pe @elseif($pseProveedor==='gior') 🟢 Gior Technology — Usa el usuario y contraseña de tu cuenta en giortechnology.com @elseif($pseProveedor==='validapse') 🟢 Validapse — Usa el usuario y contraseña de tu cuenta en validapse.com @elseif($pseProveedor==='sendfact') 🟢 SendFact — Usa el usuario y contraseña de tu cuenta en sendfact.com @endif
{{-- Campos Nubefact (Token + URL de cuenta) --}}
La encuentras en tu panel de Nubefact → "Datos de acceso a la API".
{{-- Campos Usuario + Clave (Gior, QPSE, Validapse, SendFact) --}}
{{-- ═══ Bloque Credenciales SOL + Certificado: visibles solo si el modo elegido es "certificado" ═══ --}}
Credenciales SOL
Este usuario es el que envía los comprobantes a SUNAT.
Esta es la clave que usa el sistema para enviar a SUNAT.
{{-- Certificado digital: solo tiene sentido si NO se usa PSE, se oculta automáticamente --}}
Certificado digital
@if($tieneCert) {{ $settings['sunat_cert_path'] }} @elseSin cert. Para BETA: php artisan sunat:cert:demo@endif
{{-- ══════════════════════ TICKET ══════════════════════ --}}
@csrf
Aparece al final de cada ticket impreso.
{{-- Vista previa 80mm --}}
{{ $settings['company_name']??'Mi Restaurante' }}
@if(!empty($settings['sunat_ruc']))
RUC: {{ $settings['sunat_ruc'] }}
@endif @if(!empty($settings['company_phone']))
Telf: {{ $settings['company_phone'] }}
@endif
TICKET V000001
{{ now()->format('d/m/Y H:i') }}
Producto Ejemplo
2 x S/ 10.00S/ 20.00
TOTAL:S/ 20.00
{{-- ══════════════════════ IMPRESORAS DEL LOCAL ══════════════════════ --}}
@php $printerConnected = !empty($printerLastSeen) && now()->diffInSeconds($printerLastSeen) < 20; @endphp
La comanda sale sola en la impresora que le corresponda a cada categoría, y la boleta/nota de venta sale sola en Caja al cobrar. Necesitas el puente corriendo en la laptop de caja.
@csrf
@if(!empty($settings['printer_remote_enabled'])) @if($printerConnected)
Puente conectado — {{ \Carbon\Carbon::parse($printerLastSeen)->diffForHumans() }}
@else
Puente sin conexión {{ $printerLastSeen ? 'desde ' . \Carbon\Carbon::parse($printerLastSeen)->diffForHumans() : '(nunca se ha conectado)' }}
@endif @endif {{-- Lista de impresoras --}} Impresoras del local
@foreach($printers as $printer) @php $colorClase = $printer->role === 'caja' ? 'cfg-blue' : ($printer->role === 'cocina' ? 'cfg-green' : 'cfg-purple'); $badgeClase = $printer->role === 'caja' ? 'text-bg-primary' : ($printer->role === 'cocina' ? 'text-bg-success' : 'text-bg-secondary'); @endphp
@csrf @method('PUT') {{ $printer->role === 'caja' ? 'Fija' : ($printer->role === 'cocina' ? 'Fija' : 'Estación') }} {{ $printer->role === 'caja' ? 'Boletas y notas de venta' : ($printer->role === 'cocina' ? 'Categorías sin estación' : 'Asígnale categorías') }}
@if(!in_array($printer->role, ['caja', 'cocina']))
@csrf @method('DELETE')
@endif
@endforeach
{{-- Agregar impresora nueva --}}
@csrf
Después de agregar, entra a Productos → Categorías y elige a cuál imprime cada una.
El puente por defecto usa PowerShell — ya viene instalado en Windows 10/11, no hace falta instalar nada más. Para abrirlo: clic derecho sobre el archivo descargado → "Ejecutar con PowerShell". Si Windows lo bloquea por venir de internet, abre PowerShell como administrador una sola vez y corre: Set-ExecutionPolicy RemoteSigned -Scope CurrentUser
@csrf
{{-- ══════════════════════ API DNI/RUC ══════════════════════ --}}
@csrf {{-- ─── PERÚ ─────────────────────────────────────────── --}}
🇵🇪
Perú — RENIEC / SUNAT
Usar consulta interna
Activa solo si tienes una API propia en tu servidor.
@php $presets = ['https://apiperu.dev'=>'apiperu.dev','https://apis.net.pe'=>'apis.net.pe','https://apiperu.info'=>'apiperu.info','https://dniruc.apisperu.com'=>'apisperu.com']; $urlActual = $settings['apiperu_url']??'https://apiperu.dev'; $esCustom = !array_key_exists($urlActual,$presets); @endphp
@foreach($presets as $url => $label) @endforeach
@if(!empty($settings['apiperu_token']))
Token configurado · Búsqueda activa
@else
Sin token · Búsqueda desactivada
@endif
{{-- ─── PAÍSES INTERNACIONALES ────────────────────────── --}} @php $paises = [ ['code'=>'mx','flag'=>'🇲🇽','nombre'=>'México','tipo'=>'RFC / CURP','field_url'=>'api_mx_url','field_token'=>'api_mx_token','placeholder_url'=>'https://api.ejemplo.com.mx','placeholder_token'=>'Token de tu proveedor México'], ['code'=>'ec','flag'=>'🇪🇨','nombre'=>'Ecuador','tipo'=>'RUC / CI','field_url'=>'api_ec_url','field_token'=>'api_ec_token','placeholder_url'=>'https://api.sri.gob.ec','placeholder_token'=>'Token de tu proveedor Ecuador'], ['code'=>'ar','flag'=>'🇦🇷','nombre'=>'Argentina','tipo'=>'CUIT / DNI','field_url'=>'api_ar_url','field_token'=>'api_ar_token','placeholder_url'=>'https://afip.ejemplo.com.ar','placeholder_token'=>'Token de tu proveedor Argentina'], ['code'=>'cl','flag'=>'🇨🇱','nombre'=>'Chile','tipo'=>'RUT','field_url'=>'api_cl_url','field_token'=>'api_cl_token','placeholder_url'=>'https://api.sii.cl','placeholder_token'=>'Token de tu proveedor Chile'], ['code'=>'co','flag'=>'🇨🇴','nombre'=>'Colombia','tipo'=>'NIT / CC','field_url'=>'api_co_url','field_token'=>'api_co_token','placeholder_url'=>'https://api.dian.gov.co','placeholder_token'=>'Token de tu proveedor Colombia'], ]; @endphp
@foreach($paises as $p)
{{ $p['flag'] }}
{{ $p['nombre'] }}
Consulta {{ $p['tipo'] }}
@if(!empty($settings[$p['field_token']])) Activo @else Sin configurar @endif
URL de la API
Token de acceso
@endforeach
{{-- ══════════════════════ BACKUP ══════════════════════ --}}
Descargar Backup

Genera un archivo .sql con toda la información: productos, ventas, clientes, mesas, pedidos, etc.

@csrf
backup_restaurante_{{ now()->format('Y-m-d') }}.sql
¿Cómo restaurar?
  1. Abre phpMyAdmin
  2. Selecciona la BD {{ env('DB_DATABASE','restaurante_db') }}
  3. Pestaña Importar
  4. Selecciona el .sql
  5. Clic en Continuar
Haz backup diario. Guárdalo en Google Drive o USB.
Resumen de la Base de Datos
@php $resumen = [ ['label'=>'Pedidos','icon'=>'bi-cart-check','color'=>'primary','count'=>\App\Models\Order::count()], ['label'=>'Clientes','icon'=>'bi-people','color'=>'success','count'=>\App\Models\Client::count()], ['label'=>'Productos','icon'=>'bi-box-seam','color'=>'warning','count'=>\App\Models\Product::count()], ['label'=>'Categorías','icon'=>'bi-tags','color'=>'info','count'=>\App\Models\Category::count()], ['label'=>'Mesas','icon'=>'bi-grid-3x3','color'=>'secondary','count'=>\App\Models\Table::count()], ['label'=>'Detalle','icon'=>'bi-list-ol','color'=>'danger','count'=>\App\Models\OrderDetail::count()], ]; @endphp @foreach($resumen as $item)
{{ number_format($item['count']) }}
{{ $item['label'] }}
@endforeach
{{-- ══════════════════════ REINICIO ══════════════════════ --}}
Reinicio Total del Sistema
ADVERTENCIA: Esta acción eliminará TODOS los datos:
  • Ventas, detalle de ventas, cuentas por cobrar
  • Reservas y gastos · Cajas y movimientos
  • Stock de productos (queda en cero)
  • Clientes registrados
Esta acción NO se puede deshacer. Haz un backup antes.
@php $claveSeguridad = substr(md5(date('Ymd').env('APP_KEY','secret')),0,6); @endphp
@csrf
La clave es: {{ $claveSeguridad }}
{{-- /tab-content-wrapper --}} @endsection