economic-rest 0.3.6 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +3 -0
- data/.vscode/settings.json +9 -0
- data/Gemfile.lock +67 -1
- data/README.md +21 -14
- data/economic-rest.gemspec +5 -0
- data/lib/economic/base.rb +36 -13
- data/lib/economic/base_repo.rb +9 -0
- data/lib/economic/concerns/soap_methods.rb +183 -0
- data/lib/economic/invoice.rb +56 -0
- data/lib/economic/invoices/booked_repo.rb +6 -0
- data/lib/economic/invoices/drafts_repo.rb +42 -0
- data/lib/economic/invoices/not_due_repo.rb +6 -0
- data/lib/economic/invoices/overdue_repo.rb +6 -0
- data/lib/economic/invoices/paid_repo.rb +6 -0
- data/lib/economic/invoices/repo.rb +6 -0
- data/lib/economic/invoices/sent_repo.rb +6 -0
- data/lib/economic/invoices/unpaid_repo.rb +6 -0
- data/lib/economic/line.rb +39 -0
- data/lib/economic/payment_terms_repo.rb +4 -0
- data/lib/economic/rest.rb +20 -1
- data/lib/economic/rest/version.rb +1 -1
- data/lib/economic/soap_api.rb +24 -0
- metadata +86 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7fbacaa257420baadb45e16d45ad531689e6d14d3be3cdf6571ad0a8abc791d7
|
4
|
+
data.tar.gz: cd2f866670a486f601f63da4c8a1c5bdf40289db6caae73036f471aca8200818
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0e923292ba32f2adf4832e261cfc38e6f3328cbdec42a19219b11c9133509a1e5e6fb15deb36ae169612dcb769edfde2058db848c42b0dfd0104de8c556252d7
|
7
|
+
data.tar.gz: 51e379f96f4907a9dfcdbd070fd3f8d6bb942456db674db9eb1e04faba186853cdf1b1a81d39fbf5bf55db031ebed3bbdbbb63047c137f5ff04fa4092cfb4bdb
|
data/.gitignore
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,23 +1,48 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
economic-rest (0.
|
4
|
+
economic-rest (0.4.0)
|
5
|
+
activesupport
|
6
|
+
awesome_print
|
5
7
|
rest-client
|
8
|
+
savon
|
6
9
|
|
7
10
|
GEM
|
8
11
|
remote: https://rubygems.org/
|
9
12
|
specs:
|
13
|
+
activesupport (6.0.0)
|
14
|
+
concurrent-ruby (~> 1.0, >= 1.0.2)
|
15
|
+
i18n (>= 0.7, < 2)
|
16
|
+
minitest (~> 5.1)
|
17
|
+
tzinfo (~> 1.1)
|
18
|
+
zeitwerk (~> 2.1, >= 2.1.8)
|
10
19
|
addressable (2.5.2)
|
11
20
|
public_suffix (>= 2.0.2, < 4.0)
|
21
|
+
akami (1.3.1)
|
22
|
+
gyoku (>= 0.4.0)
|
23
|
+
nokogiri
|
24
|
+
ast (2.4.0)
|
25
|
+
awesome_print (1.8.0)
|
26
|
+
builder (3.2.3)
|
27
|
+
concurrent-ruby (1.1.5)
|
12
28
|
crack (0.4.3)
|
13
29
|
safe_yaml (~> 1.0.0)
|
14
30
|
docile (1.3.1)
|
15
31
|
domain_name (0.5.20190701)
|
16
32
|
unf (>= 0.0.5, < 1.0.0)
|
33
|
+
dotenv (2.7.4)
|
34
|
+
gyoku (1.3.1)
|
35
|
+
builder (>= 2.1.2)
|
17
36
|
hashdiff (0.3.8)
|
18
37
|
http-accept (1.7.0)
|
19
38
|
http-cookie (1.0.3)
|
20
39
|
domain_name (~> 0.5)
|
40
|
+
httpi (2.4.4)
|
41
|
+
rack
|
42
|
+
socksify
|
43
|
+
i18n (1.6.0)
|
44
|
+
concurrent-ruby (~> 1.0)
|
45
|
+
jaro_winkler (1.5.3)
|
21
46
|
json (2.1.0)
|
22
47
|
m (1.5.1)
|
23
48
|
method_source (>= 0.6.7)
|
@@ -26,39 +51,80 @@ GEM
|
|
26
51
|
mime-types (3.3)
|
27
52
|
mime-types-data (~> 3.2015)
|
28
53
|
mime-types-data (3.2019.0904)
|
54
|
+
mini_portile2 (2.4.0)
|
29
55
|
minitest (5.11.3)
|
30
56
|
netrc (0.11.0)
|
57
|
+
nokogiri (1.10.4)
|
58
|
+
mini_portile2 (~> 2.4.0)
|
59
|
+
nori (2.6.0)
|
60
|
+
parallel (1.17.0)
|
61
|
+
parser (2.6.4.1)
|
62
|
+
ast (~> 2.4.0)
|
31
63
|
public_suffix (3.0.3)
|
64
|
+
rack (2.0.7)
|
65
|
+
rainbow (3.0.0)
|
32
66
|
rake (10.5.0)
|
33
67
|
rest-client (2.1.0)
|
34
68
|
http-accept (>= 1.7.0, < 2.0)
|
35
69
|
http-cookie (>= 1.0.2, < 2.0)
|
36
70
|
mime-types (>= 1.16, < 4.0)
|
37
71
|
netrc (~> 0.8)
|
72
|
+
rubocop (0.72.0)
|
73
|
+
jaro_winkler (~> 1.5.1)
|
74
|
+
parallel (~> 1.10)
|
75
|
+
parser (>= 2.6)
|
76
|
+
rainbow (>= 2.2.2, < 4.0)
|
77
|
+
ruby-progressbar (~> 1.7)
|
78
|
+
unicode-display_width (>= 1.4.0, < 1.7)
|
79
|
+
rubocop-performance (1.4.1)
|
80
|
+
rubocop (>= 0.71.0)
|
81
|
+
ruby-progressbar (1.10.1)
|
38
82
|
safe_yaml (1.0.4)
|
83
|
+
savon (2.12.0)
|
84
|
+
akami (~> 1.2)
|
85
|
+
builder (>= 2.1.2)
|
86
|
+
gyoku (~> 1.2)
|
87
|
+
httpi (~> 2.3)
|
88
|
+
nokogiri (>= 1.8.1)
|
89
|
+
nori (~> 2.4)
|
90
|
+
wasabi (~> 3.4)
|
39
91
|
simplecov (0.16.1)
|
40
92
|
docile (~> 1.1)
|
41
93
|
json (>= 1.8, < 3)
|
42
94
|
simplecov-html (~> 0.10.0)
|
43
95
|
simplecov-html (0.10.2)
|
96
|
+
socksify (1.7.1)
|
97
|
+
standard (0.1.4)
|
98
|
+
rubocop (~> 0.72.0)
|
99
|
+
rubocop-performance (~> 1.4.0)
|
100
|
+
thread_safe (0.3.6)
|
101
|
+
tzinfo (1.2.5)
|
102
|
+
thread_safe (~> 0.1)
|
44
103
|
unf (0.1.4)
|
45
104
|
unf_ext
|
46
105
|
unf_ext (0.0.7.6)
|
106
|
+
unicode-display_width (1.6.0)
|
107
|
+
wasabi (3.5.0)
|
108
|
+
httpi (~> 2.0)
|
109
|
+
nokogiri (>= 1.4.2)
|
47
110
|
webmock (3.5.1)
|
48
111
|
addressable (>= 2.3.6)
|
49
112
|
crack (>= 0.3.2)
|
50
113
|
hashdiff
|
114
|
+
zeitwerk (2.1.10)
|
51
115
|
|
52
116
|
PLATFORMS
|
53
117
|
ruby
|
54
118
|
|
55
119
|
DEPENDENCIES
|
56
120
|
bundler (~> 1.17)
|
121
|
+
dotenv
|
57
122
|
economic-rest!
|
58
123
|
m
|
59
124
|
minitest (~> 5.0)
|
60
125
|
rake (~> 10.0)
|
61
126
|
simplecov
|
127
|
+
standard
|
62
128
|
webmock (~> 3.5)
|
63
129
|
|
64
130
|
BUNDLED WITH
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Economic::Rest
|
2
2
|
|
3
|
-
|
3
|
+
[![Build Status](https://semaphoreci.com/api/v1/traels-it/economic-rest/branches/master/badge.svg)](https://semaphoreci.com/traels-it/economic-rest)
|
4
4
|
|
5
5
|
Ruby wrapper for the e-conomic REST API, that aims at making working with the API bearable.
|
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.co.uk/integration/integration-partner/'.
|
@@ -25,33 +25,40 @@ Or install it yourself as:
|
|
25
25
|
|
26
26
|
## Usage
|
27
27
|
|
28
|
+
```ruby
|
28
29
|
require 'economic/rest'
|
29
30
|
|
30
31
|
Economic::Demo.hello
|
32
|
+
```
|
31
33
|
|
32
34
|
Filter text can be added to the all query to avoid getting everything. e.g. a method for finding an accounting year for a specific date
|
33
35
|
|
36
|
+
```ruby
|
34
37
|
def get_accounting_year(date)
|
35
38
|
Economic::AccountingYearRepo.all(filter_text: "toDate$gte:#{date}$and:fromDate$lte:#{date}")
|
36
39
|
end
|
40
|
+
```
|
37
41
|
|
38
42
|
note: you need to use Lower Camel Case for variable names.
|
39
|
-
|
43
|
+
|
44
|
+
### Filter Operators
|
40
45
|
|
41
46
|
The allowed filtering operators are:
|
42
47
|
|
43
|
-
Operator
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
Greater than
|
48
|
-
|
49
|
-
Less than
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
48
|
+
| Operator | Syntax |
|
49
|
+
| -------- | --------- |
|
50
|
+
| Equals | `$eq:` |
|
51
|
+
| Not equals | `$ne:` |
|
52
|
+
| Greater than | `$gt:` |
|
53
|
+
| Greater than or equal | `$gte:` |
|
54
|
+
| Less than | `$lt:` |
|
55
|
+
| Less than or equal | `$lte:` |
|
56
|
+
| Substring match | `$like:` |
|
57
|
+
| And also | `$and:` |
|
58
|
+
| Or else | `$or:` |
|
59
|
+
| In | `$in:` |
|
60
|
+
| Not In | `$nin:` |
|
61
|
+
|
55
62
|
copy pasta from https://restdocs.e-conomic.com/#specifying-operator-affinity
|
56
63
|
|
57
64
|
## Development
|
data/economic-rest.gemspec
CHANGED
@@ -29,6 +29,11 @@ The documentation can be found at https://restdocs.e-conomic.com'
|
|
29
29
|
spec.add_development_dependency "rake", "~> 10.0"
|
30
30
|
spec.add_development_dependency "simplecov"
|
31
31
|
spec.add_development_dependency "webmock", "~> 3.5"
|
32
|
+
spec.add_development_dependency "dotenv"
|
33
|
+
spec.add_development_dependency "standard"
|
32
34
|
|
35
|
+
spec.add_dependency "savon"
|
33
36
|
spec.add_dependency "rest-client"
|
37
|
+
spec.add_dependency "activesupport"
|
38
|
+
spec.add_dependency "awesome_print"
|
34
39
|
end
|
data/lib/economic/base.rb
CHANGED
@@ -12,8 +12,8 @@ module Economic
|
|
12
12
|
(@attributes ||= []).push(name)
|
13
13
|
end
|
14
14
|
|
15
|
-
def self.add_relation(name, fields)
|
16
|
-
(@relations ||= []).push(name: name, fields: fields)
|
15
|
+
def self.add_relation(name, fields, multiple)
|
16
|
+
(@relations ||= []).push(name: name, fields: fields, multiple: multiple)
|
17
17
|
end
|
18
18
|
|
19
19
|
def self.field(name, id: false)
|
@@ -22,13 +22,19 @@ module Economic
|
|
22
22
|
alias_method snake_case(economic_cased_attibute_name), economic_cased_attibute_name
|
23
23
|
alias_method "#{snake_case(economic_cased_attibute_name)}=", "#{economic_cased_attibute_name}="
|
24
24
|
alias_method "id_key", economic_cased_attibute_name if id
|
25
|
+
alias_method "id_key=", "#{economic_cased_attibute_name}=" if id
|
25
26
|
add_attribute economic_cased_attibute_name
|
26
27
|
end
|
27
28
|
|
28
|
-
def self.relation(name, fields:)
|
29
|
+
def self.relation(name, fields:, multiple: false)
|
29
30
|
economic_cased_attibute_name = name.to_s
|
30
|
-
add_relation economic_cased_attibute_name, fields
|
31
|
-
|
31
|
+
add_relation economic_cased_attibute_name, fields, multiple
|
32
|
+
if multiple
|
33
|
+
attr_accessor economic_cased_attibute_name
|
34
|
+
alias_method "#{snake_case(economic_cased_attibute_name)}=", "#{economic_cased_attibute_name}="
|
35
|
+
else
|
36
|
+
attr_reader economic_cased_attibute_name
|
37
|
+
end
|
32
38
|
alias_method snake_case(economic_cased_attibute_name), economic_cased_attibute_name
|
33
39
|
end
|
34
40
|
|
@@ -39,10 +45,18 @@ module Economic
|
|
39
45
|
end
|
40
46
|
|
41
47
|
self.class.relations&.each do |relation_hash|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
48
|
+
if relation_hash[:multiple]
|
49
|
+
relation_name = relation_hash[:name]
|
50
|
+
model_name = relation_hash[:name].singularize
|
51
|
+
related_model_array = @internal_hash[relation_name]&.map { |data|
|
52
|
+
model_class(model_name).new(data)
|
53
|
+
}
|
54
|
+
instance_variable_set("@#{relation_name}", related_model_array)
|
55
|
+
else
|
56
|
+
name = relation_hash[:name]
|
57
|
+
related_model = model_class(name).new(@internal_hash[name])
|
58
|
+
instance_variable_set("@#{name}", related_model)
|
59
|
+
end
|
46
60
|
end
|
47
61
|
end
|
48
62
|
|
@@ -56,12 +70,21 @@ module Economic
|
|
56
70
|
end
|
57
71
|
|
58
72
|
self.class.relations&.each do |relation_hash|
|
59
|
-
|
60
|
-
|
73
|
+
if relation_hash[:multiple]
|
74
|
+
relation_name = relation_hash[:name]
|
75
|
+
relation_fields = relation_hash[:fields]
|
76
|
+
|
77
|
+
arr = public_send(relation_name).map { |relation| relation_data = relation.to_h(only_fields: relation_fields) }
|
78
|
+
|
79
|
+
return_hash[relation_name] = arr
|
80
|
+
else
|
81
|
+
relation_name = relation_hash[:name]
|
82
|
+
relation_fields = relation_hash[:fields]
|
61
83
|
|
62
|
-
|
84
|
+
relation_data = public_send(relation_name).to_h(only_fields: relation_fields)
|
63
85
|
|
64
|
-
|
86
|
+
return_hash[relation_name] = relation_data unless relation_data.empty?
|
87
|
+
end
|
65
88
|
end
|
66
89
|
return_hash
|
67
90
|
end
|
data/lib/economic/base_repo.rb
CHANGED
@@ -57,6 +57,12 @@ module Economic
|
|
57
57
|
|
58
58
|
private
|
59
59
|
|
60
|
+
def destroy(id)
|
61
|
+
response = send_request(method: :delete, url: endpoint_url + "/" + id.to_s)
|
62
|
+
|
63
|
+
JSON.parse(response.body)["message"] == "Deleted #{model.to_s.split("::").last.downcase}."
|
64
|
+
end
|
65
|
+
|
60
66
|
def model
|
61
67
|
scopes = name.split("::")
|
62
68
|
scopes[1] = scopes[1][0...-1] if scopes.count == 3
|
@@ -73,6 +79,9 @@ module Economic
|
|
73
79
|
end
|
74
80
|
end_p = end_p.gsub("Journals", "Journals-Experimental")
|
75
81
|
end_p = end_p.gsub("Selfs", "Self")
|
82
|
+
# PaymentTerms is named with a plural s for a single record, but the end point is still just paymentterms.
|
83
|
+
# Therefore the endpoint gets substituted
|
84
|
+
end_p = end_p.gsub("PaymentTermss", "PaymentTerms")
|
76
85
|
kebab(end_p)
|
77
86
|
end
|
78
87
|
|
@@ -0,0 +1,183 @@
|
|
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
|
+
soap_method_names[:send][:handle] => {
|
38
|
+
Number: model.customer.customerNumber,
|
39
|
+
},
|
40
|
+
}
|
41
|
+
)
|
42
|
+
|
43
|
+
model.id_key = result[:id]
|
44
|
+
|
45
|
+
create_lines(model) if model.lines.any?
|
46
|
+
|
47
|
+
find(result[:id].to_i)
|
48
|
+
end
|
49
|
+
|
50
|
+
def find_lines(invoice_id)
|
51
|
+
result = Economic::SoapAPI.call(
|
52
|
+
soap_method_names[:find_lines][:method],
|
53
|
+
message: {soap_method_names[:find_lines][:handle] => {Id: invoice_id}}
|
54
|
+
)
|
55
|
+
|
56
|
+
return if result.nil?
|
57
|
+
|
58
|
+
line_ids = result_array(result[soap_method_names[:find_lines][:line_handle]]).map { |line|
|
59
|
+
line[:number].to_i
|
60
|
+
}
|
61
|
+
|
62
|
+
find_all_lines(invoice_id, line_ids)
|
63
|
+
end
|
64
|
+
|
65
|
+
def destroy(id)
|
66
|
+
# The SoapAPI raises an exception if the record you try to delete is missing
|
67
|
+
|
68
|
+
result = Economic::SoapAPI.call(
|
69
|
+
soap_method_names[:destroy][:method],
|
70
|
+
message: {soap_method_names[:destroy][:handle] => {Id: id}}
|
71
|
+
)
|
72
|
+
|
73
|
+
true
|
74
|
+
rescue Savon::SOAPFault
|
75
|
+
false
|
76
|
+
end
|
77
|
+
|
78
|
+
private
|
79
|
+
|
80
|
+
# Since the soap api returns hashes, if there is a single record, and arrays, if there are more, this method
|
81
|
+
# wraps a response in an array, if it is not already.
|
82
|
+
def result_array(result)
|
83
|
+
return result if result.is_a? Array
|
84
|
+
|
85
|
+
[result]
|
86
|
+
end
|
87
|
+
|
88
|
+
def create_lines(model)
|
89
|
+
Economic::SoapAPI.call(
|
90
|
+
soap_method_names[:create_lines][:method], message: {
|
91
|
+
dataArray: build_line_data_array(model),
|
92
|
+
}
|
93
|
+
)
|
94
|
+
end
|
95
|
+
|
96
|
+
def find_all_lines(invoice_id, line_ids)
|
97
|
+
result = Economic::SoapAPI.call(
|
98
|
+
soap_method_names[:find_all_lines][:method],
|
99
|
+
message: {soap_method_names[:find_all_lines][:handle] => line_ids_array(invoice_id, line_ids, handle: soap_method_names[:find_all_lines][:line_handle])}
|
100
|
+
)
|
101
|
+
|
102
|
+
result_array(result[soap_method_names[:find_all_lines][:data]]).map do |data|
|
103
|
+
Economic::Line.build_from_soap_api(data)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def find_all_records(invoice_ids)
|
108
|
+
result = Economic::SoapAPI.call(
|
109
|
+
soap_method_names[:find_all_records][:method],
|
110
|
+
message: {
|
111
|
+
entityHandles: ids_array(invoice_ids, handle: soap_method_names[:find_all_records][:handle]),
|
112
|
+
}
|
113
|
+
)
|
114
|
+
|
115
|
+
result[soap_method_names[:find_all_records][:data]].map do |data|
|
116
|
+
model.build_from_soap_api(data)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def line_ids_array(order_id, line_ids, handle:)
|
121
|
+
arr = [handle => []]
|
122
|
+
|
123
|
+
line_ids.each do |line_id|
|
124
|
+
arr.first[handle].push(
|
125
|
+
{
|
126
|
+
Id: order_id,
|
127
|
+
Number: line_id,
|
128
|
+
}
|
129
|
+
)
|
130
|
+
end
|
131
|
+
|
132
|
+
arr
|
133
|
+
end
|
134
|
+
|
135
|
+
def ids_array(invoice_ids, handle:)
|
136
|
+
arr = [handle => []]
|
137
|
+
|
138
|
+
invoice_ids.each do |invoice_id|
|
139
|
+
arr.first[handle].push(
|
140
|
+
{
|
141
|
+
Id: invoice_id,
|
142
|
+
}
|
143
|
+
)
|
144
|
+
end
|
145
|
+
|
146
|
+
arr
|
147
|
+
end
|
148
|
+
|
149
|
+
def build_line_data_array(order)
|
150
|
+
arr = [soap_method_names[:create_lines][:line_data_handle] => []]
|
151
|
+
|
152
|
+
order.lines.each do |line|
|
153
|
+
arr.first[soap_method_names[:create_lines][:line_data_handle]].push(
|
154
|
+
{
|
155
|
+
:Handle => {
|
156
|
+
Id: order.id_key,
|
157
|
+
Number: line.line_number, # must be sent - does not have to fit with the next linenumber
|
158
|
+
},
|
159
|
+
:Id => order.id_key,
|
160
|
+
:Number => line.line_number, # must be sent - does not have to fit with the next linenumber
|
161
|
+
soap_method_names[:create_lines][:model_handle] => {
|
162
|
+
Id: order.id_key,
|
163
|
+
},
|
164
|
+
:Description => line.description,
|
165
|
+
:DeliveryDate => line.delivery.delivery_date,
|
166
|
+
:UnitHandle => {Number: line.unit.unit_number},
|
167
|
+
:ProductHandle => {Number: line.product.product_number},
|
168
|
+
:Quantity => line.quantity,
|
169
|
+
:UnitNetPrice => line.unit_net_price,
|
170
|
+
:DiscountAsPercent => line.discount_percentage,
|
171
|
+
:UnitCostPrice => line.unit_cost_price,
|
172
|
+
:TotalNetAmount => line.total_net_amount, # TODO: Should this not be sent?
|
173
|
+
:TotalMargin => line.margin_in_base_currency,
|
174
|
+
:MarginAsPercent => line.margin_percentage,
|
175
|
+
}
|
176
|
+
)
|
177
|
+
end
|
178
|
+
|
179
|
+
arr
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module Economic
|
2
|
+
class Invoice < Base
|
3
|
+
# currency, customer, date, layout, paymentTerms, recipient, recipient.name, recipient.vatZone
|
4
|
+
field :currency
|
5
|
+
field :date
|
6
|
+
field :dueDate
|
7
|
+
field :exchangeRate
|
8
|
+
field :grossAmount
|
9
|
+
field :grossAmountInBaseCurrency
|
10
|
+
field :marginInBaseCurrency
|
11
|
+
field :marginPercentage
|
12
|
+
field :netAmount
|
13
|
+
field :roundingAmount
|
14
|
+
field :vatAmount
|
15
|
+
field :draftInvoiceNumber, id: true # This changes name depending on its type (draft, unpaid etc)
|
16
|
+
|
17
|
+
relation :customer, fields: [:customerNumber]
|
18
|
+
# relation :delivery, fields: []
|
19
|
+
# relation :deliveryLocation, fields: []
|
20
|
+
relation :layout, fields: [:layoutNumber]
|
21
|
+
# relation :notes, fields: []
|
22
|
+
relation :paymentTerms, fields: [:paymentTermsNumber]
|
23
|
+
# relation :pdf, fields: []
|
24
|
+
# relation :project, fields: []
|
25
|
+
relation :recipient, fields: [:name]
|
26
|
+
relation :references, fields: [:other]
|
27
|
+
relation :lines, fields: [:lineNumber], multiple: true
|
28
|
+
|
29
|
+
def self.build_from_soap_api(data)
|
30
|
+
hash = {
|
31
|
+
"currency" => data[:currency_handle][:code],
|
32
|
+
"date" => data[:date].to_date,
|
33
|
+
"dueDate" => data[:due_date].to_date,
|
34
|
+
"exchangeRate" => data[:exchange_rate],
|
35
|
+
"grossAmount" => data[:gross_amount],
|
36
|
+
# where is grossAmountInBaseCurrency?
|
37
|
+
"lines" => repo.find_lines(data[:handle][:id]),
|
38
|
+
"marginInBaseCurrency" => data[:margin],
|
39
|
+
"marginPercentage" => data[:margin_as_percent],
|
40
|
+
"netAmount" => data[:net_amount],
|
41
|
+
"roundingAmount" => data[:rounding_amount],
|
42
|
+
"vatAmount" => data[:vat_amount],
|
43
|
+
"draftInvoiceNumber" => data[:handle][:id], # TODO: What about id?
|
44
|
+
"customer" => {"customerNumber" => data[:debtor_handle][:id].to_i},
|
45
|
+
"layout" => {"layoutNumber" => data[:layout_handle][:id].to_i},
|
46
|
+
"paymentTerms" => {"paymentTermsNumber" => data[:term_of_payment_handle][:id].to_i},
|
47
|
+
}
|
48
|
+
|
49
|
+
new(hash)
|
50
|
+
end
|
51
|
+
|
52
|
+
def self.repo
|
53
|
+
Economic::Invoices::DraftsRepo
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Economic
|
2
|
+
module Invoices
|
3
|
+
class DraftsRepo < Economic::Invoices::Repo
|
4
|
+
include Economic::SoapMethods
|
5
|
+
|
6
|
+
class << self
|
7
|
+
def soap_method_names
|
8
|
+
{
|
9
|
+
find: {method: :current_invoice_get_data, handle: :entityHandle},
|
10
|
+
all: {method: :current_invoice_get_all, handle: :current_invoice_handle},
|
11
|
+
send: {method: :current_invoice_create, handle: :debtorHandle},
|
12
|
+
find_lines: {
|
13
|
+
method: :current_invoice_get_lines,
|
14
|
+
handle: :currentInvoiceHandle,
|
15
|
+
line_handle: :current_invoice_line_handle,
|
16
|
+
},
|
17
|
+
create_lines: {
|
18
|
+
method: :current_invoice_line_create_from_data_array,
|
19
|
+
line_data_handle: :CurrentInvoiceLineData,
|
20
|
+
model_handle: :InvoiceHandle,
|
21
|
+
},
|
22
|
+
find_all_lines: {
|
23
|
+
method: :current_invoice_line_get_data_array,
|
24
|
+
handle: :entityHandles,
|
25
|
+
data: :current_invoice_line_data,
|
26
|
+
line_handle: :CurrentInvoiceLineHandle,
|
27
|
+
},
|
28
|
+
find_all_records: {
|
29
|
+
method: :current_invoice_get_data_array,
|
30
|
+
handle: :CurrentInvoiceHandle,
|
31
|
+
data: :current_invoice_data,
|
32
|
+
},
|
33
|
+
destroy: {
|
34
|
+
method: :current_invoice_delete,
|
35
|
+
handle: :currentInvoiceHandle,
|
36
|
+
},
|
37
|
+
}
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Economic
|
2
|
+
class Line < Base
|
3
|
+
field :lineNumber
|
4
|
+
field :description
|
5
|
+
field :sortKey
|
6
|
+
field :quantity
|
7
|
+
field :unitNetPrice
|
8
|
+
field :discountPercentage
|
9
|
+
field :unitCostPrice
|
10
|
+
field :marginInBaseCurrency
|
11
|
+
field :marginPercentage
|
12
|
+
field :totalNetAmount
|
13
|
+
|
14
|
+
relation :product, fields: [:productNumber]
|
15
|
+
relation :unit, fields: [:unitNumber, :name]
|
16
|
+
relation :delivery, fields: [:address, :zip, :city, :country, :deliveryDate]
|
17
|
+
|
18
|
+
def self.build_from_soap_api(data)
|
19
|
+
# This is not instantiated with the hash, as lines are never pulled out by themselves, but always as part of
|
20
|
+
# a invoice or order
|
21
|
+
{
|
22
|
+
"lineNumber" => data[:number].to_i,
|
23
|
+
"description" => data[:description],
|
24
|
+
"quantity" => data[:quantity].to_f,
|
25
|
+
"unitNetPrice" => data[:unit_net_price].to_f,
|
26
|
+
"discountPercentage" => data[:discount_as_percent].to_f,
|
27
|
+
"unitCostPrice" => data[:unit_cost_price].to_f,
|
28
|
+
"totalNetAmount" => data[:total_net_amount].to_f,
|
29
|
+
"marginPercentage" => data[:margin_as_percent].to_f,
|
30
|
+
"marginInBaseCurrency" => data[:total_margin].to_f,
|
31
|
+
"product" => {"productNumber" => data[:product_handle][:number]},
|
32
|
+
# Unmapped values in soap
|
33
|
+
# delivery_date
|
34
|
+
# :accrual_start_date => nil,
|
35
|
+
# :accrual_end_date => nil
|
36
|
+
}
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
data/lib/economic/rest.rb
CHANGED
@@ -1,8 +1,14 @@
|
|
1
1
|
require "economic/rest/version"
|
2
|
+
require "dotenv/load"
|
2
3
|
require "rest-client"
|
4
|
+
require "savon"
|
5
|
+
require "awesome_print"
|
6
|
+
require "active_support/inflector"
|
3
7
|
|
4
8
|
require "economic/base_repo"
|
5
9
|
require "economic/base"
|
10
|
+
require "economic/soap_api"
|
11
|
+
require "economic/concerns/soap_methods"
|
6
12
|
|
7
13
|
require "economic/currency"
|
8
14
|
require "economic/vat_zone"
|
@@ -19,6 +25,7 @@ require "economic/layout"
|
|
19
25
|
require "economic/layout_repo"
|
20
26
|
require "economic/notes"
|
21
27
|
require "economic/payment_terms"
|
28
|
+
require "economic/payment_terms_repo"
|
22
29
|
require "economic/pdf"
|
23
30
|
require "economic/project"
|
24
31
|
require "economic/recipient"
|
@@ -38,6 +45,16 @@ require "economic/orders/drafts_repo"
|
|
38
45
|
require "economic/orders/sent_repo"
|
39
46
|
require "economic/product_group_repo"
|
40
47
|
|
48
|
+
require "economic/invoices/repo"
|
49
|
+
require "economic/invoice"
|
50
|
+
require "economic/invoices/drafts_repo"
|
51
|
+
require "economic/invoices/booked_repo"
|
52
|
+
require "economic/invoices/not_due_repo"
|
53
|
+
require "economic/invoices/overdue_repo"
|
54
|
+
require "economic/invoices/paid_repo"
|
55
|
+
require "economic/invoices/sent_repo"
|
56
|
+
require "economic/invoices/unpaid_repo"
|
57
|
+
|
41
58
|
require "economic/journal_repo"
|
42
59
|
require "economic/journal"
|
43
60
|
require "economic/journal_voucher_repo"
|
@@ -49,10 +66,12 @@ require "economic/accounting_year_repo"
|
|
49
66
|
require "economic/unit"
|
50
67
|
require "economic/unit_repo"
|
51
68
|
|
52
|
-
require
|
69
|
+
require "economic/user"
|
70
|
+
|
53
71
|
require "economic/company"
|
54
72
|
require "economic/self"
|
55
73
|
require "economic/self_repo"
|
74
|
+
require "economic/line"
|
56
75
|
|
57
76
|
module Economic
|
58
77
|
class Demo
|
@@ -0,0 +1,24 @@
|
|
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
|
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.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Peter Klogborg
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-09-
|
11
|
+
date: 2019-09-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -94,6 +94,48 @@ dependencies:
|
|
94
94
|
- - "~>"
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '3.5'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: dotenv
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: standard
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: savon
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :runtime
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
97
139
|
- !ruby/object:Gem::Dependency
|
98
140
|
name: rest-client
|
99
141
|
requirement: !ruby/object:Gem::Requirement
|
@@ -108,6 +150,34 @@ dependencies:
|
|
108
150
|
- - ">="
|
109
151
|
- !ruby/object:Gem::Version
|
110
152
|
version: '0'
|
153
|
+
- !ruby/object:Gem::Dependency
|
154
|
+
name: activesupport
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - ">="
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '0'
|
160
|
+
type: :runtime
|
161
|
+
prerelease: false
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - ">="
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '0'
|
167
|
+
- !ruby/object:Gem::Dependency
|
168
|
+
name: awesome_print
|
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'
|
111
181
|
description:
|
112
182
|
email:
|
113
183
|
- klogborg@traels.it
|
@@ -116,6 +186,7 @@ extensions: []
|
|
116
186
|
extra_rdoc_files: []
|
117
187
|
files:
|
118
188
|
- ".gitignore"
|
189
|
+
- ".vscode/settings.json"
|
119
190
|
- CODE_OF_CONDUCT.md
|
120
191
|
- Gemfile
|
121
192
|
- Gemfile.lock
|
@@ -130,6 +201,7 @@ files:
|
|
130
201
|
- lib/economic/base.rb
|
131
202
|
- lib/economic/base_repo.rb
|
132
203
|
- lib/economic/company.rb
|
204
|
+
- lib/economic/concerns/soap_methods.rb
|
133
205
|
- lib/economic/currency.rb
|
134
206
|
- lib/economic/customer.rb
|
135
207
|
- lib/economic/customer_group.rb
|
@@ -137,11 +209,21 @@ files:
|
|
137
209
|
- lib/economic/customer_repo.rb
|
138
210
|
- lib/economic/delivery.rb
|
139
211
|
- lib/economic/inventory.rb
|
212
|
+
- lib/economic/invoice.rb
|
213
|
+
- lib/economic/invoices/booked_repo.rb
|
214
|
+
- lib/economic/invoices/drafts_repo.rb
|
215
|
+
- lib/economic/invoices/not_due_repo.rb
|
216
|
+
- lib/economic/invoices/overdue_repo.rb
|
217
|
+
- lib/economic/invoices/paid_repo.rb
|
218
|
+
- lib/economic/invoices/repo.rb
|
219
|
+
- lib/economic/invoices/sent_repo.rb
|
220
|
+
- lib/economic/invoices/unpaid_repo.rb
|
140
221
|
- lib/economic/journal.rb
|
141
222
|
- lib/economic/journal_repo.rb
|
142
223
|
- lib/economic/journal_voucher_repo.rb
|
143
224
|
- lib/economic/layout.rb
|
144
225
|
- lib/economic/layout_repo.rb
|
226
|
+
- lib/economic/line.rb
|
145
227
|
- lib/economic/notes.rb
|
146
228
|
- lib/economic/order.rb
|
147
229
|
- lib/economic/orders/archived_repo.rb
|
@@ -149,6 +231,7 @@ files:
|
|
149
231
|
- lib/economic/orders/repo.rb
|
150
232
|
- lib/economic/orders/sent_repo.rb
|
151
233
|
- lib/economic/payment_terms.rb
|
234
|
+
- lib/economic/payment_terms_repo.rb
|
152
235
|
- lib/economic/pdf.rb
|
153
236
|
- lib/economic/pricing.rb
|
154
237
|
- lib/economic/pricing_repo.rb
|
@@ -164,6 +247,7 @@ files:
|
|
164
247
|
- lib/economic/self.rb
|
165
248
|
- lib/economic/self_repo.rb
|
166
249
|
- lib/economic/session.rb
|
250
|
+
- lib/economic/soap_api.rb
|
167
251
|
- lib/economic/unit.rb
|
168
252
|
- lib/economic/unit_repo.rb
|
169
253
|
- lib/economic/user.rb
|