gobl 0.1.3 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (92) hide show
  1. checksums.yaml +4 -4
  2. data/lib/ext/hashme.rb +28 -0
  3. data/lib/gobl/bill/advances.rb +1 -77
  4. data/lib/gobl/bill/charge.rb +11 -65
  5. data/lib/gobl/bill/delivery.rb +5 -47
  6. data/lib/gobl/bill/discount.rb +11 -65
  7. data/lib/gobl/bill/exchange_rates.rb +1 -77
  8. data/lib/gobl/bill/invoice.rb +28 -104
  9. data/lib/gobl/bill/invoice_type.rb +3 -134
  10. data/lib/gobl/bill/line.rb +13 -65
  11. data/lib/gobl/bill/line_charge.rb +5 -47
  12. data/lib/gobl/bill/line_discount.rb +5 -47
  13. data/lib/gobl/bill/ordering.rb +2 -38
  14. data/lib/gobl/bill/outlay.rb +11 -59
  15. data/lib/gobl/bill/payment.rb +5 -47
  16. data/lib/gobl/bill/preceding.rb +12 -62
  17. data/lib/gobl/bill/scheme_keys.rb +1 -77
  18. data/lib/gobl/bill/tax.rb +4 -44
  19. data/lib/gobl/bill/totals.rb +17 -71
  20. data/lib/gobl/cal/date.rb +1 -90
  21. data/lib/gobl/cal/period.rb +5 -41
  22. data/lib/gobl/currency/code.rb +3 -134
  23. data/lib/gobl/currency/exchange_rate.rb +5 -41
  24. data/lib/gobl/document.rb +1 -58
  25. data/lib/gobl/dsig/digest.rb +5 -41
  26. data/lib/gobl/dsig/signature.rb +1 -90
  27. data/lib/gobl/enum.rb +81 -0
  28. data/lib/gobl/envelope.rb +9 -48
  29. data/lib/gobl/header.rb +10 -56
  30. data/lib/gobl/i18n/string.rb +1 -58
  31. data/lib/gobl/l10n/code.rb +1 -90
  32. data/lib/gobl/l10n/country_code.rb +3 -134
  33. data/lib/gobl/map.rb +62 -0
  34. data/lib/gobl/note/message.rb +5 -44
  35. data/lib/gobl/num/amount.rb +6 -35
  36. data/lib/gobl/object.rb +21 -0
  37. data/lib/gobl/operations.rb +3 -3
  38. data/lib/gobl/org/address.rb +18 -80
  39. data/lib/gobl/org/code.rb +1 -90
  40. data/lib/gobl/org/coordinates.rb +5 -47
  41. data/lib/gobl/org/email.rb +6 -47
  42. data/lib/gobl/org/inbox.rb +8 -50
  43. data/lib/gobl/org/item.rb +13 -65
  44. data/lib/gobl/org/item_code.rb +4 -41
  45. data/lib/gobl/org/key.rb +1 -90
  46. data/lib/gobl/org/meta.rb +1 -58
  47. data/lib/gobl/org/name.rb +12 -62
  48. data/lib/gobl/org/note.rb +6 -47
  49. data/lib/gobl/org/note_key.rb +3 -134
  50. data/lib/gobl/org/party.rb +14 -71
  51. data/lib/gobl/org/person.rb +9 -56
  52. data/lib/gobl/org/registration.rb +9 -59
  53. data/lib/gobl/org/source_key.rb +3 -134
  54. data/lib/gobl/org/tax_identity.rb +8 -53
  55. data/lib/gobl/org/telephone.rb +5 -44
  56. data/lib/gobl/org/unit.rb +1 -136
  57. data/lib/gobl/pay/advance.rb +11 -59
  58. data/lib/gobl/pay/card.rb +5 -41
  59. data/lib/gobl/pay/credit_transfer.rb +6 -50
  60. data/lib/gobl/pay/direct_debit.rb +4 -44
  61. data/lib/gobl/pay/due_date.rb +8 -50
  62. data/lib/gobl/pay/instructions.rb +11 -62
  63. data/lib/gobl/pay/method_key.rb +3 -134
  64. data/lib/gobl/pay/online.rb +4 -41
  65. data/lib/gobl/pay/term_key.rb +3 -134
  66. data/lib/gobl/pay/terms.rb +6 -47
  67. data/lib/gobl/stamp.rb +5 -41
  68. data/lib/gobl/struct.rb +15 -15
  69. data/lib/gobl/tax/category.rb +9 -50
  70. data/lib/gobl/tax/category_total.rb +11 -53
  71. data/lib/gobl/tax/combo.rb +6 -47
  72. data/lib/gobl/tax/localities.rb +1 -77
  73. data/lib/gobl/tax/locality.rb +6 -44
  74. data/lib/gobl/tax/rate.rb +8 -47
  75. data/lib/gobl/tax/rate_total.rb +9 -50
  76. data/lib/gobl/tax/rate_total_surcharge.rb +5 -41
  77. data/lib/gobl/tax/rate_value.rb +6 -47
  78. data/lib/gobl/tax/region.rb +12 -56
  79. data/lib/gobl/tax/scheme.rb +8 -50
  80. data/lib/gobl/tax/schemes.rb +1 -77
  81. data/lib/gobl/tax/set.rb +1 -77
  82. data/lib/gobl/tax/total.rb +4 -41
  83. data/lib/gobl/uuid/uuid.rb +1 -90
  84. data/lib/gobl/value.rb +58 -0
  85. data/lib/gobl/version.rb +1 -1
  86. data/lib/gobl.rb +3 -1
  87. data/lib/gobl_extensions/document_helper.rb +3 -3
  88. data/lib/gobl_extensions/envelope_helper.rb +5 -0
  89. data/lib/gobl_extensions/i18n/value_keys_helper.rb +3 -3
  90. data/lib/gobl_extensions/tax/region_helper.rb +3 -9
  91. metadata +11 -35
  92. data/lib/gobl/types.rb +0 -17
