intacctrb 0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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