forked from rwestlund/quickbooks-go
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathclient.go
182 lines (157 loc) · 4.6 KB
/
client.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
// Copyright (c) 2018, Randy Westlund. All rights reserved.
// This code is under the BSD-2-Clause license.
/*
Package quickbooks provides access to Intuit's QuickBooks Online API.
NOTE: This library is very incomplete. I just implemented the minimum for my
use case. Pull requests welcome :)
// Do this after you go through the normal OAuth process.
var client = oauth2.NewClient(ctx, tokenSource)
// Initialize the client handle.
var qb = quickbooks.Client{
Client: client,
Endpoint: quickbooks.SandboxEndpoint,
RealmID: "some company account ID"'
}
// Make a request!
var companyInfo, err = qb.FetchCompanyInfo()
*/
package quickbooks
import (
"encoding/json"
"log"
"net/http"
"net/url"
)
const (
AccountingScope = "com.intuit.quickbooks.accounting"
)
// Types of options available per request to the client.
type ClientOptType string
// Types of options supported by this SDK
var ClientOptTypeQueryParameter = ClientOptType("query_parameter")
// Options available on requests made by the client. Usually passed along as query parameters
type ClientOpt struct {
// The type of the option.
Type ClientOptType
// The API name of the option
Name string
// The value of the option
Value string
}
// Available Options supported by this sdk
var ClientOptAllowDuplicateDocNum = ClientOpt{
Type: ClientOptTypeQueryParameter,
Name: "include",
Value: "allowduplicatedocnum",
}
// Client is your handle to the QuickBooks API.
type Client struct {
// Get this from oauth2.NewClient().
Client *http.Client
// Set to ProductionEndpoint or SandboxEndpoint.
Endpoint EndpointURL
// The set of quickbooks APIs
discoveryAPI *DiscoveryAPI
// The client ID
clientId string
// The client Secret
clientSecret string
// The account ID you're connecting to.
RealmID string
}
func NewQuickbooksClient(clientId string, clientSecret string, realmID string, isProduction bool, token *BearerToken) (c *Client, err error) {
var client Client
client.clientId = clientId
client.clientSecret = clientSecret
client.RealmID = realmID
if isProduction {
client.Endpoint = ProductionEndpoint
client.discoveryAPI = CallDiscoveryAPI(DiscoveryProductionEndpoint)
} else {
client.Endpoint = SandboxEndpoint
client.discoveryAPI = CallDiscoveryAPI(DiscoverySandboxEndpoint)
}
if token != nil {
client.Client = getHttpClient(token)
}
return &client, nil
}
// GetAuthorizationUrl Get the authorization Url
func (c *Client) GetAuthorizationUrl(scope string, csrf string, redirectUri string) string {
var Url *url.URL
authorizationEndpoint := c.discoveryAPI.AuthorizationEndpoint
Url, err := url.Parse(authorizationEndpoint)
if err != nil {
log.Println("error parsing url")
}
parameters := url.Values{}
parameters.Add("client_id", c.clientId)
parameters.Add("response_type", "code")
parameters.Add("scope", scope)
parameters.Add("redirect_uri", redirectUri)
parameters.Add("state", csrf)
Url.RawQuery = parameters.Encode()
log.Printf("Encoded URL is %q\n", Url.String())
return Url.String()
}
// FetchCompanyInfo returns the QuickBooks CompanyInfo object. This is a good
// test to check whether you're connected.
func (c *Client) FetchCompanyInfo() (*CompanyInfo, error) {
var u, err = url.Parse(string(c.Endpoint))
if err != nil {
return nil, err
}
u.Path = "/v3/company/" + c.RealmID + "/companyinfo/" + c.RealmID
var v = url.Values{}
v.Add("minorversion", minorVersion)
u.RawQuery = v.Encode()
var req *http.Request
req, err = http.NewRequest("GET", u.String(), nil)
if err != nil {
return nil, err
}
req.Header.Add("Accept", "application/json")
var res *http.Response
res, err = c.Client.Do(req)
if err != nil {
return nil, err
}
defer res.Body.Close()
if res.StatusCode != http.StatusOK {
return nil, parseFailure(res)
}
var r struct {
CompanyInfo CompanyInfo
Time Date
}
err = json.NewDecoder(res.Body).Decode(&r)
return &r.CompanyInfo, err
}
// query makes the specified QBO `query` and unmarshals the result into `out`
func (c *Client) query(query string, out interface{}) error {
var u, err = url.Parse(string(c.Endpoint))
if err != nil {
return err
}
u.Path = "/v3/company/" + c.RealmID + "/query"
var v = url.Values{}
v.Add("minorversion", minorVersion)
v.Add("query", query)
u.RawQuery = v.Encode()
var req *http.Request
req, err = http.NewRequest("GET", u.String(), nil)
if err != nil {
return err
}
req.Header.Add("Accept", "application/json")
var res *http.Response
res, err = c.Client.Do(req)
if err != nil {
return err
}
defer res.Body.Close()
if res.StatusCode != http.StatusOK {
return parseFailure(res)
}
return json.NewDecoder(res.Body).Decode(out)
}