intacct 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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 577eb2b6dd021730af938235fd3093b00542c7d469e269099ec4c9b722ce6fdc
4
+ data.tar.gz: aa8dd3866340623ad87fb5f4f8b32294d82417dd5e4f406bec8c46f6e0bb3a0b
5
+ SHA512:
6
+ metadata.gz: b478a96bbebf5d2303ad7106dbcbb3d1ea456bad832c1cc34aced9237c1b006c670140676f717aec183916a3bbb1b55a258d8befbdf3f6e86f4c8338faf66522
7
+ data.tar.gz: a7e14e8edcb6cef4f8ff8bf0d5b4afac4c8aa5ed66182a91bac6857ffa2e23b64df10c15a83eabf459b2b7c7067e5ce336972bf674de6760e575fb6e1946c202
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/.rubocop.yml ADDED
@@ -0,0 +1,19 @@
1
+ AllCops:
2
+ NewCops: enable
3
+ SuggestExtensions: false
4
+ Exclude:
5
+ - '*.gemspec'
6
+ - 'Rakefile'
7
+ - 'spec/spec_helper.rb'
8
+
9
+ Metrics/MethodLength:
10
+ Max: 20
11
+
12
+ Style/Documentation:
13
+ Enabled: false
14
+
15
+ Style/StringConcatenation:
16
+ Enabled: false
17
+
18
+ Style/FrozenStringLiteralComment:
19
+ Enabled: false
data/.travis.yml ADDED
@@ -0,0 +1,8 @@
1
+
2
+ language: ruby
3
+ rvm:
4
+ - 3.1.1
5
+ - 3.0.0
6
+ - 2.2.3
7
+
8
+ script: bundle exec rspec spec
data/Gemfile ADDED
@@ -0,0 +1,20 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'faraday', '~> 1.10.0'
4
+ gem 'json', '~> 2.7'
5
+
6
+ group :development do
7
+ gem 'bundler'
8
+ gem 'juwelier', '~> 2.4.9'
9
+ gem 'pry-byebug'
10
+ gem 'rdoc', '~> 6.0'
11
+ gem 'rspec', '~> 3.11.0'
12
+ gem 'shoulda', '~> 4.0.0'
13
+ gem 'simplecov', '>= 0.21.0'
14
+ gem 'timecop', '~> 0.9.0'
15
+ gem 'webmock', '~> 3.18.0'
16
+
17
+ gem 'codeclimate-test-reporter', require: false
18
+ gem 'coveralls', require: false
19
+ gem 'rubocop', require: false
20
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2022 David Paluy
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,39 @@
1
+ # Intacct Sage Ruby wrapper
2
+
3
+ This is Ruby wrapper to [Intacct Sage API](https://developer.intacct.com/api/)
4
+
5
+ ## Status
6
+
7
+ TBD
8
+
9
+ ## Installation
10
+
11
+ Add this line to your application's Gemfile:
12
+
13
+ `gem 'intacct'`
14
+
15
+ ## Usage
16
+
17
+ ```
18
+ Intacct.configure do |config|
19
+ config.sender_id = 'SENDER-ID-FROM-SAGE'
20
+ config.sender_password = 'SENDER-PASSWORD-FROM-SAGE'
21
+ end
22
+ ```
23
+
24
+ TBD
25
+
26
+ ## Contributing to intacct gem
27
+
28
+ * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
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.
35
+
36
+ ## Copyright
37
+
38
+ Copyright (c) 2022 David Paluy. See LICENSE.txt for
39
+ further details.
data/Rakefile ADDED
@@ -0,0 +1,57 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'bundler'
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"]
23
+
24
+ # dependencies defined in Gemfile
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
34
+
35
+ require 'rspec/core'
36
+ require 'rspec/core/rake_task'
37
+ RSpec::Core::RakeTask.new(:spec) do |spec|
38
+ spec.pattern = FileList['spec/**/*_spec.rb']
39
+ end
40
+
41
+ desc 'Code coverage detail'
42
+ task :simplecov do
43
+ ENV['COVERAGE'] = 'true'
44
+ Rake::Task['spec'].execute
45
+ end
46
+
47
+ task default: :spec
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
data/intacct.gemspec ADDED
@@ -0,0 +1,79 @@
1
+ # Generated by juwelier
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Juwelier::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+ # stub: intacct 0 ruby lib
6
+
7
+ Gem::Specification.new do |s|
8
+ s.name = "intacct".freeze
9
+ s.version = "0".freeze
10
+
11
+ s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
12
+ s.require_paths = ["lib".freeze]
13
+ s.authors = ["David Paluy".freeze, "Yaroslav Konovets".freeze]
14
+ s.date = "1980-01-02"
15
+ s.description = "Sage Intacct API wrapper".freeze
16
+ s.email = "dpaluy@users.noreply.github.com".freeze
17
+ s.extra_rdoc_files = [
18
+ "LICENSE.txt",
19
+ "README.md"
20
+ ]
21
+ s.files = [
22
+ ".document",
23
+ ".rspec",
24
+ ".rubocop.yml",
25
+ ".travis.yml",
26
+ "Gemfile",
27
+ "LICENSE.txt",
28
+ "README.md",
29
+ "Rakefile",
30
+ "intacct.gemspec",
31
+ "lib/intacct.rb",
32
+ "lib/intacct/authentication_methods/credentials.rb",
33
+ "lib/intacct/authentication_methods/session.rb",
34
+ "lib/intacct/authentication_result.rb",
35
+ "lib/intacct/config.rb",
36
+ "lib/intacct/exceptions/client_exception.rb",
37
+ "lib/intacct/exceptions/function_failure_exception.rb",
38
+ "lib/intacct/exceptions/missing_authentication_exception.rb",
39
+ "lib/intacct/function_result.rb",
40
+ "lib/intacct/functions/create.rb",
41
+ "lib/intacct/functions/create_ar_adjustment.rb",
42
+ "lib/intacct/functions/get_api_session.rb",
43
+ "lib/intacct/functions/query.rb",
44
+ "lib/intacct/functions/read.rb",
45
+ "lib/intacct/functions/retrieve_pdf.rb",
46
+ "lib/intacct/functions/reverse_payment.rb",
47
+ "lib/intacct/functions/update.rb",
48
+ "lib/intacct/gateway.rb",
49
+ "lib/intacct/request.rb",
50
+ "lib/intacct/response.rb",
51
+ "lib/intacct/utils.rb",
52
+ "lib/intacct/version.rb",
53
+ "spec/intacct/client_spec.rb",
54
+ "spec/intacct_spec.rb",
55
+ "spec/spec_helper.rb"
56
+ ]
57
+ s.homepage = "http://github.com/dpaluy/intacct".freeze
58
+ s.licenses = ["MIT".freeze]
59
+ s.rubygems_version = "3.7.2".freeze
60
+ s.summary = "Sage Intacct API wrapper".freeze
61
+
62
+ s.specification_version = 4
63
+
64
+ s.add_runtime_dependency(%q<faraday>.freeze, ["~> 1.10.0".freeze])
65
+ s.add_runtime_dependency(%q<json>.freeze, ["~> 2.7".freeze])
66
+ s.add_development_dependency(%q<bundler>.freeze, [">= 0".freeze])
67
+ s.add_development_dependency(%q<juwelier>.freeze, ["~> 2.4.9".freeze])
68
+ s.add_development_dependency(%q<pry-byebug>.freeze, [">= 0".freeze])
69
+ s.add_development_dependency(%q<rdoc>.freeze, ["~> 6.0".freeze])
70
+ s.add_development_dependency(%q<rspec>.freeze, ["~> 3.11.0".freeze])
71
+ s.add_development_dependency(%q<shoulda>.freeze, ["~> 4.0.0".freeze])
72
+ s.add_development_dependency(%q<simplecov>.freeze, [">= 0.21.0".freeze])
73
+ s.add_development_dependency(%q<timecop>.freeze, ["~> 0.9.0".freeze])
74
+ s.add_development_dependency(%q<webmock>.freeze, ["~> 3.18.0".freeze])
75
+ s.add_development_dependency(%q<codeclimate-test-reporter>.freeze, [">= 0".freeze])
76
+ s.add_development_dependency(%q<coveralls>.freeze, [">= 0".freeze])
77
+ s.add_development_dependency(%q<rubocop>.freeze, [">= 0".freeze])
78
+ end
79
+
@@ -0,0 +1,23 @@
1
+ require 'builder'
2
+
3
+ module Intacct
4
+ module AuthenticationMethods
5
+ class Credentials
6
+ def initialize(user_id:, company_id:, password:)
7
+ @user_id = user_id
8
+ @company_id = company_id
9
+ @password = password
10
+ end
11
+
12
+ def to_xml
13
+ builder = Builder::XmlMarkup.new
14
+
15
+ builder.login do
16
+ builder.userid @user_id
17
+ builder.companyid @company_id
18
+ builder.password @password
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,17 @@
1
+ require 'builder'
2
+
3
+ module Intacct
4
+ module AuthenticationMethods
5
+ class Session
6
+ def initialize(session_token)
7
+ @session_token = session_token
8
+ end
9
+
10
+ def to_xml
11
+ builder = Builder::XmlMarkup.new
12
+
13
+ builder.sessionid @session_token
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,18 @@
1
+ module Intacct
2
+ class AuthenticationResult
3
+ attr_reader :status, :xml_data
4
+
5
+ def initialize(xml_entry)
6
+ @status = xml_entry.xpath('status').text
7
+ @xml_data = xml_entry
8
+ end
9
+
10
+ def successful?
11
+ @status == 'success'
12
+ end
13
+
14
+ def parsed_data
15
+ Crack::XML.parse(@xml_data.to_s)
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,20 @@
1
+ require 'logger'
2
+
3
+ module Intacct
4
+ class Config
5
+ attr_accessor :sender_id, :sender_password, :url, :raise_exceptions, :logger
6
+
7
+ def initialize
8
+ @logger = Logger.new($stdout, level: Logger::Severity::ERROR)
9
+ @raise_exceptions = true
10
+ end
11
+ end
12
+
13
+ def self.configure
14
+ yield config
15
+ end
16
+
17
+ def self.config
18
+ @config ||= Config.new
19
+ end
20
+ end
@@ -0,0 +1,5 @@
1
+ module Intacct
2
+ module Exceptions
3
+ class ClientException < StandardError; end
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ module Intacct
2
+ module Exceptions
3
+ class FunctionFailureException < StandardError; end
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ module Intacct
2
+ module Exceptions
3
+ class MissingAuthenticationException < StandardError; end
4
+ end
5
+ end
@@ -0,0 +1,30 @@
1
+ module Intacct
2
+ class FunctionResult
3
+ attr_reader :status, :control_id, :xml_data
4
+
5
+ def initialize(xml_entry)
6
+ @status = xml_entry.xpath('status').text
7
+ @control_id = xml_entry.xpath('controlid').text
8
+ @xml_data = xml_entry
9
+ end
10
+
11
+ def successful?
12
+ @status == 'success'
13
+ end
14
+
15
+ def parsed_data
16
+ hash = Crack::XML.parse(@xml_data.to_s).with_indifferent_access
17
+ successful? ? hash.fetch('result') : hash
18
+ end
19
+
20
+ def push_error_messages
21
+ error_details = parsed_data.dig(:result, :errormessage, :error)
22
+
23
+ error_details = [error_details] unless error_details.is_a?(Array)
24
+
25
+ error_details.compact.map do |error_data|
26
+ [error_data[:description2], error_data[:correction]].compact.join(' ')
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,20 @@
1
+ module Intacct
2
+ module Functions
3
+ class Create
4
+ def initialize(record_type, &block)
5
+ @record_type = record_type
6
+ @block = block
7
+ end
8
+
9
+ def to_xml
10
+ builder = Builder::XmlMarkup.new
11
+
12
+ builder.create do
13
+ builder.tag!(@record_type) do
14
+ @block.call(builder)
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,17 @@
1
+ module Intacct
2
+ module Functions
3
+ class CreateArAdjustment
4
+ def initialize(&block)
5
+ @block = block
6
+ end
7
+
8
+ def to_xml
9
+ builder = Builder::XmlMarkup.new
10
+
11
+ builder.create_aradjustment do
12
+ @block.call(builder)
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,21 @@
1
+ module Intacct
2
+ module Functions
3
+ class GetApiSession
4
+ def initialize(location_id: nil)
5
+ @location_id = location_id
6
+ end
7
+
8
+ def to_xml
9
+ builder = Builder::XmlMarkup.new
10
+
11
+ if @location_id.present?
12
+ builder.getAPISession do
13
+ builder.locationid @location_id
14
+ end
15
+ else
16
+ builder.getAPISession
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,69 @@
1
+ module Intacct
2
+ module Functions
3
+ class Query
4
+ def initialize(object, fields:, order: {}, case_insensitive: true, **args)
5
+ @object = object
6
+ @fields = fields
7
+ @order = order
8
+ @case_insensitive = case_insensitive
9
+ @args = args
10
+ end
11
+
12
+ def add_filter(&block)
13
+ @filter_block = block
14
+ end
15
+
16
+ def to_xml
17
+ builder = Builder::XmlMarkup.new
18
+ builder.query do
19
+ builder.object @object
20
+ if @fields.any?
21
+ builder.select do
22
+ @fields.each do |field|
23
+ builder.field field
24
+ end
25
+ end
26
+ end
27
+
28
+ if @filter_block.present?
29
+ builder.filter do
30
+ @filter_block.call(builder)
31
+ end
32
+ end
33
+
34
+ @args.each do |key, value|
35
+ builder.tag!(key, value)
36
+ end
37
+
38
+ if @order.present?
39
+ builder.orderby do
40
+ @order.each do |attribute, direction|
41
+ builder.order do
42
+ builder.field attribute
43
+ builder.tag!(to_direction(direction))
44
+ end
45
+ end
46
+ end
47
+ end
48
+
49
+ builder.options do
50
+ builder.caseinsensitive(@case_insensitive)
51
+ end
52
+ end
53
+ end
54
+
55
+ private
56
+
57
+ def to_direction(direction)
58
+ case direction
59
+ when :asc
60
+ 'ascending'
61
+ when :desc
62
+ 'descending'
63
+ else
64
+ raise ArgumentError, "Invalid direction: #{direction}"
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,27 @@
1
+ module Intacct
2
+ module Functions
3
+ class Read
4
+ attr_reader :object, :keys, :fields, :args
5
+
6
+ def initialize(object, keys:, fields:, **args)
7
+ @object = object
8
+ @keys = keys
9
+ @fields = fields
10
+ @args = args
11
+ end
12
+
13
+ def to_xml
14
+ builder = Builder::XmlMarkup.new
15
+ builder.read do
16
+ builder.object @object
17
+ builder.keys keys.join(',')
18
+ fields_value = @fields.any? ? @fields.join(',') : '*'
19
+ builder.fields fields_value
20
+ args.each do |key, value|
21
+ builder.tag!(key, value)
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,16 @@
1
+ module Intacct
2
+ module Functions
3
+ class RetrievePdf
4
+ def build_query(&block)
5
+ @query_block = block
6
+ end
7
+
8
+ def to_xml
9
+ builder = Builder::XmlMarkup.new
10
+ builder.retrievepdf do
11
+ @query_block.call(builder) if @query_block.present?
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,17 @@
1
+ module Intacct
2
+ module Functions
3
+ class ReversePayment
4
+ def initialize(key, &block)
5
+ @key = key
6
+ @block = block
7
+ end
8
+
9
+ def to_xml
10
+ builder = Builder::XmlMarkup.new
11
+ builder.reverse_arpayment(key: @key) do
12
+ @block.call(builder)
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,21 @@
1
+ module Intacct
2
+ module Functions
3
+ class Update
4
+ def initialize(record_type, &block)
5
+ @record_type = record_type
6
+ @block = block
7
+ end
8
+
9
+ def to_xml
10
+ builder = Builder::XmlMarkup.new
11
+
12
+ builder.update do
13
+ builder.tag!(@record_type) do
14
+ @block.call(builder)
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+
@@ -0,0 +1,30 @@
1
+ require 'intacct/response'
2
+
3
+ module Intacct
4
+ class Gateway
5
+ URI_STRING = 'https://api.intacct.com/ia/xml/xmlgw.phtml'.freeze
6
+
7
+ def initialize(control_config)
8
+ @control_config = control_config
9
+ @http_gateway = Net::HTTP.new(uri.host, uri.port)
10
+ @http_gateway.use_ssl = true
11
+ end
12
+
13
+ def execute_request(api_request)
14
+ post_request ||= Net::HTTP::Post.new(uri.request_uri)
15
+ post_request['Content-Type'] = 'x-intacct-xml-request'
16
+ post_request.body = api_request.to_xml(@control_config)
17
+ Intacct.logger.debug("Request Body: #{post_request.body}")
18
+ http_response = @http_gateway.request(post_request)
19
+ Intacct.logger.debug("Response Body: #{http_response.body}")
20
+
21
+ Intacct::Response.new(http_response)
22
+ end
23
+
24
+ private
25
+
26
+ def uri
27
+ @uri ||= URI.parse(URI_STRING)
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,81 @@
1
+ require 'builder'
2
+ require 'intacct/authentication_methods/credentials'
3
+ require 'intacct/authentication_methods/session'
4
+
5
+ module Intacct
6
+ class Request
7
+ def initialize(transaction_operation: false)
8
+ @functions = []
9
+ @authentication = nil
10
+ @transaction_operation = transaction_operation
11
+ end
12
+
13
+ def add_function(function, control_id)
14
+ @functions << { function:, control_id: }
15
+ end
16
+
17
+ def use_credentials_authentication(user_id:, company_id:, user_password:)
18
+ @authentication = Intacct::AuthenticationMethods::Credentials.new(
19
+ user_id:, company_id:, password: user_password
20
+ )
21
+ end
22
+
23
+ def use_session_authentication(session_token)
24
+ @authentication = Intacct::AuthenticationMethods::Session.new(session_token)
25
+ end
26
+
27
+ def to_xml(control_config)
28
+ raise MissingAuthenticationException unless @authentication
29
+
30
+ builder = Builder::XmlMarkup.new
31
+ builder.instruct!
32
+ builder.request do
33
+ add_control_block(builder, control_config)
34
+ add_operation_block(builder)
35
+ end
36
+ end
37
+
38
+ private
39
+
40
+ def add_control_block(builder, config)
41
+ builder.control do
42
+ builder.senderid config.fetch(:sender_id)
43
+ builder.password config.fetch(:sender_password)
44
+
45
+ # As recommended by Intacct API reference. This ID should be unique
46
+ # to the call: it's used to associate a response with a request.
47
+ builder.controlid config.fetch(:controlid, Time.current.to_s)
48
+ builder.uniqueid config.fetch(:uniqueid, false)
49
+ builder.dtdversion config.fetch(:dtdversion, 3.0)
50
+ builder.includewhitespace config.fetch(:includewhitespace, false)
51
+ end
52
+ end
53
+
54
+ def add_operation_block(builder)
55
+ builder.operation transaction: @transaction_operation do
56
+ builder.authentication do
57
+ builder << @authentication.to_xml
58
+ end
59
+
60
+ builder.content do
61
+ @functions.each do |function_entry|
62
+ function_xml = function_entry[:function].to_xml
63
+ builder.function controlid: function_entry[:control_id] do
64
+ builder << function_xml
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
70
+
71
+ def authentication_block(builder)
72
+ builder.authentication do
73
+ builder.login do
74
+ builder.userid opts[:userid]
75
+ builder.companyid opts[:companyid]
76
+ builder.password opts[:user_password]
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,38 @@
1
+ require 'intacct/function_result'
2
+ require 'intacct/authentication_result'
3
+
4
+ module Intacct
5
+ class Response
6
+ attr_reader :response_body
7
+
8
+ def initialize(http_response)
9
+ @response_body = Nokogiri::XML(http_response.body)
10
+
11
+ # raises an error unless the response is in the 2xx range.
12
+ http_response.value
13
+ end
14
+
15
+ def successful?
16
+ @response_body.xpath('//response/control/status').text == 'success'
17
+ end
18
+
19
+ def get_function_result(control_id)
20
+ @function_results ||= build_function_results
21
+ @function_results[control_id.to_s]
22
+ end
23
+
24
+ def get_authentication_result
25
+ Intacct::AuthenticationResult.new(@response_body.xpath('//response/operation/authentication'))
26
+ end
27
+
28
+ private
29
+
30
+ def build_function_results
31
+ @response_body.xpath("//result").map do |xml_entry|
32
+ function_result = Intacct::FunctionResult.new(xml_entry)
33
+
34
+ [function_result.control_id, function_result]
35
+ end.to_h
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,41 @@
1
+ module Intacct
2
+ module Utils
3
+ YEAR_FORMAT = "%Y".freeze
4
+ MONTH_FORMAT = "%m".freeze
5
+ DAY_FORMAT = "%d".freeze
6
+ DATE_FORMAT = "#{MONTH_FORMAT}/#{DAY_FORMAT}/#{YEAR_FORMAT}".freeze
7
+ DATETIME_FORMAT = "#{MONTH_FORMAT}/#{DAY_FORMAT}/#{YEAR_FORMAT} %H:%M:%S".freeze
8
+
9
+ def self.format_date(date)
10
+ date&.strftime(DATE_FORMAT)
11
+ end
12
+
13
+ def self.format_datetime(datetime)
14
+ datetime&.strftime(DATETIME_FORMAT)
15
+ end
16
+
17
+ def self.format_year(date)
18
+ date&.strftime(YEAR_FORMAT)
19
+ end
20
+
21
+ def self.format_month(date)
22
+ date&.strftime(MONTH_FORMAT)
23
+ end
24
+
25
+ def self.format_day(date)
26
+ date&.strftime(DAY_FORMAT)
27
+ end
28
+
29
+ def self.parse_date(date)
30
+ return nil if date.nil?
31
+
32
+ Date.strptime(date, DATE_FORMAT)
33
+ end
34
+
35
+ def self.parse_datetime(datetime)
36
+ return nil if datetime.nil?
37
+
38
+ DateTime.strptime(datetime, DATETIME_FORMAT)
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,3 @@
1
+ module Intacct
2
+ VERSION = "0.0.15"
3
+ end
data/lib/intacct.rb ADDED
@@ -0,0 +1,18 @@
1
+ require_relative 'intacct/utils'
2
+ require_relative 'intacct/config'
3
+ require_relative 'intacct/gateway'
4
+ require_relative 'intacct/request'
5
+ require_relative 'intacct/functions/create'
6
+ require_relative 'intacct/functions/create_ar_adjustment'
7
+ require_relative 'intacct/functions/update'
8
+ require_relative 'intacct/functions/get_api_session'
9
+ require_relative 'intacct/functions/query'
10
+ require_relative 'intacct/functions/read'
11
+ require_relative 'intacct/functions/retrieve_pdf'
12
+ require_relative 'intacct/functions/reverse_payment'
13
+
14
+ module Intacct
15
+ def self.logger
16
+ config.logger
17
+ end
18
+ end
@@ -0,0 +1,5 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ xdescribe 'Intacct::Client' do
4
+ # TODO
5
+ end
@@ -0,0 +1,7 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe 'Intacct' do
4
+ it 'has a version' do
5
+ expect(Intacct::VERSION).not_to be_nil
6
+ end
7
+ end
@@ -0,0 +1,34 @@
1
+ require 'codeclimate-test-reporter'
2
+ require 'simplecov'
3
+ require 'coveralls'
4
+
5
+ require 'webmock/rspec'
6
+
7
+ if ENV['COVERAGE']
8
+ WebMock.disable_net_connect!(allow: 'codeclimate.com')
9
+
10
+ Coveralls.wear!
11
+ SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
12
+ SimpleCov::Formatter::HTMLFormatter,
13
+ Coveralls::SimpleCov::Formatter
14
+ ]
15
+
16
+ # SimpleCov.start
17
+ CodeClimate::TestReporter.start
18
+ end
19
+
20
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
21
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
22
+
23
+ require 'intacct'
24
+ require 'byebug'
25
+ require 'timecop'
26
+ require 'rspec'
27
+
28
+ # Requires supporting files with custom matchers and macros, etc,
29
+ # in ./support/ and its subdirectories.
30
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
31
+
32
+ RSpec.configure do |config|
33
+ config.order = 'random'
34
+ end
metadata ADDED
@@ -0,0 +1,272 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: intacct
3
+ version: !ruby/object:Gem::Version
4
+ version: '0'
5
+ platform: ruby
6
+ authors:
7
+ - David Paluy
8
+ - Yaroslav Konovets
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 1980-01-02 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: faraday
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 1.10.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 1.10.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: json
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '2.7'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '2.7'
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: juwelier
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 2.4.9
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 2.4.9
69
+ - !ruby/object:Gem::Dependency
70
+ name: pry-byebug
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rdoc
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '6.0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '6.0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rspec
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: 3.11.0
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: 3.11.0
111
+ - !ruby/object:Gem::Dependency
112
+ name: shoulda
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: 4.0.0
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: 4.0.0
125
+ - !ruby/object:Gem::Dependency
126
+ name: simplecov
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: 0.21.0
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: 0.21.0
139
+ - !ruby/object:Gem::Dependency
140
+ name: timecop
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - "~>"
144
+ - !ruby/object:Gem::Version
145
+ version: 0.9.0
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - "~>"
151
+ - !ruby/object:Gem::Version
152
+ version: 0.9.0
153
+ - !ruby/object:Gem::Dependency
154
+ name: webmock
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - "~>"
158
+ - !ruby/object:Gem::Version
159
+ version: 3.18.0
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - "~>"
165
+ - !ruby/object:Gem::Version
166
+ version: 3.18.0
167
+ - !ruby/object:Gem::Dependency
168
+ name: codeclimate-test-reporter
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - ">="
172
+ - !ruby/object:Gem::Version
173
+ version: '0'
174
+ type: :development
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - ">="
179
+ - !ruby/object:Gem::Version
180
+ version: '0'
181
+ - !ruby/object:Gem::Dependency
182
+ name: coveralls
183
+ requirement: !ruby/object:Gem::Requirement
184
+ requirements:
185
+ - - ">="
186
+ - !ruby/object:Gem::Version
187
+ version: '0'
188
+ type: :development
189
+ prerelease: false
190
+ version_requirements: !ruby/object:Gem::Requirement
191
+ requirements:
192
+ - - ">="
193
+ - !ruby/object:Gem::Version
194
+ version: '0'
195
+ - !ruby/object:Gem::Dependency
196
+ name: rubocop
197
+ requirement: !ruby/object:Gem::Requirement
198
+ requirements:
199
+ - - ">="
200
+ - !ruby/object:Gem::Version
201
+ version: '0'
202
+ type: :development
203
+ prerelease: false
204
+ version_requirements: !ruby/object:Gem::Requirement
205
+ requirements:
206
+ - - ">="
207
+ - !ruby/object:Gem::Version
208
+ version: '0'
209
+ description: Sage Intacct API wrapper
210
+ email: dpaluy@users.noreply.github.com
211
+ executables: []
212
+ extensions: []
213
+ extra_rdoc_files:
214
+ - LICENSE.txt
215
+ - README.md
216
+ files:
217
+ - ".document"
218
+ - ".rspec"
219
+ - ".rubocop.yml"
220
+ - ".travis.yml"
221
+ - Gemfile
222
+ - LICENSE.txt
223
+ - README.md
224
+ - Rakefile
225
+ - intacct.gemspec
226
+ - lib/intacct.rb
227
+ - lib/intacct/authentication_methods/credentials.rb
228
+ - lib/intacct/authentication_methods/session.rb
229
+ - lib/intacct/authentication_result.rb
230
+ - lib/intacct/config.rb
231
+ - lib/intacct/exceptions/client_exception.rb
232
+ - lib/intacct/exceptions/function_failure_exception.rb
233
+ - lib/intacct/exceptions/missing_authentication_exception.rb
234
+ - lib/intacct/function_result.rb
235
+ - lib/intacct/functions/create.rb
236
+ - lib/intacct/functions/create_ar_adjustment.rb
237
+ - lib/intacct/functions/get_api_session.rb
238
+ - lib/intacct/functions/query.rb
239
+ - lib/intacct/functions/read.rb
240
+ - lib/intacct/functions/retrieve_pdf.rb
241
+ - lib/intacct/functions/reverse_payment.rb
242
+ - lib/intacct/functions/update.rb
243
+ - lib/intacct/gateway.rb
244
+ - lib/intacct/request.rb
245
+ - lib/intacct/response.rb
246
+ - lib/intacct/utils.rb
247
+ - lib/intacct/version.rb
248
+ - spec/intacct/client_spec.rb
249
+ - spec/intacct_spec.rb
250
+ - spec/spec_helper.rb
251
+ homepage: http://github.com/dpaluy/intacct
252
+ licenses:
253
+ - MIT
254
+ metadata: {}
255
+ rdoc_options: []
256
+ require_paths:
257
+ - lib
258
+ required_ruby_version: !ruby/object:Gem::Requirement
259
+ requirements:
260
+ - - ">="
261
+ - !ruby/object:Gem::Version
262
+ version: '0'
263
+ required_rubygems_version: !ruby/object:Gem::Requirement
264
+ requirements:
265
+ - - ">="
266
+ - !ruby/object:Gem::Version
267
+ version: '0'
268
+ requirements: []
269
+ rubygems_version: 3.7.2
270
+ specification_version: 4
271
+ summary: Sage Intacct API wrapper
272
+ test_files: []