From b9dad6e4b94a85055068c29cad629cf44bdc72ee Mon Sep 17 00:00:00 2001 From: apardods Date: Wed, 27 Nov 2024 18:10:50 +0000 Subject: [PATCH] Renaming --- cancel.go | 6 +- cmd/gobl.verifactu/cancel.go | 2 +- cmd/gobl.verifactu/root.go | 3 +- cmd/gobl.verifactu/send.go | 10 ++- cmd/gobl.verifactu/sendtest.go | 126 --------------------------------- doc/breakdown_test.go | 16 ++--- doc/cancel_test.go | 6 +- doc/doc.go | 4 +- doc/doc_test.go | 2 +- doc/invoice_test.go | 8 +-- doc/party_test.go | 8 +-- document.go | 2 +- examples_test.go | 3 + internal/gateways/gateways.go | 1 - test/data/cred-note-base.json | 2 +- verifactu.go | 4 +- 16 files changed, 41 insertions(+), 162 deletions(-) delete mode 100644 cmd/gobl.verifactu/sendtest.go diff --git a/cancel.go b/cancel.go index 3d5b8be..3d1117e 100644 --- a/cancel.go +++ b/cancel.go @@ -29,7 +29,7 @@ func (c *Client) GenerateCancel(env *gobl.Envelope) (*doc.VeriFactu, error) { } // Create the document - cd, err := doc.NewDocument(inv, ts, c.issuerRole, c.software, true) + cd, err := doc.NewVerifactu(inv, ts, c.issuerRole, c.software, true) if err != nil { return nil, err } @@ -38,9 +38,7 @@ func (c *Client) GenerateCancel(env *gobl.Envelope) (*doc.VeriFactu, error) { } // FingerprintCancel generates a fingerprint for the cancellation document using the -// data provided from the previous chain data. If there was no previous -// document in the chain, the parameter should be nil. The document is updated -// in place. +// data provided from the previous chain data. The document is updated in place. func (c *Client) FingerprintCancel(d *doc.VeriFactu, prev *doc.ChainData) error { return d.FingerprintCancel(prev) } diff --git a/cmd/gobl.verifactu/cancel.go b/cmd/gobl.verifactu/cancel.go index 250ef49..58b10bc 100644 --- a/cmd/gobl.verifactu/cancel.go +++ b/cmd/gobl.verifactu/cancel.go @@ -67,7 +67,7 @@ func (c *cancelOpts) runE(cmd *cobra.Command, args []string) error { if c.production { opts = append(opts, verifactu.InProduction()) } else { - opts = append(opts, verifactu.InTesting()) + opts = append(opts, verifactu.InSandbox()) } tc, err := verifactu.New(c.software(), opts...) diff --git a/cmd/gobl.verifactu/root.go b/cmd/gobl.verifactu/root.go index 3664089..046ac4a 100644 --- a/cmd/gobl.verifactu/root.go +++ b/cmd/gobl.verifactu/root.go @@ -35,7 +35,6 @@ func (o *rootOpts) cmd() *cobra.Command { cmd.AddCommand(versionCmd()) cmd.AddCommand(send(o).cmd()) - cmd.AddCommand(sendTest(o).cmd()) cmd.AddCommand(convert(o).cmd()) cmd.AddCommand(cancel(o).cmd()) @@ -64,7 +63,7 @@ func (o *rootOpts) software() *doc.Software { NombreSistemaInformatico: o.swName, TipoUsoPosibleSoloVerifactu: "S", TipoUsoPosibleMultiOT: "S", - IndicadorMultiplesOT: "S", + IndicadorMultiplesOT: "N", } } diff --git a/cmd/gobl.verifactu/send.go b/cmd/gobl.verifactu/send.go index 734fe06..4e16392 100644 --- a/cmd/gobl.verifactu/send.go +++ b/cmd/gobl.verifactu/send.go @@ -9,6 +9,7 @@ import ( "github.com/invopop/gobl" verifactu "github.com/invopop/gobl.verifactu" "github.com/invopop/gobl.verifactu/doc" + "github.com/invopop/xmldsig" "github.com/spf13/cobra" ) @@ -53,14 +54,19 @@ func (c *sendOpts) runE(cmd *cobra.Command, args []string) error { return fmt.Errorf("unmarshaling gobl envelope: %w", err) } + cert, err := xmldsig.LoadCertificate(c.cert, c.password) + if err != nil { + return err + } + opts := []verifactu.Option{ - verifactu.WithThirdPartyIssuer(), + verifactu.WithCertificate(cert), } if c.production { opts = append(opts, verifactu.InProduction()) } else { - opts = append(opts, verifactu.InTesting()) + opts = append(opts, verifactu.InSandbox()) } tc, err := verifactu.New(c.software(), opts...) diff --git a/cmd/gobl.verifactu/sendtest.go b/cmd/gobl.verifactu/sendtest.go deleted file mode 100644 index 8b2069f..0000000 --- a/cmd/gobl.verifactu/sendtest.go +++ /dev/null @@ -1,126 +0,0 @@ -// Package main provides the command line interface to the VeriFactu package. -package main - -import ( - "bytes" - "encoding/json" - "fmt" - - "github.com/invopop/gobl" - verifactu "github.com/invopop/gobl.verifactu" - "github.com/invopop/gobl.verifactu/doc" - "github.com/invopop/xmldsig" - "github.com/spf13/cobra" -) - -type sendTestOpts struct { - *rootOpts - previous string -} - -func sendTest(o *rootOpts) *sendTestOpts { - return &sendTestOpts{rootOpts: o} -} - -func (c *sendTestOpts) cmd() *cobra.Command { - cmd := &cobra.Command{ - Use: "sendTest [infile]", - Short: "Sends the GOBL to the VeriFactu service", - RunE: c.runE, - } - - f := cmd.Flags() - c.prepareFlags(f) - - f.StringVar(&c.previous, "prev", "", "Previous document fingerprint to chain with") - - return cmd -} - -func (c *sendTestOpts) runE(cmd *cobra.Command, args []string) error { - input, err := openInput(cmd, args) - if err != nil { - return err - } - defer input.Close() // nolint:errcheck - - buf := new(bytes.Buffer) - if _, err := buf.ReadFrom(input); err != nil { - return fmt.Errorf("reading input: %w", err) - } - - env := new(gobl.Envelope) - if err := json.Unmarshal(buf.Bytes(), env); err != nil { - return fmt.Errorf("unmarshaling gobl envelope: %w", err) - } - - cert, err := xmldsig.LoadCertificate(c.cert, c.password) - if err != nil { - return err - } - - opts := []verifactu.Option{ - verifactu.WithCertificate(cert), - verifactu.WithSupplierIssuer(), - verifactu.InTesting(), - } - - tc, err := verifactu.New(c.software(), opts...) - if err != nil { - return err - } - - td, err := tc.Convert(env) - if err != nil { - return err - } - - c.previous = `{ - "emisor": "B85905495", - "serie": "SAMPLE-011", - "fecha": "21-11-2024", - "huella": "13EC0696104D1E529667184C6CDFC67D08036BCA4CD1B7887DE9C6F8F7EEC69C" - }` - - prev := new(doc.ChainData) - if err := json.Unmarshal([]byte(c.previous), prev); err != nil { - return err - } - - err = tc.Fingerprint(td, prev) - if err != nil { - return err - } - - if err := tc.AddQR(td, env); err != nil { - return err - } - - out, err := c.openOutput(cmd, args) - if err != nil { - return err - } - defer out.Close() // nolint:errcheck - - convOut, err := td.BytesIndent() - if err != nil { - return fmt.Errorf("generating verifactu xml: %w", err) - } - if _, err = out.Write(append(convOut, '\n')); err != nil { - return fmt.Errorf("writing verifactu xml: %w", err) - } - - err = tc.Post(cmd.Context(), td) - if err != nil { - return err - } - fmt.Println("made it!") - - data, err := json.Marshal(td.ChainData()) - if err != nil { - return err - } - fmt.Printf("Generated document with fingerprint: \n%s\n", string(data)) - - return nil -} diff --git a/doc/breakdown_test.go b/doc/breakdown_test.go index f69ab47..5993f0b 100644 --- a/doc/breakdown_test.go +++ b/doc/breakdown_test.go @@ -20,7 +20,7 @@ func TestBreakdownConversion(t *testing.T) { t.Run("basic-invoice", func(t *testing.T) { inv := test.LoadInvoice("inv-base.json") _ = inv.Calculate() - d, err := doc.NewDocument(inv, time.Now(), doc.IssuerRoleSupplier, nil, false) + d, err := doc.NewVerifactu(inv, time.Now(), doc.IssuerRoleSupplier, nil, false) require.NoError(t, err) assert.Equal(t, 1800.00, d.RegistroFactura.RegistroAlta.Desglose.DetalleDesglose[0].BaseImponibleOImporteNoSujeto) @@ -50,7 +50,7 @@ func TestBreakdownConversion(t *testing.T) { }, } _ = inv.Calculate() - d, err := doc.NewDocument(inv, time.Now(), doc.IssuerRoleSupplier, nil, false) + d, err := doc.NewVerifactu(inv, time.Now(), doc.IssuerRoleSupplier, nil, false) require.NoError(t, err) assert.Equal(t, 100.00, d.RegistroFactura.RegistroAlta.Desglose.DetalleDesglose[0].BaseImponibleOImporteNoSujeto) assert.Equal(t, "01", d.RegistroFactura.RegistroAlta.Desglose.DetalleDesglose[0].Impuesto) @@ -92,7 +92,7 @@ func TestBreakdownConversion(t *testing.T) { }, } _ = inv.Calculate() - d, err := doc.NewDocument(inv, time.Now(), doc.IssuerRoleSupplier, nil, false) + d, err := doc.NewVerifactu(inv, time.Now(), doc.IssuerRoleSupplier, nil, false) require.NoError(t, err) assert.Equal(t, 100.00, d.RegistroFactura.RegistroAlta.Desglose.DetalleDesglose[0].BaseImponibleOImporteNoSujeto) assert.Equal(t, 21.00, d.RegistroFactura.RegistroAlta.Desglose.DetalleDesglose[0].CuotaRepercutida) @@ -125,7 +125,7 @@ func TestBreakdownConversion(t *testing.T) { }, } _ = inv.Calculate() - d, err := doc.NewDocument(inv, time.Now(), doc.IssuerRoleSupplier, nil, false) + d, err := doc.NewVerifactu(inv, time.Now(), doc.IssuerRoleSupplier, nil, false) require.NoError(t, err) assert.Equal(t, 100.00, d.RegistroFactura.RegistroAlta.Desglose.DetalleDesglose[0].BaseImponibleOImporteNoSujeto) assert.Equal(t, 0.00, d.RegistroFactura.RegistroAlta.Desglose.DetalleDesglose[0].CuotaRepercutida) @@ -151,7 +151,7 @@ func TestBreakdownConversion(t *testing.T) { }, } _ = inv.Calculate() - _, err := doc.NewDocument(inv, time.Now(), doc.IssuerRoleSupplier, nil, false) + _, err := doc.NewVerifactu(inv, time.Now(), doc.IssuerRoleSupplier, nil, false) require.Error(t, err) }) @@ -175,7 +175,7 @@ func TestBreakdownConversion(t *testing.T) { }, } _ = inv.Calculate() - d, err := doc.NewDocument(inv, time.Now(), doc.IssuerRoleSupplier, nil, false) + d, err := doc.NewVerifactu(inv, time.Now(), doc.IssuerRoleSupplier, nil, false) require.NoError(t, err) assert.Equal(t, 100.00, d.RegistroFactura.RegistroAlta.Desglose.DetalleDesglose[0].BaseImponibleOImporteNoSujeto) assert.Equal(t, 21.00, d.RegistroFactura.RegistroAlta.Desglose.DetalleDesglose[0].CuotaRepercutida) @@ -206,7 +206,7 @@ func TestBreakdownConversion(t *testing.T) { }, } _ = inv.Calculate() - d, err := doc.NewDocument(inv, time.Now(), doc.IssuerRoleSupplier, nil, false) + d, err := doc.NewVerifactu(inv, time.Now(), doc.IssuerRoleSupplier, nil, false) require.NoError(t, err) assert.Equal(t, 100.00, d.RegistroFactura.RegistroAlta.Desglose.DetalleDesglose[0].BaseImponibleOImporteNoSujeto) assert.Equal(t, 10.00, d.RegistroFactura.RegistroAlta.Desglose.DetalleDesglose[0].CuotaRepercutida) @@ -236,7 +236,7 @@ func TestBreakdownConversion(t *testing.T) { }, } _ = inv.Calculate() - d, err := doc.NewDocument(inv, time.Now(), doc.IssuerRoleSupplier, nil, false) + d, err := doc.NewVerifactu(inv, time.Now(), doc.IssuerRoleSupplier, nil, false) require.NoError(t, err) assert.Equal(t, 1000.00, d.RegistroFactura.RegistroAlta.Desglose.DetalleDesglose[0].BaseImponibleOImporteNoSujeto) assert.Equal(t, 100.00, d.RegistroFactura.RegistroAlta.Desglose.DetalleDesglose[0].CuotaRepercutida) diff --git a/doc/cancel_test.go b/doc/cancel_test.go index 0d0c091..a0ab11a 100644 --- a/doc/cancel_test.go +++ b/doc/cancel_test.go @@ -15,7 +15,7 @@ func TestNewRegistroAnulacion(t *testing.T) { t.Run("basic", func(t *testing.T) { inv := test.LoadInvoice("cred-note-base.json") - d, err := doc.NewDocument(inv, time.Now(), doc.IssuerRoleSupplier, nil, true) + d, err := doc.NewVerifactu(inv, time.Now(), doc.IssuerRoleSupplier, nil, true) require.NoError(t, err) reg := d.RegistroFactura.RegistroAnulacion @@ -33,7 +33,7 @@ func TestNewRegistroAnulacion(t *testing.T) { t.Run("customer issuer", func(t *testing.T) { inv := test.LoadInvoice("cred-note-base.json") - d, err := doc.NewDocument(inv, time.Now(), doc.IssuerRoleCustomer, nil, true) + d, err := doc.NewVerifactu(inv, time.Now(), doc.IssuerRoleCustomer, nil, true) require.NoError(t, err) reg := d.RegistroFactura.RegistroAnulacion @@ -51,7 +51,7 @@ func TestNewRegistroAnulacion(t *testing.T) { t.Run("third party issuer", func(t *testing.T) { inv := test.LoadInvoice("cred-note-base.json") - d, err := doc.NewDocument(inv, time.Now(), doc.IssuerRoleThirdParty, nil, true) + d, err := doc.NewVerifactu(inv, time.Now(), doc.IssuerRoleThirdParty, nil, true) require.NoError(t, err) reg := d.RegistroFactura.RegistroAnulacion diff --git a/doc/doc.go b/doc/doc.go index ff03cf9..2f3e5f6 100644 --- a/doc/doc.go +++ b/doc/doc.go @@ -52,8 +52,8 @@ func init() { } } -// NewDocument creates a new VeriFactu document -func NewDocument(inv *bill.Invoice, ts time.Time, r IssuerRole, s *Software, c bool) (*VeriFactu, error) { +// NewVerifactu creates a new VeriFactu document +func NewVerifactu(inv *bill.Invoice, ts time.Time, r IssuerRole, s *Software, c bool) (*VeriFactu, error) { doc := &VeriFactu{ Cabecera: &Cabecera{ Obligado: Obligado{ diff --git a/doc/doc_test.go b/doc/doc_test.go index f198955..39fdfdf 100644 --- a/doc/doc_test.go +++ b/doc/doc_test.go @@ -18,7 +18,7 @@ func TestInvoiceConversion(t *testing.T) { t.Run("should contain basic document info", func(t *testing.T) { inv := test.LoadInvoice("inv-base.json") - doc, err := doc.NewDocument(inv, ts, role, sw, false) + doc, err := doc.NewVerifactu(inv, ts, role, sw, false) require.NoError(t, err) assert.Equal(t, "Invopop S.L.", doc.Cabecera.Obligado.NombreRazon) diff --git a/doc/invoice_test.go b/doc/invoice_test.go index be77948..a88275e 100644 --- a/doc/invoice_test.go +++ b/doc/invoice_test.go @@ -22,7 +22,7 @@ func TestNewRegistroAlta(t *testing.T) { t.Run("should contain basic document info", func(t *testing.T) { inv := test.LoadInvoice("inv-base.json") - d, err := doc.NewDocument(inv, ts, role, sw, false) + d, err := doc.NewVerifactu(inv, ts, role, sw, false) require.NoError(t, err) reg := d.RegistroFactura.RegistroAlta @@ -55,7 +55,7 @@ func TestNewRegistroAlta(t *testing.T) { inv.SetTags(tax.TagSimplified) inv.Customer = nil - d, err := doc.NewDocument(inv, ts, role, sw, false) + d, err := doc.NewVerifactu(inv, ts, role, sw, false) require.NoError(t, err) assert.Equal(t, "S", d.RegistroFactura.RegistroAlta.FacturaSinIdentifDestinatarioArt61d) @@ -64,7 +64,7 @@ func TestNewRegistroAlta(t *testing.T) { t.Run("should handle rectificative invoices", func(t *testing.T) { inv := test.LoadInvoice("cred-note-base.json") - d, err := doc.NewDocument(inv, ts, role, sw, false) + d, err := doc.NewVerifactu(inv, ts, role, sw, false) require.NoError(t, err) reg := d.RegistroFactura.RegistroAlta @@ -89,7 +89,7 @@ func TestNewRegistroAlta(t *testing.T) { }, } - d, err := doc.NewDocument(inv, ts, role, sw, false) + d, err := doc.NewVerifactu(inv, ts, role, sw, false) require.NoError(t, err) reg := d.RegistroFactura.RegistroAlta diff --git a/doc/party_test.go b/doc/party_test.go index 719960f..0a08c22 100644 --- a/doc/party_test.go +++ b/doc/party_test.go @@ -19,7 +19,7 @@ func TestNewParty(t *testing.T) { sw := &doc.Software{} t.Run("with tax ID", func(t *testing.T) { inv := test.LoadInvoice("inv-base.json") - d, err := doc.NewDocument(inv, ts, role, sw, false) + d, err := doc.NewVerifactu(inv, ts, role, sw, false) require.NoError(t, err) p := d.RegistroFactura.RegistroAlta.Destinatarios[0].IDDestinatario @@ -40,7 +40,7 @@ func TestNewParty(t *testing.T) { }, } - d, err := doc.NewDocument(inv, ts, role, sw, false) + d, err := doc.NewVerifactu(inv, ts, role, sw, false) require.NoError(t, err) p := d.RegistroFactura.RegistroAlta.Destinatarios[0].IDDestinatario @@ -61,7 +61,7 @@ func TestNewParty(t *testing.T) { }, } - d, err := doc.NewDocument(inv, ts, role, sw, false) + d, err := doc.NewVerifactu(inv, ts, role, sw, false) require.NoError(t, err) p := d.RegistroFactura.RegistroAlta.Destinatarios[0].IDDestinatario @@ -79,7 +79,7 @@ func TestNewParty(t *testing.T) { Name: "Simple Company", } - _, err := doc.NewDocument(inv, ts, role, sw, false) + _, err := doc.NewVerifactu(inv, ts, role, sw, false) require.Error(t, err) }) } diff --git a/document.go b/document.go index a2f62a0..970196f 100644 --- a/document.go +++ b/document.go @@ -27,7 +27,7 @@ func (c *Client) Convert(env *gobl.Envelope) (*doc.VeriFactu, error) { return nil, errors.New("only spanish invoices are supported") } - out, err := doc.NewDocument(inv, c.CurrentTime(), c.issuerRole, c.software, false) + out, err := doc.NewVerifactu(inv, c.CurrentTime(), c.issuerRole, c.software, false) if err != nil { return nil, err } diff --git a/examples_test.go b/examples_test.go index 33d0d8a..304928d 100644 --- a/examples_test.go +++ b/examples_test.go @@ -155,6 +155,9 @@ func validateDoc(schema *xsd.Schema, doc []byte) []error { func addNamespaces(data []byte) ([]byte, error) { xmlString := string(data) xmlNamespaces := ` xmlns:sum="https://www2.agenciatributaria.gob.es/static_files/common/internet/dep/aplicaciones/es/aeat/tike/cont/ws/SuministroLR.xsd" xmlns:sum1="https://www2.agenciatributaria.gob.es/static_files/common/internet/dep/aplicaciones/es/aeat/tike/cont/ws/SuministroInformacion.xsd"` + if !strings.Contains(xmlString, "") { + return nil, fmt.Errorf("could not find RegFactuSistemaFacturacion tag in XML") + } xmlString = strings.Replace(xmlString, "", "", 1) finalXMLBytes := []byte(xmlString) return finalXMLBytes, nil diff --git a/internal/gateways/gateways.go b/internal/gateways/gateways.go index ad2bc92..e67658b 100644 --- a/internal/gateways/gateways.go +++ b/internal/gateways/gateways.go @@ -86,7 +86,6 @@ func (c *Connection) post(ctx context.Context, path string, payload []byte) erro e1 := out.Body.Respuesta.RespuestaLinea[0] err = err.withMessage(e1.DescripcionErrorRegistro).withCode(e1.CodigoErrorRegistro) } - fmt.Println(out.Body.Respuesta) return err } diff --git a/test/data/cred-note-base.json b/test/data/cred-note-base.json index 63dcdb1..eff8163 100644 --- a/test/data/cred-note-base.json +++ b/test/data/cred-note-base.json @@ -36,7 +36,7 @@ "name": "Provide One S.L.", "tax_id": { "country": "ES", - "code": "B98602642" + "code": "B85905495" }, "addresses": [ { diff --git a/verifactu.go b/verifactu.go index 1d3ca57..54f9745 100644 --- a/verifactu.go +++ b/verifactu.go @@ -119,8 +119,8 @@ func InProduction() Option { } } -// InTesting defines the connection to use the testing environment. -func InTesting() Option { +// InSandbox defines the connection to use the testing environment. +func InSandbox() Option { return func(c *Client) { c.env = gateways.EnvironmentSandbox }