Skip to main content

Funcionalidades principales

El sistema ofrece una solución completa para la gestión comercial y tributaria de empresas peruanas, con todas las herramientas necesarias para operar bajo la normativa SUNAT.

Facturación electrónica

Facturas electrónicas

Emisión de facturas (tipo 01) con envío síncrono a SUNAT vía SOAP. Generación automática de XML firmado digitalmente y recepción de CDR.

Boletas de venta

Boletas de venta (tipo 03) con Resumen Diario automático. Compatible con ventas al contado y crédito con cuotas.

Notas de crédito

Notas de crédito (tipo 07) vinculadas a documentos de venta. Incluye motivos SUNAT: anulación, descuentos, devoluciones, etc.

Notas de débito

Notas de débito (tipo 08) para aumentar el importe de facturas. Motivos: intereses por mora, aumentos en operaciones, penalidades.

Generación de XML y firma digital

El sistema utiliza el servicio SunatService.php (~700+ líneas) que maneja toda la lógica SUNAT:
// app/Services/SunatService.php
public function enviarFactura(Venta $venta): array
{
    $see = $this->getSee($venta->empresa);
    $invoice = $this->buildInvoice($venta);
    
    $result = $see->send($invoice);
    
    if ($result->isSuccess()) {
        $this->guardarXml($venta, $see->getFactory()->getLastXml());
        $this->guardarCdr($venta, $result->getCdrZip());
    }
    
    return $this->procesarRespuesta($result);
}
Los archivos XML y CDR se almacenan en storage/app/sunat/ organizados por RUC:
  • xml/{ruc}/ para documentos XML generados
  • cdr/{ruc}/ para constancias de recepción de SUNAT

Guías de remisión electrónicas

GRE - Guía remitente

Guías de remisión electrónicas (tipo 09) mediante API REST de SUNAT. Flujo asíncrono con tickets y consulta de estado.

Motivos de traslado

Compatible con todos los motivos SUNAT: venta, compra, traslado entre establecimientos, devolución, consignación, etc.

Flujo asíncrono GRE

Las guías utilizan OAuth 2.0 y retornan un ticket que debe consultarse:
// Envío asíncrono
Route::post('guias-remision/{id}/enviar', [GuiaRemisionController::class, 'enviar']);

// Consulta posterior del ticket
Route::get('guias-remision/{id}/ticket', [GuiaRemisionController::class, 'consultarTicket']);
La API GRE requiere credenciales OAuth separadas configuradas en SUNAT_GRE_CLIENT_ID y SUNAT_GRE_CLIENT_SECRET.

Gestión de productos e inventario

Control de stock

Gestión de inventario por almacén con stock en tiempo real. Movimientos automáticos en compras y ventas.

Productos y servicios

Catálogo completo con código, nombre, precio, unidades SUNAT, categorías y códigos de barras.

Movimientos de stock

Registro de entradas, salidas, ajustes y transferencias. Trazabilidad completa con usuario y fecha.

Importación Excel

Carga masiva de productos desde Excel. Plantilla descargable con validación de datos.

Servicio de productos

El ProductoService.php maneja toda la lógica de stock:
public function descontarStock(Producto $producto, float $cantidad, string $motivo)
{
    $producto->cantidad -= $cantidad;
    $producto->save();
    
    MovimientoStock::create([
        'id_producto' => $producto->id_producto,
        'tipo_movimiento' => 'salida',
        'cantidad' => $cantidad,
        'motivo' => $motivo
    ]);
}

Gestión comercial

Ventas

Registro de ventas con múltiples productos y servicios. Soporte para descuentos, IGV, percepciones y detracciones.

Compras

Control de compras a proveedores con ingreso automático al stock. Compatible con facturas y boletas de proveedores.

Cotizaciones

Sistema de cotizaciones con conversión a ventas. Estados: pendiente, aceptada, rechazada, vencida.

Clientes y proveedores

Registro completo con RUC/DNI, dirección, contacto. Búsqueda automática en SUNAT/RENIEC.

Formas de pago

Soporte para ventas al contado y crédito:
// Contado
$formaPago = new FormaPagoContado();
$formaPago->setMontoTotal($total);

// Crédito con cuotas
$formaPago = new FormaPagoCredito();
$formaPago->setCuotas([
    (new Cuota())->setMonto(500)->setFechaPago(new DateTime('2026-04-01')),
    (new Cuota())->setMonto(500)->setFechaPago(new DateTime('2026-05-01'))
]);

Reportes y exportaciones

PDFs personalizados

Generación de PDFs con mPDF en formatos A4 y ticket térmico. Plantillas personalizables por empresa.

Exportación Excel

Reportes de ventas, compras y productos con formato SUNAT (PLE). Estilos personalizados con PhpSpreadsheet.

Registro de ventas (RVTA)

Exportación TXT formato SUNAT para Libro Electrónico de Ventas (PLE-VENTAS).

Reportes de ganancias

