rconomic 0.4.1 → 0.5.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.
Files changed (56) hide show
  1. checksums.yaml +8 -8
  2. data/.travis.yml +1 -2
  3. data/Gemfile +1 -0
  4. data/README.md +6 -1
  5. data/lib/economic/account.rb +5 -7
  6. data/lib/economic/cash_book.rb +8 -10
  7. data/lib/economic/cash_book_entry.rb +1 -1
  8. data/lib/economic/creditor.rb +1 -1
  9. data/lib/economic/creditor_contact.rb +2 -2
  10. data/lib/economic/current_invoice.rb +10 -13
  11. data/lib/economic/current_invoice_line.rb +3 -3
  12. data/lib/economic/debtor.rb +1 -1
  13. data/lib/economic/debtor_contact.rb +2 -2
  14. data/lib/economic/entity.rb +19 -19
  15. data/lib/economic/invoice.rb +6 -6
  16. data/lib/economic/proxies/account_proxy.rb +4 -6
  17. data/lib/economic/proxies/actions/find_by_ci_number.rb +3 -5
  18. data/lib/economic/proxies/actions/find_by_date_interval.rb +4 -7
  19. data/lib/economic/proxies/actions/find_by_name.rb +71 -0
  20. data/lib/economic/proxies/actions/find_by_number.rb +3 -5
  21. data/lib/economic/proxies/cash_book_entry_proxy.rb +16 -13
  22. data/lib/economic/proxies/cash_book_proxy.rb +7 -23
  23. data/lib/economic/proxies/creditor_contact_proxy.rb +6 -49
  24. data/lib/economic/proxies/creditor_entry_proxy.rb +13 -19
  25. data/lib/economic/proxies/creditor_proxy.rb +6 -8
  26. data/lib/economic/proxies/current_invoice_line_proxy.rb +3 -9
  27. data/lib/economic/proxies/current_invoice_proxy.rb +12 -20
  28. data/lib/economic/proxies/debtor_contact_proxy.rb +6 -49
  29. data/lib/economic/proxies/debtor_entry_proxy.rb +9 -14
  30. data/lib/economic/proxies/debtor_proxy.rb +1 -1
  31. data/lib/economic/proxies/entity_proxy.rb +21 -20
  32. data/lib/economic/proxies/entry_proxy.rb +14 -20
  33. data/lib/economic/session.rb +21 -12
  34. data/lib/economic/support/string.rb +5 -1
  35. data/lib/rconomic.rb +2 -1
  36. data/lib/rconomic/version.rb +1 -1
  37. data/rconomic.gemspec +0 -2
  38. data/spec/economic/current_invoice_spec.rb +1 -1
  39. data/spec/economic/entity_spec.rb +4 -3
  40. data/spec/economic/proxies/actions/find_by_name_spec.rb +48 -0
  41. data/spec/economic/proxies/cash_book_proxy_spec.rb +30 -5
  42. data/spec/economic/proxies/creditor_contact_proxy_spec.rb +10 -0
  43. data/spec/economic/proxies/current_invoice_line_proxy_spec.rb +3 -3
  44. data/spec/economic/proxies/current_invoice_proxy_spec.rb +5 -5
  45. data/spec/economic/proxies/debtor_contact_proxy_spec.rb +10 -1
  46. data/spec/economic/proxies/debtor_entry_proxy_spec.rb +2 -2
  47. data/spec/economic/proxies/invoice_proxy_spec.rb +3 -3
  48. data/spec/economic/session_spec.rb +44 -3
  49. data/spec/fixtures/cash_book_get_data/success.xml +14 -0
  50. data/spec/fixtures/cash_book_get_data_array/multiple.xml +23 -0
  51. data/spec/fixtures/creditor_contact_find_by_name/multiple.xml +15 -0
  52. data/spec/fixtures/creditor_contact_find_by_name/none.xml +9 -0
  53. data/spec/fixtures/debtor_contact_find_by_name/multiple.xml +15 -0
  54. data/spec/fixtures/debtor_contact_find_by_name/none.xml +9 -0
  55. data/spec/spec_helper.rb +6 -0
  56. metadata +10 -16
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- MTMxZDg2MjQyNWQ5ZmY1MWIzZmI3YmFhNWZkYmJkODBjOTJkMTc1OQ==
4
+ ZGU5ZmVjMDNkNDJlMzI0ODc3OWQ5NmVmNjhiM2UzNjY2NDQ1MjMzOQ==
5
5
  data.tar.gz: !binary |-
