@php if (!function_exists('numberToWordsGs')) { function numberToWordsGs(float $number): string { $number = (int) round(abs($number)); if ($number === 0) return 'Cero guaraníes'; $units = [ '', 'uno', 'dos', 'tres', 'cuatro', 'cinco', 'seis', 'siete', 'ocho', 'nueve', 'diez', 'once', 'doce', 'trece', 'catorce', 'quince', 'dieciséis', 'diecisiete', 'dieciocho', 'diecinueve', ]; $tens = ['', '', 'veinte', 'treinta', 'cuarenta', 'cincuenta', 'sesenta', 'setenta', 'ochenta', 'noventa']; $hunds = ['', 'ciento', 'doscientos', 'trescientos', 'cuatrocientos', 'quinientos', 'seiscientos', 'setecientos', 'ochocientos', 'novecientos']; $conv = function (int $n) use ($units, $tens, $hunds, &$conv): string { if ($n === 0) return ''; if ($n === 100) return 'cien'; if ($n < 20) return $units[$n]; if ($n < 100) { $t = intdiv($n, 10); $u = $n % 10; return $tens[$t] . ($u > 0 ? ' y ' . $units[$u] : ''); } $h = intdiv($n, 100); $r = $n % 100; return $hunds[$h] . ($r > 0 ? ' ' . $conv($r) : ''); }; $milMillones = intdiv($number, 1_000_000_000); $millones = intdiv($number % 1_000_000_000, 1_000_000); $miles = intdiv($number % 1_000_000, 1_000); $resto = $number % 1_000; $result = ''; if ($milMillones > 0) $result .= ($milMillones === 1 ? 'un' : $conv($milMillones)) . ' mil millones '; if ($millones > 0) $result .= ($millones === 1 ? 'un millón' : $conv($millones) . ' millones') . ' '; if ($miles > 0) $result .= ($miles === 1 ? 'mil' : $conv($miles) . ' mil') . ' '; if ($resto > 0) $result .= $conv($resto); return ucfirst(trim($result)) . ($number === 1 ? ' guaraní' : ' guaraníes'); } } $tipoDocDesc = match ((int) ($factura->tipo_doc ?? 1)) { 1 => 'FACTURA ELECTRÓNICA', 4 => 'AUTOFACTURA ELECTRÓNICA', 5 => 'NOTA DE CRÉDITO ELECTRÓNICA', 6 => 'NOTA DE DÉBITO ELECTRÓNICA', 7 => 'NOTA DE REMISIÓN ELECTRÓNICA', default => 'DOCUMENTO ELECTRÓNICO', }; $nroDoc = str_pad($factura->establecimiento ?? '001', 3, '0', STR_PAD_LEFT) . '-' . str_pad($factura->punto_expedicion ?? '001', 3, '0', STR_PAD_LEFT) . '-' . str_pad($factura->numero_doc ?? '0000001', 7, '0', STR_PAD_LEFT); $items = $factura->items ?? collect(); $emptyRows = max(0, 15 - $items->count()); $cliente = $factura->cliente; $tipoTx = ($cliente && $cliente->ruc) ? 'B2B - Negocio a Negocio' : 'B2C - Consumidor Final'; $moneda = $factura->moneda ?? 'PYG'; $condicionDesc = match ((int) ($factura->condicion_operacion ?? 1)) { 1 => 'Contado', 2 => 'Crédito', default => '-', }; $cdcGrupos = $factura->cdc ? implode(' ', str_split($factura->cdc, 4)) : ''; $totalExento = (float) ($factura->total_exento ?? 0); $totalGrav5 = (float) ($factura->total_gravado_5 ?? 0); $totalGrav10 = (float) ($factura->total_gravado_10 ?? 0); $iva5 = (float) ($factura->iva_5 ?? 0); $iva10 = (float) ($factura->iva_10 ?? 0); $totalIva = (float) ($factura->total_iva ?? 0); $total = (float) ($factura->total ?? 0); @endphp {{-- ══════════════════════════════════════════════════════════ --}} {{-- BLOQUE 1 — HEADER --}} {{-- Borde exterior, sin bordes internos horizontales. --}} {{-- Solo border-right entre celdas y border-top interno --}} {{-- dentro de la celda derecha. --}} {{-- ══════════════════════════════════════════════════════════ --}} {{-- Celda izquierda 70%: logo y texto lado a lado --}} {{-- Celda derecha 30%: parte superior (RUC/timbrado) + border-top + parte inferior (tipo doc) --}}
{{-- Logo --}} {{-- Datos del emisor --}}
@if(!empty($logoPath) && file_exists($logoPath)) Logo @endif
{{ $emisor?->razon_social ?? '' }}
@if($emisor?->actividad_economica_desc)
{{ $emisor->actividad_economica_desc }}
@endif @if($emisor?->direccion)
{{ $emisor->direccion }}
@endif @if($emisor?->ciudad_desc)
{{ $emisor->ciudad_desc }}
@endif @if($emisor?->telefono)
Tel.: {{ $emisor->telefono }}
@endif @if($emisor?->email)
{{ $emisor->email }}
@endif
{{-- Parte superior: RUC, Timbrado Nº, Fecha de Vigencia --}}
RUC: {{ $emisor?->ruc ?? '' }}
Timbrado Nº: {{ $factura->timbrado ?? $emisor?->timbrado ?? '' }}
Fecha de Vigencia: {{ $emisor?->timbrado_fecha_inicio?->format('d/m/Y') ?? '' }} al {{ $emisor?->timbrado_fecha_fin?->format('d/m/Y') ?? '' }}
{{-- border-top separa las dos partes --}}
{{ $tipoDocDesc }}
Nº {{ $nroDoc }}
{{-- ══════════════════════════════════════════════════════════ --}} {{-- BLOQUE 2 — RECEPTOR --}} {{-- Borde exterior, sin bordes internos horizontales. --}} {{-- Solo border-right entre las dos celdas. --}} {{-- ══════════════════════════════════════════════════════════ --}} {{-- Celda izquierda 50%: datos de la operación --}} {{-- Celda derecha 50%: datos del receptor --}}
Fecha y Hora de Emisión: {{ $factura->fecha_emision?->format('d/m/Y H:i') ?? '-' }}
Condición de Venta: {{ $condicionDesc }}
Moneda: {{ $moneda }}
Tipo de Transacción: {{ $tipoTx }}
RUC / CI: {{ $cliente?->ruc ?? $cliente?->ci ?? $cliente?->doc_numero ?? '-' }}
Razón Social: {{ $cliente?->razon_social ?? '-' }}
Dirección: {{ $cliente?->direccion ?? '-' }}@if($cliente?->ciudad_desc), {{ $cliente->ciudad_desc }}@endif
@if($cliente?->telefono)
Teléfono: {{ $cliente->telefono }}
@endif @if($cliente?->id)
Cód. Cliente: {{ str_pad($cliente->id, 6, '0', STR_PAD_LEFT) }}
@endif
{{-- ══════════════════════════════════════════════════════════ --}} {{-- BLOQUE 3 — TABLA DE ÍTEMS --}} {{-- Borde exterior. Header negro/blanco con border-bottom. --}} {{-- Filas de ítems: SIN bordes horizontales entre filas, --}} {{-- solo border-right entre columnas. --}} {{-- Sección subtotales: fondo #e0e0e0, border-top:2px. --}} {{-- EN LETRAS y LIQUIDACIÓN IVA: #e0e0e0, border-top:1px. --}} {{-- ══════════════════════════════════════════════════════════ --}} {{-- Filas de ítems: solo border-right entre columnas, sin bordes horizontales --}} @foreach($items as $item) @php $tasa = (float) ($item->tasa_iva ?? 0); $afec = (int) ($item->afectacion_iva ?? 0); $itemTotal = (float) ($item->total_item ?? 0); $colExenta = ($tasa == 0 || $afec == 3) ? $itemTotal : 0; $col5 = ($tasa == 5) ? $itemTotal : 0; $col10 = ($tasa == 10) ? $itemTotal : 0; $cantStr = rtrim(rtrim(number_format((float)$item->cantidad, 2, ',', '.'), '0'), ','); @endphp @endforeach {{-- Filas vacías hasta mínimo 15: misma estructura de bordes --}} @for($i = 0; $i < $emptyRows; $i++) @endfor {{-- SUBTOTALES: fondo #e0e0e0, border-top:2px separa de ítems --}} {{-- SUMA TOTAL: sin borde top (continúa gris sin separador) --}} {{-- EN LETRAS: border-top:1px separa de los subtotales --}} {{-- LIQUIDACIÓN IVA: border-top:1px separa de EN LETRAS --}}
Código Descripción Unidad
Medida
Precio
Unitario
Cantidad Descuento Exentas 5% 10%
{{ $item->codigo ?? '' }} {{ $item->descripcion }} {{ $item->unidad_medida_desc ?? $item->unidad_medida ?? 'UND' }} {{ number_format((float)$item->precio_unitario, 0, ',', '.') }} {{ $cantStr }} {{ (float)($item->descuento??0)>0 ? number_format((float)$item->descuento,0,',','.') : '' }} {{ $colExenta>0 ? number_format($colExenta,0,',','.') : '' }} {{ $col5>0 ? number_format($col5,0,',','.') : '' }} {{ $col10>0 ? number_format($col10,0,',','.') : '' }}
                 
SUBTOTALES: {{ $totalExento>0 ? number_format($totalExento,0,',','.') : '' }} {{ $totalGrav5>0 ? number_format($totalGrav5,0,',','.') : '' }} {{ $totalGrav10>0 ? number_format($totalGrav10,0,',','.') : '' }}
SUMA TOTAL:     {{ number_format($total,0,',','.') }}
DESCUENTO / ANTICIPO GLOBAL:     0
TOTAL DE LA OPERACIÓN:     {{ number_format($total,0,',','.') }}
EN LETRAS: {{ numberToWordsGs($total) }}
LIQUIDACIÓN IVA:     (5%) {{ number_format($iva5,0,',','.') }}     (10%): {{ number_format($iva10,0,',','.') }}     Total IVA: {{ number_format($totalIva,0,',','.') }}
{{-- ══════════════════════════════════════════════════════════ --}} {{-- BLOQUE 4 — FOOTER --}} {{-- Borde exterior. Celda izquierda QR (110px) con --}} {{-- border-right. Celda derecha CDC. Fila inferior con --}} {{-- border-top y texto 72 horas centrado. --}} {{-- ══════════════════════════════════════════════════════════ --}} {{-- Celda izquierda: QR 90x90 --}} {{-- Celda derecha: texto de validez + CDC + disclaimer --}} {{-- Fila inferior: texto 72 horas, border-top dentro del bloque footer --}}
@if(!empty($qrBase64)) QR @endif
Consulte la validez de esta Factura Electrónica con el número de CDC impreso abajo
https://ekuatia.set.gov.py/consultas
@if($cdcGrupos)
{{ $cdcGrupos }}
@endif
ESTE DOCUMENTO ES UNA REPRESENTACIÓN GRÁFICA DE UN DOCUMENTO ELECTRÓNICO (XML)
Si su documento electrónico presenta algún error puede solicitar la modificación dentro de las 72 horas siguientes a la emisión de este comprobante.
{{-- Número de página: fuera del borde --}}
1