economic-rest 0.6.3 → 0.6.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/.ruby-version +1 -0
  3. data/Gemfile.lock +98 -96
  4. data/README.md +87 -1
  5. data/economic-rest.gemspec +6 -7
  6. data/lib/economic/accounting_year_repo.rb +2 -0
  7. data/lib/economic/attribute.rb +9 -0
  8. data/lib/economic/base_repo.rb +7 -12
  9. data/lib/economic/configuration.rb +7 -0
  10. data/lib/economic/credentials.rb +26 -0
  11. data/lib/economic/customer_contact_repo.rb +2 -0
  12. data/lib/economic/customer_repo.rb +2 -0
  13. data/lib/economic/invoice.rb +0 -25
  14. data/lib/economic/invoices/booked_repo.rb +1 -1
  15. data/lib/economic/invoices/drafts_repo.rb +2 -0
  16. data/lib/economic/invoices/repo.rb +1 -1
  17. data/lib/economic/line.rb +0 -21
  18. data/lib/economic/model.rb +99 -0
  19. data/lib/economic/models/accounting_year.rb +9 -0
  20. data/lib/economic/models/attention.rb +8 -0
  21. data/lib/economic/models/customer.rb +41 -0
  22. data/lib/economic/models/customer_group.rb +11 -0
  23. data/lib/economic/models/customers/contact.rb +19 -0
  24. data/lib/economic/models/invoice.rb +32 -0
  25. data/lib/economic/models/invoices/booked.rb +11 -0
  26. data/lib/economic/models/invoices/draft.rb +9 -0
  27. data/lib/economic/models/layout.rb +9 -0
  28. data/lib/economic/models/line.rb +21 -0
  29. data/lib/economic/models/note.rb +9 -0
  30. data/lib/economic/models/payment_term.rb +10 -0
  31. data/lib/economic/models/product.rb +22 -0
  32. data/lib/economic/models/recipient.rb +17 -0
  33. data/lib/economic/models/reference.rb +11 -0
  34. data/lib/economic/models/sales_person.rb +7 -0
  35. data/lib/economic/models/unit.rb +8 -0
  36. data/lib/economic/models/vat_zone.rb +10 -0
  37. data/lib/economic/models/vendor_reference.rb +7 -0
  38. data/lib/economic/nested_base_repo.rb +0 -5
  39. data/lib/economic/orders/repo.rb +1 -1
  40. data/lib/economic/relation.rb +17 -0
  41. data/lib/economic/repo.rb +127 -0
  42. data/lib/economic/repos/accounting_year.rb +6 -0
  43. data/lib/economic/repos/customer.rb +6 -0
  44. data/lib/economic/repos/customers/contact.rb +21 -0
  45. data/lib/economic/repos/invoices/booked.rb +19 -0
  46. data/lib/economic/repos/invoices/draft.rb +8 -0
  47. data/lib/economic/repos/invoices/drafts/line.rb +26 -0
  48. data/lib/economic/response/pagination.rb +16 -0
  49. data/lib/economic/response.rb +51 -0
  50. data/lib/economic/rest/version.rb +1 -1
  51. data/lib/economic/rest.rb +41 -6
  52. metadata +52 -34
  53. data/lib/economic/concerns/soap_methods.rb +0 -217
  54. data/lib/economic/soap_api.rb +0 -24
@@ -0,0 +1,51 @@
1
+ module Economic
2
+ class Response
3
+ def initialize(self_link:, meta_data:, pagination: nil, collection: nil, entity: nil)
4
+ @self_link = self_link
5
+ @meta_data = meta_data
6
+ @pagination = pagination
7
+ @collection = collection
8
+ @entity = entity
9
+ end
10
+
11
+ attr_accessor :self_link, :meta_data, :pagination, :collection, :entity
12
+
13
+ class << self
14
+ def from_json(json)
15
+ parsed = JSON.parse(json)
16
+
17
+ if parsed.key?("collection")
18
+ endpoint = parsed["self"][30..].split("?").first
19
+ model_class = model_class_from_endpoint(endpoint)
20
+
21
+ collection = parsed["collection"].map do |hash|
22
+ # This method is very heavy. It takes about 2 seconds to run test/resources/customer_resource_test.rb:9, which instantiates 3684 customers
23
+ # Not instantiating them results in a runtime of 0.056 seconds.
24
+ model_class.from_hash(hash)
25
+ end
26
+
27
+ new(
28
+ collection: collection,
29
+ meta_data: parsed["metaData"],
30
+ self_link: parsed["self"],
31
+ pagination: Economic::Response::Pagination.from_hash(parsed["pagination"])
32
+ )
33
+ else
34
+ # find model class
35
+ endpoint = parsed["self"][30..].split("/")[0..-2].join("/")
36
+ model_class = model_class_from_endpoint(endpoint)
37
+
38
+ new(
39
+ entity: model_class.from_json(json),
40
+ self_link: parsed["self"],
41
+ meta_data: parsed["metaData"]
42
+ )
43
+ end
44
+ end
45
+
46
+ def model_class_from_endpoint(endpoint)
47
+ "Economic::Models::#{endpoint.underscore.tr("0-9", "").gsub("//", "/").classify}".constantize
48
+ end
49
+ end
50
+ end
51
+ end
@@ -1,5 +1,5 @@
1
1
  module Economic