@@ -9,7 +9,7 @@
9
9
  module GOBL
10
10
  module Pay
11
11
  # Method Key describes how a payment should be made
12
- class MethodKey < GOBL::Struct
12
+ class MethodKey < GOBL::Enum
13
13
  # The Schema ID of the GOBL MethodKey structure
14
14
  SCHEMA_ID = 'https://gobl.org/draft-0/pay/instructions#/$defs/MethodKey'
15
15
 
@@ -24,139 +24,8 @@ module GOBL
24
24
  'online' => 'Online or web payment'
25
25
  }.freeze
26
26
 
27
- attribute :_value, GOBL::Types::String.enum(*ENUM.keys)
28
- private :_value
29
-
30
- # Creates a new object from a GOBL value
31
- #
32
- # @param data [String] the GOBL value
33
- #
34
- # @return [MethodKey] the object created from the given data
35
- def self.from_gobl!(data)
36
- new(_value: data)
37
- end
38
-
39
- # Returns a GOBL value representing the current object
40
- #
41
- # @return [String] the GOBL value that represents the current object
42
- def to_gobl
43
- _value
44
- end
45
-
46
- # Returns a {MethodKey} that corresponds to a given object. The object can be a
47
- # `Symbol`, a `String` or anything coercible into one (via `#to_s`).
48
- #
49
- # @param object [Symbol, String, #to_s] the value of the object.
50
- #
51
- # @return [MethodKey] the object corresponding to the given value.
52
- #
53
- # @example Instantiating from a symbol
54
- # method_key = GOBL::Pay::MethodKey.new(:any)
55
- #
56
- # @example Instantiating from a string
57
- # method_key = GOBL::Pay::MethodKey.new('any')
58
- def self.new(object)
59
- case object
60
- when Hash, self # internal use, not to be used in public calls
61
- super
62
- when Symbol
63
- new find_by_sym(object)
64
- else
65
- super _value: object.to_s
66
- end
67
- end
68
-
69
- # Returns the string representation of the current object
70
- #
71
- # @return [String] the string representation of the current object
72
- def to_s
73
- _value.to_s
74
- end
75
-
76
- # Returns the symbol representation of the current object
77
- #
78
- # @return [Symbol] the symbol representation of the current object
79
- def to_sym
80
- to_s.parameterize.underscore.to_sym
81
- end
82
-
83
- # Returns whether the current object is equivalent to a given one. In addition
84
- # to {MethodKey} objects, the current object can be compared to a `Symbol`, a
85
- # `String` or anything coercible into one (via `#to_s`)
86
- #
87
- # @param other [MethodKey, Symbol, String, #to_s] the other object to compare to
88
- #
89
- # @return [Boolean] `true` if the objects are equivalent, `false` otherwise
90
- #
91
- # @example Comparing to another {MethodKey} object
92
- # method_key = GOBL::Pay::MethodKey.new('any')
93
- # method_key == GOBL::Pay::MethodKey.new('any') #=> true
94
- # method_key == GOBL::Pay::MethodKey.new('card') #=> false
95
- #
96
- # @example Comparing to a string
97
- # method_key = GOBL::Pay::MethodKey.new('any')
98
- # method_key == 'any' #=> true
99
- # method_key == 'card' #=> false
100
- #
101
- # @example Comparing to a symbol
102
- # method_key = GOBL::Pay::MethodKey.new('any')
103
- # method_key == :any #=> true
104
- # method_key == :card #=> false
105
- def ==(other)
106
- case other
107
- when self.class
108
- super
109
- when Symbol
110
- to_sym == other
111
- else
112
- to_s == other.to_s
113
- end
114
- end
115
-
116
- # Returns an array with all the enumerated objects of this type
117
- #
118
- # @return [Array<MethodKey>] the array of enumerated objects
119
- def self.all
120
- ENUM.keys.map { |key| new(key) }
121
- end
122
-
123
- # @api private
124
- def self.find_by_sym(sym)
125
- all.find { |object| object.to_sym == sym }
126
- end
127
-
128
- # @api private
129
- def self.find_by_inquirer(method_name)
130
- method_name =~ /(.+)\?$/ && find_by_sym(Regexp.last_match(1).to_sym)
131
- end
132
-
133
- # Returns the description of the current object
134
- #
135
- # @return [String] the description of the current object
136
- def description
137
- ENUM.fetch(_value, _value)
138
- end
139
-
140
- # @api private
141
- def respond_to_missing?(method_name, include_private = false)
142
- self.class.find_by_inquirer(method_name) || super
143
- end
144
-
145
- # Enables dynamic value inquirers like `MethodKey#any?` for
146
- # each of the declared enum values (see {ENUM}). Each inquirer returns a
147
- # `Boolean` denoting whether the value equals the enquired value (`true`) or
148
- # not (`false`)
149
- #
150
- # @example
151
- # method_key = GOBL::Pay::MethodKey.new('any')
152
- # method_key.any? # => true
153
- # method_key.card? # => false
154
- def method_missing(method_name, *args, &block)
155
- if value = self.class.find_by_inquirer(method_name)
156
- self == value
157
- else
158
- super
159
- end
27
+ def strict_enum?
28
+ true
160
29
  end
