-
Notifications
You must be signed in to change notification settings - Fork 0
/
verifactu.go
126 lines (106 loc) · 2.91 KB
/
verifactu.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
// Package verifactu provides the VeriFactu client
package verifactu
import (
"context"
"time"
"github.com/invopop/gobl.verifactu/doc"
"github.com/invopop/gobl.verifactu/internal/gateways"
"github.com/invopop/xmldsig"
)
// Client provides the main interface to the VeriFactu package.
type Client struct {
software *doc.Software
env gateways.Environment
issuerRole doc.IssuerRole
curTime time.Time
cert *xmldsig.Certificate
gw *gateways.Connection
}
// Option is used to configure the client.
type Option func(*Client)
// WithCertificate defines the signing certificate to use when producing the
// VeriFactu document.
func WithCertificate(cert *xmldsig.Certificate) Option {
return func(c *Client) {
c.cert = cert
}
}
// WithCurrentTime defines the current time to use when generating the VeriFactu
// document. Useful for testing.
func WithCurrentTime(curTime time.Time) Option {
return func(c *Client) {
c.curTime = curTime
}
}
// New creates a new VeriFactu client with shared software and configuration
// options for creating and sending new documents.
func New(software *doc.Software, opts ...Option) (*Client, error) {
c := new(Client)
c.software = software
// 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.cert == nil {
return c, nil
}
if c.gw == nil {
var err error
c.gw, err = gateways.New(c.env, c.cert)
if err != nil {
return nil, err
}
}
return c, nil
}
// WithSupplierIssuer set the issuer type to supplier.
func WithSupplierIssuer() Option {
return func(c *Client) {
c.issuerRole = doc.IssuerRoleSupplier
}
}
// WithCustomerIssuer set the issuer type to customer.
func WithCustomerIssuer() Option {
return func(c *Client) {
c.issuerRole = doc.IssuerRoleCustomer
}
}
// WithThirdPartyIssuer set the issuer type to third party.
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
}
}
// Post will send the document to the VeriFactu gateway.
func (c *Client) Post(ctx context.Context, d []byte) error {
if err := c.gw.Post(ctx, d); err != nil {
return doc.NewErrorFrom(err)
}
return nil
}
// CurrentTime returns the current time to use when generating
// the VeriFactu document.
func (c *Client) CurrentTime() time.Time {
if !c.curTime.IsZero() {
return c.curTime
}
return time.Now()
}
// Sandbox returns true if the client is using the sandbox environment.
func (c *Client) Sandbox() bool {
return c.env == gateways.EnvironmentSandbox
}