gobl 0.7.0 → 0.7.2

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.
Files changed (4) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +257 -0
  3. data/lib/gobl/version.rb +1 -1
  4. metadata +3 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 78b100eaffbd2c950338c44d3e84840281f1ff155e35beb993d6873f3e893a28
4
- data.tar.gz: b865e5e7cd8cc1c27fc7a043e6e290f739710e895f7d040b53ff8250492e9cf8
3
+ metadata.gz: a0eeb23e35c8e6a71e80538d5ea0416b0d3ce5cdfd1ab30a42bc96291450d1cb
4
+ data.tar.gz: 6bf0d67871769486fd924c363c637e34dca14791e24df72e71c776b9ceca893d
5
5
  SHA512:
6
- metadata.gz: 85298a4930680c0a044eb8c92e03e0d5d6888e727e82849cf1dab56083f19e9475f2476b6178f9b7d24277bec95853c91a74ecbd34206005a61e78a4a99b7cfe
7
- data.tar.gz: d2ce9cfa5f5d539fbd79ea5d6e2df724046c045d28b627b8827d383ce1510e74a11d1aef5fe1ba0776420fb94c986cc7a278f26a17384c6a40776f6094d2a528
6
+ metadata.gz: 63d7f2fd50b76786c888101c0caeb3d978c875629253f3c300f6e9ab7d44489b7285906182a0430b54515ac108921f5a527b407df15118d0a45636626ec42d24
7
+ data.tar.gz: d4878ff574e3c33c8014d560ff657b0d2f7d86b48eba12791e0627b95cec63405fadc1073db39741f4589bcc226d1cdb4684477eb8a01b9da4b7d13047f7d1ed
data/README.md ADDED
@@ -0,0 +1,257 @@
1
+ # GOBL Ruby
2
+
3
+ <img src="https://github.com/invopop/gobl/blob/main/gobl_logo_black_rgb.svg?raw=true" width="181" height="219" alt="GOBL Logo">
4
+
5
+ Go Business Language – Ruby.
6
+
7
+ Released under the Apache 2.0 [LICENSE](https://github.com/invopop/gobl/blob/main/LICENSE), Copyright 2021,2022 [Invopop Ltd.](https://invopop.com). Trademark pending.
8
+
9
+ ## Introduction
10
+
11
+ Ruby library for reading, producing, manipulating and operating over [GOBL][3] documents and structures.
12
+
13
+ ### Features
14
+
15
+ * Dedicated Ruby classes for each GOBL structure with typed attributes
16
+ * [Object instantiation from nested hashes and arrays of attributes](#instantiating-structures)
17
+ * [Object serialization/deserialization to/from JSON GOBL data](#serializing-to-and-deserializing-from-json)
18
+ * [Idiomatic value objects with enumerations support](#handling-value-objects-and-enumerations)
19
+ * Access to operations in the [GOBL CLI][4] service: [build, validate and sign](#running-operations)
20
+ * [Full API reference documentation][1]
21
+
22
+ ### Documentation
23
+
24
+ * [User guide](#user-guide)
25
+ * [API reference][6]
26
+ * [GOBL documentation][2]
27
+
28
+ ## User guide
29
+
30
+ ### Installation
31
+
32
+ Add this line to your application's Gemfile:
33
+
34
+ ```ruby
35
+ gem 'gobl'
36
+ ```
37
+
38
+ And then execute:
39
+
40
+ ```shell
41
+ bundle install
42
+ ```
43
+
44
+ ### Instantiating structures
45
+
46
+ You can instantiate any struct in the library using a hash of nested attributes. For example:
47
+
48
+ ```ruby
49
+ invoice = GOBL::Bill::Invoice.new(
50
+ code: 'SAMPLE-001',
51
+ currency: :eur,
52
+ issue_date: Date.new(2021, 1, 1),
53
+ supplier: { tax_id: { country: :es, code: '55105445K' }, name: 'Provide One S.L.' },
54
+ customer: { tax_id: { country: :es, code: '65870696F' }, name: 'Sample Consumer' },
55
+ lines: [{
56
+ quantity: 20,
57
+ item: { name: 'Development services', price: 90.0 },
58
+ taxes: [ { cat: 'VAT', rate: :standard } ]
59
+ }]
60
+ )
61
+ invoice #=> #<GOBL::Bill::Invoice uuid=nil code="SAMPLE-001" ...>
62
+ invoice.code # => "SAMPLE-001"
63
+ invoice.currency # => #<GOBL::Currency::Code _value="EUR">
64
+ invoice.date # => #<GOBL::Cal::Date _value="2021-01-01">
65
+ invoice.lines.first.item.price #=> #<GOBL::Num::Amount:... @value=900, @exp=1>
66
+ ```
67
+
68
+ Note how the constructor took care of creating every nested object in the attributes hash and also coercing strings, symbols and dates into GOBL objects.
69
+
70
+ The constructor requires any attribute marked as mandatory and not calculated in the GOBL schema to be present in the input data. Otherwise, it will raise an error. For example:
71
+
72
+ ```ruby
73
+ message = GOBL::Note::Message.new #=> Dry::Struct::Error ([GOBL::Note::Message.new] :content is missing in Hash input)
74
+ ```
75
+
76
+ _See also: [`GOBL::Bill::Invoice#new`](https://rubydoc.info/github/invopop/gobl.ruby/GOBL/Bill/Invoice#new-class_method)_
77
+
78
+ ### Serializing to and deserializing from JSON
79
+
80
+ GOBL is a JSON format. So, you'll probably need to read or produce valid GOBL JSON at some point. Every struct class in the library provides a `.from_json!` and a `#to_json` method for those very purposes:
81
+
82
+ ```ruby
83
+ json = '{"$schema":"https://gobl.org/draft-0/note/message", "content":"Hello World!"}'
84
+ document = GOBL::Document.from_json!(json) #=> #<GOBL::Document _value={"$schema"=>"https://gobl.org/draft-0/note/message", "content"=>"Hello World!"}>
85
+ message = document.extract #=> #<GOBL::Note::Message title=nil content="Hello World!" meta=nil>
86
+ message.content #=> "Hello World!"
87
+ ```
88
+
89
+ Note that, in the previous example, we parsed the JSON fragment as a document. A [document](https://docs.gobl.org/core/documents) is one of the fundamental entities of GOBL, and it represents a business document in an abstract way. To get the specific document type instantiated –a message, in the example above–, we needed to call the [`#extract`](https://rubydoc.info/github/invopop/gobl.ruby/GOBL%2FExtensions%2FDocumentHelper:extract) method of the document object.
90
+
91
+ The previous instantiation method is useful if you don't know the document type in advance. If you do, you could also instantiate the object in this more direct way:
92
+
93
+ ```ruby
94
+ json = '{"$schema":"https://gobl.org/draft-0/note/message", "content":"Hello World!"}'
95
+ message = GOBL::Note::Message.from_json!(json) #=> #<GOBL::Note::Message title=nil content="Hello World!" meta=nil>
96
+ message.content #=> "Hello World!"
97
+ ```
98
+
99
+ Conversely, you can generate JSON GOBL from any instantiated object:
100
+
101
+ ```ruby
102
+ message = GOBL::Note::Message.new(content: 'Hello World!')
103
+ message.to_json #=> "{\"content\":\"Hello World!\"}"
104
+ ```
105
+
106
+ Note that, in the previous example, the generated JSON doesn't include a `$schema` attribute. This is because the GOBL schema doesn't require that attribute in a standalone message structure. If you want to use that structure as a document, you will need a `$schema` to be present. You can get that from your Ruby code by simply [_embedding_](https://rubydoc.info/github/invopop/gobl.ruby/GOBL%2FExtensions%2FDocumentHelper%2FClassMethods:embed) the struct in a document:
107
+
108
+ ```ruby
109
+ message = GOBL::Note::Message.new(content: 'Hello World!')
110
+ document = GOBL::Document.embed(message)
111
+ document.to_json #=> "{\"content\":\"Hello World!\",\"$schema\":\"https://gobl.org/draft-0/note/message\"}"
112
+ ```
113
+
114
+ _See also [`GOBL::Struct.from_json!`](https://rubydoc.info/github/invopop/gobl.ruby/GOBL%2FStruct%2Efrom_json!), [`GOBL::Struct#to_json`](https://rubydoc.info/github/invopop/gobl.ruby/GOBL%2FStruct:to_json), [`GOBL::Document#embed`](https://rubydoc.info/github/invopop/gobl.ruby/GOBL%2FExtensions%2FDocumentHelper%2FClassMethods:embed), [`GOBL::Document.extract`](https://rubydoc.info/github/invopop/gobl.ruby/GOBL%2FExtensions%2FDocumentHelper:extract)_
115
+
116
+ ### Handling value objects and enumerations
117
+
118
+ You can instantiate value objects in the library from a Symbol, a String or something that can be coerced into one via `#to_s`:
119
+
120
+ ```ruby
121
+ code = GOBL::Org::Code.new('A123') #=> #<GOBL::Org::Code _value="A123">
122
+ date = GOBL::Cal::Date.new(Date.today) #=> #<GOBL::Cal::Date _value="2022-09-23">
123
+ type = GOBL::Bill::InvoiceType.new(:credit_note) #=> #<GOBL::Bill::InvoiceType _value="credit-note">
124
+ ```
125
+
126
+ Similarly, you can compare value objects to symbols, strings or any object coercible into one:
127
+
128
+ ```ruby
129
+ GOBL::Org::Code.new('A123') == 'A123' #=> true
130
+ GOBL::Org::Code.new('2022-01-01') == Date.new(2022,1,1) #=> true
131
+ GOBL::Bill::InvoiceType.new('credit-note') == :credit_note #=> true
132
+ ```
133
+
134
+ The GOBL schema uses composition with certain value objects to delimit the range of allowed values. For those enumerated types, the library provides additional convenience methods:
135
+
136
+ ```ruby
137
+ # `.all` class method
138
+ GOBL::Bill::InvoiceType.all #=> Returns an array with all the objects in the enumeration
139
+
140
+ # Inquirers
141
+ type = GOBL::Bill::InvoiceType.new('credit-note')
142
+ type.proforma? #=> false
143
+ type.credit_note? #=> true
144
+
145
+ # Descriptions
146
+ type = GOBL::Org::Unit.new('kg')
147
+ type.description #=> "Metric kilograms"
148
+ ```
149
+
150
+ _See also [`GOBL::Org::Code`](https://rubydoc.info/github/invopop/gobl.ruby/GOBL/Org/Code), [`GOBL::Bill::InvoiceType`](https://rubydoc.info/github/invopop/gobl.ruby/GOBL/Bill/InvoiceType)_
151
+
152
+ ### Running operations
153
+
154
+ The library also provides an interface to run operations over GOBL structs in the GOBL CLI service. To run those operations, you'll need the [CLI installed][4] and the service running:
155
+
156
+ ```shell
157
+ $ gobl serve -p 3033
158
+ ```
159
+
160
+ Then, in your app, you need to configure the host and the port where the service is listening:
161
+
162
+ ```ruby
163
+ GOBL.config.service_host = '127.0.0.1'
164
+ GOBL.config.service_port = 3033
165
+ ```
166
+
167
+ And then you run your operations! For instance, you can build an invoice document, which will validate and calculate it:
168
+
169
+ ```ruby
170
+ invoice = GOBL::Bill::Invoice.new(
171
+ code: 'SAMPLE-001',
172
+ currency: :eur,
173
+ issue_date: Date.new(2021, 1, 1),
174
+ supplier: { tax_id: { country: :es, code: '55105445K' }, name: 'Provide One S.L.' },
175
+ customer: { tax_id: { country: :es, code: '65870696F' }, name: 'Sample Consumer' },
176
+ lines: [{
177
+ quantity: 20,
178
+ item: { name: 'Development services', price: 90.0 },
179
+ taxes: [ { cat: 'VAT', rate: :standard } ]
180
+ }]
181
+ )
182
+ document = GOBL::Document.embed(invoice)
183
+ calculated_document = GOBL.build(document)
184
+ calculated_invoice = calculated_document.extract
185
+ calculated_invoice.totals.total_with_tax #=> "2178.00"
186
+ ```
187
+
188
+ Note how the `#build` operation expects and returns either document or envelope structs. That's why we needed to embed our invoice in a document and extract the calculated invoice from the returned document. See the [operations API reference][5] for more details about this and the rest of the available operations.
189
+
190
+ _See also [`GOBL::Operations`][5]_
191
+
192
+ ## Developer guide
193
+
194
+ ### Project Structure
195
+
196
+ #### `lib`
197
+
198
+ Contains the `gobl` library components to be imported into other projects.
199
+
200
+ All the auto-generated files from the JSON schema are also defined here. You must not modify files containing an auto-generate header should not be modified. Under the hood, the gem uses `Zeitwerk` to load.
201
+
202
+ #### `tasks`
203
+
204
+ The tasks directory contains code able to parse (`tasks/parser`) GOBL JSON Schema and generate (`tasks/generators`) the Ruby versions of the GOBL structures.
205
+
206
+ ### Development tasks
207
+
208
+ The project provides a `mage.go` file with a set of [Mage](https://magefile.org) tasks to be used by developers of the library. All these tasks run within a Docker container.
209
+
210
+ You can avoid mage and the docker container if you prefer so. Take a look at the `mage.go` file to learn the commands it invokes under the hood and run them yourself.
211
+
212
+ #### Installation
213
+
214
+ The command `mage setup` fetches and installs all the required dependencies to use the gem.
215
+
216
+ #### Code generation
217
+
218
+ Ensure all the GOBL JSON Schema files are available by manually copying the base GOBL project's `build/schemas` path to the `data/schemas` path in this repository. Schemas are _.gitignored_, and you must copy them every time you want to update the generated code:
219
+
220
+ ```bash
221
+ rm -rf ./data/schemas
222
+ cp -r ../gobl/build/schemas ./data
223
+ ```
224
+
225
+ You can also update the regimes’ data with:
226
+
227
+ ```bash
228
+ rm -rf ./data/regimes
229
+ cp -r ../gobl/build/regimes ./data
230
+ ```
231
+
232
+ Now you can delete any previously generated code with
233
+
234
+ ```bash
235
+ find lib -name "*.rb" -exec grep -l "Generated with GOBL" {} \; | xargs rm
236
+ ```
237
+
238
+ The command `mage -v generate` generates the Ruby files from the JSON Schema. If the schema is updated, it will update the Ruby files.
239
+
240
+ #### Tests
241
+
242
+ Use the `mage spec` command to run the entire test suite.
243
+
244
+ #### Console
245
+
246
+ The command `mage console` spins up an IRB session with the library required.
247
+
248
+ #### YARD documentation
249
+
250
+ The library is fully documented using YARD. You can spin up a YARD server with the command `mage yardserver`.
251
+
252
+ [1]: https://rubydoc.info/github/invopop/gobl.ruby
253
+ [2]: https://docs.gobl.org/
254
+ [3]: https://gobl.org/
255
+ [4]: https://github.com/invopop/gobl.cli
256
+ [5]: https://rubydoc.info/github/invopop/gobl.ruby/GOBL/Operations
257
+ [6]: https://rubydoc.info/github/invopop/gobl.ruby/index
data/lib/gobl/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module GOBL
4
- VERSION = '0.7.0'
4
+ VERSION = '0.7.2'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gobl
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.0
4
+ version: 0.7.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Lilue
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2023-01-23 00:00:00.000000000 Z
13
+ date: 2023-01-27 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: activesupport
@@ -60,6 +60,7 @@ executables: []
60
60
  extensions: []
61
61
  extra_rdoc_files: []
62
62
  files:
63
+ - README.md
63
64
  - data/regimes/co.json
64
65
  - data/regimes/es.json
65
66
  - data/regimes/fr.json