161
30
  end
162
31
  end
@@ -9,57 +9,20 @@
9
9
  module GOBL
10
10
  module Pay
11
11
  # Online provides the details required to make a payment online using a website
12
- class Online < GOBL::Struct
12
+ class Online < GOBL::Object
13
13
  # The Schema ID of the GOBL Online structure
14
14
  SCHEMA_ID = 'https://gobl.org/draft-0/pay/instructions#/$defs/Online'
15
15
 
16
16
  # @!attribute [r] name
17
17
  # Descriptive name given to the online provider.
18
18
  # @return [String]
19
- attribute? :name, GOBL::Types::String.optional
19
+ property :name, String
20
20
 
21
21
  # @!attribute [r] addr
22
22
  # Full URL to be used for payment.
23
23
  # @return [String]
24
- attribute :addr, GOBL::Types::String
25
-
26
- # Creates a new object from a hash of GOBL data
27
- #
28
- # @param data [Hash] a hash of GOBL data
29
- #
30
- # @return [Online] the object created from the given data
31
- def self.from_gobl!(data)
32
- data = GOBL::Types::Hash[data]
33
-
34
- new(
35
- name: data['name'],
36
- addr: data['addr']
37
- )
38
- end
39
-
40
- # Returns a hash of GOBL data representing the current object
41
- #
42
- # @return [Hash] the array of GOBL data that represents the current object
43
- def to_gobl
44
- {
45
- 'name' => attributes[:name],
46
- 'addr' => attributes[:addr]
47
- }.compact
48
- end
49
-
50
- # @!method self.new(attrs)
51
- #
52
- # Returns a {Online} object from a given hash of attributes. Nested
53
- # attributes are supported: the constructor will instantiate the proper GOBL
54
- # objects when nested hashes or arrays are given as part of the `attrs`
55
- # parameter.
56
- #
57
- # The `new` method will only allow to create a new object if all attributes
58
- # marked as mandatory and not calculated in the JSON schema are provided.
59
- #
60
- # @param attrs [Hash] the hash of attributes
61
- #
62
- # @return [Online] the object corresponding to the given input
24
+ property :addr, String
25
+ validates :addr, presence: true
63
26
  end