6
- ZGYxYjM4MjI1N2E1MmM4ZWY4ZWJhZTVlMWRkOWZmM2E4MmVkNWNlMA==
6
+ ZWFjN2EyNGExYTNiZTNhNWM3Mzk0YTNhOTg2ODgxNWJhOGMxODY2Zg==
7
7
  !binary "U0hBNTEy":
8
8
  metadata.gz: !binary |-
9
- MGFlMzg5YTc1MDZhOTA2NjdjMmJlYWFjMGQzZWE4NjlkY2Y4OTJjYTQ1Yzkx
10
- MWQ0OTY2YjRlNmZjODljZjk2ZDBiOTg0N2U1OTgwZGZhYjM2MzkyY2ExM2Nk
11
- ZGE1NTkyZjg2NWEyNzM0MTJiMmE0NzVhOTY1ZDI0ZjhjOWNiYmU=
9
+ NDMzYWQwOWMzYTE4NzUwNjA2YTBlMzJhZTA2ZjdjOTZhYmUzOTE2NmU5YzAx
10
+ NWU5OWYyYmI0YzA2MWFmMTliZGFjNzY0MDc4YjgxYThjMTIzMTQyOTE5Yjg5
11
+ YzU1ZTE4ZmM4OWM0ODcyNmNmM2JjZmMxMDdlZmU1MzdkMzgxYTQ=
12
12
  data.tar.gz: !binary |-
13
- NmJkOTk0MmExOTgwYmIwMGQyMGNkMjdhODUwZTY5MWY1OGQwYzNlNGJmMGNh
14
- NjU1ZjdkYWVmNTNmYjJlYzcyZjRiZmMxYTRiNzUzZWRhODZlNWE5MzAwY2Rh
15
- NDA3YTFlODExYjM0NjFiZGUyNjM3MDk4YjNmNTM3M2FlNWNkZGM=
13
+ N2Q2MzYxYTIxZmVmZWRlNDhiMDg3ZjE5N2U2MWI0NzJiM2RlODdmNjBlNGVk
14
+ NTgwZGRmMDI2YzczZGI5OGM2NmUzNjRhOTFjZjkwY2ZhYjBlOWU0MGE2YmM5
15
+ Y2NkYTQ5N2RlOGE5Zjg0NjliZDEyNzE5MzQwN2RmZTllODc4NWM=
@@ -1,9 +1,8 @@
1
1
  # Specify which ruby versions you wish to run your tests on, each version will be used
2
2
  rvm:
3
- - 1.8.7
4
3
  - 1.9.2
5
4
  - 1.9.3
6
- - ree
5
+ - 2.0.0
7
6
 
8
7
  # Specify the recipients for email notification
9
8
  notifications:
data/Gemfile CHANGED
@@ -3,6 +3,7 @@ source "https://rubygems.org"
3
3
  gemspec
4
4
 
5
5
  group :test do
6
+ gem 'coveralls', :require => false
6
7
  gem 'rake'
7
8
  gem 'savon_spec', '0.1.6'
8
9
  end
