my_data 0.1.0 → 0.9.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.
- 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
@@ -3,15 +3,5 @@
|
|
3
3
|
class MyData::Resources::Inv::InvoicesDoc
|
4
4
|
include MyData::Resource
|
5
5
|
|
6
|
-
|
7
|
-
xmlns: "http://www.aade.gr/myDATA/invoice/v1.0",
|
8
|
-
"xmlns:xsi": "http://www.w3.org/2001/XMLSchema-instance",
|
9
|
-
"xsi:schemaLocation": "http://www.aade.gr/myDATA/invoice/v1.0 schema.xsd",
|
10
|
-
"xmlns:icls": "https://www.aade.gr/myDATA/incomeClassificaton/v1.0"
|
11
|
-
}
|
12
|
-
|
13
|
-
attribute :invoice, :resource,
|
14
|
-
class_name: "Inv::AadeBookInvoiceType", collection: true
|
15
|
-
|
16
|
-
validates_presence_of :invoice
|
6
|
+
xsd_doc
|
17
7
|
end
|
@@ -3,17 +3,5 @@
|
|
3
3
|
class MyData::Resources::ResponseType
|
4
4
|
include MyData::Resource
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
attribute :invoice_uid, :string
|
9
|
-
attribute :invoice_mark, :integer
|
10
|
-
attribute :classification_mark, :integer
|
11
|
-
attribute :cancellation_mark, :integer
|
12
|
-
attribute :authentication_code, :string
|
13
|
-
|
14
|
-
attribute :errors, :resource,
|
15
|
-
class_name: "ErrorType",
|
16
|
-
collection: true, collection_element_name: "error"
|
17
|
-
|
18
|
-
attribute :status_code, :string
|
6
|
+
xsd_complex_type
|
19
7
|
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class MyData::ResponseParser
|
4
|
+
def initialize(response, resource: nil, root: nil)
|
5
|
+
@original_response = response
|
6
|
+
@resource = resource
|
7
|
+
@root = root
|
8
|
+
end
|
9
|
+
|
10
|
+
def success?
|
11
|
+
original_response.status == 200 &&
|
12
|
+
(!response_type? || response.response.all? { |r| r.status_code == "Success" })
|
13
|
+
end
|
14
|
+
|
15
|
+
def errors
|
16
|
+
@errors ||=
|
17
|
+
if success?
|
18
|
+
[]
|
19
|
+
elsif response_type?
|
20
|
+
response.response.map(&:errors).flatten
|
21
|
+
else
|
22
|
+
[MyData::Resources::ErrorType.new(JSON.parse(original_response.body))]
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def response
|
27
|
+
return @response if defined? @response
|
28
|
+
|
29
|
+
@response =
|
30
|
+
if original_response.status == 200
|
31
|
+
MyData::XmlParser.xml_to_resource(xml: original_response.body, resource: resource, root: root)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def response_type?
|
38
|
+
response&.is_a?(MyData::Resources::Response)
|
39
|
+
end
|
40
|
+
|
41
|
+
attr_reader :original_response, :resource, :root
|
42
|
+
end
|
data/lib/my_data/type_caster.rb
CHANGED
@@ -11,8 +11,7 @@ module MyData
|
|
11
11
|
:date,
|
12
12
|
:time,
|
13
13
|
:boolean,
|
14
|
-
:resource
|
15
|
-
:ignore
|
14
|
+
:resource
|
16
15
|
].freeze
|
17
16
|
|
18
17
|
def valid_type?(type)
|
@@ -28,7 +27,7 @@ module MyData
|
|
28
27
|
private
|
29
28
|
|
30
29
|
def type_cast_string(value)
|
31
|
-
value.to_s.strip
|
30
|
+
value ? value.to_s.strip : nil
|
32
31
|
end
|
33
32
|
|
34
33
|
def type_cast_integer(value)
|
@@ -48,7 +47,9 @@ module MyData
|
|
48
47
|
end
|
49
48
|
|
50
49
|
def type_cast_boolean(value)
|
51
|
-
value
|
50
|
+
return value if value.nil?
|
51
|
+
|
52
|
+
value.is_a?(String) ? value.downcase == "true" : value == true
|
52
53
|
end
|
53
54
|
|
54
55
|
def type_cast_resource(value, resource)
|
data/lib/my_data/version.rb
CHANGED
@@ -22,28 +22,40 @@ module MyData
|
|
22
22
|
|
23
23
|
def to_xml_structure
|
24
24
|
resource.attributes.each_with_object([]) do |(key, value), structure|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
if attr_mappings[:collection_element_name]
|
32
|
-
struct = val.map { |v| attr_structure(attr_mappings[:collection_element_name], v) }
|
33
|
-
structure.push(attr_structure(key, struct))
|
34
|
-
else
|
35
|
-
struct = val.map { |v| attr_structure(key, v) }
|
36
|
-
structure.push(*struct)
|
37
|
-
end
|
38
|
-
else
|
39
|
-
val = attr_mappings[:resource] ? self.class.new(value, parent_namespace: namespace).to_xml_structure : value.to_s
|
40
|
-
structure.push(attr_structure(key, val))
|
41
|
-
end
|
25
|
+
next if value.nil? || (value.respond_to?(:empty?) && value.empty?)
|
26
|
+
|
27
|
+
value = value_to_xml_structure(key, value)
|
28
|
+
|
29
|
+
structure.push(*extract_attributes(key, value))
|
42
30
|
end
|
43
31
|
end
|
44
32
|
|
45
33
|
private
|
46
34
|
|
35
|
+
def value_to_xml_structure(key, value)
|
36
|
+
is_resource = mappings[key][:resource].present?
|
37
|
+
|
38
|
+
transform = lambda do |v|
|
39
|
+
is_resource ? self.class.new(v, parent_namespace: namespace).to_xml_structure : v.to_s
|
40
|
+
end
|
41
|
+
|
42
|
+
value.is_a?(Array) ? value.map(&transform) : transform.call(value)
|
43
|
+
end
|
44
|
+
|
45
|
+
def extract_attributes(key, value)
|
46
|
+
collection, collection_element_name = mappings[key].values_at(:collection, :collection_element_name)
|
47
|
+
|
48
|
+
if !collection
|
49
|
+
[attr_structure(key, value)]
|
50
|
+
elsif collection_element_name
|
51
|
+
attrs = value.map { |v| attr_structure(collection_element_name, v) }
|
52
|
+
|
53
|
+
[attr_structure(key, attrs)]
|
54
|
+
else
|
55
|
+
value.map { |v| attr_structure(key, v) }
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
47
59
|
def attr_structure(key, value)
|
48
60
|
prefix = parent_namespace && namespace != parent_namespace ? "#{namespace}:" : ""
|
49
61
|
|
data/lib/my_data/xml_parser.rb
CHANGED
@@ -1,96 +1,57 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
module MyData
|
4
|
-
|
5
|
-
attr_reader :doc, :mappings, :class_name
|
3
|
+
module MyData::XmlParser
|
4
|
+
extend self
|
6
5
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
@class_name = class_name
|
11
|
-
end
|
12
|
-
|
13
|
-
def parse_xml
|
14
|
-
doc.children.select(&:element?).each_with_object({}) do |element, parse_attrs|
|
15
|
-
attr_names = extract_attr_names(element)
|
16
|
-
|
17
|
-
attr_names.each do |attr_name|
|
18
|
-
value = extract_value(element, attr_name)
|
19
|
-
parse_attrs[attr_name] = value if value
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
6
|
+
def xml_to_resource(xml:, resource:, root: nil)
|
7
|
+
h = transofrm_xml_to_hash(fix_xml(xml))
|
8
|
+
h = h[root] if root
|
23
9
|
|
24
|
-
|
25
|
-
|
26
|
-
def extract_attr_names(element)
|
27
|
-
posible_attrs = mappings.select { |_, opts| element.name == opts[:tag_name] }
|
10
|
+
resource.new hash_mapping(h, resource)
|
11
|
+
end
|
28
12
|
|
29
|
-
|
30
|
-
attr_names = posible_attrs
|
31
|
-
.select { |_name, opts| match_static_tag_attributes?(element, opts[:static_tag_attrs]) }
|
32
|
-
else
|
33
|
-
attr_names = []
|
34
|
-
# raise "Not implemented: #{class_name}: #{element.name}"
|
35
|
-
end
|
13
|
+
private
|
36
14
|
|
37
|
-
|
38
|
-
|
39
|
-
|
15
|
+
def hash_mapping(hash, resource)
|
16
|
+
flatten(hash, resource).each_with_object({}) do |(key, value), h|
|
17
|
+
mappings = resource.mappings[key]
|
40
18
|
|
41
|
-
|
19
|
+
h[key] = value_mapping(value, mappings)
|
42
20
|
end
|
21
|
+
end
|
43
22
|
|
44
|
-
|
45
|
-
|
46
|
-
attr_opts = mappings[attr_name]
|
47
|
-
|
48
|
-
# TODO: current we dont check that the attribute setting matcing the elements
|
49
|
-
if attr_opts[:nested_tags].present?
|
50
|
-
attr_opts[:nested_tags].each do |tag|
|
51
|
-
return if value.nil?
|
23
|
+
def value_mapping(value, mappings)
|
24
|
+
return value if mappings[:resource].nil?
|
52
25
|
|
53
|
-
|
54
|
-
|
26
|
+
if mappings[:collection]
|
27
|
+
value = value.is_a?(Array) ? value : [value]
|
28
|
+
value.map { |v| hash_mapping(v, mappings[:resource]) }
|
29
|
+
else
|
30
|
+
hash_mapping(value, mappings[:resource])
|
31
|
+
end
|
32
|
+
end
|
55
33
|
|
56
|
-
|
57
|
-
|
34
|
+
def fix_xml(xml)
|
35
|
+
xml.strip.gsub("<", "<").gsub(">", ">")
|
36
|
+
end
|
58
37
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
end
|
38
|
+
def transofrm_xml_to_hash(xml)
|
39
|
+
Hash
|
40
|
+
.from_xml(xml)
|
41
|
+
.deep_transform_keys(&:underscore)["string"]
|
42
|
+
end
|
65
43
|
|
66
|
-
|
67
|
-
|
68
|
-
nested_parser = self.class.new(
|
69
|
-
value,
|
70
|
-
attr_opts[:class_name].mappings,
|
71
|
-
attr_opts[:class_name].name
|
72
|
-
)
|
73
|
-
value = nested_parser.parse_xml
|
74
|
-
else
|
75
|
-
value = if attr_opts[:dynamic_tag_attr].present?
|
76
|
-
value.attributes[attr_opts[:dynamic_tag_attr]].value
|
77
|
-
else
|
78
|
-
value.text
|
79
|
-
end
|
80
|
-
end
|
81
|
-
end
|
44
|
+
def flatten(hash, resource)
|
45
|
+
return {} unless hash
|
82
46
|
|
83
|
-
|
84
|
-
|
85
|
-
element_attr = element.attributes[tag_attribute.name]
|
47
|
+
hash.each_with_object({}) do |(k, v), h|
|
48
|
+
next if resource.attributes.none?(k) || !v
|
86
49
|
|
87
|
-
|
50
|
+
mappings = resource.mappings[k]
|
88
51
|
|
89
|
-
|
90
|
-
(tag_attribute.namespace.nil? || tag_attribute.namespace == element_attr.namespace.prefix)
|
52
|
+
next h[k] = v unless mappings[:collection] && mappings[:collection_element_name]
|
91
53
|
|
92
|
-
|
93
|
-
end
|
54
|
+
h[k] = v[mappings[:collection_element_name]]
|
94
55
|
end
|
95
56
|
end
|
96
57
|
end
|