buildVoucherDocument()
toma el comprobante autorizado, los mismos ítems con los que lo emitiste y los
datos del emisor, y devuelve todo lo que el comprobante impreso tiene que
mostrar. @facturas/pdf lo dibuja en A4 con la ubicación que fija la norma.
Si preferís tu propia plantilla, el modelo ya viene derivado y controlado, sin
I/O, para que no tenga que saber de clases, leyendas ni IVA.
Del comprobante autorizado al modelo
Este bloque es examples/comprobante-impreso.ts:authorized, directo o recuperado, y para las
notas de crédito y débito. Guardá los ítems junto a la venta: si se reimprime
más tarde, el modelo sale igual.
Qué te pide
Si falta un dato obligatorio, tira
ArcaInputError con
ARCA_INPUT_MISSING_FIELD y el field que falta.
Qué devuelve
- La letra, el código de tres dígitos, el título y el número con punto de
venta, como
00003-00000041. EnletterLegend, la leyenda que va junto a la letra A:OPERACIÓN SUJETA A RETENCIÓNpara los tipos 51 a 53 oPAGO EN CBU INFORMADA. - El emisor y el receptor con su leyenda de condición frente al IVA, por
ejemplo
IVA RESPONSABLE INSCRIPTOoA CONSUMIDOR FINAL, y el documento del receptor cuando está identificado. - Las líneas. En la clase A van sin IVA y con su alícuota, en la clase B con IVA. Suman exactamente lo que autorizó ARCA.
- Los totales: el descuento global, el subtotal, el exento, el no gravado, el
IVA por alícuota en la clase A, los tributos y el total. Si un ajuste de IVA de la cabecera no entra
en ninguna línea, aparece en
totals.adjustmentpara que lo muestres. - En la clase B, el bloque del Régimen de Transparencia Fiscal al Consumidor con el IVA contenido y los otros impuestos nacionales indirectos.
- El CAE con su vencimiento, el QR y las leyendas que correspondan: la de la Ley 27.618 en una factura A a un monotributista y, en la clase A, los códigos de las observaciones de ARCA.
YYYY-MM-DD. El formato de
moneda y el diseño quedan en tu plantilla.
PRINTED_VOUCHER_TEXT trae los textos fijos tal como los escriben las normas,
por ejemplo C.A.E. N° y el título de transparencia fiscal.
Dónde va cada dato
La RG 1415, Anexo II, Apartado B ubica los datos. El SDK sigue esa ubicación en el comprobante impreso aunque la RG 4291 dé por cumplidas las medidas de un comprobante electrónico:- Arriba a la izquierda: nombre de fantasía, razón social, domicilio y condición frente al IVA.
- Arriba en el centro y destacada: la letra, y debajo
Código Nºcon el código. Si hayletterLegend, va junto a la letra. - Arriba a la derecha: número, fecha, CUIT, ingresos brutos e inicio de actividades. Estos datos y los de la izquierda van dentro de un recuadro de al menos 7 × 3 cm.
- Después: el receptor, las condiciones de venta y las líneas, con el IVA por alícuota a continuación en la clase A.
- Abajo a la izquierda: el bloque de transparencia fiscal.
- Abajo a la derecha: el CAE y
Fecha Vto.:con su vencimiento, en letra de 12 puntos o más (PRINTED_CAE_DUE_DATE_MIN_FONT_SIZE_PT).
Dibujarlo con @facturas/pdf
@facturas/pdf es el paquete que dibuja el modelo. Sale siempre con la misma
versión que facturas, así que el modelo y el dibujo nunca quedan desfasados.
theme: tipografía y colores. Los tamaños no, porque la norma fija algunos.logo: va arriba a la izquierda, sobre la razón social.notes: garantía, cambios, CBU, condiciones o lo que quieras decir. Va después del receptor y antes de las líneas, fuera de las zonas fiscales, y puede ser tan largo como haga falta: sigue en la hoja siguiente.
<VoucherAside> a su izquierda, queda con el CAE. Las
líneas y las notas, en cambio, siguen en la hoja siguiente cuando no entran,
aunque una sola descripción sea más larga que una hoja.
Los bloques fiscales no se exportan: <Voucher> los ubica solo. Cualquier
otro hijo de <Voucher>, o un espacio repetido, hace que renderVoucherPdf()
tire un error que nombra el problema antes de dibujar nada. Usá
renderVoucherPdf() también con JSX: si llamás directo a renderToBuffer de
react-pdf, ese error llega como un TypeError sin el mensaje.
Descuento global
En las clases A, B y C, ARCA no tiene un campo para un descuento sobre todo el comprobante: lo autoriza ya restado de los ítems. Para imprimir las líneas antes del descuento y un renglón “Descuento global”, pasá los ítems sin descontar y el descuento como lo repartiste al emitir:globalDiscount es un número y se compara con el neto. El exento y el no
gravado no llevan descuento.
El PDF imprime un solo renglón “Descuento global” con la suma, antes del
importe neto gravado en la clase A y antes del subtotal en las clases B y C. Las
líneas conservan su importe y su bonificación propia, si la tienen.
Qué rechaza
buildVoucherDocument() prefiere fallar a imprimir algo incorrecto:
- Ítems que no suman lo autorizado:
ARCA_INPUT_AMOUNT_MISMATCH. ConglobalDiscount, elfieldnombra la alícuota que no cierra, comoglobalDiscount[5]. - Un
globalDiscountcon la forma de otra clase, una clave que no es un id de alícuota o que ningún ítem lleva, o un importe negativo o con decimales:ARCA_INPUT_INVALID_VALUE. - Un receptor sin documento que no sea consumidor final:
ARCA_INPUT_MISSING_FIELD. - Una cantidad por precio unitario que no da el importe de la línea:
ARCA_INPUT_AMOUNT_MISMATCH. - Un emisor que no puede emitir esa clase o un CUIT distinto del comprobante:
ARCA_INPUT_INVALID_VALUE. - Comprobantes FCE, que todavía no arma, comprobantes M de los tipos 51 a 53
anteriores al 1 de diciembre de 2025 y un comprobante sin QR:
ARCA_INPUT_INVALID_VALUE.