intacct 0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.yardopts +6 -0
- data/CHANGELOG.md +33 -0
- data/README.md +262 -20
- data/Rakefile +15 -51
- data/lib/intacct/authentication_methods/credentials.rb +3 -1
- data/lib/intacct/authentication_methods/session.rb +3 -1
- data/lib/intacct/authentication_result.rb +4 -2
- data/lib/intacct/config.rb +19 -9
- data/lib/intacct/exceptions/client_exception.rb +2 -0
- data/lib/intacct/exceptions/function_failure_exception.rb +2 -0
- data/lib/intacct/exceptions/missing_authentication_exception.rb +2 -0
- data/lib/intacct/function_result.rb +7 -5
- data/lib/intacct/functions/create.rb +2 -0
- data/lib/intacct/functions/create_ar_adjustment.rb +2 -0
- data/lib/intacct/functions/get_api_session.rb +2 -0
- data/lib/intacct/functions/query.rb +4 -2
- data/lib/intacct/functions/read.rb +4 -2
- data/lib/intacct/functions/retrieve_pdf.rb +2 -0
- data/lib/intacct/functions/reverse_payment.rb +2 -0
- data/lib/intacct/functions/update.rb +2 -1
- data/lib/intacct/gateway.rb +5 -3
- data/lib/intacct/request.rb +5 -3
- data/lib/intacct/response.rb +34 -6
- data/lib/intacct/utils.rb +5 -3
- data/lib/intacct/version.rb +4 -1
- data/lib/intacct.rb +53 -14
- metadata +34 -148
- data/.document +0 -5
- data/.rspec +0 -1
- data/.rubocop.yml +0 -19
- data/.travis.yml +0 -8
- data/Gemfile +0 -20
- data/intacct.gemspec +0 -79
- data/spec/intacct/client_spec.rb +0 -5
- data/spec/intacct_spec.rb +0 -7
- data/spec/spec_helper.rb +0 -34
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 3da8dce2d382735a59912c753d460edbc9021d45edf3542f3ede11b44cf9c16a
|
|
4
|
+
data.tar.gz: 3a0e07e077cbc8d130ce62a0271810010d12609bf56d4c659165d85ad2e59e7a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: cdf889a9dea9bc2a7736fc09e802bf1d3ba9eecab1fd0fa1f11e5d74c3202f3a2b442232bda9852e69f8fc662d9b0464503354d7b2f76dc8f1f36a4b7a3f03a1
|
|
7
|
+
data.tar.gz: 1a20e4e45387551c434a122d6f9cf9b8a0ed3fcc86e25760e2a04a908912cb0d89ac6e20121645651b4db4c38bd107c0931fe43a6907d0ad4a74d481c7a450ce
|
data/.yardopts
ADDED
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [1.0.0] - 2025-11-13
|
|
9
|
+
|
|
10
|
+
### Changed
|
|
11
|
+
- **BREAKING**: Minimum Ruby version raised to 3.2.0
|
|
12
|
+
- Migrated from RSpec to Minitest
|
|
13
|
+
- Modernized gemspec with comprehensive metadata
|
|
14
|
+
- Replaced Juwelier with standard Bundler gem tasks
|
|
15
|
+
- Updated RuboCop configuration for Ruby 3.2
|
|
16
|
+
- Added frozen string literal pragma to all files
|
|
17
|
+
|
|
18
|
+
### Added
|
|
19
|
+
- YARD documentation with comprehensive examples
|
|
20
|
+
- Complete test coverage with Minitest
|
|
21
|
+
- CHANGELOG.md (this file)
|
|
22
|
+
- Enhanced README with usage examples and badges
|
|
23
|
+
- RuboCop to default rake task
|
|
24
|
+
|
|
25
|
+
### Removed
|
|
26
|
+
- Support for Ruby < 3.2
|
|
27
|
+
- RSpec test framework
|
|
28
|
+
- Juwelier gem management
|
|
29
|
+
- Legacy coverage tools (CodeClimate, Coveralls)
|
|
30
|
+
|
|
31
|
+
## [0.0.15] - Previous Release
|
|
32
|
+
|
|
33
|
+
Historical changes before 1.0.0 modernization.
|
data/README.md
CHANGED
|
@@ -1,39 +1,281 @@
|
|
|
1
|
-
# Intacct
|
|
1
|
+
# Intacct Ruby Gem
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://badge.fury.io/rb/intacct)
|
|
4
|
+
[](https://rubydoc.info/gems/intacct)
|
|
5
|
+
[](https://github.com/dpaluy/intacct/actions)
|
|
4
6
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
TBD
|
|
7
|
+
A Ruby gem for interacting with the [Sage Intacct API](https://developer.intacct.com/api/).
|
|
8
8
|
|
|
9
9
|
## Installation
|
|
10
10
|
|
|
11
11
|
Add this line to your application's Gemfile:
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
```ruby
|
|
14
|
+
gem "intacct"
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
**Requirements:** Ruby 3.2 or higher.
|
|
14
18
|
|
|
15
19
|
## Usage
|
|
16
20
|
|
|
17
|
-
|
|
21
|
+
### Configuration
|
|
22
|
+
|
|
23
|
+
Configure the gem with your Intacct credentials:
|
|
24
|
+
|
|
25
|
+
```ruby
|
|
18
26
|
Intacct.configure do |config|
|
|
19
|
-
config.sender_id =
|
|
20
|
-
config.sender_password =
|
|
27
|
+
config.sender_id = ENV["INTACCT_SENDER_ID"]
|
|
28
|
+
config.sender_password = ENV["INTACCT_SENDER_PASSWORD"]
|
|
29
|
+
end
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
**Security Note:** Never commit credentials to version control. Use environment variables or a secrets management system.
|
|
33
|
+
|
|
34
|
+
### Making Requests
|
|
35
|
+
|
|
36
|
+
#### Query Records
|
|
37
|
+
|
|
38
|
+
Query Intacct objects with filters and sorting:
|
|
39
|
+
|
|
40
|
+
```ruby
|
|
41
|
+
query = Intacct::Functions::Query.new(
|
|
42
|
+
object: "CUSTOMER",
|
|
43
|
+
select: ["CUSTOMERID", "NAME", "EMAIL", "STATUS"],
|
|
44
|
+
filter: { "STATUS" => "active" },
|
|
45
|
+
order: { "NAME" => "asc" }
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
request = Intacct::Request.new
|
|
49
|
+
request.use_credentials_authentication(
|
|
50
|
+
user_id: ENV["INTACCT_USER_ID"],
|
|
51
|
+
company_id: ENV["INTACCT_COMPANY_ID"],
|
|
52
|
+
user_password: ENV["INTACCT_USER_PASSWORD"]
|
|
53
|
+
)
|
|
54
|
+
request.add_function(query, "query-001")
|
|
55
|
+
|
|
56
|
+
response = Intacct::Gateway.new.send_request(request)
|
|
57
|
+
|
|
58
|
+
if response.successful?
|
|
59
|
+
result = response.get_function_result("query-001")
|
|
60
|
+
if result.successful?
|
|
61
|
+
customers = result.data
|
|
62
|
+
customers.each do |customer|
|
|
63
|
+
puts "#{customer['CUSTOMERID']}: #{customer['NAME']}"
|
|
64
|
+
end
|
|
65
|
+
else
|
|
66
|
+
puts "Function error: #{result.errors.join(', ')}"
|
|
67
|
+
end
|
|
68
|
+
else
|
|
69
|
+
puts "Request failed"
|
|
21
70
|
end
|
|
22
71
|
```
|
|
23
72
|
|
|
24
|
-
|
|
73
|
+
#### Create Records
|
|
74
|
+
|
|
75
|
+
Create new records in Intacct:
|
|
76
|
+
|
|
77
|
+
```ruby
|
|
78
|
+
create = Intacct::Functions::Create.new(
|
|
79
|
+
object: "CUSTOMER",
|
|
80
|
+
fields: {
|
|
81
|
+
"CUSTOMERID" => "C-001",
|
|
82
|
+
"NAME" => "Acme Corporation",
|
|
83
|
+
"EMAIL" => "contact@acme.com",
|
|
84
|
+
"STATUS" => "active"
|
|
85
|
+
}
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
request = Intacct::Request.new
|
|
89
|
+
request.use_credentials_authentication(
|
|
90
|
+
user_id: ENV["INTACCT_USER_ID"],
|
|
91
|
+
company_id: ENV["INTACCT_COMPANY_ID"],
|
|
92
|
+
user_password: ENV["INTACCT_USER_PASSWORD"]
|
|
93
|
+
)
|
|
94
|
+
request.add_function(create, "create-001")
|
|
95
|
+
|
|
96
|
+
response = Intacct::Gateway.new.send_request(request)
|
|
97
|
+
|
|
98
|
+
if response.successful?
|
|
99
|
+
result = response.get_function_result("create-001")
|
|
100
|
+
puts "Customer created!" if result.successful?
|
|
101
|
+
end
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
#### Update Records
|
|
105
|
+
|
|
106
|
+
Update existing records:
|
|
107
|
+
|
|
108
|
+
```ruby
|
|
109
|
+
update = Intacct::Functions::Update.new(
|
|
110
|
+
object: "CUSTOMER",
|
|
111
|
+
keys: { "CUSTOMERID" => "C-001" },
|
|
112
|
+
fields: {
|
|
113
|
+
"EMAIL" => "newemail@acme.com",
|
|
114
|
+
"STATUS" => "inactive"
|
|
115
|
+
}
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
request = Intacct::Request.new
|
|
119
|
+
request.use_credentials_authentication(
|
|
120
|
+
user_id: ENV["INTACCT_USER_ID"],
|
|
121
|
+
company_id: ENV["INTACCT_COMPANY_ID"],
|
|
122
|
+
user_password: ENV["INTACCT_USER_PASSWORD"]
|
|
123
|
+
)
|
|
124
|
+
request.add_function(update, "update-001")
|
|
125
|
+
|
|
126
|
+
response = Intacct::Gateway.new.send_request(request)
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
#### Read by ID
|
|
130
|
+
|
|
131
|
+
Read a specific record by ID:
|
|
132
|
+
|
|
133
|
+
```ruby
|
|
134
|
+
read = Intacct::Functions::Read.new(
|
|
135
|
+
object: "CUSTOMER",
|
|
136
|
+
keys: "C-001",
|
|
137
|
+
fields: ["CUSTOMERID", "NAME", "EMAIL"]
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
request = Intacct::Request.new
|
|
141
|
+
request.use_credentials_authentication(
|
|
142
|
+
user_id: ENV["INTACCT_USER_ID"],
|
|
143
|
+
company_id: ENV["INTACCT_COMPANY_ID"],
|
|
144
|
+
user_password: ENV["INTACCT_USER_PASSWORD"]
|
|
145
|
+
)
|
|
146
|
+
request.add_function(read, "read-001")
|
|
147
|
+
|
|
148
|
+
response = Intacct::Gateway.new.send_request(request)
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
#### Case-Insensitive Queries
|
|
152
|
+
|
|
153
|
+
Perform case-insensitive queries:
|
|
154
|
+
|
|
155
|
+
```ruby
|
|
156
|
+
query = Intacct::Functions::Query.new(
|
|
157
|
+
object: "CUSTOMER",
|
|
158
|
+
select: ["CUSTOMERID", "NAME"],
|
|
159
|
+
filter: { "NAME" => "acme" },
|
|
160
|
+
case_insensitive: true
|
|
161
|
+
)
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### Error Handling
|
|
165
|
+
|
|
166
|
+
Always check response status and handle errors:
|
|
167
|
+
|
|
168
|
+
```ruby
|
|
169
|
+
response = Intacct::Gateway.new.send_request(request)
|
|
170
|
+
|
|
171
|
+
if response.successful?
|
|
172
|
+
result = response.get_function_result("my-control-id")
|
|
173
|
+
if result.successful?
|
|
174
|
+
puts "Success: #{result.data}"
|
|
175
|
+
else
|
|
176
|
+
puts "Function error: #{result.errors.join(', ')}"
|
|
177
|
+
end
|
|
178
|
+
else
|
|
179
|
+
puts "Request failed"
|
|
180
|
+
end
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
### Session Authentication
|
|
184
|
+
|
|
185
|
+
Get an API session for subsequent requests:
|
|
186
|
+
|
|
187
|
+
```ruby
|
|
188
|
+
get_session = Intacct::Functions::GetApiSession.new(location_id: "US")
|
|
189
|
+
|
|
190
|
+
request = Intacct::Request.new
|
|
191
|
+
request.use_credentials_authentication(
|
|
192
|
+
user_id: ENV["INTACCT_USER_ID"],
|
|
193
|
+
company_id: ENV["INTACCT_COMPANY_ID"],
|
|
194
|
+
user_password: ENV["INTACCT_USER_PASSWORD"]
|
|
195
|
+
)
|
|
196
|
+
request.add_function(get_session, "session-001")
|
|
197
|
+
|
|
198
|
+
response = Intacct::Gateway.new.send_request(request)
|
|
199
|
+
|
|
200
|
+
if response.successful?
|
|
201
|
+
result = response.get_function_result("session-001")
|
|
202
|
+
if result.successful?
|
|
203
|
+
session_id = result.data["sessionid"]
|
|
204
|
+
# Use session_id for subsequent requests
|
|
205
|
+
end
|
|
206
|
+
end
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
## Available Functions
|
|
210
|
+
|
|
211
|
+
- **Query** - Execute read queries with filters and sorting
|
|
212
|
+
- **Create** - Create new records
|
|
213
|
+
- **Read** - Read specific records by ID
|
|
214
|
+
- **Update** - Update existing records
|
|
215
|
+
- **CreateArAdjustment** - Create AR adjustments
|
|
216
|
+
- **GetApiSession** - Get API session for authentication
|
|
217
|
+
- **RetrievePdf** - Retrieve PDF documents
|
|
218
|
+
- **ReversePayment** - Reverse payments
|
|
219
|
+
|
|
220
|
+
For detailed API documentation, see [RubyDoc](https://rubydoc.info/gems/intacct).
|
|
221
|
+
|
|
222
|
+
## Development
|
|
223
|
+
|
|
224
|
+
After checking out the repo, run:
|
|
225
|
+
|
|
226
|
+
```bash
|
|
227
|
+
bundle install
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
Run tests:
|
|
231
|
+
|
|
232
|
+
```bash
|
|
233
|
+
bundle exec rake test
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
Run linter:
|
|
237
|
+
|
|
238
|
+
```bash
|
|
239
|
+
bundle exec rubocop
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
Generate documentation:
|
|
243
|
+
|
|
244
|
+
```bash
|
|
245
|
+
bundle exec yard doc
|
|
246
|
+
bundle exec yard server # View docs at http://localhost:8808
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
To install this gem onto your local machine:
|
|
250
|
+
|
|
251
|
+
```bash
|
|
252
|
+
bundle exec rake install
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
To release a new version:
|
|
256
|
+
|
|
257
|
+
1. Update version in `lib/intacct/version.rb`
|
|
258
|
+
2. Update `CHANGELOG.md`
|
|
259
|
+
3. Commit changes
|
|
260
|
+
4. Run `bundle exec rake release` (creates tag and pushes to RubyGems)
|
|
261
|
+
|
|
262
|
+
## Contributing
|
|
263
|
+
|
|
264
|
+
1. Fork it (https://github.com/dpaluy/intacct/fork)
|
|
265
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
|
266
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
|
267
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
|
268
|
+
5. Create a new Pull Request
|
|
269
|
+
|
|
270
|
+
Please ensure:
|
|
271
|
+
- Tests pass (`bundle exec rake test`)
|
|
272
|
+
- Code follows style guide (`bundle exec rubocop`)
|
|
273
|
+
- New features include tests and documentation
|
|
25
274
|
|
|
26
|
-
##
|
|
275
|
+
## License
|
|
27
276
|
|
|
28
|
-
|
|
29
|
-
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
|
|
30
|
-
* Fork the project.
|
|
31
|
-
* Start a feature/bugfix branch.
|
|
32
|
-
* Commit and push until you are happy with your contribution.
|
|
33
|
-
* Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
|
|
34
|
-
* Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
|
|
277
|
+
The gem is available as open source under the terms of the [MIT License](LICENSE.txt).
|
|
35
278
|
|
|
36
279
|
## Copyright
|
|
37
280
|
|
|
38
|
-
Copyright (c) 2022 David Paluy. See LICENSE.txt for
|
|
39
|
-
further details.
|
|
281
|
+
Copyright (c) 2022-2025 David Paluy. See LICENSE.txt for further details.
|
data/Rakefile
CHANGED
|
@@ -1,57 +1,21 @@
|
|
|
1
|
-
#
|
|
1
|
+
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
4
|
-
require
|
|
5
|
-
begin
|
|
6
|
-
Bundler.setup(:default, :development)
|
|
7
|
-
rescue Bundler::BundlerError => e
|
|
8
|
-
$stderr.puts e.message
|
|
9
|
-
$stderr.puts "Run `bundle install` to install missing gems"
|
|
10
|
-
exit e.status_code
|
|
11
|
-
end
|
|
12
|
-
require 'rake'
|
|
13
|
-
require 'juwelier'
|
|
14
|
-
Juwelier::Tasks.new do |gem|
|
|
15
|
-
# gem is a Gem::Specification... see http://guides.rubygems.org/specification-reference/ for more options
|
|
16
|
-
gem.name = "intacct"
|
|
17
|
-
gem.homepage = "http://github.com/dpaluy/intacct"
|
|
18
|
-
gem.license = "MIT"
|
|
19
|
-
gem.summary = %Q{Sage Intacct API wrapper}
|
|
20
|
-
gem.description = %Q{Sage Intacct API wrapper}
|
|
21
|
-
gem.email = "dpaluy@users.noreply.github.com"
|
|
22
|
-
gem.authors = ["David Paluy", "Yaroslav Konovets"]
|
|
3
|
+
require "bundler/gem_tasks"
|
|
4
|
+
require "minitest/test_task"
|
|
23
5
|
|
|
24
|
-
|
|
25
|
-
end
|
|
26
|
-
Juwelier::RubygemsDotOrgTasks.new
|
|
27
|
-
|
|
28
|
-
require 'rake/testtask'
|
|
29
|
-
Rake::TestTask.new(:test) do |test|
|
|
30
|
-
test.libs << 'lib' << 'test'
|
|
31
|
-
test.pattern = 'test/**/test_*.rb'
|
|
32
|
-
test.verbose = true
|
|
33
|
-
end
|
|
6
|
+
Minitest::TestTask.create
|
|
34
7
|
|
|
35
|
-
require
|
|
36
|
-
|
|
37
|
-
RSpec::Core::RakeTask.new(:spec) do |spec|
|
|
38
|
-
spec.pattern = FileList['spec/**/*_spec.rb']
|
|
39
|
-
end
|
|
8
|
+
require "rubocop/rake_task"
|
|
9
|
+
RuboCop::RakeTask.new
|
|
40
10
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
11
|
+
begin
|
|
12
|
+
require "yard"
|
|
13
|
+
YARD::Rake::YardocTask.new do |t|
|
|
14
|
+
t.files = ["lib/**/*.rb"]
|
|
15
|
+
t.options = ["--markup", "markdown", "--no-private"]
|
|
16
|
+
end
|
|
17
|
+
rescue LoadError
|
|
18
|
+
# YARD not available
|
|
45
19
|
end
|
|
46
20
|
|
|
47
|
-
task default:
|
|
48
|
-
|
|
49
|
-
require 'rdoc/task'
|
|
50
|
-
Rake::RDocTask.new do |rdoc|
|
|
51
|
-
version = File.exist?('VERSION') ? File.read('VERSION') : ''
|
|
52
|
-
|
|
53
|
-
rdoc.rdoc_dir = 'rdoc'
|
|
54
|
-
rdoc.title = "intacct #{version}"
|
|
55
|
-
rdoc.rdoc_files.include('README*')
|
|
56
|
-
rdoc.rdoc_files.include('lib/**/*.rb')
|
|
57
|
-
end
|
|
21
|
+
task default: %i[test rubocop]
|
|
@@ -1,14 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Intacct
|
|
2
4
|
class AuthenticationResult
|
|
3
5
|
attr_reader :status, :xml_data
|
|
4
6
|
|
|
5
7
|
def initialize(xml_entry)
|
|
6
|
-
@status = xml_entry.xpath(
|
|
8
|
+
@status = xml_entry.xpath("status").text
|
|
7
9
|
@xml_data = xml_entry
|
|
8
10
|
end
|
|
9
11
|
|
|
10
12
|
def successful?
|
|
11
|
-
@status ==
|
|
13
|
+
@status == "success"
|
|
12
14
|
end
|
|
13
15
|
|
|
14
16
|
def parsed_data
|
data/lib/intacct/config.rb
CHANGED
|
@@ -1,20 +1,30 @@
|
|
|
1
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "logger"
|
|
2
4
|
|
|
3
5
|
module Intacct
|
|
6
|
+
# Configuration object for Intacct API credentials and settings.
|
|
7
|
+
#
|
|
8
|
+
# @attr sender_id [String] Intacct Web Services sender ID
|
|
9
|
+
# @attr sender_password [String] Intacct Web Services sender password
|
|
10
|
+
# @attr url [String] Custom API endpoint URL (optional)
|
|
11
|
+
# @attr raise_exceptions [Boolean] Whether to raise exceptions on API errors (default: true)
|
|
12
|
+
# @attr logger [Logger] Logger instance for debugging (default: ERROR level stdout logger)
|
|
13
|
+
#
|
|
14
|
+
# @example Basic configuration
|
|
15
|
+
# config = Intacct::Config.new
|
|
16
|
+
# config.sender_id = "my-sender-id"
|
|
17
|
+
# config.sender_password = "my-sender-password"
|
|
18
|
+
# config.raise_exceptions = false
|
|
4
19
|
class Config
|
|
5
20
|
attr_accessor :sender_id, :sender_password, :url, :raise_exceptions, :logger
|
|
6
21
|
|
|
22
|
+
# Initialize a new configuration with default logger and exception handling
|
|
23
|
+
#
|
|
24
|
+
# @return [Config] a new configuration instance
|
|
7
25
|
def initialize
|
|
8
26
|
@logger = Logger.new($stdout, level: Logger::Severity::ERROR)
|
|
9
27
|
@raise_exceptions = true
|
|
10
28
|
end
|
|
11
29
|
end
|
|
12
|
-
|
|
13
|
-
def self.configure
|
|
14
|
-
yield config
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
def self.config
|
|
18
|
-
@config ||= Config.new
|
|
19
|
-
end
|
|
20
30
|
end
|
|
@@ -1,20 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Intacct
|
|
2
4
|
class FunctionResult
|
|
3
5
|
attr_reader :status, :control_id, :xml_data
|
|
4
6
|
|
|
5
7
|
def initialize(xml_entry)
|
|
6
|
-
@status = xml_entry.xpath(
|
|
7
|
-
@control_id = xml_entry.xpath(
|
|
8
|
+
@status = xml_entry.xpath("status").text
|
|
9
|
+
@control_id = xml_entry.xpath("controlid").text
|
|
8
10
|
@xml_data = xml_entry
|
|
9
11
|
end
|
|
10
12
|
|
|
11
13
|
def successful?
|
|
12
|
-
@status ==
|
|
14
|
+
@status == "success"
|
|
13
15
|
end
|
|
14
16
|
|
|
15
17
|
def parsed_data
|
|
16
18
|
hash = Crack::XML.parse(@xml_data.to_s).with_indifferent_access
|
|
17
|
-
successful? ? hash.fetch(
|
|
19
|
+
successful? ? hash.fetch("result") : hash
|
|
18
20
|
end
|
|
19
21
|
|
|
20
22
|
def push_error_messages
|
|
@@ -23,7 +25,7 @@ module Intacct
|
|
|
23
25
|
error_details = [error_details] unless error_details.is_a?(Array)
|
|
24
26
|
|
|
25
27
|
error_details.compact.map do |error_data|
|
|
26
|
-
[error_data[:description2], error_data[:correction]].compact.join(
|
|
28
|
+
[error_data[:description2], error_data[:correction]].compact.join(" ")
|
|
27
29
|
end
|
|
28
30
|
end
|
|
29
31
|
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Intacct
|
|
2
4
|
module Functions
|
|
3
5
|
class Query
|
|
@@ -57,9 +59,9 @@ module Intacct
|
|
|
57
59
|
def to_direction(direction)
|
|
58
60
|
case direction
|
|
59
61
|
when :asc
|
|
60
|
-
|
|
62
|
+
"ascending"
|
|
61
63
|
when :desc
|
|
62
|
-
|
|
64
|
+
"descending"
|
|
63
65
|
else
|
|
64
66
|
raise ArgumentError, "Invalid direction: #{direction}"
|
|
65
67
|
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Intacct
|
|
2
4
|
module Functions
|
|
3
5
|
class Read
|
|
@@ -14,8 +16,8 @@ module Intacct
|
|
|
14
16
|
builder = Builder::XmlMarkup.new
|
|
15
17
|
builder.read do
|
|
16
18
|
builder.object @object
|
|
17
|
-
builder.keys keys.join(
|
|
18
|
-
fields_value = @fields.any? ? @fields.join(
|
|
19
|
+
builder.keys keys.join(",")
|
|
20
|
+
fields_value = @fields.any? ? @fields.join(",") : "*"
|
|
19
21
|
builder.fields fields_value
|
|
20
22
|
args.each do |key, value|
|
|
21
23
|
builder.tag!(key, value)
|
data/lib/intacct/gateway.rb
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "intacct/response"
|
|
2
4
|
|
|
3
5
|
module Intacct
|
|
4
6
|
class Gateway
|
|
5
|
-
URI_STRING =
|
|
7
|
+
URI_STRING = "https://api.intacct.com/ia/xml/xmlgw.phtml"
|
|
6
8
|
|
|
7
9
|
def initialize(control_config)
|
|
8
10
|
@control_config = control_config
|
|
@@ -12,7 +14,7 @@ module Intacct
|
|
|
12
14
|
|
|
13
15
|
def execute_request(api_request)
|
|
14
16
|
post_request ||= Net::HTTP::Post.new(uri.request_uri)
|
|
15
|
-
post_request[
|
|
17
|
+
post_request["Content-Type"] = "x-intacct-xml-request"
|
|
16
18
|
post_request.body = api_request.to_xml(@control_config)
|
|
17
19
|
Intacct.logger.debug("Request Body: #{post_request.body}")
|
|
18
20
|
http_response = @http_gateway.request(post_request)
|
data/lib/intacct/request.rb
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
require
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "builder"
|
|
4
|
+
require "intacct/authentication_methods/credentials"
|
|
5
|
+
require "intacct/authentication_methods/session"
|
|
4
6
|
|
|
5
7
|
module Intacct
|
|
6
8
|
class Request
|