intacctrb 0.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.
@@ -0,0 +1,119 @@
1
+ module IntacctRB
2
+ class Base < Struct.new(:object, :current_user)
3
+ include Hooks
4
+ include Hooks::InstanceHooks
5
+
6
+ define_hook :after_create, :after_update, :after_delete,
7
+ :after_get, :after_send_xml, :on_error, :before_create
8
+
9
+ after_create :set_intacct_system_id
10
+ after_delete :delete_intacct_system_id
11
+ after_delete :delete_intacct_key
12
+ after_send_xml :set_date_time
13
+
14
+ attr_accessor :response, :data, :sent_xml, :intacct_action
15
+
16
+ def initialize *params
17
+ params[0] = OpenStruct.new(params[0]) if params[0].is_a? Hash
18
+ super(*params)
19
+ end
20
+
21
+ private
22
+
23
+ def send_xml action
24
+ @intacct_action = action.to_s
25
+ run_hook :"before_#{intacct_action}" if action=="create"
26
+
27
+ builder = Nokogiri::XML::Builder.new do |xml|
28
+ xml.request {
29
+ xml.control {
30
+ xml.senderid IntacctRB.xml_sender_id
31
+ xml.password IntacctRB.xml_password
32
+ xml.controlid "INVOICE XML"
33
+ xml.uniqueid "false"
34
+ xml.dtdversion "2.1"
35
+ }
36
+ xml.operation(transaction: "false") {
37
+ xml.authentication {
38
+ xml.login {
39
+ xml.userid IntacctRB.app_user_id
40
+ xml.companyid IntacctRB.app_company_id
41
+ xml.password IntacctRB.app_password
42
+ }
43
+ }
44
+ xml.content {
45
+ yield xml
46
+ }
47
+ }
48
+ }
49
+ end
50
+
51
+ xml = builder.doc.root.to_xml
52
+ puts xml
53
+ @sent_xml = xml
54
+
55
+ url = "https://www.intacct.com/ia/xml/xmlgw.phtml"
56
+ uri = URI(url)
57
+
58
+ res = Net::HTTP.post_form(uri, 'xmlrequest' => xml)
59
+ @response = Nokogiri::XML(res.body)
60
+ puts res.body
61
+ if successful?
62
+ if key = response.at('//result//key')
63
+ set_intacct_key key.content
64
+ end
65
+
66
+ if intacct_action
67
+ run_hook :after_send_xml, intacct_action
68
+ #run_hook :"after_#{intacct_action}"
69
+ end
70
+ else
71
+ run_hook :on_error
72
+ end
73
+
74
+ @response
75
+ end
76
+
77
+ def successful?
78
+ if status = response.at('//result//status') and status.content == "success"
79
+ true
80
+ else
81
+ false
82
+ end
83
+ end
84
+
85
+ %w(invoice bill vendor customer).each do |type|
86
+ define_method "intacct_#{type}_prefix" do
87
+ Intacct.send("#{type}_prefix")
88
+ end
89
+ end
90
+
91
+ def intacct_system_id
92
+ intacct_object_id
93
+ end
94
+
95
+ def set_intacct_system_id
96
+ object.intacct_system_id = intacct_object_id
97
+ end
98
+
99
+ def delete_intacct_system_id
100
+ object.intacct_system_id = nil
101
+ end
102
+
103
+ def set_intacct_key key
104
+ object.intacct_key = key if object.respond_to? :intacct_key
105
+ end
106
+
107
+ def delete_intacct_key
108
+ object.intacct_key = nil if object.respond_to? :intacct_key
109
+ end
110
+
111
+ def set_date_time type
112
+ if %w(create update delete).include? type
113
+ if object.respond_to? :"intacct_#{type}d_at"
114
+ object.send("intacct_#{type}d_at=", DateTime.now)
115
+ end
116
+ end
117
+ end
118
+ end
119
+ end
@@ -0,0 +1,159 @@
1
+ module IntacctRB
2
+ class Bill < IntacctRB::Base
3
+ attr_accessor :customer_data
4
+ define_hook :custom_bill_fields, :bill_item_fields
5
+
6
+ def create
7
+ return false if object.payment.intacct_system_id.present?
8
+
9
+ # Need to create the customer if one doesn't exist
10
+ unless object.customer.intacct_system_id
11
+ intacct_customer = Intacct::Customer.new object.customer
12
+ unless intacct_customer.create
13
+ raise 'Could not grab Intacct customer data'
14
+ end
15
+ end
16
+
17
+ # Create vendor if we have one and not in Intacct
18
+ if object.vendor and object.vendor.intacct_system_id.blank?
19
+ intacct_vendor = Intacct::Vendor.new object.vendor
20
+ if intacct_vendor.create
21
+ object.vendor = intacct_vendor.object
22
+ else
23
+ raise 'Could not create vendor'
24
+ end
25
+ end
26
+
27
+ send_xml('create') do |xml|
28
+ xml.function(controlid: "f1") {
29
+ xml.send("create_bill") {
30
+ bill_xml xml
31
+ }
32
+ }
33
+ end
34
+
35
+ successful?
36
+ end
37
+
38
+ def delete
39
+ # return false unless object.payment.intacct_system_id.present?
40
+
41
+ send_xml('delete') do |xml|
42
+ xml.function(controlid: "1") {
43
+ xml.delete_bill(externalkey: "false", key: object.intacct_key)
44
+ }
45
+ end
46
+
47
+ successful?
48
+ end
49
+
50
+ def get_list(options = {})
51
+ send_xml('get_list') do |xml|
52
+ xml.function(controlid: "f4") {
53
+ xml.get_list(object: "bill", maxitems: (options[:max_items] || 0),
54
+ start: (options[:start] || 0), showprivate:"true") {
55
+ if options[:filters]
56
+ xml.filter {
57
+ options[:filters].each do |filter|
58
+ xml.expression do
59
+ filter.each_pair do |k,v|
60
+ xml.send(k,v)
61
+ end
62
+ end
63
+ end
64
+ }
65
+ end
66
+ if options[:fields]
67
+ xml.fields {
68
+ fields.each do |field|
69
+ xml.field field.to_s
70
+ end
71
+ }
72
+ end
73
+ }
74
+ }
75
+ end
76
+
77
+ if successful?
78
+ @data = []
79
+ @response.xpath('//bill').each do |invoice|
80
+ @data << OpenStruct.new({
81
+ id: invoice.at("key").content,
82
+ vendor_id: invoice.at("vendorid").content,
83
+ bill_number: invoice.at("billno").content,
84
+ po_number: invoice.at("ponumber").content,
85
+ state: invoice.at("state").content,
86
+ date_posted: get_date_at('dateposted', invoice),
87
+ date_due: get_date_at('datedue', invoice),
88
+ date_paid: get_date_at('datepaid', invoice),
89
+ total: invoice.at("totalamount").content,
90
+ total_paid: invoice.at("totalpaid").content,
91
+ total_due: invoice.at("totaldue").content,
92
+ termname: invoice.at("termname").content,
93
+ description: invoice.at("description").content,
94
+ modified_at: invoice.at("whenmodified").content
95
+ })
96
+ end
97
+ @data
98
+ else
99
+ false
100
+ end
101
+ end
102
+
103
+ def get_date_at(xpath, object)
104
+ year = object.at("#{xpath}/year").content
105
+ month = object.at("#{xpath}/month").content
106
+ day = object.at("#{xpath}/day").content
107
+ if [year,month,day].any?(&:empty?)
108
+ nil
109
+ else
110
+ Date.new(year.to_i,month.to_i,day.to_i)
111
+ end
112
+ end
113
+
114
+ def intacct_object_id
115
+ "#{intacct_bill_prefix}#{object.payment.id}"
116
+ end
117
+
118
+ def bill_xml xml
119
+ xml.vendorid object.vendor.intacct_system_id
120
+ xml.datecreated {
121
+ xml.year object.payment.created_at.strftime("%Y")
122
+ xml.month object.payment.created_at.strftime("%m")
123
+ xml.day object.payment.created_at.strftime("%d")
124
+ }
125
+ xml.dateposted {
126
+ xml.year object.payment.created_at.strftime("%Y")
127
+ xml.month object.payment.created_at.strftime("%m")
128
+ xml.day object.payment.created_at.strftime("%d")
129
+ }
130
+ xml.datedue {
131
+ xml.year object.payment.paid_at.strftime("%Y")
132
+ xml.month object.payment.paid_at.strftime("%m")
133
+ xml.day object.payment.paid_at.strftime("%d")
134
+ }
135
+ run_hook :custom_bill_fields, xml
136
+ run_hook :bill_item_fields, xml
137
+ end
138
+
139
+ def set_intacct_system_id
140
+ object.payment.intacct_system_id = intacct_object_id
141
+ end
142
+
143
+ def delete_intacct_system_id
144
+ object.payment.intacct_system_id = nil
145
+ end
146
+
147
+ def delete_intacct_key
148
+ object.payment.intacct_key = nil
149
+ end
150
+
151
+ def set_date_time type
152
+ if %w(create update delete).include? type
153
+ if object.payment.respond_to? :"intacct_#{type}d_at"
154
+ object.payment.send("intacct_#{type}d_at=", DateTime.now)
155
+ end
156
+ end
157
+ end
158
+ end
159
+ end
@@ -0,0 +1,116 @@
1
+ module IntacctRB
2
+ class Customer < IntacctRB::Base
3
+ def create
4
+ send_xml('create') do |xml|
5
+ xml.function(controlid: "1") {
6
+ xml.send("create_customer") {
7
+ xml.customerid intacct_object_id
8
+ xml.name object.name
9
+ xml.comments
10
+ xml.status "active"
11
+ }
12
+ }
13
+ end
14
+
15
+ successful?
16
+ end
17
+
18
+ def get *fields
19
+ #return false unless object.intacct_system_id.present?
20
+
21
+ fields = [
22
+ :customerid,
23
+ :name,
24
+ :termname
25
+ ] if fields.empty?
26
+
27
+ send_xml('get') do |xml|
28
+ xml.function(controlid: "f4") {
29
+ xml.get(object: "customer", key: "intacct_system_id") {
30
+ xml.fields {
31
+ fields.each do |field|
32
+ xml.field field.to_s
33
+ end
34
+ }
35
+ }
36
+ }
37
+ end
38
+
39
+ if successful?
40
+ @data = OpenStruct.new({
41
+ id: response.at("//customer//customerid").content,
42
+ name: response.at("//customer//name").content,
43
+ termname: response.at("//customer//termname").content
44
+ })
45
+ end
46
+
47
+ successful?
48
+ end
49
+
50
+ def get_list *fields
51
+ #return false unless object.intacct_system_id.present?
52
+
53
+ fields = [
54
+ :customerid,
55
+ :name,
56
+ :termname
57
+ ] if fields.empty?
58
+
59
+ send_xml('get_list') do |xml|
60
+ xml.function(controlid: "f4") {
61
+ xml.get_list(object: "customer", maxitems: "10", showprivate:"false") {
62
+ # xml.fields {
63
+ # fields.each do |field|
64
+ # xml.field field.to_s
65
+ # end
66
+ # }
67
+ }
68
+ }
69
+ end
70
+
71
+ # if successful?
72
+ # @data = OpenStruct.new({
73
+ # id: response.at("//customer//customerid").content,
74
+ # name: response.at("//customer//name").content,
75
+ # termname: response.at("//customer//termname").content
76
+ # })
77
+ # end
78
+ #
79
+ # successful?
80
+ puts response
81
+ end
82
+
83
+ def update updated_customer = false
84
+ @object = updated_customer if updated_customer
85
+ return false unless object.intacct_system_id.present?
86
+
87
+ send_xml('update') do |xml|
88
+ xml.function(controlid: "1") {
89
+ xml.update_customer(customerid: intacct_system_id) {
90
+ xml.name object.name
91
+ xml.comments
92
+ xml.status "active"
93
+ }
94
+ }
95
+ end
96
+
97
+ successful?
98
+ end
99
+
100
+ def delete
101
+ return false unless object.intacct_system_id.present?
102
+
103
+ @response = send_xml('delete') do |xml|
104
+ xml.function(controlid: "1") {
105
+ xml.delete_customer(customerid: intacct_system_id)
106
+ }
107
+ end
108
+
109
+ successful?
110
+ end
111
+
112
+ def intacct_object_id
113
+ "#{intacct_customer_prefix}#{object.id}"
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,133 @@
1
+ module IntacctRB
2
+ class Invoice < IntacctRB::Base
3
+ attr_accessor :customer_data
4
+ define_hook :custom_invoice_fields
5
+
6
+ def get_list *fields
7
+ # return false unless object.intacct_system_id.present?
8
+
9
+ fields = [
10
+ :customerid,
11
+ :name,
12
+ :termname
13
+ ] if fields.empty?
14
+
15
+ send_xml('get_list') do |xml|
16
+ xml.function(controlid: "f4") {
17
+ xml.get_list(object: "invoice", maxitems: "10", showprivate:"false") {
18
+ # xml.fields {
19
+ # fields.each do |field|
20
+ # xml.field field.to_s
21
+ # end
22
+ # }
23
+ }
24
+ }
25
+ end
26
+
27
+ if successful?
28
+ @data = []
29
+ @response.xpath('//invoice').each do |invoice|
30
+ @data << Invoice.new({
31
+ id: invoice.at("//customerid").content,
32
+ total: invoice.at("//totalamount").content,
33
+ total_paid: invoice.at("//totalpaid").content,
34
+ termname: invoice.at("//termname").content
35
+ })
36
+ end
37
+ @data
38
+ else
39
+ false
40
+ end
41
+ end
42
+
43
+ def create
44
+ return false if object.invoice.intacct_system_id.present?
45
+
46
+ # Need to create the customer if one doesn't exist
47
+ intacct_customer = Intacct::Customer.new object.customer
48
+ unless object.customer.intacct_system_id.present?
49
+ unless intacct_customer.create
50
+ raise 'Could not create customer'
51
+ end
52
+ end
53
+
54
+ if intacct_customer.get
55
+ object.customer = intacct_customer.object
56
+ @customer_data = intacct_customer.data
57
+ else
58
+ raise 'Could not grab Intacct customer data'
59
+ end
60
+
61
+ # Create vendor if we have one and not in Intacct
62
+ if object.vendor and object.vendor.intacct_system_id.blank?
63
+ intacct_vendor = Intacct::Vendor.new object.vendor
64
+ if intacct_vendor.create
65
+ object.vendor = intacct_vendor.object
66
+ else
67
+ raise 'Could not create vendor'
68
+ end
69
+ end
70
+
71
+ send_xml('create') do |xml|
72
+ xml.function(controlid: "f1") {
73
+ xml.create_invoice {
74
+ invoice_xml xml
75
+ }
76
+ }
77
+ end
78
+
79
+ successful?
80
+ end
81
+
82
+ def delete
83
+ return false unless object.invoice.intacct_system_id.present?
84
+
85
+ send_xml('delete') do |xml|
86
+ xml.function(controlid: "1") {
87
+ xml.delete_invoice(externalkey: "false", key: object.invoice.intacct_key)
88
+ }
89
+ end
90
+
91
+ successful?
92
+ end
93
+
94
+ def intacct_object_id
95
+ "#{intacct_invoice_prefix}#{object.invoice.id}"
96
+ end
97
+
98
+ def invoice_xml xml
99
+ xml.customerid "#{object.customer.intacct_system_id}"
100
+ xml.datecreated {
101
+ xml.year object.invoice.created_at.strftime("%Y")
102
+ xml.month object.invoice.created_at.strftime("%m")
103
+ xml.day object.invoice.created_at.strftime("%d")
104
+ }
105
+
106
+ termname = customer_data.termname
107
+ xml.termname termname.present?? termname : "Net 30"
108
+
109
+ xml.invoiceno intacct_object_id
110
+ run_hook :custom_invoice_fields, xml
111
+ end
112
+
113
+ def set_intacct_system_id
114
+ object.invoice.intacct_system_id = intacct_object_id
115
+ end
116
+
117
+ def delete_intacct_system_id
118
+ object.invoice.intacct_system_id = nil
119
+ end
120
+
121
+ def delete_intacct_key
122
+ object.invoice.intacct_key = nil
123
+ end
124
+
125
+ def set_date_time type
126
+ if %w(create update delete).include? type
127
+ if object.invoice.respond_to? :"intacct_#{type}d_at"
128
+ object.invoice.send("intacct_#{type}d_at=", DateTime.now)
129
+ end
130
+ end
131
+ end
132
+ end
133
+ end