data/README.md CHANGED
@@ -5,7 +5,8 @@ Ruby wrapper for the [e-conomic](http://www.e-conomic.co.uk) SOAP API, that aims
5
5
 
6
6
  E-conomic is a web-based accounting system. For their marketing speak, see [http://www.e-conomic.co.uk/about/](). More details about their API at [http://www.e-conomic.com/developer]().
7
7
 
8
- [![Build Status](https://secure.travis-ci.org/lokalebasen/rconomic.png?branch=master)](http://travis-ci.org/lokalebasen/rconomic)
8
+ [![Build Status](https://secure.travis-ci.org/lokalebasen/rconomic.png?branch=master)](http://travis-ci.org/lokalebasen/rconomic) [![Coverage Status](https://coveralls.io/repos/lokalebasen/rconomic/badge.png?branch=master)](https://coveralls.io/r/lokalebasen/rconomic?branch=master) [![Code Climate](https://codeclimate.com/github/lokalebasen/rconomic.png)](https://codeclimate.com/github/lokalebasen/rconomic)
9
+
9
10
 
10
11
  Usage example
11
12
  -------------
@@ -87,10 +88,14 @@ Not even remotely... For now, limited to a small subset of all the [available op
87
88
  -------------------+--------+------+--------+-------
88
89
  CashBook | X | X | X | X
89
90
  CashBookEntry | X | X | X | X
91
+ Creditor | X | X | X | X
92
+ CreditorContact | X | X | X | X
93
+ CreditorEntry | X | X | X | X
90
94
  CurrentInvoice | X | X | X | X
91
95
  CurrentInvoiceLine | X | X | X | X
92
96
  Debtor | X | X | X | X
93
97
  DebtorContact | X | X | X | X
98
+ DebtorEntry | X | X | X | X
94
99
  Entry | X | X | X | X
95
100
  Invoice | X | X | |
96
101
 
@@ -13,13 +13,11 @@ module Economic
13
13
  protected
14
14
 
15
15
  def build_soap_data
16
- data = ActiveSupport::OrderedHash.new
17
-
18
- data['Handle'] = handle.to_hash
19
- data['Name'] = handle.number
20
- data['Number'] = number
21
-
22
- return data
16
+ {
17
+ 'Handle' => handle.to_hash,
18
+ 'Name' => handle.number,
19
+ 'Number' => number
20
+ }
23
21
  end
24
22
  end
25
23
  end
@@ -18,22 +18,20 @@ module Economic
18
18
 
19
19
  # Books all entries in the cashbook. Returns book result.
20
20
  def book
21
- response = session.request(soap_action(:book)) do
22
- soap.body = { "cashBookHandle" => handle.to_hash }
23
- end
21
+ response = request(:book, {
22
+ "cashBookHandle" => handle.to_hash
23
+ })
24
24
  response[:number].to_i
25
25
  end
26
26
 
27
27
  protected
28
28
 
29
29
  def build_soap_data
30
- data = ActiveSupport::OrderedHash.new
31
-
32
- data['Handle'] = handle.to_hash
33
- data['Name'] = name
34
- data['Number'] = number
35
-
36
- return data
30
+ {
31
+ 'Handle' => handle.to_hash,
32
+ 'Name' => name,
33
+ 'Number' => number
34
+ }
37
35
  end
38
36
  end
39
37
  end
@@ -74,7 +74,7 @@ module Economic
74
74
  protected
75
75
 
76
76
  def build_soap_data
77
- data = ActiveSupport::OrderedHash.new
77
+ data = {}
78
78
 
79
79
  data['Handle'] = handle.to_hash unless handle.empty?
80
80
  data['Id1'] = id1 unless id1.blank?
@@ -36,7 +36,7 @@ module Economic
36
36
  protected
37
37
 
38
38
  def build_soap_data
39
- data = ActiveSupport::OrderedHash.new
39
+ data = {}
40
40
 
41
41
  data['Handle'] = handle.to_hash
42
42
  data['Number'] = handle.number
@@ -9,7 +9,7 @@ module Economic
9
9
  # Examples
10
10
  #
11
11
  # # Find contact
12
- # contact = economic.contacts.find(5)
12
+ # contact = economic.contacts.find(:id => 5)
13
13
  #
14
14
  # # Creating a contact
15
15
  # contact = creditor.contacts.build
@@ -42,7 +42,7 @@ module Economic
42
42
  protected
43
43
 
44
44
  def build_soap_data
45
- data = ActiveSupport::OrderedHash.new
45
+ data = {}
46
46
 
47
47
  data['Handle'] = handle.to_hash
48
48
  data['Id'] = id unless id.blank?
@@ -70,9 +70,9 @@ module Economic
70
70
  #
71
71
  # Returns the resulting Economic::Invoice object
72
72
  def book
73
- response = session.request soap_action(:book) do
74
- soap.body = { "currentInvoiceHandle" => handle.to_hash }
75
- end
73
+ response = request(:book, {
74
+ "currentInvoiceHandle" => handle.to_hash
75
+ })
76
76
 
77
77
  # Find the created Invoice
78
78
  session.invoices.find(response[:number])
@@ -83,13 +83,10 @@ module Economic
83
83
  #
84
84
  # Returns the resulting Economic::Invoice object
85
85
  def book_with_number(number)
86
- response = session.request soap_action(:book_with_number) do
87
- soap.body = {
88
- "currentInvoiceHandle" => handle.to_hash,
89
- "number" => number,
90
- :order! => ["currentInvoiceHandle", "number"]
91
- }
92
- end
86
+ response = request(:book_with_number, {
87
+ "currentInvoiceHandle" => handle.to_hash,
88
+ "number" => number
89
+ })
93
90
 
94
91
  # Find the created Invoice
95
92
  session.invoices.find(response[:number])
@@ -134,10 +131,10 @@ module Economic
134
131
 
135
132
  protected
136
133
 
137
- # Returns OrderedHash with the properties of CurrentInvoice in the correct order, camelcased and ready
138
- # to be sent via SOAP
134
+ # Returns Hash with the properties of CurrentInvoice in the correct order,
135
+ # camelcased and ready to be sent via SOAP
139
136
  def build_soap_data
140
- data = ActiveSupport::OrderedHash.new
137
+ data = {}
141
138
 
142
139
  data['Id'] = id
143
140
  data['DebtorHandle'] = debtor.handle.to_hash unless debtor.blank?
@@ -47,10 +47,10 @@ module Economic
47
47
 
48
48
  protected
49
49
 
50
- # Returns OrderedHash with the properties of CurrentInvoice in the correct order, camelcased and ready
51
- # to be sent via SOAP
50
+ # Returns Hash with the properties of CurrentInvoice in the correct order,
51
+ # camelcased and ready to be sent via SOAP
52
52
  def build_soap_data
53
- data = ActiveSupport::OrderedHash.new
53
+ data = {}
54
54
 
55
55
  data['Number'] = 0 # Doesn't seem to be used
56
56
  data['InvoiceHandle'] = invoice.handle.to_hash unless invoice.blank?
@@ -44,7 +44,7 @@ module Economic
44
44
  protected
45
45
 
46
46
  def build_soap_data
47
- data = ActiveSupport::OrderedHash.new
47
+ data = {}
48
48
 
49
49
  data['Handle'] = handle.to_hash
50
50
  data['Number'] = handle.number
@@ -9,7 +9,7 @@ module Economic
9
9
  # Examples
10
10
  #
11
11
  # # Find contact
12
- # contact = economic.contacts.find(5)
12
+ # contact = economic.contacts.find(:id => 5)
13
13
  #
14
14
  # # Creating a contact
15
15
  # contact = debtor.contacts.build
@@ -42,7 +42,7 @@ module Economic
42
42
  protected
43
43
 
44
44
  def build_soap_data
45
- data = ActiveSupport::OrderedHash.new
45
+ data = {}
46
46
 
47
47
  data['Handle'] = handle.to_hash
48
48
  data['Id'] = handle.id
@@ -52,7 +52,7 @@ module Economic
52
52
  end
53
53
 
54
54
  # Returns the E-conomic API action name to call
55
- def soap_action(action)
55
+ def soap_action_name(action)
56
56
  class_name = self.name
57
57
  class_name_without_modules = class_name.split('::').last
58
58
  "#{class_name_without_modules.snakecase}_#{action.to_s.snakecase}".intern
@@ -133,15 +133,13 @@ module Economic
133
133
 
134
134
  # Deletes entity permanently from E-conomic.
135
135
  def destroy
136
- handleKey = "#{camel_back(class_name)}Handle"
137
- response = session.request soap_action(:delete) do
138
- soap.body = { handleKey => handle.to_hash }
139
- end
136
+ handleKey = "#{Support::String.camel_back(class_name)}Handle"
137
+ response = request(:delete, {handleKey => handle.to_hash})
140
138
 
141
139
  @persisted = false
142
140
  @partial = true
143
141
 
144
- response
142
+ response
145
143
  end
146
144
 
147
145
  # Updates properties of Entity with the values from hash
@@ -170,9 +168,9 @@ module Economic
170
168
  end
171
169
 
172
170
  def create
173
- response = session.request soap_action(:create_from_data) do
174
- soap.body = {'data' => build_soap_data}
175
- end
171
+ response = request(:create_from_data, {
172
+ 'data' => build_soap_data
173
+ })
176
174
 
177
175
  if response
178
176
  @number = response[:number]
@@ -192,9 +190,9 @@ module Economic
192
190
  end
193
191
 
194
192
  def update
195
- response = session.request soap_action(:update_from_data) do
196
- soap.body = {'data' => build_soap_data}
197
- end
193
+ response = request(:update_from_data, {
194
+ 'data' => build_soap_data
195
+ })
198
196
 
199
197
  @persisted = true
200
198
  @partial = false
@@ -202,20 +200,22 @@ module Economic
202
200
  return response
203
201
  end
204
202
 
205
- # Returns OrderedHash with the data structure to send to the API
203
+ # Returns Hash with the data structure to send to the API
206
204
  def build_soap_data
205
+ raise NotImplementedError, "Subclasses of Economic::Entity must implement `build_soap_data`"
207
206
  end
208
207
 
209
- def soap_action(action)
210
- self.class.soap_action(action)
208
+ # Requests an action from the API endpoint
209
+ def request(action, data = nil)
210
+ session.request(soap_action_name(action), data)
211
211
  end
212
212
 
213
- def class_name
214
- self.class.to_s.split("::").last
213
+ def soap_action_name(action)
214
+ self.class.soap_action_name(action)
215
215
  end
216
216
 
217
- def camel_back(name)
218
- name[0,1].downcase + name[1..-1]
217
+ def class_name
218
+ self.class.to_s.split("::").last
219
219
  end
220
220
 
221
221
  def initialize_defaults
@@ -35,9 +35,9 @@ module Economic
35
35
  end
36
36
 
37
37
  def remainder
38
- session.request(soap_action(:get_remainder)) do
39
- soap.body = { "invoiceHandle" => handle.to_hash }
40
- end
38
+ request(:get_remainder, {
39
+ "invoiceHandle" => handle.to_hash
40
+ })
41
41
  end
42
42
 
43
43
  # Returns the PDF version of Invoice as a String.
@@ -48,9 +48,9 @@ module Economic
48
48
  # file << invoice.pdf
49
49
  # end
50
50
  def pdf
51
- response = session.request soap_action(:get_pdf) do
52
- soap.body = { "invoiceHandle" => handle.to_hash }
53
- end
51
+ response = request(:get_pdf, {
52
+ "invoiceHandle" => handle.to_hash
53
+ })
54
54
 
55
55
  Base64.decode64(response)
56
56
  end
@@ -3,11 +3,9 @@ require 'economic/proxies/entity_proxy'
3
3
  module Economic
4
4
  class AccountProxy < EntityProxy
5
5
  def find_by_name(name)
6
- response = session.request entity_class.soap_action('FindByName') do
7
- soap.body = {
8
- 'name' => name
9
- }
10
- end
6
+ response = request('FindByName', {
7
+ 'name' => name
8
+ })
11
9
 
12
10
  handle = response[:account_handle]
13
11
 
@@ -19,4 +17,4 @@ module Economic
19
17
 
20
18
  end
21
19
  end
22
- end
20
+ end
@@ -2,11 +2,9 @@ module FindByCiNumber
2
2
  # Returns Debtors that have the given ci_number. The Debtor objects will only be partially loaded
3
3
  def find_by_ci_number(ci_number)
4
4
  # Get a list of handles from e-conomic
5
- response = session.request entity_class.soap_action('FindByCINumber') do
6
- soap.body = {
7
- 'ciNumber' => ci_number
8
- }
9
- end
5
+ response = request(:find_by_ci_number, {
6
+ 'ciNumber' => ci_number
7
+ })
10
8
 
11
9
  # Make sure we always have an array of handles even if the result only contains one
12
10
  handle_key = "#{entity_class_name.downcase}_handle".intern
@@ -3,13 +3,10 @@ module Economic
3
3
 
4
4
  # Returns entity objects for a given interval of days.
5
5
  def find_by_date_interval(from, unto)
6
- response = session.request entity_class.soap_action("FindByDateInterval") do
7
- soap.body = {
8
- 'first' => from.iso8601,
9
- 'last' => unto.iso8601,
10
- :order! => ['first', 'last']
11
- }
12
- end
6
+ response = request(:find_by_date_interval, {
7
+ 'first' => from.iso8601,
8
+ 'last' => unto.iso8601
9
+ })
13
10
 
14
11
  handle_key = "#{Support::String.underscore(entity_class_name)}_handle".intern
15
12
  handles = [ response[handle_key] ].flatten.reject(&:blank?).collect do |handle|
@@ -0,0 +1,71 @@
1
+ module Economic
2
+ module Proxies
3
+ module Actions
4
+ class FindByName
5
+ attr_reader :name
6
+
7
+ def initialize(caller, name)
8
+ @caller = caller
9
+ @name = name
10
+ end
11
+
12
+ def call
13
+ contacts = build_partial_contact_entities(handles_from_endpoint)
14
+ scope_to_owner(contacts)
15
+ end
16
+
17
+ private
18
+
19
+ def build(*options)
20
+ @caller.build(options)
21
+ end
22
+
23
+ def build_partial_contact_entities(handles)
24
+ handles.collect do |handle|
25
+ contact = build
26
+ contact.partial = true
27
+ contact.persisted = true
28
+ contact.handle = handle
29
+ contact.id = handle[:id]
30
+ contact.number = handle[:number]
31
+ contact
32
+ end
33
+ end
34
+
35
+ def handles_from_endpoint
36
+ [response[handle_key]].flatten.reject(&:blank?)
37
+ end
38
+
39
+ def handle_key
40
+ (Support::String.underscore(@caller.class.entity_class_name) + "_handle").to_sym
41
+ end
42
+
43
+ def owner
44
+ @caller.owner
45
+ end
46
+
47
+ def request(action, data)
48
+ @caller.request(action, data)
49
+ end
50
+
51
+ def response
52
+ request('FindByName', {'name' => name})
53
+ end
54
+
55
+ def scope_to_owner(contacts)
56
+ if owner.is_a?(Session)
57
+ contacts
58
+ else
59
+ owner_type = Support::String.underscore(
60
+ Support::String.demodulize(owner.class.name)
61
+ )
62
+ contacts.select do |contact|
63
+ contact.get_data
64
+ contact.send(owner_type) == owner
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end