Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/mdiago/VeriFactu/llms.txt

Use this file to discover all available pages before exploring further.

InvoiceFix resubmits an invoice that was previously rejected by the AEAT. It extends InvoiceEntry but sets the Subsanacion = "S" flag on the RegistroAlta, telling the AEAT that this is a correction of a previously failed record rather than a brand-new invoice. All invoice data must match the original rejected submission exactly.

Namespace

VeriFactu.Business

Herencia

InvoiceFix → InvoiceEntry → InvoiceAction → InvoiceActionPost → InvoiceActionMessage → InvoiceActionData

Constructor

InvoiceFix(Invoice invoice)

Creates a new fix/subsanation entry for the given invoice.
invoice
Invoice
required
A fully populated Invoice with the same data as the original rejected submission. All fields — InvoiceID, InvoiceDate, SellerID, SellerName, TaxItems, etc. — must match the original record. The constructor validates business rules and throws InvalidOperationException if any are violated.
InvoiceFix-specific validation (from GetBusErrors()):
  • A previously submitted file for this seller + year + invoice number must already exist on disk. Unlike InvoiceEntry, which rejects duplicates, InvoiceFix requires the original entry to be present.
  • All other InvoiceEntry rules apply (SellerName required, TaxItems ≤ 12, etc.).

Comportamiento de subsanación

When SetRegistro() is called internally, InvoiceFix performs the normal RegistroAlta build (via the base class) and then sets:
registroAlta.Subsanacion = "S";
This single flag signals to the AEAT that the submission is a subsanación (correction of a previously rejected record). The AEAT links it to the original rejected record using the invoice ID and date.

Propiedades adicionales

OriginalInvoiceFilePath
string
Full path to the original (rejected) invoice XML file in the posted invoices directory: {InvoicePostedPath}{EncodedInvoiceID}.xml.
InvoiceFilePath
string
Path where the new fix XML will be stored. Includes a .SUB. infix and a timestamp to avoid overwriting the original: {InvoicePostedPath}{EncodedInvoiceID}.SUB.yyyy.MM.dd.HH.mm.ss.ffff.xml.
InvoiceEntryFilePath
string
Path to the outbox chain record for this fix: {InvoiceEntryPath}{InvoiceEntryID}.SUB.yyyy.MM.dd.HH.mm.ss.ffff.xml.
ResponseFilePath
string
Path to the AEAT response XML for this fix: {ResponsesPath}{InvoiceEntryID}.SUB.yyyy.MM.dd.HH.mm.ss.ffff.xml.
All response properties (Status, CSV, ErrorCode, ErrorDescription, Posted, IsSent) are inherited from InvoiceEntry.

Ejemplo

using VeriFactu.Business;
using VeriFactu.Xml.Factu;
using VeriFactu.Xml.Factu.Alta;

// Rebuild the invoice with the same data as the rejected submission
var invoice = new Invoice("FAC-2024-001", new DateTime(2024, 11, 15), "B72877814")
{
    InvoiceType = TipoFactura.F1,
    SellerName  = "MI EMPRESA SL",
    BuyerID     = "B44531218",
    BuyerName   = "CLIENTE SL",
    Text        = "SERVICIOS PROFESIONALES",
    TaxItems    = new List<TaxItem>
    {
        new TaxItem
        {
            TaxScheme = ClaveRegimen.RegimenGeneral,
            TaxType   = CalificacionOperacion.S1,
            TaxRate   = 21,
            TaxBase   = 1000,
            TaxAmount = 210
        }
    }
};

var fix = new InvoiceFix(invoice);
fix.Save();

if (fix.Status == "Correcto")
    Console.WriteLine($"Subsanación accepted — CSV: {fix.CSV}");
else
    Console.WriteLine($"Error — {fix.ErrorCode}: {fix.ErrorDescription}");
Use InvoiceFix only for records that were rejected by the AEAT (i.e. the original submission returned a non-Correcto status). For invoices that need to be corrected after successful acceptance, use a rectification invoice (TipoFactura.R1R5) via a standard InvoiceEntry.

Build docs developers (and LLMs) love