Análisis de rentabilidad por producto, período y cliente. Exportación a Excel con gráficos.

Endpoints de exportación

Route::get('ventas/exportar-txt', [VentaExportController::class, 'exportarTxt']);
Route::get('ventas/exportar-excel', [VentaExportController::class, 'exportarExcel']);
Route::get('ventas/reporte-rvta', [VentaExportController::class, 'reporteRVTA']);
Route::get('ventas/reporte-producto', [VentaExportController::class, 'reporteVentasProducto']);
Route::get('ventas/reporte-ganancias', [VentaExportController::class, 'reporteGanancias']);

Operaciones SUNAT avanzadas

Resumen Diario

Envío de Resumen Diario de boletas (RC). Proceso asíncrono con generación de ticket y consulta posterior.

Comunicación de Baja

Anulación de documentos electrónicos mediante Comunicación de Baja. Compatible con facturas, notas y guías.

Consulta de comprobantes

Verificación de validez de comprobantes en SUNAT. Consulta por RUC, tipo, serie y número.

Modo beta y producción

Cambio fácil entre entorno de pruebas (beta) y producción. Certificados y credenciales por empresa.

Resumen Diario

Las boletas requieren un proceso adicional:
// 1. Emitir boletas durante el día
// 2. Generar Resumen Diario al cierre
Route::post('resumen-diario', [ResumenDiarioController::class, 'store']);

// 3. Consultar ticket para obtener CDR
Route::post('resumen-diario/consultar', [ResumenDiarioController::class, 'consultarTicket']);
El queue worker debe estar activo para procesar operaciones asíncronas (Resumen Diario, Comunicación de Baja). Usa composer dev para iniciarlo automáticamente.

Sistema de permisos

Roles y permisos

Sistema granular de permisos por recurso y acción: ventas.create, productos.view, reportes.export, etc.

Usuarios multi-empresa

Cada usuario puede pertenecer a múltiples empresas y cambiar entre ellas sin cerrar sesión.

Middleware de permisos

Route::get('ventas', [VentasController::class, 'index'])
    ->middleware('permission:ventas.view');

Route::post('ventas', [VentasController::class, 'store'])
    ->middleware('permission:ventas.create');
El rol Admin (rol_id=1) tiene acceso completo a todos los recursos sin verificación de permisos.

Configuración empresarial

Multi-empresa

Gestión de múltiples empresas con RUC, razón social, dirección y logo. Cada empresa con sus propios certificados SUNAT.

Series de documentos

Configuración de series para cada tipo de documento: F001 (facturas), B001 (boletas), T001 (guías), FC01/BC01 (notas).

Plantillas de impresión

Personalización de PDFs por empresa: logo, colores, footer, datos de contacto y textos legales.

Certificados digitales

Gestión de certificados .pem por empresa. Soporte para modo beta con certificado de prueba compartido.

Cambio de empresa activa

Route::post('/switch-empresa', [AuthController::class, 'switchEmpresa']);

// Todas las consultas se filtran automáticamente
$ventas = Venta::where('id_empresa', auth()->user()->empresa_activa_id)->get();

Dashboard y estadísticas

Dashboard ejecutivo

Vista general con ventas del día, mes y año. Gráficos de evolución y productos más vendidos.

Estadísticas en tiempo real

Totales de comprobantes emitidos, estado SUNAT, pendientes de envío y anulados.
Route::get('/dashboard/stats', [DashboardController::class, 'getStats']);

// Retorna:
// - ventasHoy, ventasMes, ventasAnio
// - totalComprobantes, aceptados, rechazados, pendientes
// - productosTopVentas
// - graficoVentasMensual

Integración frontend

El frontend React está organizado por features:
resources/js/components/
├── Facturacion/
│   └── Ventas/
│       ├── page.jsx          # Lista con DataTable
│       ├── columns/          # Definición de columnas
│       ├── hooks/            # useVentas, useCreateVenta
│       └── VentaDetailModal.jsx
├── GuiaRemision/
├── NotaCredito/
├── Cotizaciones/
└── ui/                       # Componentes base Radix UI
Cada módulo sigue el patrón: page.jsxcolumns/hooks/ → servicios API. Los hooks llaman a servicios en resources/js/services/ que manejan fetch con tokens.

Características técnicas adicionales

  • Autenticación Sanctum: Tokens Bearer almacenados en localStorage
  • PDF con tokens en URL: Middleware TokenFromQuery permite ?token= para descargas
  • Búsqueda SUNAT/RENIEC: Integración para validar y autocompletar datos de RUC/DNI
  • Ubigeos INEI: Base de datos completa de departamentos, provincias y distritos
  • Validaciones SUNAT: Formato de RUC, series, numeración correlativa
  • Timezone Perú: Todos los DateTime en America/Lima para correcta generación XML
  • Code formatting: Laravel Pint para backend, Prettier para frontend

Ver documentación API

Explora todos los endpoints disponibles con ejemplos de request/response.

Build docs developers (and LLMs) love