2
2
  module Rest
3
- VERSION = "0.6.3".freeze
3
+ VERSION = "0.6.4".freeze
4
4
  end
5
5
  end
data/lib/economic/rest.rb CHANGED
@@ -1,14 +1,49 @@
1
1
  require "economic/rest/version"
2
2
 
3
3
  require "rest-client"
4
- require "savon"
5
4
  require "active_support/inflector"
5
+ require "active_support/core_ext/object/blank"
6
+ require "active_support/core_ext/object/try"
7
+ require "active_support/core_ext/hash/reverse_merge"
6
8
 
7
9
  require "economic/base_repo"
8
10
  require "economic/nested_base_repo"
9
11
  require "economic/base"
10
- require "economic/soap_api"
11
- require "economic/concerns/soap_methods"
12
+ require "economic/configuration"
13
+ require "economic/credentials"
14
+ require "economic/model"
15
+ require "economic/attribute"
16
+ require "economic/relation"
17
+ require "economic/repo"
18
+
19
+ require "economic/response"
20
+ require "economic/response/pagination"
21
+
22
+ require "economic/repos/accounting_year"
23
+ require "economic/models/accounting_year"
24
+ require "economic/repos/customer"
25
+ require "economic/models/customer"
26
+ require "economic/models/customer_group"
27
+ require "economic/models/payment_term"
28
+ require "economic/models/vat_zone"
29
+ require "economic/models/invoice"
30
+ require "economic/repos/invoices/draft"
31
+ require "economic/models/invoices/draft"
32
+ require "economic/repos/invoices/drafts/line"
33
+ require "economic/repos/invoices/booked"
34
+ require "economic/models/invoices/booked"
35
+ require "economic/models/line"
36
+ require "economic/models/product"
37
+ require "economic/models/unit"
38
+ require "economic/models/recipient"
39
+ require "economic/models/note"
40
+ require "economic/models/reference"
41
+ require "economic/models/customers/contact"
42
+ require "economic/repos/customers/contact"
43
+ require "economic/models/sales_person"
44
+ require "economic/models/vendor_reference"
45
+ require "economic/models/layout"
46
+ require "economic/models/attention"
12
47
 
13
48
  require "economic/attention"
14
49
  require "economic/currency"
@@ -107,9 +142,9 @@ module Economic
107
142
  class Demo
108
143
  def self.hello
109
144
  RestClient.get("https://restapi.e-conomic.com/",
110
- 'X-AppSecretToken': "Demo",
111
- 'X-AgreementGrantToken': "Demo",
112
- 'Content-Type': "application/json")
145
+ "X-AppSecretToken": "Demo",
146
+ "X-AgreementGrantToken": "Demo",
147
+ "Content-Type": "application/json")
113
148
  end
114
149
  end
115
150
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: economic-rest
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.3
4
+ version: 0.6.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter Klogborg
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-09-26 00:00:00.000000000 Z
11
+ date: 2024-10-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.17'
19
+ version: '2.4'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '1.17'
26
+ version: '2.4'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: m
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -44,28 +44,28 @@ dependencies:
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '5.0'
47
+ version: '5.25'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '5.0'
54
+ version: '5.25'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: rake
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: '10.0'
61
+ version: '13.2'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: '10.0'
68
+ version: '13.2'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: simplecov
71
71
  requirement: !ruby/object:Gem::Requirement
@@ -86,14 +86,14 @@ dependencies:
86
86
  requirements:
87
87
  - - "~>"
88
88
  - !ruby/object:Gem::Version
89
- version: '3.5'
89
+ version: '3.24'
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
94
  - - "~>"
95
95
  - !ruby/object:Gem::Version
96
- version: '3.5'
96
+ version: '3.24'
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: dotenv
99
99
  requirement: !ruby/object:Gem::Requirement
@@ -164,48 +164,34 @@ dependencies:
164
164
  - - ">="