64
27
  end
65
28
  end
@@ -9,7 +9,7 @@
9
9
  module GOBL
10
10
  module Pay
11
11
  # Payment terms key
12
- class TermKey < GOBL::Struct
12
+ class TermKey < GOBL::Enum
13
13
  # The Schema ID of the GOBL TermKey structure
14
14
  SCHEMA_ID = 'https://gobl.org/draft-0/pay/terms#/$defs/TermKey'
15
15
 
@@ -27,139 +27,8 @@ module GOBL
27
27
  'delivery' => 'Payment on Delivery'
28
28
  }.freeze
29
29
 
30
- attribute :_value, GOBL::Types::String.enum(*ENUM.keys)
31
- private :_value
32
-
33
- # Creates a new object from a GOBL value
34
- #
35
- # @param data [String] the GOBL value
36
- #
37
- # @return [TermKey] the object created from the given data
38
- def self.from_gobl!(data)
39
- new(_value: data)
40
- end
41
-
42
- # Returns a GOBL value representing the current object
43
- #
44
- # @return [String] the GOBL value that represents the current object
45
- def to_gobl
46
- _value
47
- end
48
-
49
- # Returns a {TermKey} that corresponds to a given object. The object can be a
50
- # `Symbol`, a `String` or anything coercible into one (via `#to_s`).
51
- #
52
- # @param object [Symbol, String, #to_s] the value of the object.
53
- #
54
- # @return [TermKey] the object corresponding to the given value.
55
- #
56
- # @example Instantiating from a symbol
57
- # term_key = GOBL::Pay::TermKey.new(:)
58
- #
59
- # @example Instantiating from a string
60
- # term_key = GOBL::Pay::TermKey.new('')
61
- def self.new(object)
62
- case object
63
- when Hash, self # internal use, not to be used in public calls
64
- super
65
- when Symbol
66
- new find_by_sym(object)
67
- else
68
- super _value: object.to_s
69
- end
70
- end
71
-
72
- # Returns the string representation of the current object
73
- #
74
- # @return [String] the string representation of the current object
75
- def to_s
76
- _value.to_s
77
- end
78
-
79
- # Returns the symbol representation of the current object
80
- #
81
- # @return [Symbol] the symbol representation of the current object
82
- def to_sym
83
- to_s.parameterize.underscore.to_sym
84
- end
85
-
86
- # Returns whether the current object is equivalent to a given one. In addition
87
- # to {TermKey} objects, the current object can be compared to a `Symbol`, a
88
- # `String` or anything coercible into one (via `#to_s`)
89
- #
90
- # @param other [TermKey, Symbol, String, #to_s] the other object to compare to
91
- #
92
- # @return [Boolean] `true` if the objects are equivalent, `false` otherwise
93
- #
94
- # @example Comparing to another {TermKey} object
95
- # term_key = GOBL::Pay::TermKey.new('')
96
- # term_key == GOBL::Pay::TermKey.new('') #=> true
97
- # term_key == GOBL::Pay::TermKey.new('end-of-month') #=> false
98
- #
99
- # @example Comparing to a string
100
- # term_key = GOBL::Pay::TermKey.new('')
101
- # term_key == '' #=> true
102
- # term_key == 'end-of-month' #=> false
103
- #
104
- # @example Comparing to a symbol
105
- # term_key = GOBL::Pay::TermKey.new('')
106
- # term_key == : #=> true
107
- # term_key == :end_of_month #=> false
108
- def ==(other)
109
- case other
110
- when self.class
111
- super
112
- when Symbol
113
- to_sym == other
114
- else
115
- to_s == other.to_s
116
- end
117
- end
118
-
119
- # Returns an array with all the enumerated objects of this type
120
- #
121
- # @return [Array<TermKey>] the array of enumerated objects
122
- def self.all
123
- ENUM.keys.map { |key| new(key) }
124
- end
125
-
126
- # @api private
127
- def self.find_by_sym(sym)
128
- all.find { |object| object.to_sym == sym }
129
- end
130
-
131
- # @api private
132
- def self.find_by_inquirer(method_name)
133
- method_name =~ /(.+)\?$/ && find_by_sym(Regexp.last_match(1).to_sym)
134
- end
135
-
136
- # Returns the description of the current object
137
- #
138
- # @return [String] the description of the current object
139
- def description
140
- ENUM.fetch(_value, _value)
141
- end
142
-
143
- # @api private
144
- def respond_to_missing?(method_name, include_private = false)
145
- self.class.find_by_inquirer(method_name) || super
146
- end
147
-
148
- # Enables dynamic value inquirers like `TermKey#?` for
149
- # each of the declared enum values (see {ENUM}). Each inquirer returns a
150
- # `Boolean` denoting whether the value equals the enquired value (`true`) or
151
- # not (`false`)
152
- #
153
- # @example
154
- # term_key = GOBL::Pay::TermKey.new('')
155
- # term_key.? # => true
156
- # term_key.end_of_month? # => false
157
- def method_missing(method_name, *args, &block)
158
- if value = self.class.find_by_inquirer(method_name)
159
- self == value
160
- else
161
- super
162
- end
30
+ def strict_enum?
31
+ true
163
32
  end
