-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathticketbai.go
185 lines (159 loc) · 4.84 KB
/
ticketbai.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
// Package ticketbai provides a client for generating and sending TicketBAI
// documents to the different regional services in the Basque Country.
package ticketbai
import (
"context"
"time"
"github.com/invopop/gobl.ticketbai/doc"
"github.com/invopop/gobl.ticketbai/internal/gateways"
"github.com/invopop/gobl/l10n"
"github.com/invopop/xmldsig"
"github.com/nbio/xml"
)
// Expose zone codes for external use.
const (
ZoneBI l10n.Code = doc.ZoneBI // Bizkaia
ZoneSS l10n.Code = doc.ZoneSS // Gipuzkoa
ZoneVI l10n.Code = doc.ZoneVI // Araba
)
// Client provides the main interface to the TicketBAI package.
type Client struct {
software *Software
zone l10n.Code
cert *xmldsig.Certificate
env gateways.Environment
issuerRole doc.IssuerRole
curTime time.Time
gw gateways.Connection
}
// Option is used to configure the client.
type Option func(*Client)
// WithCertificate defines the signing certificate to use when producing the
// TicketBAI document.
func WithCertificate(cert *xmldsig.Certificate) Option {
return func(c *Client) {
c.cert = cert
}
}
// WithCurrentTime defines the current time to use when generating the TicketBAI
// document. Useful for testing.
func WithCurrentTime(curTime time.Time) Option {
return func(c *Client) {
c.curTime = curTime
}
}
// WithConnection defines a new gateway connection to use for the client.
// Useful for testing and mocking the connection responses.
func WithConnection(conn gateways.Connection) Option {
return func(c *Client) {
c.gw = conn
}
}
// WithSupplierIssuer set the issuer type to supplier. To be used when the
// invoice's supplier, using their own certificate, is issuing the document.
func WithSupplierIssuer() Option {
return func(c *Client) {
c.issuerRole = doc.IssuerRoleSupplier
}
}
// WithCustomerIssuer set the issuer type to customer. To be used when the
// invoice's supplier, using their own certificate, is issuing the document.
func WithCustomerIssuer() Option {
return func(c *Client) {
c.issuerRole = doc.IssuerRoleCustomer
}
}
// WithThirdPartyIssuer set the issuer type to third party. To be used when the
// an authorised third party, using their own certificate, is issuing the
// document on behalf of the invoice's supplier.
func WithThirdPartyIssuer() Option {
return func(c *Client) {
c.issuerRole = doc.IssuerRoleThirdParty
}
}
// InProduction defines the connection to use the production environment.
func InProduction() Option {
return func(c *Client) {
c.env = gateways.EnvironmentProduction
}
}
// InSandbox defines the connection to use the testing environment.
func InSandbox() Option {
return func(c *Client) {
c.env = gateways.EnvironmentSandbox
}
}
// Software defines the details about the software that is using this library to
// generate TicketBAI documents. These details are included in the final
// document.
type Software struct {
License string
NIF string
Name string
CompanyName string
Version string
}
// New creates a new TicketBAI client with shared software and configuration
// options for creating and sending new documents.
func New(software *Software, zone l10n.Code, opts ...Option) (*Client, error) {
c := new(Client)
c.software = software
c.zone = zone
// Set default values that can be overwritten by the options
c.env = gateways.EnvironmentSandbox
c.issuerRole = doc.IssuerRoleSupplier
for _, opt := range opts {
opt(c)
}
if c.gw == nil {
var err error
c.gw, err = gateways.New(c.env, c.zone, c.cert)
if err != nil {
return nil, err
}
}
return c, nil
}
// Post will send the document to the TicketBAI gateway.
func (c *Client) Post(ctx context.Context, d *doc.TicketBAI) error {
if err := c.gw.Post(ctx, d); err != nil {
return newErrorFrom(err)
}
return nil
}
// Cancel will send the cancel document in the TicketBAI gateway.
func (c *Client) Cancel(ctx context.Context, d *doc.AnulaTicketBAI) error {
return c.gw.Cancel(ctx, d)
}
// ParseDocument will parse the XML data into a TicketBAI document.
func ParseDocument(data []byte) (*doc.TicketBAI, error) {
d := new(doc.TicketBAI)
if err := xml.Unmarshal(data, d); err != nil {
return nil, err
}
return d, nil
}
// ParseCancelDocument will parse the XML data into a Cancel TicketBAI document.
func ParseCancelDocument(data []byte) (*doc.AnulaTicketBAI, error) {
d := new(doc.AnulaTicketBAI)
if err := xml.Unmarshal(data, d); err != nil {
return nil, err
}
return d, nil
}
// CurrentTime returns the current time to use when generating
// the TicketBAI document.
func (c *Client) CurrentTime() time.Time {
if !c.curTime.IsZero() {
return c.curTime
}
return time.Now()
}
// Zone returns the zone for this client.
func (c *Client) Zone() l10n.Code {
return c.zone
}
// Sandbox returns true if the client is using the sandbox environment.
func (c *Client) Sandbox() bool {
return c.env == gateways.EnvironmentSandbox
}