165
165
  - !ruby/object:Gem::Version
166
166
  version: '0'
167
- - !ruby/object:Gem::Dependency
168
- name: savon
169
- requirement: !ruby/object:Gem::Requirement
170
- requirements:
171
- - - ">="
172
- - !ruby/object:Gem::Version
173
- version: '0'
174
- type: :runtime
175
- prerelease: false
176
- version_requirements: !ruby/object:Gem::Requirement
177
- requirements:
178
- - - ">="
179
- - !ruby/object:Gem::Version
180
- version: '0'
181
167
  - !ruby/object:Gem::Dependency
182
168
  name: rest-client
183
169
  requirement: !ruby/object:Gem::Requirement
184
170
  requirements:
185
- - - ">="
171
+ - - "~>"
186
172
  - !ruby/object:Gem::Version
187
- version: '0'
173
+ version: '2.1'
188
174
  type: :runtime
189
175
  prerelease: false
190
176
  version_requirements: !ruby/object:Gem::Requirement
191
177
  requirements:
192
- - - ">="
178
+ - - "~>"
193
179
  - !ruby/object:Gem::Version
194
- version: '0'
180
+ version: '2.1'
195
181
  - !ruby/object:Gem::Dependency
196
182
  name: activesupport
197
183
  requirement: !ruby/object:Gem::Requirement
198
184
  requirements:
199
- - - ">="
185
+ - - "~>"
200
186
  - !ruby/object:Gem::Version
201
- version: '0'
187
+ version: '7.0'
202
188
  type: :runtime
203
189
  prerelease: false
204
190
  version_requirements: !ruby/object:Gem::Requirement
205
191
  requirements:
206
- - - ">="
192
+ - - "~>"
207
193
  - !ruby/object:Gem::Version
208
- version: '0'
194
+ version: '7.0'
209
195
  description:
210
196
  email:
211
197
  - klogborg@traels.it
@@ -214,6 +200,7 @@ extensions: []
214
200
  extra_rdoc_files: []
215
201
  files:
216
202
  - ".gitignore"
203
+ - ".ruby-version"
217
204
  - ".vscode/settings.json"
218
205
  - CODE_OF_CONDUCT.md
219
206
  - Gemfile
@@ -230,12 +217,14 @@ files:
230
217
  - lib/economic/accounting_year_repo.rb
231
218
  - lib/economic/accounts_summed.rb
232
219
  - lib/economic/attention.rb
220
+ - lib/economic/attribute.rb
233
221
  - lib/economic/base.rb
234
222
  - lib/economic/base_repo.rb
235
223
  - lib/economic/company.rb
236
- - lib/economic/concerns/soap_methods.rb
224
+ - lib/economic/configuration.rb
237
225
  - lib/economic/contra_account.rb
238
226
  - lib/economic/cost_account.rb
227
+ - lib/economic/credentials.rb
239
228
  - lib/economic/currency.rb
240
229
  - lib/economic/customer.rb
241
230
  - lib/economic/customer_contact.rb
@@ -265,6 +254,26 @@ files:
265
254
  - lib/economic/layout.rb
266
255
  - lib/economic/layout_repo.rb
267
256
  - lib/economic/line.rb
257
+ - lib/economic/model.rb
258
+ - lib/economic/models/accounting_year.rb
259
+ - lib/economic/models/attention.rb
260
+ - lib/economic/models/customer.rb
261
+ - lib/economic/models/customer_group.rb
262
+ - lib/economic/models/customers/contact.rb
263
+ - lib/economic/models/invoice.rb
264
+ - lib/economic/models/invoices/booked.rb
265
+ - lib/economic/models/invoices/draft.rb
266
+ - lib/economic/models/layout.rb
267
+ - lib/economic/models/line.rb
268
+ - lib/economic/models/note.rb
269
+ - lib/economic/models/payment_term.rb
270
+ - lib/economic/models/product.rb
271
+ - lib/economic/models/recipient.rb
272
+ - lib/economic/models/reference.rb
273
+ - lib/economic/models/sales_person.rb
274
+ - lib/economic/models/unit.rb
275
+ - lib/economic/models/vat_zone.rb
276
+ - lib/economic/models/vendor_reference.rb
268
277
  - lib/economic/nested_base_repo.rb
269
278
  - lib/economic/notes.rb
270
279
  - lib/economic/order.rb
@@ -286,14 +295,23 @@ files:
286
295
  - lib/economic/project.rb
287
296
  - lib/economic/recipient.rb
288
297
  - lib/economic/references.rb
298
+ - lib/economic/relation.rb
289
299
  - lib/economic/remittance_advice.rb