164
33
  end
165
34
  end
@@ -9,71 +9,30 @@
9
9
  module GOBL
10
10
  module Pay
11
11
  # Terms defines when we expect the customer to pay, or have paid, for the contents of the document.
12
- class Terms < GOBL::Struct
12
+ class Terms < GOBL::Object
13
13
  # The Schema ID of the GOBL Terms structure
14
14
  SCHEMA_ID = 'https://gobl.org/draft-0/pay/terms'
15
15
 
16
16
  # @!attribute [r] key
17
17
  # Type of terms to be applied.
18
18
  # @return [TermKey]
19
- attribute :key, TermKey
19
+ property :key, TermKey
20
+ validates :key, presence: true
20
21
 
21
22
  # @!attribute [r] detail
22
23
  # Text detail of the chosen payment terms.
23
24
  # @return [String]
24
- attribute? :detail, GOBL::Types::String.optional
25
+ property :detail, String
25
26
 
26
27
  # @!attribute [r] due_dates
27
28
  # Set of dates for agreed payments.
28
29
  # @return [Array<DueDate>]
29
- attribute? :due_dates, GOBL::Types::Array.of(DueDate).optional
30
+ property :due_dates, [DueDate]
30
31
 
31
32
  # @!attribute [r] notes
32
33
  # Description of the conditions for payment.
33
34
  # @return [String]
34
- attribute? :notes, GOBL::Types::String.optional
35
-
36
- # Creates a new object from a hash of GOBL data
37
- #
38
- # @param data [Hash] a hash of GOBL data
39
- #
40
- # @return [Terms] the object created from the given data
41
- def self.from_gobl!(data)
42
- data = GOBL::Types::Hash[data]
43
-
44
- new(
45
- key: TermKey.from_gobl!(data['key']),
46
- detail: data['detail'],
47
- due_dates: data['due_dates']&.map { |item| DueDate.from_gobl!(item) },
48
- notes: data['notes']
49
- )
50
- end
51
-
52
- # Returns a hash of GOBL data representing the current object
53
- #
54
- # @return [Hash] the array of GOBL data that represents the current object
55
- def to_gobl
56
- {
57
- 'key' => attributes[:key]&.to_gobl,
58
- 'detail' => attributes[:detail],
59
- 'due_dates' => attributes[:due_dates]&.map { |item| item&.to_gobl },
60
- 'notes' => attributes[:notes]
61
- }.compact
62
- end
63
-
64
- # @!method self.new(attrs)
65
- #
66
- # Returns a {Terms} object from a given hash of attributes. Nested
67
- # attributes are supported: the constructor will instantiate the proper GOBL
68
- # objects when nested hashes or arrays are given as part of the `attrs`
69
- # parameter.
70
- #
71
- # The `new` method will only allow to create a new object if all attributes
72
- # marked as mandatory and not calculated in the JSON schema are provided.
73
- #
74
- # @param attrs [Hash] the hash of attributes
75
- #
76
- # @return [Terms] the object corresponding to the given input
35
+ property :notes, String
77
36
  end
