Con este código podrás generar una factura en XML desde tu programa de Access y la factura ya firmada en formato XSIG de eFactura.
Copia y pega el código en un botón de tu programa de facturación.
Tendrás que cambiar tus datos de empresa y el nombre de los campos que usas en tu programa.
Serán necesarios 6 campos nuevos en tu ficha de cliente y en ellos se almacenan la información que da la institución a la que facturas (Órgano Gestor, Unidad Tramitadora y Oficina Contable). Estos campos son: GestorCode, GestorNombre, UnidadCode, UnidadNombre, OficinaCode y OficinaNombre. Todos ellos de texto.
Se abrirá automáticamente autofirma de forma oculta y te pesentará los certificados que tengas disponibles para firmar digitalmente la factura.
Se generará el fichero firmado que podrás subirlo directamente a FACE.
Tener en cuenta una cosa, las líneas de detalle de la factura no pueden contener solo texto en el concepto, si hay una línea de detalle con sólo texto hay que rellenar los campos de cantidad, precio unidad y líneatotal con ceros o unos (según el campo) porque FACE no admite líneas de detalle con datos parciales o campos sin datos.
'®Tantor Systems Creative Commons CC BY
Dim dbs As Database, tdf2 As Recordset, fld As Field, tdf3 As Recordset
Dim stDocName As String
Dim xxx, nrolineas As Integer
Dim cuantoiva As Double
Dim lineacomando as string
Dim retval
Set dbs = CurrentDb
' abro la tabla donde tengo al cliente
stDocName = "SELECT * FROM Agenda WHERE Agenda.Id_Agenda=" + Str(Me.Id_Clientes) + "; "
Set tdf2 = dbs.OpenRecordset(stDocName)
tdf2.MoveFirst
'Creo el fichero XML de destino cuyo nombre será Emit-nºfactura.xml
'Open "C:\Directorio\Borrador-" & Trim(Str(Me.NroFact)) & ".xml" For Output As #1
Open "C:\Directorio\Emit-" & Trim(Str(Me.NroFact)) & ".xml" For Output As #1
Print #1, "<?xml version=""1.0"" encoding=""UTF-8""?>"
Print #1, "<fe:Facturae xmlns:ds=""http://www.w3.org/2000/09/xmldsig#"" xmlns:fe=""http://www.facturae.es/Facturae/2014/v3.2.1/Facturae"">";
Print #1, "<FileHeader>";
Print #1, "<SchemaVersion>3.2.1</SchemaVersion>";
Print #1, "<Modality>I</Modality>";
Print #1, "<InvoiceIssuerType>EM</InvoiceIssuerType>";
Print #1, "<Batch>";
Print #1, "<BatchIdentifier>" & Trim(tdf2!CIF) & Trim(Str(Me.NroFact)) & "Emit-</BatchIdentifier>"; ' grabo nro de factura
Print #1, "<InvoicesCount>1</InvoicesCount>";
Print #1, "<TotalInvoicesAmount><TotalAmount>" & Trim(Str(Me.ImporteFactura)) & "</TotalAmount></TotalInvoicesAmount>"; ' grabo importe factura
Print #1, "<TotalOutstandingAmount><TotalAmount>" & Trim(Str(Me.ImporteFactura)) & "</TotalAmount></TotalOutstandingAmount>"; ' grabo importe factura
Print #1, "<TotalExecutableAmount><TotalAmount>" & Trim(Str(Me.ImporteFactura)) & "</TotalAmount></TotalExecutableAmount>"; ' grabo importe factura
Print #1, "<InvoiceCurrencyCode>EUR</InvoiceCurrencyCode>";
Print #1, "</Batch>";
Print #1, "</FileHeader>";
Print #1, "<Parties>";
' Vendedor
Print #1, "<SellerParty>";
Print #1, "<TaxIdentification><PersonTypeCode>J</PersonTypeCode><ResidenceTypeCode>U</ResidenceTypeCode><TaxIdentificationNumber>MI NIF/CIF</TaxIdentificationNumber></TaxIdentification>";
Print #1, "<LegalEntity>";
Print #1, "<CorporateName>NOMBRE DE MI EMPRESA</CorporateName>";
' CAMBIA LOS DATOS POR LOS TUYOS
Print #1, "<RegistrationData><RegisterOfCompaniesLocation>Santander</RegisterOfCompaniesLocation><Sheet>5555</Sheet><Folio>666</Folio><Volume>777</Volume></RegistrationData>";
Print #1, "<AddressInSpain><Address>FERNANDEZ DE ISLA 10, BAJO</Address><PostCode>39008</PostCode><Town>SANTANDER</Town><Province>CANTABRIA</Province><CountryCode>ESP</CountryCode></AddressInSpain>";
Print #1, "<ContactDetails><Telephone>942123456</Telephone><TeleFax>942123456</TeleFax><WebAddress>www.miweb.com</WebAddress><ElectronicMail>micorreo@miempresa.com</ElectronicMail></ContactDetails>";
Print #1, "</LegalEntity>";
Print #1, "</SellerParty>";
' Comprador
Print #1, "<BuyerParty>";
' grabo los datos del cliente
Print #1, "<TaxIdentification><PersonTypeCode>J</PersonTypeCode><ResidenceTypeCode>U</ResidenceTypeCode><TaxIdentificationNumber>" & tdf2!CIF & "</TaxIdentificationNumber></TaxIdentification>";
Print #1, "<AdministrativeCentres>";
' Los campos GestorCode, GestorNombre, UnidadCode, UnidadNombre, OficinaCode y OficinaNombre los tienes que tener en la tabla del cliente y estos datos
' los consigues de la página web o llamando a la institución a la que facturas
'Receptor / Organo Gestor
Print #1, "<AdministrativeCentre>";
Print #1, "<CentreCode>" & tdf2!GestorCode & "</CentreCode><RoleTypeCode>02</RoleTypeCode><Name>" & tdf2!GestorNombre & "</Name>";
Print #1, "<AddressInSpain><Address>" & tdf2!DIRECCION & "</Address><PostCode>" & tdf2!cp & "</PostCode><Town>" & tdf2!POBLACION & "</Town><Province>" & tdf2!PROVINCIA & "</Province><CountryCode>ESP</CountryCode></AddressInSpain>";
Print #1, "</AdministrativeCentre>";
'Fiscal / Unidad tramitadora
Print #1, "<AdministrativeCentre>";
Print #1, "<CentreCode>" & tdf2!UnidadCode & "</CentreCode><RoleTypeCode>03</RoleTypeCode><Name>" & tdf2!UnidadNombre & "</Name>";
Print #1, "<AddressInSpain><Address>" & tdf2!DIRECCION & "</Address><PostCode>" & tdf2!cp & "</PostCode><Town>" & tdf2!POBLACION & "</Town><Province>" & tdf2!PROVINCIA & "</Province><CountryCode>ESP</CountryCode></AddressInSpain>";
Print #1, "</AdministrativeCentre>";
'Pagador / Oficina contable
Print #1, "<AdministrativeCentre>";
Print #1, "<CentreCode>" & tdf2!OficinaCode & "</CentreCode><RoleTypeCode>01</RoleTypeCode><Name>" & tdf2!OficinaNombre & "</Name>";
Print #1, "<AddressInSpain><Address>" & tdf2!DIRECCION & "</Address><PostCode>" & tdf2!cp & "</PostCode><Town>" & tdf2!POBLACION & "</Town><Province>" & tdf2!PROVINCIA & "</Province><CountryCode>ESP</CountryCode></AddressInSpain>";
Print #1, "</AdministrativeCentre>";
Print #1, "</AdministrativeCentres>";
Print #1, "<LegalEntity>";
Print #1, "<CorporateName>" & tdf2!NOMBRE & "</CorporateName>";
Print #1, "<TradeName>" & tdf2!RAZONSOCIA & "</TradeName>";
Print #1, "<AddressInSpain>";
Print #1, "<Address>" & tdf2!DIRECCION & "</Address><PostCode>" & tdf2!cp & "</PostCode><Town>" & tdf2!POBLACION & "</Town><Province>" & tdf2!PROVINCIA & "</Province><CountryCode>ESP</CountryCode>";
Print #1, "</AddressInSpain>";
Print #1, "</LegalEntity>";
Print #1, "</BuyerParty>";
Print #1, "</Parties>";
' Grabo los datos de la Factura
Print #1, "<Invoices>";
Print #1, "<Invoice>";
Print #1, "<InvoiceHeader>";
Print #1, "<InvoiceNumber>" & Trim(Str(Me.NroFact)) & "</InvoiceNumber>";
Print #1, "<InvoiceSeriesCode>Borrador-</InvoiceSeriesCode>";
Print #1, "<InvoiceDocumentType>FC</InvoiceDocumentType>";
Print #1, "<InvoiceClass>OO</InvoiceClass>";
Print #1, "</InvoiceHeader>";
Print #1, "<InvoiceIssueData>";
Print #1, "<IssueDate>" & Format(Me.FechaFactura, "yyyy-mm-dd") & "</IssueDate>";
Print #1, "<PlaceOfIssue><PostCode>39008</PostCode><PlaceOfIssueDescription>Asiento nro 30</PlaceOfIssueDescription></PlaceOfIssue>";
Print #1, "<InvoiceCurrencyCode>EUR</InvoiceCurrencyCode><TaxCurrencyCode>EUR</TaxCurrencyCode><LanguageName>es</LanguageName>";
Print #1, "</InvoiceIssueData>";
Print #1, "<TaxesOutputs>";
Print #1, "<Tax>";
Print #1, "<TaxTypeCode>01</TaxTypeCode><TaxRate>" & Trim(Str(Me.Iva)) & "</TaxRate>";
Print #1, "<TaxableBase><TotalAmount>" & Trim(Str(Me.SubtotalFactura)) & "</TotalAmount></TaxableBase>";
Print #1, "<TaxAmount><TotalAmount>" & Trim(Str(Me.ImporteIVA)) & "</TotalAmount></TaxAmount>";
Print #1, "</Tax>";
Print #1, "</TaxesOutputs>";
Print #1, "<InvoiceTotals>";
Print #1, "<TotalGrossAmount>" & Trim(Str(Me.SubtotalFactura)) & "</TotalGrossAmount>";
Print #1, "<TotalGeneralDiscounts>0.0</TotalGeneralDiscounts>";
Print #1, "<TotalGeneralSurcharges>0.0</TotalGeneralSurcharges>";
Print #1, "<TotalGrossAmountBeforeTaxes>" & Trim(Str(Me.SubtotalFactura)) & "</TotalGrossAmountBeforeTaxes>";
Print #1, "<TotalTaxOutputs>" & Trim(Str(Me.ImporteIVA)) & "</TotalTaxOutputs>";
Print #1, "<TotalTaxesWithheld>0.0</TotalTaxesWithheld>";
Print #1, "<InvoiceTotal>" & Trim(Str(Me.ImporteFactura)) & "</InvoiceTotal>";
Print #1, "<TotalOutstandingAmount>" & Trim(Str(Me.ImporteFactura)) & "</TotalOutstandingAmount>";
Print #1, "<TotalExecutableAmount>" & Trim(Str(Me.ImporteFactura)) & "</TotalExecutableAmount>";
Print #1, "</InvoiceTotals>";
' Líneas de detalle
stDocName = "SELECT * FROM FacturasLineas WHERE FacturasLineas.IdFactura=" + Str(Me.IdFactura) + "; "
Set tdf3 = dbs.OpenRecordset(stDocName)
Print #1, "<Items>";
If tdf3.EOF = False Then
tdf3.MoveFirst
Do
Print #1, "<InvoiceLine>";
Print #1, "<ItemDescription>" & tdf3!DENOMINACION & "</ItemDescription>";
If IsNull(tdf3!Cantidad) Then
Print #1, "<Quantity>0</Quantity>";
Else
Print #1, "<Quantity>" & Trim(Str(tdf3!Cantidad)) & "</Quantity>";
End If
Print #1, "<UnitOfMeasure>01</UnitOfMeasure>";
If IsNull(tdf3!PrecioUnidad) Then
Print #1, "<UnitPriceWithoutTax>0</UnitPriceWithoutTax>";
Else
Print #1, "<UnitPriceWithoutTax>" & Trim(Str((Int((tdf3!PrecioUnidad * 100) + 0.5)) / 100)) & "</UnitPriceWithoutTax>";
End If
If IsNull(tdf3!LíneaTotal) Then
Print #1, "<TotalCost>0</TotalCost>";
Print #1, "<GrossAmount>0</GrossAmount>";
Else
Print #1, "<TotalCost>" & Trim(Str((Int((tdf3!LíneaTotal * 100) + 0.5)) / 100)) & "</TotalCost>";
Print #1, "<GrossAmount>" & Trim(Str((Int((tdf3!LíneaTotal * 100) + 0.5)) / 100)) & "</GrossAmount>";
End If
Print #1, "<TaxesOutputs>";
Print #1, "<Tax>";
Print #1, "<TaxTypeCode>01</TaxTypeCode>";
Print #1, "<TaxRate>" & Trim(Str(Me.Iva)) & "</TaxRate>";
Print #1, "<TaxableBase><TotalAmount>" & Trim(Str((Int((tdf3!LíneaTotal * 100) + 0.5)) / 100)) & "</TotalAmount></TaxableBase>";
If IsNull(tdf3!LíneaTotal) Then
cuantoiva = 0
Else
cuantoiva = (Int((tdf3!LíneaTotal * 100) + 0.5)) / 100
cuantoiva = (cuantoiva * Me.Iva / 100)
End If
Print #1, "<TaxAmount><TotalAmount>" & Trim(Str((Int((cuantoiva * 100) + 0.5)) / 100)) & "</TotalAmount></TaxAmount>";
Print #1, "</Tax>";
Print #1, "</TaxesOutputs>";
If Not (IsNull(tdf3!Notas)) Then
Print #1, "<AdditionalLineItemInformation>" & tdf3!DENOMINACI&; "</AdditionalLineItemInformation>";
End If
Print #1, "</InvoiceLine>";
tdf3.MoveNext
Loop While tdf3.EOF = False
End If
Print #1, "</Items>";
Print #1, "</Invoice>";
Print #1, "</Invoices>";
Print #1, "</fe:Facturae>";
Close #1
tdf2.Close
tdf3.Close
Set dbs = Nothing
lineacomando = "sign -i C:\Directorio\Emit-" & Trim(Str(Me.NroFact)) & ".xml -o C:\Directorio\Emit-" & Trim(Str(Me.NroFact)) & ".xsig -certgui"
retval = Shell("C:\Program Files\AutoFirma\AutoFirma\autofirma.exe " & lineacomando)