lexoffice_client 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +28 -0
- data/lib/lexoffice_client/address.rb +5 -0
- data/lib/lexoffice_client/company.rb +5 -0
- data/lib/lexoffice_client/configuration.rb +25 -0
- data/lib/lexoffice_client/contact/read_service.rb +42 -0
- data/lib/lexoffice_client/contact.rb +40 -0
- data/lib/lexoffice_client/customer.rb +4 -0
- data/lib/lexoffice_client/document.rb +15 -0
- data/lib/lexoffice_client/file/read_service.rb +47 -0
- data/lib/lexoffice_client/invoice/create_service.rb +50 -0
- data/lib/lexoffice_client/invoice/document/read_service.rb +51 -0
- data/lib/lexoffice_client/invoice/read_service.rb +38 -0
- data/lib/lexoffice_client/invoice.rb +74 -0
- data/lib/lexoffice_client/invoices.rb +4 -0
- data/lib/lexoffice_client/line_item.rb +19 -0
- data/lib/lexoffice_client/model/base.rb +76 -0
- data/lib/lexoffice_client/payment_conditions.rb +7 -0
- data/lib/lexoffice_client/related_voucher.rb +4 -0
- data/lib/lexoffice_client/role.rb +5 -0
- data/lib/lexoffice_client/shipping_conditions.rb +5 -0
- data/lib/lexoffice_client/tax_amount.rb +7 -0
- data/lib/lexoffice_client/tax_conditions.rb +5 -0
- data/lib/lexoffice_client/total_price.rb +11 -0
- data/lib/lexoffice_client/unit_price.rb +8 -0
- data/lib/lexoffice_client/vendor.rb +4 -0
- data/lib/lexoffice_client/version.rb +3 -0
- data/lib/lexoffice_client.rb +16 -0
- data/spec/factories/lexoffice_client/addresses.rb +10 -0
- data/spec/factories/lexoffice_client/conpanies.rb +4 -0
- data/spec/factories/lexoffice_client/contacts.rb +5 -0
- data/spec/factories/lexoffice_client/documents.rb +7 -0
- data/spec/factories/lexoffice_client/invoices.rb +17 -0
- data/spec/factories/lexoffice_client/line_items.rb +12 -0
- data/spec/factories/lexoffice_client/payment_conditions.rb +7 -0
- data/spec/factories/lexoffice_client/related_vouchers.rb +4 -0
- data/spec/factories/lexoffice_client/shipping_conditions.rb +6 -0
- data/spec/factories/lexoffice_client/tax_amount.rb +7 -0
- data/spec/factories/lexoffice_client/tax_conditions.rb +5 -0
- data/spec/factories/lexoffice_client/total_prices.rb +8 -0
- data/spec/factories/lexoffice_client/unit_prices.rb +8 -0
- metadata +239 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 292209af53199b01bf803cf21eadd8149a5d4ac5be87768342b92cc9d3db8714
|
4
|
+
data.tar.gz: eae9b11146af36bcd575dd0b94e31bb7784bf2224ac67c0bb5aae72a2bf14331
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 980cca1013d22293b63c5da21f24bc5c38434ffb14662df923bbb001745b26c646a467b6c881afd939a7f65263f63952329b88c848777a3b18cba715e2c8d99f
|
7
|
+
data.tar.gz: 2475f3b2bb1d0a688ecdd8bc6141d5a8f48f460411d6d3dc57adbc64b31fe2f21b9ef16f571afe4ee156f61651e86d99be12b0090af8ea3387d8cb269f9a74ac
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2023 BeeGood IT
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# Lexoffice API Client
|
2
|
+
Provides a client for the Lexoffice API.
|
3
|
+
|
4
|
+
## Usage
|
5
|
+
How to use my plugin.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
Add this line to your application's Gemfile:
|
9
|
+
|
10
|
+
```ruby
|
11
|
+
gem "lexoffice_client"
|
12
|
+
```
|
13
|
+
|
14
|
+
And then execute:
|
15
|
+
```bash
|
16
|
+
$ bundle
|
17
|
+
```
|
18
|
+
|
19
|
+
Or install it yourself as:
|
20
|
+
```bash
|
21
|
+
$ gem install lexoffice_client
|
22
|
+
```
|
23
|
+
|
24
|
+
## Contributing
|
25
|
+
Contribution directions go here.
|
26
|
+
|
27
|
+
## License
|
28
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module LexofficeClient
|
2
|
+
class Configuration
|
3
|
+
class << self
|
4
|
+
extend Forwardable
|
5
|
+
|
6
|
+
attr_accessor :values
|
7
|
+
|
8
|
+
def define_option(key, default: nil)
|
9
|
+
@values[key] = default
|
10
|
+
define_singleton_method(key) do
|
11
|
+
@values[key]
|
12
|
+
end
|
13
|
+
|
14
|
+
define_singleton_method("#{key}=") do |value|
|
15
|
+
@values[key] = value
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
@values = {}
|
21
|
+
|
22
|
+
define_option :api_token, default: -> { ENV.fetch("LEXOFFICE_CLIENT_API_TOKEN", nil) }
|
23
|
+
define_option :api_base_url, default: -> { ENV.fetch("LEXOFFICE_CLIENT_API_BASE_URL", "https://api.lexoffice.io/v1") }
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module LexofficeClient
|
2
|
+
class Contact::ReadService < Rao::Service::Base
|
3
|
+
class Result < Rao::Service::Result::Base
|
4
|
+
attr_accessor :contact, :request_response
|
5
|
+
end
|
6
|
+
|
7
|
+
attr_accessor :contact_id
|
8
|
+
|
9
|
+
validates :contact_id, presence: true
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def _perform
|
14
|
+
@result.contact = get_contact!
|
15
|
+
end
|
16
|
+
|
17
|
+
def get_contact!
|
18
|
+
response = HTTParty.get("#{instance_exec(&LexofficeClient::Configuration.api_base_url)}/contacts/#{contact_id}", headers: request_headers)
|
19
|
+
|
20
|
+
@result.request_response = response
|
21
|
+
|
22
|
+
if response.code != 200
|
23
|
+
add_error_and_say(:request, "HTTP Error: #{response.code}")
|
24
|
+
return
|
25
|
+
end
|
26
|
+
|
27
|
+
parsed_response = JSON.parse(response.body).deep_transform_keys(&:underscore)
|
28
|
+
|
29
|
+
say "Contact found:" do
|
30
|
+
contact = Contact.new(parsed_response)
|
31
|
+
say "#{contact.as_json}"
|
32
|
+
contact
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def request_headers
|
37
|
+
@request_headers ||= {
|
38
|
+
"Authorization" => "Bearer #{instance_exec(&LexofficeClient::Configuration.api_token)}"
|
39
|
+
}
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module LexofficeClient
|
2
|
+
class Contact < LexofficeClient::Model::Base
|
3
|
+
attr_accessor :id,
|
4
|
+
:organization_id,
|
5
|
+
:version,
|
6
|
+
:roles,
|
7
|
+
:company,
|
8
|
+
:addresses,
|
9
|
+
:archived,
|
10
|
+
:email_addresses
|
11
|
+
|
12
|
+
def addresses=(values)
|
13
|
+
@addresses = values.each_with_object({}) do |(key, value), hash|
|
14
|
+
hash[key] = value.map { |v| v.is_a?(LexofficeClient::Address) ? v : LexofficeClient::Address.new(v) }
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def addresses
|
19
|
+
@addresses ||= {}
|
20
|
+
end
|
21
|
+
|
22
|
+
def company=(value)
|
23
|
+
@company = value.is_a?(LexofficeClient::Company) ? value : LexofficeClient::Company.new(value)
|
24
|
+
end
|
25
|
+
|
26
|
+
def roles=(values)
|
27
|
+
@roles = values.each_with_object({}) do |(key, value), hash|
|
28
|
+
hash[key] = value.is_a?(LexofficeClient::Role) ? value : "LexofficeClient::#{key.camelize}".constantize.new(value)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# def address=(value)
|
33
|
+
# @address = value.is_a?(LexofficeClient::Address) ? value : LexofficeClient::Address.new(value)
|
34
|
+
# end
|
35
|
+
|
36
|
+
# def line_items=(value)
|
37
|
+
# @line_items = value.map { |v| v.is_a?(LexofficeClient::LineItem) ? v : LexofficeClient::LineItem.new(v) }
|
38
|
+
# end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module LexofficeClient
|
2
|
+
class Document < LexofficeClient::Model::Base
|
3
|
+
attr_accessor :original_filename, :content_type, :blob
|
4
|
+
|
5
|
+
def to_string_io
|
6
|
+
StringIO.new(blob || "").tap do |string_io|
|
7
|
+
string_io.class.class_eval do
|
8
|
+
attr_accessor :original_filename, :content_type
|
9
|
+
end
|
10
|
+
string_io.content_type = content_type
|
11
|
+
string_io.original_filename = original_filename
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module LexofficeClient
|
2
|
+
class File::ReadService < Rao::Service::Base
|
3
|
+
class Result < Rao::Service::Result::Base
|
4
|
+
attr_accessor :file_io, :request_response
|
5
|
+
end
|
6
|
+
|
7
|
+
attr_accessor :file_id
|
8
|
+
|
9
|
+
validates :file_id, presence: true
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def _perform
|
14
|
+
@result.file_io = get_file_io!
|
15
|
+
end
|
16
|
+
|
17
|
+
def get_file_io!
|
18
|
+
say "Getting file with id #{file_id} from lexoffice" do
|
19
|
+
response = HTTParty.get("#{instance_exec(&LexofficeClient::Configuration.api_base_url)}/files/#{file_id}", headers: request_headers)
|
20
|
+
|
21
|
+
@result.request_response = response
|
22
|
+
|
23
|
+
if response.code != 200
|
24
|
+
add_error_and_say(:request, "HTTP Error: #{response.code}")
|
25
|
+
return
|
26
|
+
end
|
27
|
+
|
28
|
+
@result.file_io = build_document(response)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def request_headers
|
33
|
+
@request_headers ||= {
|
34
|
+
"Accept" => "*/*",
|
35
|
+
"Authorization" => "Bearer #{instance_exec(&LexofficeClient::Configuration.api_token)}"
|
36
|
+
}
|
37
|
+
end
|
38
|
+
|
39
|
+
def build_document(response)
|
40
|
+
LexofficeClient::Document.new(
|
41
|
+
blob: response.body,
|
42
|
+
content_type: response.content_type,
|
43
|
+
original_filename: response.headers["content-disposition"].match(/^.*=(.*);$/)[1]
|
44
|
+
)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module LexofficeClient
|
2
|
+
class Invoice::CreateService < Rao::Service::Base
|
3
|
+
class Result < Rao::Service::Result::Base
|
4
|
+
attr_accessor :invoice_meta, :request_response
|
5
|
+
end
|
6
|
+
|
7
|
+
attr_accessor :invoice
|
8
|
+
|
9
|
+
validates :invoice, presence: true
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def _perform
|
14
|
+
@result.invoice_meta = post_invoice!
|
15
|
+
end
|
16
|
+
|
17
|
+
def post_invoice!
|
18
|
+
say "Posting invoice to lexoffice" do
|
19
|
+
response = HTTParty.post(request_url, headers: request_headers, body: request_body)
|
20
|
+
|
21
|
+
@result.request_response = response
|
22
|
+
|
23
|
+
if response.code != 201
|
24
|
+
add_error_and_say(:request, "HTTP Error: #{response.code}")
|
25
|
+
say "Request body: #{request_body}"
|
26
|
+
say "Response body: #{response.body}"
|
27
|
+
return
|
28
|
+
end
|
29
|
+
|
30
|
+
JSON.parse(response.body).deep_transform_keys(&:underscore)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def request_url
|
35
|
+
@request_url ||= "#{instance_exec(&LexofficeClient::Configuration.api_base_url)}/invoices"
|
36
|
+
end
|
37
|
+
|
38
|
+
def request_headers
|
39
|
+
@request_headers ||= {
|
40
|
+
"Accept" => "application/json",
|
41
|
+
"Content-Type" => "application/json",
|
42
|
+
"Authorization" => "Bearer #{instance_exec(&LexofficeClient::Configuration.api_token)}"
|
43
|
+
}
|
44
|
+
end
|
45
|
+
|
46
|
+
def request_body
|
47
|
+
invoice.as_json.deep_transform_keys { |k| k.to_s.camelize(:lower) }.to_json
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module LexofficeClient
|
2
|
+
class Invoice::Document::ReadService < Rao::Service::Base
|
3
|
+
class Result < Rao::Service::Result::Base
|
4
|
+
attr_accessor :document, :document_file_id, :request_response
|
5
|
+
end
|
6
|
+
|
7
|
+
attr_accessor :invoice_id # Lexoffice UUID
|
8
|
+
|
9
|
+
validates :invoice_id, presence: true
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def _perform
|
14
|
+
@result.document_file_id = get_document_file_id!
|
15
|
+
@result.document = get_document!
|
16
|
+
end
|
17
|
+
|
18
|
+
def get_document_file_id!
|
19
|
+
say "Getting document file id for invoice with id #{invoice_id}" do
|
20
|
+
response = HTTParty.get("#{instance_exec(&LexofficeClient::Configuration.api_base_url)}/invoices/#{invoice_id}/document", headers: request_headers)
|
21
|
+
|
22
|
+
@result.request_response = response
|
23
|
+
|
24
|
+
if response.code != 200
|
25
|
+
if response.code == 406
|
26
|
+
add_error_and_say(:request, "HTTP Error: #{response.code} - #{parsed_response["message"]}")
|
27
|
+
else
|
28
|
+
add_error_and_say(:request, "HTTP Error: #{response.code}")
|
29
|
+
end
|
30
|
+
nil
|
31
|
+
end
|
32
|
+
|
33
|
+
parsed_response["document_file_id"]
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def request_headers
|
38
|
+
@request_headers ||= {
|
39
|
+
"Authorization" => "Bearer #{instance_exec(&LexofficeClient::Configuration.api_token)}"
|
40
|
+
}
|
41
|
+
end
|
42
|
+
|
43
|
+
def parsed_response
|
44
|
+
@parsed_response ||= JSON.parse(@result.request_response.body).deep_transform_keys(&:underscore)
|
45
|
+
end
|
46
|
+
|
47
|
+
def get_document!
|
48
|
+
LexofficeClient::File::ReadService.call({file_id: @result.document_file_id}).file_io
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module LexofficeClient
|
2
|
+
class Invoice::ReadService < Rao::Service::Base
|
3
|
+
class Result < Rao::Service::Result::Base
|
4
|
+
attr_accessor :invoice, :request_response
|
5
|
+
end
|
6
|
+
|
7
|
+
attr_accessor :invoice_id
|
8
|
+
|
9
|
+
validates :invoice_id, presence: true
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def _perform
|
14
|
+
@result.invoice = get_invoice!
|
15
|
+
end
|
16
|
+
|
17
|
+
def get_invoice!
|
18
|
+
response = HTTParty.get("#{instance_exec(&LexofficeClient::Configuration.api_base_url)}/invoices/#{invoice_id}", headers: request_headers)
|
19
|
+
|
20
|
+
@result.request_response = response
|
21
|
+
|
22
|
+
if response.code != 200
|
23
|
+
add_error_and_say(:request, "HTTP Error: #{response.code}")
|
24
|
+
return
|
25
|
+
end
|
26
|
+
|
27
|
+
parsed_response = JSON.parse(response.body).deep_transform_keys(&:underscore)
|
28
|
+
|
29
|
+
Invoice.new(parsed_response)
|
30
|
+
end
|
31
|
+
|
32
|
+
def request_headers
|
33
|
+
@request_headers ||= {
|
34
|
+
"Authorization" => "Bearer #{instance_exec(&LexofficeClient::Configuration.api_token)}"
|
35
|
+
}
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
module LexofficeClient
|
2
|
+
class Invoice < LexofficeClient::Model::Base
|
3
|
+
attr_accessor :id,
|
4
|
+
:organization_id,
|
5
|
+
:created_date,
|
6
|
+
:updated_date,
|
7
|
+
:version,
|
8
|
+
:language,
|
9
|
+
:archived,
|
10
|
+
:voucher_status,
|
11
|
+
:voucher_number,
|
12
|
+
:voucher_date,
|
13
|
+
:due_date,
|
14
|
+
:address,
|
15
|
+
:line_items,
|
16
|
+
:total_price,
|
17
|
+
:tax_amounts,
|
18
|
+
:tax_conditions,
|
19
|
+
:payment_conditions,
|
20
|
+
:shipping_conditions,
|
21
|
+
:closing_invoice,
|
22
|
+
:related_vouchers,
|
23
|
+
:introduction,
|
24
|
+
:remark,
|
25
|
+
:title,
|
26
|
+
:files
|
27
|
+
|
28
|
+
def address=(value)
|
29
|
+
@address = value.is_a?(LexofficeClient::Address) ? value : LexofficeClient::Address.new(value)
|
30
|
+
end
|
31
|
+
|
32
|
+
def line_items=(value)
|
33
|
+
@line_items = value.map { |v| v.is_a?(LexofficeClient::LineItem) ? v : LexofficeClient::LineItem.new(v) }
|
34
|
+
end
|
35
|
+
|
36
|
+
def shipping_conditions=(value)
|
37
|
+
@shipping_conditions = value.is_a?(LexofficeClient::ShippingConditions) ? value : LexofficeClient::ShippingConditions.new(value)
|
38
|
+
end
|
39
|
+
|
40
|
+
def total_price=(value)
|
41
|
+
@total_price = value.is_a?(LexofficeClient::TotalPrice) ? value : LexofficeClient::TotalPrice.new(value)
|
42
|
+
end
|
43
|
+
|
44
|
+
def tax_amounts=(value)
|
45
|
+
@tax_amounts = value.map { |v| v.is_a?(LexofficeClient::TaxAmount) ? v : LexofficeClient::TaxAmount.new(v) }
|
46
|
+
end
|
47
|
+
|
48
|
+
def tax_conditions=(value)
|
49
|
+
@tax_conditions = value.is_a?(LexofficeClient::TaxConditions) ? value : LexofficeClient::TaxConditions.new(value)
|
50
|
+
end
|
51
|
+
|
52
|
+
def related_vouchers=(value)
|
53
|
+
@related_vouchers = value.map { |v| v.is_a?(LexofficeClient::RelatedVoucher) ? v : LexofficeClient::RelatedVoucher.new(v) }
|
54
|
+
end
|
55
|
+
|
56
|
+
def voucher_date=(value)
|
57
|
+
@voucher_date = case value
|
58
|
+
when String
|
59
|
+
Date.parse(value)
|
60
|
+
else
|
61
|
+
value
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def due_date=(value)
|
66
|
+
@due_date = case value
|
67
|
+
when String
|
68
|
+
Date.parse(value)
|
69
|
+
else
|
70
|
+
value
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module LexofficeClient
|
2
|
+
class LineItem < LexofficeClient::Model::Base
|
3
|
+
attr_accessor :id,
|
4
|
+
:type,
|
5
|
+
:name,
|
6
|
+
:description,
|
7
|
+
:quantity,
|
8
|
+
:unit_name,
|
9
|
+
:unit_price,
|
10
|
+
:discount_percentage,
|
11
|
+
:line_item_amount
|
12
|
+
|
13
|
+
delegate :net_amount, :gross_amount, :tax_rate_percentage, :currency, to: :unit_price, prefix: true
|
14
|
+
|
15
|
+
def unit_price=(value)
|
16
|
+
@unit_price = value.is_a?(LexofficeClient::UnitPrice) ? value : LexofficeClient::UnitPrice.new(value)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
module LexofficeClient
|
2
|
+
module Model
|
3
|
+
class Base
|
4
|
+
if Object.const_defined?(:Rails)
|
5
|
+
extend ActiveModel::Translation
|
6
|
+
extend ActiveModel::Naming
|
7
|
+
include ActiveModel::Conversion
|
8
|
+
end
|
9
|
+
|
10
|
+
def initialize(attributes = {})
|
11
|
+
attributes.each do |k, v|
|
12
|
+
send("#{k.to_s.underscore}=", v)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def attributes=(attributes)
|
17
|
+
attributes.each do |k, v|
|
18
|
+
send("#{k.to_s.underscore}=", v)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
module AttributeNamesConcern
|
23
|
+
def self.included(base)
|
24
|
+
base.extend(ClassMethods)
|
25
|
+
end
|
26
|
+
|
27
|
+
module ClassMethods
|
28
|
+
def attr_accessor(*)
|
29
|
+
super
|
30
|
+
add_attribute_names(*)
|
31
|
+
end
|
32
|
+
|
33
|
+
def attr_reader(*)
|
34
|
+
super
|
35
|
+
add_attribute_names(*)
|
36
|
+
end
|
37
|
+
|
38
|
+
def add_attribute_names(*args)
|
39
|
+
args.each do |attr_name|
|
40
|
+
attribute_names << attr_name
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def attribute_names
|
45
|
+
@attr_names ||= []
|
46
|
+
end
|
47
|
+
|
48
|
+
# alias attributes_names to column_names for ActiveModel compatibility
|
49
|
+
alias_method :column_names, :attribute_names
|
50
|
+
end
|
51
|
+
|
52
|
+
def attributes
|
53
|
+
self.class.attribute_names.each_with_object({}) do |attr_name, memo|
|
54
|
+
memo[attr_name.to_sym] = send(attr_name)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
include AttributeNamesConcern
|
60
|
+
|
61
|
+
module SerializationConcern
|
62
|
+
def as_json(options = {})
|
63
|
+
attributes.each_with_object({}) do |(attr_name, value), memo|
|
64
|
+
memo[attr_name.to_sym] = value.respond_to?(:as_json) ? value.as_json(options) : value
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def to_json(options = {})
|
69
|
+
as_json(options).to_json
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
include SerializationConcern
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module LexofficeClient
|
2
|
+
class TotalPrice < LexofficeClient::Model::Base
|
3
|
+
attr_accessor :currency,
|
4
|
+
:total_net_amount,
|
5
|
+
:total_gross_amount,
|
6
|
+
:total_tax_amount,
|
7
|
+
:tax_rate_percentage,
|
8
|
+
:total_discount_absolute,
|
9
|
+
:total_discount_percentage
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require "httparty"
|
2
|
+
require "rao-service"
|
3
|
+
|
4
|
+
require "zeitwerk"
|
5
|
+
loader = Zeitwerk::Loader.for_gem
|
6
|
+
loader.setup
|
7
|
+
|
8
|
+
module LexofficeClient
|
9
|
+
def self.root
|
10
|
+
Pathname.new(::File.expand_path("../..", __FILE__))
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.configure
|
14
|
+
yield Configuration
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
FactoryBot.define do
|
2
|
+
factory :lexoffice_client_address, class: LexofficeClient::Address do
|
3
|
+
name { "Art der Gestaltung GbR" }
|
4
|
+
supplement { "c/o Christoph Bönning" }
|
5
|
+
street { "Parkstraße 17" }
|
6
|
+
city { "Bad Vilbel" }
|
7
|
+
zip { "61118" }
|
8
|
+
country_code { "DE" }
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,7 @@
|
|
1
|
+
FactoryBot.define do
|
2
|
+
factory :lexoffice_client_document, class: LexofficeClient::Document do
|
3
|
+
original_filename { "Rechnung_RE0009.pdf" }
|
4
|
+
content_type { "application/pdf" }
|
5
|
+
blob { File.read(LexofficeClient.root.join(*%w[spec files lexoffice_client documents example.pdf])) }
|
6
|
+
end
|
7
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
FactoryBot.define do
|
2
|
+
factory :lexoffice_client_invoice, class: LexofficeClient::Invoice do
|
3
|
+
trait :default do
|
4
|
+
after(:build) do |invoice|
|
5
|
+
attributes = File.open(LexofficeClient.root.join(*%w[spec files lexoffice_client invoices example.json]))
|
6
|
+
invoice.attributes = JSON.parse(attributes.read)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
trait :for_create do
|
11
|
+
after(:build) do |invoice|
|
12
|
+
attributes = File.open(LexofficeClient.root.join(*%w[spec files lexoffice_client invoices create.json]))
|
13
|
+
invoice.attributes = JSON.parse(attributes.read)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
FactoryBot.define do
|
2
|
+
factory :lexoffice_client_line_item, class: LexofficeClient::LineItem do
|
3
|
+
type { "custom" }
|
4
|
+
name { "IT-Services" }
|
5
|
+
description { "Webentwicklung" }
|
6
|
+
quantity { 1 }
|
7
|
+
unit_name { "Stunde" }
|
8
|
+
association(:unit_price, factory: :lexoffice_client_unit_price)
|
9
|
+
discount_percentage { 0 }
|
10
|
+
line_item_amount { 100.0 }
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,7 @@
|
|
1
|
+
FactoryBot.define do
|
2
|
+
factory :lexoffice_client_payment_conditions, class: LexofficeClient::PaymentConditions do
|
3
|
+
payment_term_label { "Zahlbar sofort, rein netto" }
|
4
|
+
payment_term_label_template { "Zahlbar sofort, rein netto" }
|
5
|
+
payment_term_duration { 0 }
|
6
|
+
end
|
7
|
+
end
|
metadata
ADDED
@@ -0,0 +1,239 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: lexoffice_client
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- BeeGood IT
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2024-01-12 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: httparty
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rao-service
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: zeitwerk
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: factory_bot
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: guard-bundler
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: guard-rspec
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: guard-standardrb
|
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: rspec
|
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: standardrb
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: vcr
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - ">="
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0'
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - ">="
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0'
|
153
|
+
- !ruby/object:Gem::Dependency
|
154
|
+
name: webmock
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - ">="
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '0'
|
160
|
+
type: :development
|
161
|
+
prerelease: false
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - ">="
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '0'
|
167
|
+
description: Provides a client for the Lexoffice API.
|
168
|
+
email:
|
169
|
+
- info@beegoodit.de
|
170
|
+
executables: []
|
171
|
+
extensions: []
|
172
|
+
extra_rdoc_files: []
|
173
|
+
files:
|
174
|
+
- MIT-LICENSE
|
175
|
+
- README.md
|
176
|
+
- lib/lexoffice_client.rb
|
177
|
+
- lib/lexoffice_client/address.rb
|
178
|
+
- lib/lexoffice_client/company.rb
|
179
|
+
- lib/lexoffice_client/configuration.rb
|
180
|
+
- lib/lexoffice_client/contact.rb
|
181
|
+
- lib/lexoffice_client/contact/read_service.rb
|
182
|
+
- lib/lexoffice_client/customer.rb
|
183
|
+
- lib/lexoffice_client/document.rb
|
184
|
+
- lib/lexoffice_client/file/read_service.rb
|
185
|
+
- lib/lexoffice_client/invoice.rb
|
186
|
+
- lib/lexoffice_client/invoice/create_service.rb
|
187
|
+
- lib/lexoffice_client/invoice/document/read_service.rb
|
188
|
+
- lib/lexoffice_client/invoice/read_service.rb
|
189
|
+
- lib/lexoffice_client/invoices.rb
|
190
|
+
- lib/lexoffice_client/line_item.rb
|
191
|
+
- lib/lexoffice_client/model/base.rb
|
192
|
+
- lib/lexoffice_client/payment_conditions.rb
|
193
|
+
- lib/lexoffice_client/related_voucher.rb
|
194
|
+
- lib/lexoffice_client/role.rb
|
195
|
+
- lib/lexoffice_client/shipping_conditions.rb
|
196
|
+
- lib/lexoffice_client/tax_amount.rb
|
197
|
+
- lib/lexoffice_client/tax_conditions.rb
|
198
|
+
- lib/lexoffice_client/total_price.rb
|
199
|
+
- lib/lexoffice_client/unit_price.rb
|
200
|
+
- lib/lexoffice_client/vendor.rb
|
201
|
+
- lib/lexoffice_client/version.rb
|
202
|
+
- spec/factories/lexoffice_client/addresses.rb
|
203
|
+
- spec/factories/lexoffice_client/conpanies.rb
|
204
|
+
- spec/factories/lexoffice_client/contacts.rb
|
205
|
+
- spec/factories/lexoffice_client/documents.rb
|
206
|
+
- spec/factories/lexoffice_client/invoices.rb
|
207
|
+
- spec/factories/lexoffice_client/line_items.rb
|
208
|
+
- spec/factories/lexoffice_client/payment_conditions.rb
|
209
|
+
- spec/factories/lexoffice_client/related_vouchers.rb
|
210
|
+
- spec/factories/lexoffice_client/shipping_conditions.rb
|
211
|
+
- spec/factories/lexoffice_client/tax_amount.rb
|
212
|
+
- spec/factories/lexoffice_client/tax_conditions.rb
|
213
|
+
- spec/factories/lexoffice_client/total_prices.rb
|
214
|
+
- spec/factories/lexoffice_client/unit_prices.rb
|
215
|
+
homepage: https://hosting.beegoodit.de
|
216
|
+
licenses: []
|
217
|
+
metadata:
|
218
|
+
allowed_push_host: https://rubygems.org
|
219
|
+
homepage_uri: https://hosting.beegoodit.de
|
220
|
+
post_install_message:
|
221
|
+
rdoc_options: []
|
222
|
+
require_paths:
|
223
|
+
- lib
|
224
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
225
|
+
requirements:
|
226
|
+
- - ">="
|
227
|
+
- !ruby/object:Gem::Version
|
228
|
+
version: '0'
|
229
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
230
|
+
requirements:
|
231
|
+
- - ">="
|
232
|
+
- !ruby/object:Gem::Version
|
233
|
+
version: '0'
|
234
|
+
requirements: []
|
235
|
+
rubygems_version: 3.5.4
|
236
|
+
signing_key:
|
237
|
+
specification_version: 4
|
238
|
+
summary: Lexoffice API Client
|
239
|
+
test_files: []
|