78
37
  end
79
38
  end
data/lib/gobl/stamp.rb CHANGED
@@ -8,56 +8,20 @@
8
8
 
9
9
  module GOBL
10
10
  # Stamp defines an official seal of approval from a third party like a governmental agency or intermediary and should thus be included in any official envelopes.
11
- class Stamp < GOBL::Struct
11
+ class Stamp < GOBL::Object
12
12
  # The Schema ID of the GOBL Stamp structure
13
13
  SCHEMA_ID = 'https://gobl.org/draft-0/envelope#/$defs/Stamp'
14
14
 
15
15
  # @!attribute [r] prv
16
16
  # Identity of the agency used to create the stamp usually defined by each region.
17
17
  # @return [GOBL::Org::Key]
18
- attribute :prv, GOBL::Org::Key
18
+ property :prv, GOBL::Org::Key
19
+ validates :prv, presence: true
19
20
 
20
21
  # @!attribute [r] val
21
22
  # The serialized stamp value generated for or by the external agency
22
23
  # @return [String]
23
- attribute :val, GOBL::Types::String
24
-
25
- # Creates a new object from a hash of GOBL data
26
- #
27
- # @param data [Hash] a hash of GOBL data
28
- #
29
- # @return [Stamp] the object created from the given data
30
- def self.from_gobl!(data)
31
- data = GOBL::Types::Hash[data]
32
-
33
- new(
34
- prv: GOBL::Org::Key.from_gobl!(data['prv']),
35
- val: data['val']
36
- )
37
- end
38
-
39
- # Returns a hash of GOBL data representing the current object
40
- #
41
- # @return [Hash] the array of GOBL data that represents the current object
42
- def to_gobl
43
- {
44
- 'prv' => attributes[:prv]&.to_gobl,
45
- 'val' => attributes[:val]
46
- }.compact
47
- end
48
-
49
- # @!method self.new(attrs)
50
- #
51
- # Returns a {Stamp} object from a given hash of attributes. Nested
52
- # attributes are supported: the constructor will instantiate the proper GOBL
53
- # objects when nested hashes or arrays are given as part of the `attrs`
54
- # parameter.
55
- #
56
- # The `new` method will only allow to create a new object if all attributes
57
- # marked as mandatory and not calculated in the JSON schema are provided.
58
- #
59
- # @param attrs [Hash] the hash of attributes
60
- #
61
- # @return [Stamp] the object corresponding to the given input
24
+ property :val, String
25
+ validates :val, presence: true
62
26
  end
63
27
  end
data/lib/gobl/struct.rb CHANGED
@@ -1,18 +1,15 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module GOBL
4
- # Base class for any GOBL structure
5
- class Struct < Dry::Struct
4
+ # Base class for any structure present in the GOBL Schema
5
+ class Struct
6
6
  # Returns a new GOBL struct from a hash of GOBL data. The type of the returned struct
7
7
  # is determined from the `$schema` attribute.
8
8
  #
9
- # This method is usually overwritten at sub-class level, where the `$schema` attribute
10
- # isn't necessary since the type is determined by the sub-class itself.
11
- #
12
9
  # @param data [Hash] the hash of GOBL data
13
10
  #
14
11
  # @return [GOBL::Struct] the created GOBL struct
15
- def self.from_gobl!(data)
12
+ def self.from_data(data)
16
13
  raise ArgumentError, 'Schema not present in the given data' unless data&.key?('$schema')
17
14
 
18
15
  schema = GOBL::ID.new(data['$schema'])
@@ -21,9 +18,9 @@ module GOBL
21
18
  # being an envelope is considered to be a document as these are the only two structures
22
19
  # that are required to specify its schema.
23
20
  if schema.name == 'envelope'
24
- GOBL::Envelope.from_gobl! data
21
+ GOBL::Envelope.new data
25
22
  else
26
- GOBL::Document.from_gobl! data
23
+ GOBL::Document.new data
27
24
  end
28
25
  end
29
26
 
@@ -33,16 +30,19 @@ module GOBL
33
30
  #
34
31
  # @return [GOBL::Struct] the deserialized GOBL struct
35
32
  def self.from_json!(json)
36
- from_gobl!(JSON.parse(json))
33
+ new JSON.parse(json)
37
34
  end
38
35
 
