my_data 0.1.0 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/lint.yml +37 -0
- data/.rubocop.yml +12 -2
- data/Gemfile +9 -4
- data/Guardfile +7 -0
- data/README.md +55 -8
- data/lib/my_data.rb +9 -10
- data/lib/my_data/client.rb +34 -11
- data/lib/my_data/resource.rb +43 -29
- data/lib/my_data/resources/continuation_token_type.rb +7 -0
- data/lib/my_data/resources/ecls/expenses_classification.rb +7 -0
- data/lib/my_data/resources/ecls/expenses_classification_type.rb +1 -1
- data/lib/my_data/resources/ecls/invoice_expenses_classification_type.rb +1 -1
- data/lib/my_data/resources/ecls/invoices_expenses_classification_detail_type.rb +1 -1
- data/lib/my_data/resources/error_type.rb +1 -2
- data/lib/my_data/resources/icls/income_classification.rb +7 -0
- data/lib/my_data/resources/icls/income_classification_type.rb +1 -1
- data/lib/my_data/resources/icls/invoice_income_classification_type.rb +1 -1
- data/lib/my_data/resources/icls/invoices_income_classification_detail_type.rb +1 -1
- data/lib/my_data/resources/inv/aade_book_invoice_type.rb +1 -1
- data/lib/my_data/resources/inv/address_type.rb +1 -1
- data/lib/my_data/resources/inv/cancelled_invoice_type.rb +7 -0
- data/lib/my_data/resources/inv/continuation_token_type.rb +7 -0
- data/lib/my_data/resources/inv/invoice_header_type.rb +1 -1
- data/lib/my_data/resources/inv/invoice_row_type.rb +1 -1
- data/lib/my_data/resources/inv/invoice_summary_type.rb +1 -1
- data/lib/my_data/resources/inv/invoices_doc.rb +1 -11
- data/lib/my_data/resources/inv/party_type.rb +1 -1
- data/lib/my_data/resources/inv/payment_method_detail_type.rb +1 -1
- data/lib/my_data/resources/inv/request_doc.rb +7 -0
- data/lib/my_data/resources/inv/requested_invoices_doc.rb +7 -0
- data/lib/my_data/resources/inv/ship_type.rb +1 -1
- data/lib/my_data/resources/inv/tax_totals_type.rb +1 -1
- data/lib/my_data/resources/invoice_provider_type.rb +7 -0
- data/lib/my_data/resources/requested_provider_doc.rb +7 -0
- data/lib/my_data/resources/response.rb +7 -0
- data/lib/my_data/resources/response_type.rb +1 -13
- data/lib/my_data/response_parser.rb +42 -0
- data/lib/my_data/type_caster.rb +5 -4
- data/lib/my_data/version.rb +1 -1
- data/lib/my_data/xml_generator.rb +29 -17
- data/lib/my_data/xml_parser.rb +37 -76
- data/lib/my_data/xsd/complex_type.rb +11 -3
- data/lib/my_data/xsd/doc.rb +77 -0
- data/lib/my_data/xsd/element.rb +20 -8
- data/lib/my_data/xsd/resource_generator.rb +26 -13
- data/lib/my_data/xsd/structure.rb +41 -35
- data/my_data.gemspec +4 -3
- metadata +41 -19
- data/lib/my_data/resources.rb +0 -10
- data/lib/my_data/resources/ecls.rb +0 -7
- data/lib/my_data/resources/icls.rb +0 -7
- data/lib/my_data/resources/inv.rb +0 -14
- data/lib/my_data/resources/responses_doc.rb +0 -8
- data/lib/my_data/xsd.rb +0 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 21734192525f3cdc66a24be64cfc3f147647f8decb6f71a6cd17094f5fc79bcb
|
4
|
+
data.tar.gz: ce56b3d0ec170898a593cbfab881e843c1a89a3e3de6a055dce39f0d302f6a67
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e18093c80a0108ee8fe815ab50ca359cc019e2346a297b62e45d7c27f83652cab79461c5549bf6e69cad6752a546ae536bf84a10ecf23e320b2bdbb426cb932b
|
7
|
+
data.tar.gz: 9d64a6162fbb18bb511159e8c43d2117c795e91e222ce7e5ca10523b6cc7aea72b6bf9412245185537dadd7a512ade270f46672278b982f8377e86a68d5e3ca1
|
@@ -0,0 +1,37 @@
|
|
1
|
+
name: Lint
|
2
|
+
|
3
|
+
on: push
|
4
|
+
|
5
|
+
jobs:
|
6
|
+
run-test-lint:
|
7
|
+
name: Run tests and linter
|
8
|
+
runs-on: ubuntu-latest
|
9
|
+
|
10
|
+
strategy:
|
11
|
+
fail-fast: false
|
12
|
+
matrix:
|
13
|
+
ruby: ['2.5', '2.6', '2.7', '3.0']
|
14
|
+
gemfile: ['Gemfile']
|
15
|
+
|
16
|
+
env:
|
17
|
+
BUNDLE_GEMFILE: ${{ matrix.gemfile }}
|
18
|
+
|
19
|
+
steps:
|
20
|
+
- name: Check out Git repository
|
21
|
+
uses: actions/checkout@v2
|
22
|
+
|
23
|
+
- name: Set up Ruby
|
24
|
+
uses: ruby/setup-ruby@v1
|
25
|
+
with:
|
26
|
+
ruby-version: ${{ matrix.ruby }}
|
27
|
+
bundler-cache: true
|
28
|
+
|
29
|
+
- name: Run Rubocop
|
30
|
+
uses: wearerequired/lint-action@v1
|
31
|
+
with:
|
32
|
+
rubocop: true
|
33
|
+
rubocop_command_prefix: bundle exec
|
34
|
+
|
35
|
+
- name: Run specs
|
36
|
+
run: bundle exec rake spec
|
37
|
+
|
data/.rubocop.yml
CHANGED
@@ -1,11 +1,17 @@
|
|
1
|
+
require:
|
2
|
+
- rubocop-rake
|
3
|
+
|
4
|
+
AllCops:
|
5
|
+
NewCops: enable
|
6
|
+
|
1
7
|
Metrics/ModuleLength:
|
2
8
|
Max: 200
|
3
9
|
|
4
10
|
Metrics/MethodLength:
|
5
|
-
|
11
|
+
Max: 15
|
6
12
|
|
7
13
|
Metrics/BlockLength:
|
8
|
-
|
14
|
+
IgnoredMethods:
|
9
15
|
- class_methods
|
10
16
|
|
11
17
|
Style/Documentation:
|
@@ -30,3 +36,7 @@ Style/StringLiteralsInInterpolation:
|
|
30
36
|
|
31
37
|
Layout/LineLength:
|
32
38
|
Max: 120
|
39
|
+
|
40
|
+
Lint/UselessAccessModifier:
|
41
|
+
ContextCreatingMethods:
|
42
|
+
- class_methods
|
data/Gemfile
CHANGED
@@ -7,9 +7,14 @@ gemspec
|
|
7
7
|
|
8
8
|
gem "rake", "~> 13.0"
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
|
10
|
+
group :development, :test do
|
11
|
+
gem "factory_bot"
|
12
|
+
gem "guard-rspec", require: false
|
13
13
|
gem "pry"
|
14
|
-
gem "
|
14
|
+
gem "rspec", "~> 3.0"
|
15
|
+
gem "rubocop", "~> 1.0"
|
16
|
+
gem "rubocop-rake", "~> 0.5"
|
17
|
+
gem "rubocop-rspec", "~> 2.0"
|
18
|
+
gem "vcr"
|
19
|
+
gem "webmock"
|
15
20
|
end
|
data/Guardfile
ADDED
data/README.md
CHANGED
@@ -1,8 +1,6 @@
|
|
1
|
-
# MyData
|
1
|
+
# AADE MyData ruby client
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
TODO: Delete this and the text above, and describe your gem
|
3
|
+
A Ruby client for [AADE myDATA](https://www.aade.gr/mydata) API
|
6
4
|
|
7
5
|
## Installation
|
8
6
|
|
@@ -20,15 +18,64 @@ Or install it yourself as:
|
|
20
18
|
|
21
19
|
$ gem install my_data
|
22
20
|
|
21
|
+
## Resources
|
22
|
+
There are all the [resources](https://github.com/mikezaby/my_data/tree/master/lib/my_data/resources)
|
23
|
+
that are specified by the given
|
24
|
+
[xsd files](https://www.aade.gr/sites/default/files/2020-11/version%20v1.0.2%20XSDs.zip) from AADE.
|
25
|
+
|
26
|
+
e.x.
|
27
|
+
```irb
|
28
|
+
irb> MyData::Resources::Inv::PartyType
|
29
|
+
=> MyData::Resources::Inv::PartyType vat_number: string, country: string, branch: integer, name: string, address: MyData::Resources::Inv::AddressType
|
30
|
+
```
|
31
|
+
|
23
32
|
## Usage
|
24
33
|
|
25
|
-
|
34
|
+
##### Initialize client
|
35
|
+
```ruby
|
36
|
+
client = MyData::Client.new(user_id: "johndoe", subscription_key: "c9b79ff1841fb5cfecc66e1ea5a29b4d")
|
37
|
+
```
|
26
38
|
|
27
|
-
|
39
|
+
##### Send invoices
|
40
|
+
```ruby
|
41
|
+
# send invoices
|
42
|
+
invoice_data = {
|
43
|
+
issuer: { vat_number: "111111111", country: "GR", branch: 0 },
|
44
|
+
invoice_header: { series: "A", aa: "1", issue_date: "2021-02-21", invoice_type: "11.2", currency: "EUR" },
|
45
|
+
invoice_details: [{
|
46
|
+
line_number: "1",
|
47
|
+
net_value: 100.00,
|
48
|
+
vat_category: 1,
|
49
|
+
vat_amount: 24.00,
|
50
|
+
income_classification: [{ classification_type: "E3_561_003", classification_category: "category1_3", amount: 100.00 }]
|
51
|
+
}],
|
52
|
+
invoice_summary: {
|
53
|
+
total_net_value: 100.00,
|
54
|
+
total_vat_amount: 24.00,
|
55
|
+
total_withheld_amount: 0.0,
|
56
|
+
total_fees_amount: 0.0,
|
57
|
+
total_stamp_duty_amount: 0.0,
|
58
|
+
total_other_taxes_amount: 0.0,
|
59
|
+
total_deductions_amount: 0.0,
|
60
|
+
total_gross_value: 124.00,
|
61
|
+
income_classification: [{ classification_type: "E3_561_003", classification_category: "category1_3", amount: 100.00 }]
|
62
|
+
},
|
63
|
+
payment_methods: [{ type: 3, amount: 124.00 }]
|
64
|
+
}
|
65
|
+
|
66
|
+
invoices_doc = MyData::Resources::Inv::InvoicesDoc.new(invoice: [invoice_data])
|
67
|
+
client.send_invoices(doc: invoices_doc.to_xml)
|
68
|
+
```
|
28
69
|
|
29
|
-
|
70
|
+
##### Request transmitted docs
|
71
|
+
```ruby
|
72
|
+
client.request_transmitted_docs(mark: 1)
|
73
|
+
```
|
30
74
|
|
31
|
-
|
75
|
+
##### Cancel Invoice
|
76
|
+
```ruby
|
77
|
+
client.cancel_invoice(mark: 400001831924171)
|
78
|
+
```
|
32
79
|
|
33
80
|
## Contributing
|
34
81
|
|
data/lib/my_data.rb
CHANGED
@@ -4,21 +4,20 @@ require "active_model"
|
|
4
4
|
require "active_support/all"
|
5
5
|
require "faraday"
|
6
6
|
require "nokogiri"
|
7
|
-
|
8
|
-
require_relative "my_data/version"
|
7
|
+
require "zeitwerk"
|
9
8
|
|
10
9
|
module MyData
|
10
|
+
LOADER = Zeitwerk::Loader.for_gem
|
11
|
+
LOADER.enable_reloading
|
12
|
+
LOADER.setup
|
13
|
+
|
11
14
|
class Error < StandardError; end
|
12
15
|
|
13
16
|
def self.root
|
14
|
-
File.expand_path
|
17
|
+
File.expand_path "..", __dir__
|
15
18
|
end
|
16
19
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
autoload :TypeCaster, "my_data/type_caster"
|
21
|
-
autoload :XmlGenerator, "my_data/xml_generator"
|
22
|
-
autoload :XmlParser, "my_data/xml_parser"
|
23
|
-
autoload :Xsd, "my_data/xsd"
|
20
|
+
def self.reload!
|
21
|
+
MyData::LOADER.reload
|
22
|
+
end
|
24
23
|
end
|
data/lib/my_data/client.rb
CHANGED
@@ -9,25 +9,48 @@ module MyData
|
|
9
9
|
@subscription_key = subscription_key
|
10
10
|
end
|
11
11
|
|
12
|
-
def
|
13
|
-
|
14
|
-
|
15
|
-
|
12
|
+
def send_invoices(doc:)
|
13
|
+
response = connection.post("SendInvoices", doc)
|
14
|
+
|
15
|
+
parse_response(
|
16
|
+
response,
|
17
|
+
resource: MyData::Resources::Response,
|
18
|
+
root: "response_doc"
|
19
|
+
)
|
20
|
+
end
|
21
|
+
|
22
|
+
def request_transmitted_docs(mark:)
|
23
|
+
response = connection.get("RequestTransmittedDocs", mark: mark)
|
24
|
+
|
25
|
+
parse_response(
|
26
|
+
response,
|
27
|
+
resource: MyData::Resources::Inv::RequestDoc,
|
28
|
+
root: "requested_doc"
|
29
|
+
)
|
16
30
|
end
|
17
31
|
|
18
|
-
def
|
19
|
-
response = connection.post("
|
32
|
+
def cancel_invoice(mark:)
|
33
|
+
response = connection.post("CancelInvoice") do |req|
|
34
|
+
req.params["mark"] = mark
|
35
|
+
end
|
20
36
|
|
21
|
-
|
37
|
+
parse_response(
|
38
|
+
response,
|
39
|
+
resource: MyData::Resources::Response,
|
40
|
+
root: "response_doc"
|
41
|
+
)
|
22
42
|
end
|
23
43
|
|
24
44
|
private
|
25
45
|
|
26
|
-
def
|
27
|
-
|
28
|
-
|
46
|
+
def connection
|
47
|
+
@connection ||= Faraday.new(BASE_URL) do |conn|
|
48
|
+
conn.headers = headers
|
49
|
+
end
|
50
|
+
end
|
29
51
|
|
30
|
-
|
52
|
+
def parse_response(response, resource:, root:)
|
53
|
+
MyData::ResponseParser.new(response, resource: resource, root: root)
|
31
54
|
end
|
32
55
|
|
33
56
|
def headers
|
data/lib/my_data/resource.rb
CHANGED
@@ -29,15 +29,15 @@ module MyData
|
|
29
29
|
@container[:attributes] = opts
|
30
30
|
end
|
31
31
|
|
32
|
-
def
|
33
|
-
MyData::Xsd::Structure.
|
34
|
-
|
35
|
-
required = opts.delete :required
|
32
|
+
def xsd_doc
|
33
|
+
doc_name, doc = MyData::Xsd::Structure.doc(name)
|
34
|
+
container_tag(doc_name, doc.attributes)
|
36
35
|
|
37
|
-
|
36
|
+
xsd_resource_attributes(name, :doc)
|
37
|
+
end
|
38
38
|
|
39
|
-
|
40
|
-
|
39
|
+
def xsd_complex_type
|
40
|
+
xsd_resource_attributes(name, :complex_type)
|
41
41
|
end
|
42
42
|
|
43
43
|
# @param name [String] the name of the attribute
|
@@ -59,9 +59,8 @@ module MyData
|
|
59
59
|
@attributes.push(name)
|
60
60
|
attr_mappings(name, type, opts)
|
61
61
|
|
62
|
-
|
63
|
-
|
64
|
-
define_attr_setter name, collection: !!opts[:collection]
|
62
|
+
define_attr_getter name, collection: opts[:collection]
|
63
|
+
define_attr_setter name, collection: opts[:collection]
|
65
64
|
end
|
66
65
|
|
67
66
|
def inspect
|
@@ -76,13 +75,19 @@ module MyData
|
|
76
75
|
"#{name} #{format_attrs.join(", ")}"
|
77
76
|
end
|
78
77
|
|
79
|
-
def from_xml(doc_or_string)
|
80
|
-
doc = doc_or_string.is_a?(String) ? Nokogiri::XML(doc_or_string).child : doc_or_string
|
81
|
-
new(parse_xml(doc))
|
82
|
-
end
|
83
|
-
|
84
78
|
private
|
85
79
|
|
80
|
+
def xsd_resource_attributes(name, type)
|
81
|
+
MyData::Xsd::Structure.resource_attributes(name, type).each do |attrs|
|
82
|
+
e_name, type, opts = attrs
|
83
|
+
required = opts.delete :required
|
84
|
+
|
85
|
+
attribute(e_name, type, opts)
|
86
|
+
|
87
|
+
validates_presence_of e_name if required
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
86
91
|
def attr_mappings(name, type, opts)
|
87
92
|
resource =
|
88
93
|
if type == :resource
|
@@ -98,6 +103,14 @@ module MyData
|
|
98
103
|
}
|
99
104
|
end
|
100
105
|
|
106
|
+
def define_attr_getter(name, collection: false)
|
107
|
+
define_method name do
|
108
|
+
value = instance_variable_get("@#{name}")
|
109
|
+
|
110
|
+
collection && value.nil? ? [] : value
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
101
114
|
def define_attr_setter(name, collection: false)
|
102
115
|
define_method "#{name}=" do |value|
|
103
116
|
type, resource = self.class.mappings[name].values_at(:type, :resource)
|
@@ -112,11 +125,6 @@ module MyData
|
|
112
125
|
instance_variable_set("@#{name}", type_casted_value)
|
113
126
|
end
|
114
127
|
end
|
115
|
-
|
116
|
-
def parse_xml(doc)
|
117
|
-
parser = MyData::XmlParser.new(doc, mappings, name)
|
118
|
-
parser.parse_xml
|
119
|
-
end
|
120
128
|
end
|
121
129
|
|
122
130
|
def initialize(attrs = {})
|
@@ -134,6 +142,8 @@ module MyData
|
|
134
142
|
end
|
135
143
|
|
136
144
|
def attributes=(attrs)
|
145
|
+
attrs = attrs.respond_to?(:attributes) ? attrs.attributes : attrs
|
146
|
+
|
137
147
|
attrs.each do |key, value|
|
138
148
|
next unless attribute_names.include?(key.to_s)
|
139
149
|
|
@@ -152,15 +162,7 @@ module MyData
|
|
152
162
|
|
153
163
|
return true if is_valid
|
154
164
|
|
155
|
-
|
156
|
-
rs = resource.is_a?(Array) ? resource : [resource]
|
157
|
-
|
158
|
-
next if rs.all?(&:valid?)
|
159
|
-
|
160
|
-
rs.each do |r|
|
161
|
-
errors.add(k, :invalid_resource, message: r.errors.full_messages.join(", "))
|
162
|
-
end
|
163
|
-
end
|
165
|
+
add_nested_errors
|
164
166
|
|
165
167
|
false
|
166
168
|
end
|
@@ -187,5 +189,17 @@ module MyData
|
|
187
189
|
generator = MyData::XmlGenerator.new(self)
|
188
190
|
generator.to_xml
|
189
191
|
end
|
192
|
+
|
193
|
+
private
|
194
|
+
|
195
|
+
def add_nested_errors
|
196
|
+
resources.compact.each do |k, resource|
|
197
|
+
rs = resource.is_a?(Array) ? resource : [resource]
|
198
|
+
|
199
|
+
rs.reject(&:valid?).each do |r|
|
200
|
+
errors.add(k, :invalid_resource, message: r.errors.full_messages.join(", "))
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end
|
190
204
|
end
|
191
205
|
end
|