300
+ - lib/economic/repo.rb
301
+ - lib/economic/repos/accounting_year.rb
302
+ - lib/economic/repos/customer.rb
303
+ - lib/economic/repos/customers/contact.rb
304
+ - lib/economic/repos/invoices/booked.rb
305
+ - lib/economic/repos/invoices/draft.rb
306
+ - lib/economic/repos/invoices/drafts/line.rb
307
+ - lib/economic/response.rb
308
+ - lib/economic/response/pagination.rb
290
309
  - lib/economic/rest.rb
291
310
  - lib/economic/rest/version.rb
292
311
  - lib/economic/sales_person.rb
293
312
  - lib/economic/self.rb
294
313
  - lib/economic/self_repo.rb
295
314
  - lib/economic/session.rb
296
- - lib/economic/soap_api.rb
297
315
  - lib/economic/supplier.rb
298
316
  - lib/economic/supplier_contact.rb
299
317
  - lib/economic/supplier_group.rb
@@ -1,217 +0,0 @@
1
- require "active_support/concern"
2
-
3
- module Economic
4
- module SoapMethods
5
- extend ActiveSupport::Concern
6
-
7
- class_methods do
8
- def find(id)
9
- result = Economic::SoapAPI.call(
10
- soap_method_names[:find][:method],
11
- message: {soap_method_names[:find][:handle] => {Id: id}}
12
- )
13
-
14
- model.build_from_soap_api(result)
15
- end
16
-
17
- def all
18
- result = Economic::SoapAPI.call(
19
- soap_method_names[:all][:method],
20
- )
21
-
22
- ids = result_array(result[soap_method_names[:all][:handle]]).map { |record|
23
- record[:id].to_i
24
- }
25
-
26
- find_all_records(ids)
27
- end
28
-
29
- def send(model)
30
- # There is a current_invoice_create_from_data_array method for bulk creation of invoices as well, but bulk
31
- # creation is not supported by the e-conomic REST api or any other REST api. To avoid implementing
32
- # functionality that will be removed once e-conomic finish the REST api, we only use the standard create end
33
- # point
34
-
35
- result = Economic::SoapAPI.call(
36
- soap_method_names[:send][:method], message: {
37
- data: {
38
- Handle: {
39
- Id: model.id_key,
40
- },
41
- DebtorHandle: {
42
- Number: model.customer.customer_number,
43
- },
44
- DebtorName: model.customer.name,
45
- Date: to_iso8601z(model.date.to_datetime),
46
- TermOfPaymentHandle: {
47
- Id: model.payment_terms.payment_terms_number,
48
- },
49
- DueDate: to_iso8601z(model.due_date.to_datetime),
50
- CurrencyHandle: {
51
- Code: model.currency,
52
- },
53
- ExchangeRate: model.exchange_rate,
54
- IsVatIncluded: is_vat_included?(model),
55
- LayoutHandle: {
56
- Id: model.layout.layout_number,
57
- },
58
- DeliveryAddress: model.delivery.address,
59
- DeliveryPostalCode: model.delivery.zip,
60
- DeliveryCity: model.delivery.city,
61
- DeliveryCountry: model.delivery.country,
62
- DeliveryDate: to_iso8601z(model.delivery.delivery_date.to_datetime),
63
- Heading: model.notes.heading,
64
- NetAmount: model.net_amount,
65
- VatAmount: model.vat_amount,
66
- GrossAmount: model.gross_amount,
67
- Margin: model.margin_in_base_currency,
68
- MarginAsPercent: model.margin_percentage,
69
- },
70
- }
71
- )
72
-
73
- model.id_key = result[:id]
74
-
75
- create_lines(model) if model.lines.any?
76
-
77
- find(result[:id].to_i)
78
- end
79
-
80
- def find_lines(invoice_id)
81
- result = Economic::SoapAPI.call(
82
- soap_method_names[:find_lines][:method],
83
- message: {soap_method_names[:find_lines][:handle] => {Id: invoice_id}}
84
- )
85
-
86
- return if result.nil?
87
-
88
- line_ids = result_array(result[soap_method_names[:find_lines][:line_handle]]).map { |line|
89
- line[:number].to_i
90
- }
91
-
92
- find_all_lines(invoice_id, line_ids)
93
- end
94
-
95
- def destroy(id)
96
- # The SoapAPI raises an exception if the record you try to delete is missing
97
-
98
- result = Economic::SoapAPI.call(
99
- soap_method_names[:destroy][:method],
100
- message: {soap_method_names[:destroy][:handle] => {Id: id}}
101
- )
102
-
103
- true
104
- rescue Savon::SOAPFault
105
- false
106
- end
107
-
108
- private
109
-
110
- # Since the soap api returns hashes, if there is a single record, and arrays, if there are more, this method
111
- # wraps a response in an array, if it is not already.
112
- def result_array(result)
113
- return result if result.is_a? Array
114
-
115
- [result]
116
- end
117
-
118
- def create_lines(model)
119
- Economic::SoapAPI.call(
120
- soap_method_names[:create_lines][:method], message: {
121
- dataArray: build_line_data_array(model),
122
- }
123
- )
124
- end
125
-
126
- def find_all_lines(invoice_id, line_ids)
127
- result = Economic::SoapAPI.call(
128
- soap_method_names[:find_all_lines][:method],
129
- message: {soap_method_names[:find_all_lines][:handle] => line_ids_array(invoice_id, line_ids, handle: soap_method_names[:find_all_lines][:line_handle])}
130
- )
131
-
132
- result_array(result[soap_method_names[:find_all_lines][:data]]).map do |data|
133
- Economic::Line.build_from_soap_api(data)
134
- end
135
- end
136
-
137
- def find_all_records(invoice_ids)
138
- result = Economic::SoapAPI.call(
139
- soap_method_names[:find_all_records][:method],
140
- message: {
141
- entityHandles: ids_array(invoice_ids, handle: soap_method_names[:find_all_records][:handle]),
142
- }
143
- )
144
-
145
- result[soap_method_names[:find_all_records][:data]].map do |data|
146
- model.build_from_soap_api(data)
147
- end
148
- end
149
-
150
- def line_ids_array(order_id, line_ids, handle:)
151
- arr = [handle => []]
152
-
153
- line_ids.each do |line_id|
154
- arr.first[handle].push(
155
- {
156
- Id: order_id,
157
- Number: line_id,
158
- }
159
- )
160
- end
161
-
162
- arr
163
- end
164
-
165
- def ids_array(invoice_ids, handle:)
166
- arr = [handle => []]
167
-
168
- invoice_ids.each do |invoice_id|
169
- arr.first[handle].push(
170
- {
171
- Id: invoice_id,
172
- }
173
- )
174
- end
175
-
176
- arr
177
- end
178
-
179
- def build_line_data_array(order)
180
- arr = [soap_method_names[:create_lines][:line_data_handle] => []]
181
-
182
- order.lines.each do |line|
183
- arr.first[soap_method_names[:create_lines][:line_data_handle]].push(
184
- {
185
- :Handle => {
186
- Id: order.id_key,
187
- Number: line.line_number, # must be sent - does not have to fit with the next linenumber
188
- },
189
- :Id => order.id_key,
190
- :Number => line.line_number, # must be sent - does not have to fit with the next linenumber
191
- soap_method_names[:create_lines][:model_handle] => {
192
- Id: order.id_key,
193
- },
194
- :Description => line.description,
195
- :DeliveryDate => line.delivery.delivery_date,
196
- :UnitHandle => {Number: line.unit.unit_number},
197
- :ProductHandle => {Number: line.product.product_number},
198
- :Quantity => line.quantity,
199
- :UnitNetPrice => line.unit_net_price,
200
- :DiscountAsPercent => line.discount_percentage,
201
- :UnitCostPrice => line.unit_cost_price,
202
- :TotalNetAmount => line.total_net_amount, # TODO: Should this not be sent?
203
- :TotalMargin => line.margin_in_base_currency,
204
- :MarginAsPercent => line.margin_percentage,
205
- }
206
- )
207
- end
208
-
209
- arr
210
- end
211
-
212
- def is_vat_included?(model)
213
- model.vat_amount != 0
214
- end
215
- end
216
- end
217
- end
@@ -1,24 +0,0 @@
1
- module Economic
2
- class SoapAPI
3
- URL = "https://api.e-conomic.com/secure/api1/EconomicWebService.asmx?WSDL".freeze
4
-
5
- class << self
6
- def call(method, message: {})
7
- response = client.call(method, message: message, cookies: auth_cookies)
8
-
9
- response.body["#{method}_response".to_sym]["#{method}_result".to_sym]
10
- end
11
-
12
- def auth_cookies
13
- @auth_cookies ||= client.call(:connect_with_token, message: {token: Economic::Session.agreement_grant_token, appToken: Economic::Session.app_secret_token}).http.cookies
14
- end
15
-
16
- def client
17
- @client ||= Savon.client {
18
- wsdl(URL)
19
- convert_request_keys_to :none # or one of [:lower_camelcase, :upcase, :none]
20
- }
21
- end
22
- end
23
- end
24
- end