39
- # Serializes a GOBL struct into a JSON string
40
- #
41
- # @param options [#to_h] a Hash-like object to pass to `JSON.generate`
36
+ # Serializes the current GOBL struct into a JSON string
42
37
  #
43
- # @return [GOBL::Struct] the JSON string representing the GOBL struct
44
- def to_json(options = nil)
45
- JSON.generate(to_gobl, options)
38
+ # @return [String] the JSON string representing the struct
39
+ def to_json(...)
40
+ as_json.to_json(...)
41
+ end
42
+
43
+ # @api private
44
+ def as_json
45
+ raise NotImplementedError, 'Subclasses are expected to overload'
46
46
  end
47
47
  end
48
48
  end
@@ -9,75 +9,34 @@
9
9
  module GOBL
10
10
  module Tax
11
11
  # Category contains the definition of a general type of tax inside a region.
12
- class Category < GOBL::Struct
12
+ class Category < GOBL::Object
13
13
  # The Schema ID of the GOBL Category structure
14
14
  SCHEMA_ID = 'https://gobl.org/draft-0/tax/region#/$defs/Category'
15
15
 
16
16
  # @!attribute [r] code
17
17
  # @return [GOBL::Org::Code]
18
- attribute :code, GOBL::Org::Code
18
+ property :code, GOBL::Org::Code
19
+ validates :code, presence: true
19
20
 
20
21
  # @!attribute [r] name
21
22
  # @return [GOBL::I18n::String]
22
- attribute :name, GOBL::I18n::String
23
+ property :name, GOBL::I18n::String
24
+ validates :name, presence: true
23
25
 
24
26
  # @!attribute [r] desc
25
27
  # @return [GOBL::I18n::String]
26
- attribute? :desc, GOBL::I18n::String.optional
28
+ property :desc, GOBL::I18n::String
27
29
 
28
30
  # @!attribute [r] retained
29
31
  # Retained when true implies that the tax amount will be retained by the buyer on behalf of the supplier, and thus subtracted from the invoice taxable base total. Typically used for taxes related to income.
30
32
  # @return [Boolean]
31
- attribute? :retained, GOBL::Types::Bool.optional
33
+ property :retained, Boolean
32
34
 
33
35
  # @!attribute [r] rates
34
36
  # Specific tax definitions inside this category.
35
37
  # @return [Array<Rate>]
36
- attribute :rates, GOBL::Types::Array.of(Rate)
37
-
38
- # Creates a new object from a hash of GOBL data
39
- #
40
- # @param data [Hash] a hash of GOBL data
41
- #
42
- # @return [Category] the object created from the given data
43
- def self.from_gobl!(data)
44
- data = GOBL::Types::Hash[data]
45
-
46
- new(
47
- code: GOBL::Org::Code.from_gobl!(data['code']),
48
- name: GOBL::I18n::String.from_gobl!(data['name']),
49
- desc: data['desc'] ? GOBL::I18n::String.from_gobl!(data['desc']) : nil,
50
- retained: data['retained'],
51
- rates: data['rates']&.map { |item| Rate.from_gobl!(item) }
52
- )
53
- end
54
-
55
- # Returns a hash of GOBL data representing the current object
56
- #
57
- # @return [Hash] the array of GOBL data that represents the current object
58
- def to_gobl
59
- {
60
- 'code' => attributes[:code]&.to_gobl,
61
- 'name' => attributes[:name]&.to_gobl,
62
- 'desc' => attributes[:desc]&.to_gobl,
63
- 'retained' => attributes[:retained],
64
- 'rates' => attributes[:rates]&.map { |item| item&.to_gobl }
65
- }.compact
66
- end
67
-
68
- # @!method self.new(attrs)
69
- #
70
- # Returns a {Category} object from a given hash of attributes. Nested
71
- # attributes are supported: the constructor will instantiate the proper GOBL
72
- # objects when nested hashes or arrays are given as part of the `attrs`
73
- # parameter.
74
- #
75
- # The `new` method will only allow to create a new object if all attributes
76
- # marked as mandatory and not calculated in the JSON schema are provided.
77
- #
78
- # @param attrs [Hash] the hash of attributes
79
- #
80
- # @return [Category] the object corresponding to the given input
38
+ property :rates, [Rate]
39
+ validates :rates, presence: true
81
40
  end
82
41
  end
83
42
  end