Apéndice P — Notas de crédito automáticas (E34)¶
Cuando se anula factura ya emitida (e-CF aceptado), NO se borra: se emite Nota de Crédito E34 que la referencia.
P.1. Modelo¶
class SaleInvoice(models.Model):
nota_credito_de = models.ForeignKey(
"self", on_delete=models.PROTECT, null=True, blank=True,
related_name="notas_credito",
)
motivo_anulacion = models.CharField(
max_length=20,
choices=[
("DEVOLUCION_TOTAL", "Devolución total"),
("DEVOLUCION_PARCIAL", "Devolución parcial"),
("ERROR_FACTURACION", "Error de facturación"),
("ANULACION_OPERACION", "Anulación de operación"),
("DESCUENTO_POSTERIOR", "Descuento posterior"),
("OMISION_OPERACION", "Omisión de operación"),
],
blank=True, null=True,
)
P.2. Servicio de generación¶
@transaction.atomic
def crear_nota_credito(factura_original_pk, motivo, items_a_devolver=None, usuario=None):
original = SaleInvoice.objects.select_for_update().get(pk=factura_original_pk)
if original.ecf_estado not in ("ACEPTADO", "ACEPTADO_CONDICIONAL"):
raise ValueError(f"Solo NC sobre facturas aceptadas")
if original.ecf_tipo not in ("E31", "E32", "E45", "E46"):
raise ValueError(f"Tipo {original.ecf_tipo} no admite NC directa")
nc = SaleInvoice.objects.create(
ecf_tipo="E34",
ecf_ambiente=original.ecf_ambiente,
ecf_estado="BORRADOR",
cliente=original.cliente,
nota_credito_de=original,
motivo_anulacion=motivo,
subtotal=-original.subtotal,
itbis=-original.itbis,
total=-original.total,
)
# Copiar items con cantidades negativas
for item in original.items.all():
SaleInvoiceItem.objects.create(
invoice=nc,
producto=item.producto,
cantidad=-item.cantidad,
precio_unitario=item.precio_unitario,
subtotal=-item.subtotal,
)
asignar_encf(nc, nc.ecf_ambiente)
if motivo in ("DEVOLUCION_TOTAL", "ANULACION_OPERACION"):
original.ecf_estado = "ANULADO"
original.save(update_fields=["ecf_estado"])
AccountingAuditLog.objects.create(
usuario=usuario, accion="EMITIR_NC", modelo="SaleInvoice",
objeto_id=nc.pk,
detalles={"factura_original": original.ecf_encf, "motivo": motivo},
)
return nc
P.3. Plazos DGII¶
| Plazo | Acción |
|---|---|
| 0-24h | Receptor puede rechazar ACR → emisor obligado a E34 |
| 1-30 días | E34 sin restricciones |
| 31-90 días | E34 permitido, receptor debe re-aprobar |
| >90 días | E34 requiere justificación ante DGII |
| >1 año | No permitido — facturas cierran al cierre fiscal |
Buena práctica: bloquear botón de anulación >90 días salvo rol ADMIN. Registrar siempre en AccountingAuditLog.
FIN DEL MANUAL — v1.0 · 2026-05-14