intacct_ruby_team 1.7.1
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 +7 -0
- data/.gitignore +10 -0
- data/.rspec +2 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +179 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/intacct_ruby.gemspec +36 -0
- data/lib/intacct_ruby.rb +27 -0
- data/lib/intacct_ruby/api.rb +31 -0
- data/lib/intacct_ruby/exceptions/empty_request_exception.rb +5 -0
- data/lib/intacct_ruby/exceptions/function_failure_exception.rb +5 -0
- data/lib/intacct_ruby/exceptions/insufficient_credentials_exception.rb +5 -0
- data/lib/intacct_ruby/exceptions/unknown_function_type.rb +5 -0
- data/lib/intacct_ruby/function.rb +92 -0
- data/lib/intacct_ruby/functions/base_function.rb +48 -0
- data/lib/intacct_ruby/functions/create_aradjustment.rb +48 -0
- data/lib/intacct_ruby/functions/create_customer.rb +23 -0
- data/lib/intacct_ruby/functions/create_employee.rb +21 -0
- data/lib/intacct_ruby/functions/create_gltransaction.rb +28 -0
- data/lib/intacct_ruby/functions/create_item.rb +21 -0
- data/lib/intacct_ruby/functions/create_location.rb +21 -0
- data/lib/intacct_ruby/functions/create_project.rb +20 -0
- data/lib/intacct_ruby/functions/create_statgltransaction.rb +28 -0
- data/lib/intacct_ruby/functions/customer_base_function.rb +27 -0
- data/lib/intacct_ruby/functions/employee_base_function.rb +36 -0
- data/lib/intacct_ruby/functions/gltransaction_base_function.rb +64 -0
- data/lib/intacct_ruby/functions/item_base_function.rb +29 -0
- data/lib/intacct_ruby/functions/location_base_function.rb +24 -0
- data/lib/intacct_ruby/functions/project_base_function.rb +22 -0
- data/lib/intacct_ruby/functions/update_customer.rb +22 -0
- data/lib/intacct_ruby/functions/update_employee.rb +20 -0
- data/lib/intacct_ruby/functions/update_item.rb +20 -0
- data/lib/intacct_ruby/functions/update_location.rb +20 -0
- data/lib/intacct_ruby/functions/update_project.rb +20 -0
- data/lib/intacct_ruby/helpers/contacts_helper.rb +32 -0
- data/lib/intacct_ruby/helpers/date_helper.rb +22 -0
- data/lib/intacct_ruby/request.rb +138 -0
- data/lib/intacct_ruby/response.rb +43 -0
- data/lib/intacct_ruby/version.rb +3 -0
- metadata +205 -0
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
require 'intacct_ruby/functions/base_function'
|
|
2
|
+
require 'intacct_ruby/helpers/date_helper'
|
|
3
|
+
|
|
4
|
+
module IntacctRuby
|
|
5
|
+
module Functions
|
|
6
|
+
# creates gltransaction instance in Intacct
|
|
7
|
+
class GLTransactionBaseFunction < BaseFunction
|
|
8
|
+
include DateHelper
|
|
9
|
+
|
|
10
|
+
private
|
|
11
|
+
|
|
12
|
+
def gltransaction_header_params(attributes)
|
|
13
|
+
xml = Builder::XmlMarkup.new
|
|
14
|
+
|
|
15
|
+
xml << extract_from_attrs(attributes, :journalid)
|
|
16
|
+
xml << date_params(:datecreated, attributes[:datecreated])
|
|
17
|
+
xml << extract_from_attrs(attributes, :description)
|
|
18
|
+
|
|
19
|
+
xml.target!
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def gltransactionentry_params(transaction_entries)
|
|
23
|
+
xml = Builder::XmlMarkup.new
|
|
24
|
+
|
|
25
|
+
transaction_entries.each do |entry_attrs|
|
|
26
|
+
xml << glentry_params(entry_attrs)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
xml.target!
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def glentry_params(attrs)
|
|
33
|
+
xml = Builder::XmlMarkup.new
|
|
34
|
+
|
|
35
|
+
xml.glentry do
|
|
36
|
+
xml << extract_from_attrs(attrs, :trtype, :amount, :glaccountno)
|
|
37
|
+
xml << date_params(:datecreated, attrs[:datecreated])
|
|
38
|
+
xml << extract_from_attrs(
|
|
39
|
+
attrs,
|
|
40
|
+
:memo,
|
|
41
|
+
:locationid,
|
|
42
|
+
:customerid,
|
|
43
|
+
:employeeid,
|
|
44
|
+
:projectid,
|
|
45
|
+
:itemid
|
|
46
|
+
)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
xml.target!
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def extract_from_attrs(attributes_hash, *keys)
|
|
53
|
+
xml = Builder::XmlMarkup.new
|
|
54
|
+
|
|
55
|
+
keys.each do |key|
|
|
56
|
+
value = attributes_hash[key]
|
|
57
|
+
xml.tag!(key) { xml << value.to_s } if value
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
xml.target!
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
require 'intacct_ruby/functions/base_function'
|
|
2
|
+
|
|
3
|
+
module IntacctRuby
|
|
4
|
+
module Functions
|
|
5
|
+
# function that all item functions are built off of, to decreate dupe code
|
|
6
|
+
class ItemBaseFunction < BaseFunction
|
|
7
|
+
ALL_PARAMS = [
|
|
8
|
+
:name,
|
|
9
|
+
:itemtype,
|
|
10
|
+
:extended_description,
|
|
11
|
+
:productlineid,
|
|
12
|
+
:standard_cost,
|
|
13
|
+
:glgroup,
|
|
14
|
+
:uomgrp
|
|
15
|
+
].freeze
|
|
16
|
+
|
|
17
|
+
def item_params
|
|
18
|
+
xml = Builder::XmlMarkup.new
|
|
19
|
+
|
|
20
|
+
ALL_PARAMS.each do |param_name|
|
|
21
|
+
param_value = @attrs[param_name]
|
|
22
|
+
xml.tag!(param_name) { xml << param_value } if param_value
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
xml.target!
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
require 'intacct_ruby/functions/base_function'
|
|
2
|
+
require 'intacct_ruby/helpers/date_helper'
|
|
3
|
+
|
|
4
|
+
module IntacctRuby
|
|
5
|
+
module Functions
|
|
6
|
+
# base for all location-related functions, to cut down on duplicate code
|
|
7
|
+
class LocationBaseFunction < BaseFunction
|
|
8
|
+
include IntacctRuby::DateHelper
|
|
9
|
+
|
|
10
|
+
private
|
|
11
|
+
|
|
12
|
+
def location_params
|
|
13
|
+
xml = Builder::XmlMarkup.new
|
|
14
|
+
|
|
15
|
+
xml.name @attrs[:name]
|
|
16
|
+
xml.parentid @attrs[:parentid]
|
|
17
|
+
|
|
18
|
+
xml << start_date_params
|
|
19
|
+
|
|
20
|
+
xml.target!
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
require 'intacct_ruby/functions/base_function'
|
|
2
|
+
|
|
3
|
+
module IntacctRuby
|
|
4
|
+
module Functions
|
|
5
|
+
# contains shared code for creating and updating projects
|
|
6
|
+
class ProjectBaseFunction < BaseFunction
|
|
7
|
+
private
|
|
8
|
+
|
|
9
|
+
def project_params
|
|
10
|
+
xml = Builder::XmlMarkup.new
|
|
11
|
+
|
|
12
|
+
[:projectid, :name, :projectcategory, :customerid].each do |key|
|
|
13
|
+
xml.tag!(key.to_s) { xml << @attrs[key].to_s }
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
xml << custom_field_params(@attrs[:customfields])
|
|
17
|
+
|
|
18
|
+
xml.target!
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
require 'intacct_ruby/functions/customer_base_function'
|
|
2
|
+
|
|
3
|
+
module IntacctRuby
|
|
4
|
+
module Functions
|
|
5
|
+
# update customer instance
|
|
6
|
+
class UpdateCustomer < CustomerBaseFunction
|
|
7
|
+
include ContactsHelper
|
|
8
|
+
|
|
9
|
+
def initialize(attrs = {})
|
|
10
|
+
super "update_customer_#{attrs[:customerid]} (#{timestamp})", attrs
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def to_xml
|
|
14
|
+
super do |xml|
|
|
15
|
+
xml.update_customer customerid: @attrs[:customerid] do
|
|
16
|
+
xml << customer_params
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
require 'intacct_ruby/functions/employee_base_function'
|
|
2
|
+
|
|
3
|
+
module IntacctRuby
|
|
4
|
+
module Functions
|
|
5
|
+
# function used to update employee instances
|
|
6
|
+
class UpdateEmployee < EmployeeBaseFunction
|
|
7
|
+
def initialize(attrs = {})
|
|
8
|
+
super("update_employee_#{attrs[:employeeid]} (#{timestamp})", attrs)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def to_xml
|
|
12
|
+
super do |xml|
|
|
13
|
+
xml.update_employee employeeid: @attrs[:employeeid] do
|
|
14
|
+
xml << employee_params
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
require 'intacct_ruby/functions/item_base_function'
|
|
2
|
+
|
|
3
|
+
module IntacctRuby
|
|
4
|
+
module Functions
|
|
5
|
+
# updates item instance in Intacct
|
|
6
|
+
class UpdateItem < ItemBaseFunction
|
|
7
|
+
def initialize(attrs = {})
|
|
8
|
+
super "update_item_#{attrs[:itemid]} (#{timestamp})", attrs
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def to_xml
|
|
12
|
+
super do |xml|
|
|
13
|
+
xml.update_item itemid: @attrs[:itemid] do
|
|
14
|
+
xml << item_params
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
require 'intacct_ruby/functions/location_base_function'
|
|
2
|
+
|
|
3
|
+
module IntacctRuby
|
|
4
|
+
module Functions
|
|
5
|
+
# used to update location instances in Intacct
|
|
6
|
+
class UpdateLocation < LocationBaseFunction
|
|
7
|
+
def initialize(attrs = {})
|
|
8
|
+
super("update_location_#{attrs[:locationid]} (#{timestamp})", attrs)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def to_xml
|
|
12
|
+
super do |xml|
|
|
13
|
+
xml.update_location locationid: @attrs[:locationid] do
|
|
14
|
+
xml << location_params
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
require 'intacct_ruby/functions/project_base_function'
|
|
2
|
+
|
|
3
|
+
module IntacctRuby
|
|
4
|
+
module Functions
|
|
5
|
+
# creates a project instance in Intacct
|
|
6
|
+
class UpdateProject < ProjectBaseFunction
|
|
7
|
+
def initialize(attrs = {})
|
|
8
|
+
super("update_project_#{attrs[:projectid]} (#{timestamp})", attrs)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def to_xml
|
|
12
|
+
super do |xml|
|
|
13
|
+
xml.update_project key: @attrs[:projectid] do
|
|
14
|
+
xml << project_params
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
module IntacctRuby
|
|
2
|
+
# methods to avoid duplication when creating and updating contact records
|
|
3
|
+
module ContactsHelper
|
|
4
|
+
def contact_params(attributes, id, person_type)
|
|
5
|
+
xml = Builder::XmlMarkup.new
|
|
6
|
+
|
|
7
|
+
name = full_name(attributes)
|
|
8
|
+
|
|
9
|
+
xml.contact do
|
|
10
|
+
xml.contactname contactname(name, id, person_type)
|
|
11
|
+
xml.printas full_name(attributes)
|
|
12
|
+
xml.firstname attributes[:first_name]
|
|
13
|
+
xml.lastname attributes[:last_name]
|
|
14
|
+
xml.email1 attributes[:email1]
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
xml.target!
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def contactname(name, id, person_type)
|
|
21
|
+
# a unique identifier for a contact, to be used for Intacct's
|
|
22
|
+
# contactname field. Person Type required to ensure that there aren't
|
|
23
|
+
# duplicates (e.g. a customer and employee w/ ID 1 both named
|
|
24
|
+
# 'John Smith')
|
|
25
|
+
"#{name} (#{person_type} \##{id})"
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def full_name(attrs = {})
|
|
29
|
+
"#{attrs[:first_name]} #{attrs[:last_name]}"
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
require 'builder'
|
|
2
|
+
|
|
3
|
+
module IntacctRuby
|
|
4
|
+
# methods to help generate date XML for calls
|
|
5
|
+
module DateHelper
|
|
6
|
+
def date_params(block_name, attrs = {})
|
|
7
|
+
xml = Builder::XmlMarkup.new
|
|
8
|
+
|
|
9
|
+
xml.tag!(block_name) do
|
|
10
|
+
xml.year attrs[:year]
|
|
11
|
+
xml.month attrs[:month]
|
|
12
|
+
xml.day attrs[:day]
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# Note: @attrs[:startdate] MUST be defined in the invoking context for this
|
|
17
|
+
# bad boy to work
|
|
18
|
+
def start_date_params
|
|
19
|
+
date_params :startdate, @attrs[:startdate]
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
require 'builder'
|
|
2
|
+
|
|
3
|
+
require 'intacct_ruby/api'
|
|
4
|
+
require 'intacct_ruby/response'
|
|
5
|
+
require 'intacct_ruby/function'
|
|
6
|
+
|
|
7
|
+
require 'intacct_ruby/exceptions/insufficient_credentials_exception'
|
|
8
|
+
require 'intacct_ruby/exceptions/empty_request_exception'
|
|
9
|
+
|
|
10
|
+
module IntacctRuby
|
|
11
|
+
# An outgoing request to the Intacct API. Can have multiple functions.
|
|
12
|
+
# Complete with send method that gets (and wraps) response from Intacct.
|
|
13
|
+
class Request
|
|
14
|
+
attr_reader :functions
|
|
15
|
+
|
|
16
|
+
DEFAULTS = {
|
|
17
|
+
uniqueid: false,
|
|
18
|
+
dtdversion: 3.0,
|
|
19
|
+
includewhitespace: false,
|
|
20
|
+
transaction: true
|
|
21
|
+
}.freeze
|
|
22
|
+
|
|
23
|
+
REQUIRED_AUTHENTICATION_KEYS = [
|
|
24
|
+
:senderid,
|
|
25
|
+
:sender_password,
|
|
26
|
+
:userid,
|
|
27
|
+
:companyid,
|
|
28
|
+
:user_password
|
|
29
|
+
].freeze
|
|
30
|
+
|
|
31
|
+
def initialize(*functions, request_params)
|
|
32
|
+
# request_params should contain all req'd authentication information. If
|
|
33
|
+
# not, an error will be thrown on #send
|
|
34
|
+
@opts = DEFAULTS.dup.merge request_params
|
|
35
|
+
|
|
36
|
+
# If a hash is provided + popped, the remaining attrs are functions
|
|
37
|
+
@functions = functions
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def to_xml
|
|
41
|
+
@to_xml ||= begin
|
|
42
|
+
@request = Builder::XmlMarkup.new
|
|
43
|
+
|
|
44
|
+
@request.instruct!
|
|
45
|
+
@request.request do
|
|
46
|
+
control_block
|
|
47
|
+
operation_block
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def send(opts = {})
|
|
53
|
+
if opts.is_a? Hash
|
|
54
|
+
api = opts[:api] || Api.new
|
|
55
|
+
|
|
56
|
+
validate_keys!
|
|
57
|
+
validate_functions!
|
|
58
|
+
|
|
59
|
+
Response.new api.send_request(self)
|
|
60
|
+
else
|
|
61
|
+
# so that Request#send can play nice alongside Object#send
|
|
62
|
+
super
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
private
|
|
67
|
+
|
|
68
|
+
def method_missing(method_name, *arguments, &block)
|
|
69
|
+
super unless Function::ALLOWED_TYPES.include? method_name.to_s
|
|
70
|
+
|
|
71
|
+
# object_type must be the first argument in arguments
|
|
72
|
+
@functions << Function.new(method_name, arguments.shift, *arguments)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def respond_to_missing?(method_name, include_private = false)
|
|
76
|
+
Function::ALLOWED_TYPES.include?(method_name) || super
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def validate_functions!
|
|
80
|
+
unless functions.any?
|
|
81
|
+
raise Exceptions::EmptyRequestException,
|
|
82
|
+
'a successful request must contain at least one function'
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def validate_keys!
|
|
87
|
+
missing_keys = REQUIRED_AUTHENTICATION_KEYS - @opts.keys
|
|
88
|
+
|
|
89
|
+
unless missing_keys.empty?
|
|
90
|
+
missing_keys.map! { |s| ":#{s}" } # so they appear as symbols in output
|
|
91
|
+
|
|
92
|
+
raise Exceptions::InsufficientCredentialsException,
|
|
93
|
+
"[#{missing_keys.join(', ')}] required for a valid request. "
|
|
94
|
+
'All authentication-related keys should be provided on ' \
|
|
95
|
+
'instantiation in IntacctRuby::Request#new'
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def timestamp
|
|
100
|
+
@timestamp ||= Time.now.utc.to_s
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def control_block
|
|
104
|
+
@request.control do
|
|
105
|
+
@request.senderid @opts[:senderid]
|
|
106
|
+
@request.password @opts[:sender_password]
|
|
107
|
+
|
|
108
|
+
# As recommended by Intacct API reference. This ID should be unique
|
|
109
|
+
# to the call: it's used to associate a response with a request.
|
|
110
|
+
@request.controlid timestamp
|
|
111
|
+
@request.uniqueid @opts[:uniqueid]
|
|
112
|
+
@request.dtdversion @opts[:dtdversion]
|
|
113
|
+
@request.includewhitespace @opts[:includewhitespace]
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def authentication_block
|
|
118
|
+
@request.authentication do
|
|
119
|
+
@request.login do
|
|
120
|
+
@request.userid @opts[:userid]
|
|
121
|
+
@request.companyid @opts[:companyid]
|
|
122
|
+
@request.password @opts[:user_password]
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def operation_block
|
|
128
|
+
@request.operation transaction: @opts[:transaction] do
|
|
129
|
+
authentication_block
|
|
130
|
+
@request.content do
|
|
131
|
+
functions.each do |function|
|
|
132
|
+
@request << function.to_xml
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
end
|