intacct_ruby 0.2.0 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +60 -29
- data/intacct_ruby.gemspec +0 -1
- data/lib/intacct_ruby/exceptions/empty_request_exception.rb +5 -0
- data/lib/intacct_ruby/exceptions/insufficient_credentials_exception.rb +5 -0
- data/lib/intacct_ruby/request.rb +42 -12
- data/lib/intacct_ruby/version.rb +1 -1
- metadata +4 -22
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: baaffa6dd9353222e537633286a01ebdbbc0e196
|
4
|
+
data.tar.gz: 4f174bbff844a691902f8e6cf9059d0f4c11b86c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 33f2fc22db5cbc9dc1b4f0bbc65b37cbd674411e8c0972309c7d77b6d46e431b33a677429383b7ad17ce84dcd7b084ecc386361dc4754fd0564eb8f813ad8510
|
7
|
+
data.tar.gz: c03c9f4b18d77285b6c333fbeb0d8097ce256004a44d9814a150194485d8a3251740f9424d24d903827f6853f7ccd0d8304a4ca2d83f1fdbfb859fd88f756166
|
data/README.md
CHANGED
@@ -34,7 +34,7 @@ create_project = IntacctRuby::Functions::CreateProject.new(
|
|
34
34
|
}
|
35
35
|
)
|
36
36
|
|
37
|
-
request = IntacctRuby::Request.new(create_customer, create_project)
|
37
|
+
request = IntacctRuby::Request.new(create_customer, create_project, authentication_params)
|
38
38
|
request.send
|
39
39
|
```
|
40
40
|
|
@@ -91,25 +91,78 @@ This will fire off a request that looks something like this:
|
|
91
91
|
```
|
92
92
|
If there are function errors (e.g. you omitted a required field) you'll see an error on response. Same if you see an internal server error, or any error outside of the 2xx range.
|
93
93
|
|
94
|
-
##
|
95
|
-
|
94
|
+
## Authentication
|
96
95
|
Before we go any further, make sure you've read the [Intacct API Quickstart Guide](https://developer.intacct.com/wiki/constructing-web-services-request#The%20Intacct%20DTDs).
|
97
96
|
|
97
|
+
In IntacctRuby - as with the Intacct API that the gem wraps - your system credentials are pass along with each separate `Request` instance. The functions that define a request are followed by a hash that spells out each piece of information required by Intacct for authentication. These fields are:
|
98
|
+
|
99
|
+
- `senderid`
|
100
|
+
- `sender_password`\*
|
101
|
+
- `userid`
|
102
|
+
- `companyid`
|
103
|
+
- `user_password`\*
|
104
|
+
|
105
|
+
\* _In [Intacct's documentation](https://developer.intacct.com/wiki/constructing-web-services-request), these are referred to only as `password`. This won't work in Rubyland, though, because we're unable to have multiple hash entries with the same key._
|
106
|
+
|
107
|
+
### Authentication Example:
|
108
|
+
|
109
|
+
```ruby
|
110
|
+
IntacctRuby::Request.new(
|
111
|
+
some_function,
|
112
|
+
another_function,
|
113
|
+
senderid: 'some_senderid_value',
|
114
|
+
sender_password: 'some_sender_password_value',
|
115
|
+
userid: 'some_userid_value',
|
116
|
+
companyid: 'some_companyid_value',
|
117
|
+
user_password: 'some_user_password_value'
|
118
|
+
)
|
119
|
+
```
|
120
|
+
|
121
|
+
Though, it probably makes more sense to keep all of these in some handy constant for easy reuse:
|
122
|
+
```ruby
|
123
|
+
REQUEST_OPTS = {
|
124
|
+
senderid: 'some_senderid_value',
|
125
|
+
sender_password: 'some_sender_password_value',
|
126
|
+
userid: 'some_userid_value',
|
127
|
+
companyid: 'some_companyid_value',
|
128
|
+
user_password: 'some_user_password_value'
|
129
|
+
}
|
130
|
+
|
131
|
+
IntacctRuby::Request.new(some_function, another_function, REQUEST_OPTS)
|
132
|
+
```
|
133
|
+
|
134
|
+
### Important Notes on Authentication
|
135
|
+
#### These Are Required!
|
136
|
+
Obviously, Intacct won't do anything if you don't tell it who you are. To save you the bandwidth, this gem will throw errors if any of these auth params are not provided.
|
137
|
+
|
138
|
+
#### BE SAFE!
|
139
|
+
Though the examples above show hard-coded username/password pairs, this is a really bad idea to do in production code. Instead, we recommend storing these variables in ENVs, using a tool like [Figaro](https://github.com/laserlemon/figaro) to bring it all together.
|
140
|
+
|
141
|
+
## Customizing Calls
|
142
|
+
|
98
143
|
This gem creates calls using the following defaults:
|
99
144
|
- **uniqueid:** false,
|
100
145
|
- **dtdversion:** 3.0,
|
101
146
|
- **includewhitespace:** false,
|
102
147
|
- **transaction:** true
|
103
148
|
|
104
|
-
If you'd like to override any of these, you can do so when you create a new request
|
149
|
+
If you'd like to override any of these, you can do so when you create a new request by adding additional fields to the options hash passed into `Request#new`:
|
105
150
|
|
106
151
|
```ruby
|
107
|
-
|
108
|
-
|
109
|
-
|
152
|
+
REQUEST_OPTS = {
|
153
|
+
senderid: 'some_senderid_value',
|
154
|
+
sender_password: 'some_sender_password_value',
|
155
|
+
userid: 'some_userid_value',
|
156
|
+
companyid: 'some_companyid_value',
|
157
|
+
user_password: 'some_user_password_value'
|
158
|
+
}
|
159
|
+
|
160
|
+
REQUEST_OPTS.merge!(
|
110
161
|
uniqueid: 'some_uniqueid_override',
|
111
162
|
dtdversion: 'some_dtd_override'
|
112
163
|
)
|
164
|
+
|
165
|
+
IntacctRuby::Request.new(some_function, another_function, REQUEST_OPTS)
|
113
166
|
```
|
114
167
|
## Installation
|
115
168
|
|
@@ -128,28 +181,6 @@ Or install it yourself as:
|
|
128
181
|
|
129
182
|
$ gem install intacct_ruby
|
130
183
|
|
131
|
-
### The Configuration (Don't Skip This Part!)
|
132
|
-
Once the gem's in place, you'll have it teach it your company secrets.
|
133
|
-
|
134
|
-
Intacct requires that the following credentials be passed along in the `<control>` block of each request:
|
135
|
-
- `senderid`
|
136
|
-
- (sender) `password`
|
137
|
-
|
138
|
-
and that the following be sent in the `<authentication>` block, too:
|
139
|
-
- `userid`
|
140
|
-
- `companyid`
|
141
|
-
- `password`
|
142
|
-
|
143
|
-
IntacctRuby handles all this for you, but you'll need to tell it which is which. The gem pulls these values from Environmental variables, and it uses [Figaro](https://github.com/laserlemon/figaro) to manage the whole process. In order to get this to work, you'll need to have an `application.yml` file in your project directory with the following definitions:
|
144
|
-
```yaml
|
145
|
-
intacct_senderid: 'some senderid'
|
146
|
-
intacct_sender_password: 'some password'
|
147
|
-
intacct_userid: 'some userid'
|
148
|
-
intacct_user_password: 'some password'
|
149
|
-
intacct_companyid: 'some companyid'
|
150
|
-
```
|
151
|
-
Once those are in place, IntacctRuby will suck 'em up and deposit them in the requests that you generate. Eeeasy squeezey.
|
152
|
-
|
153
184
|
## Adding New Functions
|
154
185
|
This gem was designed, as so many are, for a specific use case. The Intacct API has hundreds of API calls, though I only built out a dozen or so. Within that dozen, I only built out the fields that I needed in each call.
|
155
186
|
|
data/intacct_ruby.gemspec
CHANGED
data/lib/intacct_ruby/request.rb
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
require 'builder'
|
2
|
-
require 'figaro'
|
3
2
|
|
4
3
|
require 'intacct_ruby/api'
|
5
4
|
require 'intacct_ruby/response'
|
5
|
+
require 'intacct_ruby/exceptions/insufficient_credentials_exception'
|
6
|
+
require 'intacct_ruby/exceptions/empty_request_exception'
|
6
7
|
|
7
8
|
module IntacctRuby
|
8
9
|
# An outgoing request to the Intacct API. Can have multiple functions.
|
@@ -15,15 +16,21 @@ module IntacctRuby
|
|
15
16
|
transaction: true
|
16
17
|
}.freeze
|
17
18
|
|
18
|
-
|
19
|
-
|
19
|
+
REQUIRED_AUTHENTICATION_KEYS = [
|
20
|
+
:senderid,
|
21
|
+
:sender_password,
|
22
|
+
:userid,
|
23
|
+
:companyid,
|
24
|
+
:user_password
|
25
|
+
].freeze
|
20
26
|
|
21
|
-
|
22
|
-
#
|
23
|
-
|
27
|
+
def initialize(*functions, request_params)
|
28
|
+
# request_params should contain all req'd authentication information. If
|
29
|
+
# not, an error will be thrown on #send
|
30
|
+
@opts = DEFAULTS.dup.merge request_params
|
24
31
|
|
25
32
|
# If a hash is provided + popped, the remaining attrs are functions
|
26
|
-
@functions =
|
33
|
+
@functions = functions
|
27
34
|
end
|
28
35
|
|
29
36
|
def to_xml
|
@@ -39,6 +46,9 @@ module IntacctRuby
|
|
39
46
|
def send(api = nil)
|
40
47
|
api ||= Api.new
|
41
48
|
|
49
|
+
validate_keys!
|
50
|
+
validate_functions!
|
51
|
+
|
42
52
|
Response.new api.send(self)
|
43
53
|
end
|
44
54
|
|
@@ -46,14 +56,34 @@ module IntacctRuby
|
|
46
56
|
|
47
57
|
attr_reader :request, :functions
|
48
58
|
|
59
|
+
def validate_functions!
|
60
|
+
unless functions.any?
|
61
|
+
raise Exceptions::EmptyRequestException,
|
62
|
+
'a successful request must contain at least one function'
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def validate_keys!
|
67
|
+
missing_keys = REQUIRED_AUTHENTICATION_KEYS - @opts.keys
|
68
|
+
|
69
|
+
unless missing_keys.empty?
|
70
|
+
missing_keys.map! { |s| ":#{s}" } # so they appear as symbols in output
|
71
|
+
|
72
|
+
raise Exceptions::InsufficientCredentialsException,
|
73
|
+
"[#{missing_keys.join(', ')}] required for a valid request. "
|
74
|
+
'All authentication-related keys should be provided on ' \
|
75
|
+
'instantiation in IntacctRuby::Request#new'
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
49
79
|
def timestamp
|
50
80
|
@timestamp ||= Time.now.utc.to_s
|
51
81
|
end
|
52
82
|
|
53
83
|
def control_block
|
54
84
|
request.control do
|
55
|
-
request.senderid
|
56
|
-
request.password
|
85
|
+
request.senderid @opts[:senderid]
|
86
|
+
request.password @opts[:sender_password]
|
57
87
|
|
58
88
|
# As recommended by Intacct API reference. This ID should be unique
|
59
89
|
# to the call: it's used to associate a response with a request.
|
@@ -67,9 +97,9 @@ module IntacctRuby
|
|
67
97
|
def authentication_block
|
68
98
|
request.authentication do
|
69
99
|
request.login do
|
70
|
-
request.userid
|
71
|
-
request.companyid
|
72
|
-
request.password
|
100
|
+
request.userid @opts[:userid]
|
101
|
+
request.companyid @opts[:companyid]
|
102
|
+
request.password @opts[:user_password]
|
73
103
|
end
|
74
104
|
end
|
75
105
|
end
|
data/lib/intacct_ruby/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: intacct_ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jeremy Zornow
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-04-
|
11
|
+
date: 2017-04-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -126,26 +126,6 @@ dependencies:
|
|
126
126
|
- - ">="
|
127
127
|
- !ruby/object:Gem::Version
|
128
128
|
version: 3.0.4
|
129
|
-
- !ruby/object:Gem::Dependency
|
130
|
-
name: figaro
|
131
|
-
requirement: !ruby/object:Gem::Requirement
|
132
|
-
requirements:
|
133
|
-
- - "~>"
|
134
|
-
- !ruby/object:Gem::Version
|
135
|
-
version: '1.1'
|
136
|
-
- - ">="
|
137
|
-
- !ruby/object:Gem::Version
|
138
|
-
version: 1.1.1
|
139
|
-
type: :runtime
|
140
|
-
prerelease: false
|
141
|
-
version_requirements: !ruby/object:Gem::Requirement
|
142
|
-
requirements:
|
143
|
-
- - "~>"
|
144
|
-
- !ruby/object:Gem::Version
|
145
|
-
version: '1.1'
|
146
|
-
- - ">="
|
147
|
-
- !ruby/object:Gem::Version
|
148
|
-
version: 1.1.1
|
149
129
|
description: Allows for multi-function API calls, the addition of custom fields, and
|
150
130
|
more. All in an easy-to-use package!
|
151
131
|
email:
|
@@ -167,7 +147,9 @@ files:
|
|
167
147
|
- intacct_ruby.gemspec
|
168
148
|
- lib/intacct_ruby.rb
|
169
149
|
- lib/intacct_ruby/api.rb
|
150
|
+
- lib/intacct_ruby/exceptions/empty_request_exception.rb
|
170
151
|
- lib/intacct_ruby/exceptions/function_failure_exception.rb
|
152
|
+
- lib/intacct_ruby/exceptions/insufficient_credentials_exception.rb
|
171
153
|
- lib/intacct_ruby/functions/base_function.rb
|
172
154
|
- lib/intacct_ruby/functions/create_aradjustment.rb
|
173
155
|
- lib/intacct_ruby/functions/create_customer.rb
|