Ir al contenido

Nota de Crédito

La Nota de Crédito Electrónica (tipo 07) anula o reduce el valor de una factura o boleta previamente emitida. Se emite por devoluciones, descuentos o errores en el comprobante original.

CampoTipoDescripciónValidación
seriestringSerie de la notaPatrón ^[BCbc][A-Za-z0-9]{2,3}$. Ej: FC01 para factura, BC01 para boleta.
numerointegerCorrelativoMayor a 0.
comprobanteAfectadoSerieNumerostringSerie-número del comprobante afectadoEj: F001-123.
sustentoDescripcionstringMotivo de la nota de créditoTexto libre.
proveedorProveedorDatos del emisorruc de 11 dígitos y razonSocial obligatorios.
clienteClienteDatos del adquirentenombre, numeroDocumentoIdentidad y tipoDocumentoIdentidad (Catálogo N.° 06).
detallesDocumentoVentaDetalle[]Líneas de ajusteAl menos una línea.
CampoTipoDefaultDescripción
monedastringPENMoneda del comprobante (Catálogo N.° 02).
fechaEmisiondatehoyFecha de emisión (YYYY-MM-DD).
igvTotalDecimalautoSuma de IGV de las líneas.
valorVentaTotalDecimalautoSuma de valores de venta.
importeTotalDecimalautovalorVentaTotal + igvTotal.
CampoTipoRequeridoDefaultDescripción
descripcionstringDescripción del bien o servicio.
cantidadDecimalCantidad.
precioDecimalValor unitario (sin IGV). Use negativo para reducciones.
unidadMedidastringNoNIUUnidad de medida (Catálogo N.° 03).
tipoAfectacionIGVstringNo10Tipo de afectación del IGV (Catálogo N.° 07).
igvDecimalNoautoIGV de la línea.
valorVentaDecimalNoautocantidad × precio.
precioVentaDecimalNoautovalorVenta + igv.
Código / ReglaDescripción
2074UBLVersionID debe ser 2.1.
2072CustomizationID debe ser 2.0.
1001El ID del comprobante debe tener formato serie-número.
2070DocumentCurrencyCode es obligatorio.
1007schemeID del emisor debe ser 6 (RUC).
1008RUC del emisor debe tener 11 dígitos.
1037RegistrationName del emisor es obligatorio.
2015schemeID del cliente es obligatorio.
2062PayableAmount debe ser mayor a 0.
3305TaxInclusiveAmount es obligatorio.
3294El TaxTotal debe cuadrar con la sumatoria de líneas.
3278El LineExtensionAmount debe cuadrar con la sumatoria de líneas.
SerieDebe iniciar con B/C o F/E según el tipo de comprobante afectado.
TotalEl importe total de la nota no puede exceder el importe del comprobante original.
from openubl.models import (
CreditNote, Proveedor, Cliente, DocumentoVentaDetalle,
)
from openubl.renderer import render_credit_note
from openubl.validator import SunatValidator
from decimal import Decimal
credit_note = CreditNote(
serie="FC01",
numero=1,
comprobanteAfectadoSerieNumero="F001-45",
sustentoDescripcion="Descuento por pronto pago",
proveedor=Proveedor(
ruc="20100100100",
razonSocial="Mi Empresa S.A.C.",
),
cliente=Cliente(
nombre="Juan Pérez",
numeroDocumentoIdentidad="46779327",
tipoDocumentoIdentidad="1",
),
detalles=[
DocumentoVentaDetalle(
descripcion="Descuento pronto pago - Laptop Dell XPS 13",
cantidad=Decimal("1"),
precio=Decimal("-250.00"),
),
],
)
xml = render_credit_note(credit_note)
errors = SunatValidator().validate_credit_note(xml)
assert errors == []
print(xml)

ContentEnricher calcula fechaEmision, valorVenta, igv, precioVenta, valorVentaTotal, igvTotal e importeTotal.

from openubl.models import (
CreditNote, Proveedor, Cliente, DocumentoVentaDetalle,
)
from openubl.enricher import ContentEnricher
from openubl.renderer import render_credit_note
from openubl.validator import SunatValidator
from decimal import Decimal
credit_note = CreditNote(
serie="FC01",
numero=1,
comprobanteAfectadoSerieNumero="F001-45",
sustentoDescripcion="Descuento por pronto pago",
proveedor=Proveedor(
ruc="20100100100",
razonSocial="Mi Empresa S.A.C.",
),
cliente=Cliente(
nombre="Juan Pérez",
numeroDocumentoIdentidad="46779327",
tipoDocumentoIdentidad="1",
),
detalles=[
DocumentoVentaDetalle(
descripcion="Descuento pronto pago - Laptop Dell XPS 13",
cantidad=Decimal("1"),
precio=Decimal("-250.00"),
# No se envían igv, valorVenta ni precioVenta
),
],
)
ContentEnricher().enrich(credit_note)
xml = render_credit_note(credit_note)
errors = SunatValidator().validate_credit_note(xml)
assert errors == [], errors
print(xml)
from openubl.models import (
CreditNote, Proveedor, Cliente, DocumentoVentaDetalle,
)
from openubl.renderer import render_credit_note
from decimal import Decimal
credit_note = CreditNote(
serie="FC01",
numero=1,
comprobanteAfectadoSerieNumero="F001-45",
sustentoDescripcion="Descuento por pronto pago",
proveedor=Proveedor(
ruc="20100100100",
razonSocial="Mi Empresa S.A.C.",
),
cliente=Cliente(
nombre="Juan Pérez",
numeroDocumentoIdentidad="46779327",
tipoDocumentoIdentidad="1",
),
detalles=[
DocumentoVentaDetalle(
descripcion="Descuento pronto pago",
cantidad=Decimal("1"),
precio=Decimal("-250.00"),
),
],
)
xml = render_credit_note(credit_note)
print(xml)

Si la nota de crédito anula el importe total de la factura original, el precio de la línea debe ser igual al importe total del comprobante afectado con signo negativo.

from openubl.models import (
CreditNote, Proveedor, Cliente, DocumentoVentaDetalle,
)
from openubl.enricher import ContentEnricher
from openubl.renderer import render_credit_note
from openubl.validator import SunatValidator
from decimal import Decimal
credit_note = CreditNote(
serie="FC01",
numero=1,
comprobanteAfectadoSerieNumero="F001-1",
sustentoDescripcion="Anulación de venta",
proveedor=Proveedor(ruc="20100100100", razonSocial="Mi Empresa S.A.C."),
cliente=Cliente(
nombre="Cliente Ejemplo S.A.C.",
numeroDocumentoIdentidad="98765432101",
tipoDocumentoIdentidad="6",
),
detalles=[
DocumentoVentaDetalle(
descripcion="Anulación total - Factura F001-1",
cantidad=Decimal("1"),
precio=Decimal("-300.00"),
),
],
)
ContentEnricher().enrich(credit_note)
xml = render_credit_note(credit_note)
errors = SunatValidator().validate_credit_note(xml)
assert errors == [], errors
print(xml)
{
"xml": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>..."
}

Si validate=true y el XML no cumple las reglas SUNAT, la API devuelve un error 422 con la lista de errores.