lexoffice_client 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +28 -0
  4. data/lib/lexoffice_client/address.rb +5 -0
  5. data/lib/lexoffice_client/company.rb +5 -0
  6. data/lib/lexoffice_client/configuration.rb +25 -0
  7. data/lib/lexoffice_client/contact/read_service.rb +42 -0
  8. data/lib/lexoffice_client/contact.rb +40 -0
  9. data/lib/lexoffice_client/customer.rb +4 -0
  10. data/lib/lexoffice_client/document.rb +15 -0
  11. data/lib/lexoffice_client/file/read_service.rb +47 -0
  12. data/lib/lexoffice_client/invoice/create_service.rb +50 -0
  13. data/lib/lexoffice_client/invoice/document/read_service.rb +51 -0
  14. data/lib/lexoffice_client/invoice/read_service.rb +38 -0
  15. data/lib/lexoffice_client/invoice.rb +74 -0
  16. data/lib/lexoffice_client/invoices.rb +4 -0
  17. data/lib/lexoffice_client/line_item.rb +19 -0
  18. data/lib/lexoffice_client/model/base.rb +76 -0
  19. data/lib/lexoffice_client/payment_conditions.rb +7 -0
  20. data/lib/lexoffice_client/related_voucher.rb +4 -0
  21. data/lib/lexoffice_client/role.rb +5 -0
  22. data/lib/lexoffice_client/shipping_conditions.rb +5 -0
  23. data/lib/lexoffice_client/tax_amount.rb +7 -0
  24. data/lib/lexoffice_client/tax_conditions.rb +5 -0
  25. data/lib/lexoffice_client/total_price.rb +11 -0
  26. data/lib/lexoffice_client/unit_price.rb +8 -0
  27. data/lib/lexoffice_client/vendor.rb +4 -0
  28. data/lib/lexoffice_client/version.rb +3 -0
  29. data/lib/lexoffice_client.rb +16 -0
  30. data/spec/factories/lexoffice_client/addresses.rb +10 -0
  31. data/spec/factories/lexoffice_client/conpanies.rb +4 -0
  32. data/spec/factories/lexoffice_client/contacts.rb +5 -0
  33. data/spec/factories/lexoffice_client/documents.rb +7 -0
  34. data/spec/factories/lexoffice_client/invoices.rb +17 -0
  35. data/spec/factories/lexoffice_client/line_items.rb +12 -0
  36. data/spec/factories/lexoffice_client/payment_conditions.rb +7 -0
  37. data/spec/factories/lexoffice_client/related_vouchers.rb +4 -0
  38. data/spec/factories/lexoffice_client/shipping_conditions.rb +6 -0
  39. data/spec/factories/lexoffice_client/tax_amount.rb +7 -0
  40. data/spec/factories/lexoffice_client/tax_conditions.rb +5 -0
  41. data/spec/factories/lexoffice_client/total_prices.rb +8 -0
  42. data/spec/factories/lexoffice_client/unit_prices.rb +8 -0
  43. 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,5 @@
1
+ module LexofficeClient
2
+ class Address < LexofficeClient::Model::Base
3
+ attr_accessor :name, :supplement, :street, :city, :zip, :country_code, :contact_id, :contact_person
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ module LexofficeClient
2
+ class Company < LexofficeClient::Model::Base
3
+ attr_accessor :allow_tax_free_invoices, :name, :tax_number, :vat_registration_id
4
+ end
5
+ end
@@ -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,4 @@
1
+ module LexofficeClient
2
+ class Customer < Role
3
+ end
4
+ 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,4 @@
1
+ module LexofficeClient
2
+ module Invoices
3
+ end
4
+ 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,7 @@
1
+ module LexofficeClient
2
+ class PaymentConditions < LexofficeClient::Model::Base
3
+ attr_accessor :payment_term_label,
4
+ :payment_term_label_template,
5
+ :payment_term_duration
6
+ end
7
+ end
@@ -0,0 +1,4 @@
1
+ module LexofficeClient
2
+ class RelatedVoucher < LexofficeClient::Model::Base
3
+ end
4
+ end
@@ -0,0 +1,5 @@
1
+ module LexofficeClient
2
+ class Role < LexofficeClient::Model::Base
3
+ attr_accessor :number
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ module LexofficeClient
2
+ class ShippingConditions < LexofficeClient::Model::Base
3
+ attr_accessor :shipping_date, :shipping_end_date, :shipping_type
4
+ end
5
+ end
@@ -0,0 +1,7 @@
1
+ module LexofficeClient
2
+ class TaxAmount < LexofficeClient::Model::Base
3
+ attr_accessor :tax_rate_percentage,
4
+ :tax_amount,
5
+ :net_amount
6
+ end
7
+ end
@@ -0,0 +1,5 @@
1
+ module LexofficeClient
2
+ class TaxConditions < LexofficeClient::Model::Base
3
+ attr_accessor :tax_type
4
+ end
5
+ 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,8 @@
1
+ module LexofficeClient
2
+ class UnitPrice < LexofficeClient::Model::Base
3
+ attr_accessor :currency,
4
+ :net_amount,
5
+ :gross_amount,
6
+ :tax_rate_percentage
7
+ end
8
+ end
@@ -0,0 +1,4 @@
1
+ module LexofficeClient
2
+ class Vendor < Role
3
+ end
4
+ end
@@ -0,0 +1,3 @@
1
+ module LexofficeClient
2
+ VERSION = "0.0.1"
3
+ 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,4 @@
1
+ FactoryBot.define do
2
+ factory :lexoffice_client_company, class: LexofficeClient::Company do
3
+ end
4
+ end
@@ -0,0 +1,5 @@
1
+ FactoryBot.define do
2
+ factory :lexoffice_client_contact, class: LexofficeClient::Contact do
3
+ addresses { {"billing" => [build(:lexoffice_client_address)]} }
4
+ end
5
+ 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
@@ -0,0 +1,4 @@
1
+ FactoryBot.define do
2
+ factory :lexoffice_client_related_voucher, class: LexofficeClient::RelatedVoucher do
3
+ end
4
+ end
@@ -0,0 +1,6 @@
1
+ FactoryBot.define do
2
+ factory :lexoffice_client_shipping_conditions, class: LexofficeClient::ShippingConditions do
3
+ shipping_date { "2023-08-31T00:00:00.000+02:00" }
4
+ shipping_type { "delivery" }
5
+ end
6
+ end
@@ -0,0 +1,7 @@
1
+ FactoryBot.define do
2
+ factory :lexoffice_client_tax_amount, class: LexofficeClient::TaxAmount do
3
+ tax_rate_percentage { 19.00 }
4
+ tax_amount { 19.00 }
5
+ net_amount { 100.00 }
6
+ end
7
+ end
@@ -0,0 +1,5 @@
1
+ FactoryBot.define do
2
+ factory :lexoffice_client_tax_conditions, class: LexofficeClient::TaxConditions do
3
+ tax_type { "net" }
4
+ end
5
+ end
@@ -0,0 +1,8 @@
1
+ FactoryBot.define do
2
+ factory :lexoffice_client_total_price, class: LexofficeClient::TotalPrice do
3
+ currency { "EUR" }
4
+ total_net_amount { 100.00 }
5
+ total_gross_amount { 119.00 }
6
+ total_tax_amount { 19.00 }
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ FactoryBot.define do
2
+ factory :lexoffice_client_unit_price, class: LexofficeClient::UnitPrice do
3
+ currency { "EUR" }
4
+ net_amount { 100 }
5
+ gross_amount { 119 }
6
+ tax_rate_percentage { 19 }
7
+ end
8
+ 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: []