dear_inventory 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (110) hide show
  1. checksums.yaml +7 -0
  2. data/.env.example +2 -0
  3. data/.gitignore +15 -0
  4. data/.rspec +5 -0
  5. data/.rubocop.yml +84 -0
  6. data/.travis.yml +7 -0
  7. data/CODE_OF_CONDUCT.md +74 -0
  8. data/Gemfile +6 -0
  9. data/LICENSE.txt +21 -0
  10. data/README.md +69 -0
  11. data/Rakefile +8 -0
  12. data/bin/console +14 -0
  13. data/bin/setup +8 -0
  14. data/dear_inventory.gemspec +45 -0
  15. data/lib/dear_inventory.rb +79 -0
  16. data/lib/dear_inventory/config.rb +55 -0
  17. data/lib/dear_inventory/environment.rb +54 -0
  18. data/lib/dear_inventory/error.rb +16 -0
  19. data/lib/dear_inventory/errors/request.rb +40 -0
  20. data/lib/dear_inventory/errors/validation.rb +6 -0
  21. data/lib/dear_inventory/lib/date_time.rb +18 -0
  22. data/lib/dear_inventory/lib/endpoint_class.rb +57 -0
  23. data/lib/dear_inventory/lib/is_a_subclass.rb +19 -0
  24. data/lib/dear_inventory/model.rb +98 -0
  25. data/lib/dear_inventory/models/additional_attributes.rb +53 -0
  26. data/lib/dear_inventory/models/additional_charge.rb +45 -0
  27. data/lib/dear_inventory/models/address.rb +45 -0
  28. data/lib/dear_inventory/models/attachment.rb +33 -0
  29. data/lib/dear_inventory/models/inventory_movement.rb +29 -0
  30. data/lib/dear_inventory/models/sale.rb +217 -0
  31. data/lib/dear_inventory/models/sale_list.rb +133 -0
  32. data/lib/dear_inventory/models/sale_lists.rb +26 -0
  33. data/lib/dear_inventory/models/sales/credit_note.rb +75 -0
  34. data/lib/dear_inventory/models/sales/fulfilment.rb +46 -0
  35. data/lib/dear_inventory/models/sales/fulfilments/pick_pack.rb +26 -0
  36. data/lib/dear_inventory/models/sales/fulfilments/pick_pack_line.rb +57 -0
  37. data/lib/dear_inventory/models/sales/fulfilments/ship.rb +35 -0
  38. data/lib/dear_inventory/models/sales/fulfilments/ship_line.rb +45 -0
  39. data/lib/dear_inventory/models/sales/invoice.rb +86 -0
  40. data/lib/dear_inventory/models/sales/invoice_line.rb +19 -0
  41. data/lib/dear_inventory/models/sales/line.rb +59 -0
  42. data/lib/dear_inventory/models/sales/manual_journal.rb +24 -0
  43. data/lib/dear_inventory/models/sales/manual_journal_line.rb +35 -0
  44. data/lib/dear_inventory/models/sales/order.rb +49 -0
  45. data/lib/dear_inventory/models/sales/payment_line.rb +43 -0
  46. data/lib/dear_inventory/models/sales/quote.rb +50 -0
  47. data/lib/dear_inventory/models/shipping_address.rb +25 -0
  48. data/lib/dear_inventory/models/transaction.rb +41 -0
  49. data/lib/dear_inventory/parameters.rb +209 -0
  50. data/lib/dear_inventory/parameters/sale/index.rb +35 -0
  51. data/lib/dear_inventory/parameters/sale_list/index.rb +119 -0
  52. data/lib/dear_inventory/resource.rb +59 -0
  53. data/lib/dear_inventory/resources/sale.rb +22 -0
  54. data/lib/dear_inventory/resources/sale_list.rb +24 -0
  55. data/lib/dear_inventory/response.rb +75 -0
  56. data/lib/dear_inventory/validator.rb +61 -0
  57. data/lib/dear_inventory/validators/boolean.rb +18 -0
  58. data/lib/dear_inventory/validators/enum.rb +23 -0
  59. data/lib/dear_inventory/validators/guid.rb +27 -0
  60. data/lib/dear_inventory/validators/integer.rb +19 -0
  61. data/lib/dear_inventory/validators/required.rb +17 -0
  62. data/lib/dear_inventory/validators/string.rb +35 -0
  63. data/lib/dear_inventory/validators/time.rb +21 -0
  64. data/lib/dear_inventory/version.rb +6 -0
  65. data/sorbet/config +2 -0
  66. data/sorbet/rbi/gems/addressable.rbi +199 -0
  67. data/sorbet/rbi/gems/ast.rbi +48 -0
  68. data/sorbet/rbi/gems/byebug.rbi +1040 -0
  69. data/sorbet/rbi/gems/coderay.rbi +92 -0
  70. data/sorbet/rbi/gems/crack.rbi +48 -0
  71. data/sorbet/rbi/gems/domain_name.rbi +52 -0
  72. data/sorbet/rbi/gems/dotenv.rbi +68 -0
  73. data/sorbet/rbi/gems/ffi-compiler.rbi +27 -0
  74. data/sorbet/rbi/gems/ffi.rbi +560 -0
  75. data/sorbet/rbi/gems/hashdiff.rbi +66 -0
  76. data/sorbet/rbi/gems/http-cookie.rbi +93 -0
  77. data/sorbet/rbi/gems/http-form_data.rbi +76 -0
  78. data/sorbet/rbi/gems/http-parser.rbi +121 -0
  79. data/sorbet/rbi/gems/http.rbi +616 -0
  80. data/sorbet/rbi/gems/jaro_winkler.rbi +15 -0
  81. data/sorbet/rbi/gems/method_source.rbi +64 -0
  82. data/sorbet/rbi/gems/parallel.rbi +82 -0
  83. data/sorbet/rbi/gems/parser.rbi +857 -0
  84. data/sorbet/rbi/gems/pry-byebug.rbi +155 -0
  85. data/sorbet/rbi/gems/pry.rbi +1965 -0
  86. data/sorbet/rbi/gems/public_suffix.rbi +104 -0
  87. data/sorbet/rbi/gems/rainbow.rbi +118 -0
  88. data/sorbet/rbi/gems/rake.rbi +646 -0
  89. data/sorbet/rbi/gems/rspec-core.rbi +1732 -0
  90. data/sorbet/rbi/gems/rspec-expectations.rbi +388 -0
  91. data/sorbet/rbi/gems/rspec-mocks.rbi +820 -0
  92. data/sorbet/rbi/gems/rspec-support.rbi +269 -0
  93. data/sorbet/rbi/gems/rspec.rbi +15 -0
  94. data/sorbet/rbi/gems/rubocop-performance.rbi +277 -0
  95. data/sorbet/rbi/gems/rubocop-rspec.rbi +887 -0
  96. data/sorbet/rbi/gems/rubocop.rbi +6952 -0
  97. data/sorbet/rbi/gems/ruby-progressbar.rbi +305 -0
  98. data/sorbet/rbi/gems/unf.rbi +19 -0
  99. data/sorbet/rbi/gems/unicode-display_width.rbi +17 -0
  100. data/sorbet/rbi/gems/vcr.rbi +572 -0
  101. data/sorbet/rbi/gems/webmock.rbi +569 -0
  102. data/sorbet/rbi/hidden-definitions/errors.txt +11809 -0
  103. data/sorbet/rbi/hidden-definitions/hidden.rbi +20627 -0
  104. data/sorbet/rbi/sorbet-typed/lib/bundler/all/bundler.rbi +8684 -0
  105. data/sorbet/rbi/sorbet-typed/lib/rainbow/all/rainbow.rbi +276 -0
  106. data/sorbet/rbi/sorbet-typed/lib/ruby/all/gem.rbi +4222 -0
  107. data/sorbet/rbi/sorbet-typed/lib/ruby/all/open3.rbi +111 -0
  108. data/sorbet/rbi/sorbet-typed/lib/ruby/all/resolv.rbi +543 -0
  109. data/sorbet/rbi/todo.rbi +11 -0
  110. metadata +339 -0
@@ -0,0 +1,55 @@
1
+ # typed: ignore
2
+ # frozen_string_literal: true
3
+
4
+ module DearInventory
5
+ class Config
6
+ extend T::Sig
7
+
8
+ sig { returns(DearInventory::Environment.class) }
9
+ def environment
10
+ DearInventory::Environment
11
+ end
12
+
13
+ sig { params(value: Symbol).void }
14
+ def environment=(value)
15
+ DearInventory::Environment.set(value)
16
+ end
17
+
18
+ sig { returns(T.nilable(String)) }
19
+ attr_accessor :account_id
20
+
21
+ sig { returns(T.nilable(String)) }
22
+ attr_accessor :key
23
+
24
+ sig { params(param: Symbol).returns(String) }
25
+ def require(param)
26
+ value = public_send(param)
27
+ return value unless value.nil? || value.empty?
28
+
29
+ require_error(param)
30
+ end
31
+
32
+ sig { params(param: Symbol).returns(String) }
33
+ def require_parameter(param)
34
+ require(param)
35
+ rescue ArgumentError => e
36
+ message = e.message + "\n" \
37
+ "Alternatively, you can pass dynamic values with your request " \
38
+ "parameters"
39
+ raise ArgumentError, message
40
+ end
41
+
42
+ private
43
+
44
+ sig { params(param: Symbol).void }
45
+ def require_error(param)
46
+ raise(
47
+ ArgumentError,
48
+ "#{param} is required but hasn't been set.\n" \
49
+ "DearInventory.configure do |config|\n" +
50
+ %( config.#{param} = "value") + "\n" \
51
+ "end"
52
+ )
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,54 @@
1
+ # typed: ignore
2
+ # frozen_string_literal: true
3
+
4
+ # Usually this class wouldn't be called directly, the environment can be managed
5
+ # via the DearInventory::Config class or one of it's sub-classes
6
+ module DearInventory
7
+ class Environment
8
+ class << self
9
+ def production?
10
+ to_sym == :production
11
+ end
12
+
13
+ def test?
14
+ to_sym == :test
15
+ end
16
+
17
+ def to_sym
18
+ @to_sym ||= set(default)
19
+ end
20
+
21
+ ENVIRONMENTS = %i[production test].freeze
22
+
23
+ def set(value)
24
+ return @to_sym = value if ENVIRONMENTS.include?(value)
25
+
26
+ error_value = value.is_a?(Symbol) ? ":#{value}" : value.to_s
27
+ raise(
28
+ ArgumentError,
29
+ "#{error_value} is not an acceptable environment; " \
30
+ "please use either :production or :test"
31
+ )
32
+ end
33
+
34
+ private
35
+
36
+ def default
37
+ return :test if ENV["ENV"] == "test"
38
+ return rails if rails?
39
+
40
+ :production
41
+ end
42
+
43
+ def rails?
44
+ defined?(Rails)
45
+ end
46
+
47
+ def rails
48
+ return :production if Rails.env.production?
49
+
50
+ :test
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,16 @@
1
+ # typed: strong
2
+ # frozen_string_literal: true
3
+
4
+ module DearInventory
5
+ class Error < StandardError
6
+ extend T::Sig
7
+
8
+ sig { returns(T.nilable(String)) }
9
+ attr_reader :message
10
+
11
+ sig { params(message: T.nilable(String)).void }
12
+ def initialize(message = nil)
13
+ @message = T.let(message, T.nilable(String))
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,40 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ module DearInventory
5
+ class RequestError < Error
6
+ extend T::Sig
7
+
8
+ sig do
9
+ params(
10
+ message: T.nilable(String),
11
+ response: T.nilable(DearInventory::Response)
12
+ ).void
13
+ end
14
+ def initialize(message = nil, response = nil)
15
+ super(message)
16
+
17
+ @response = T.let(response, T.nilable(DearInventory::Response))
18
+ end
19
+
20
+ sig { returns(T.nilable(String)) }
21
+ def http_body
22
+ @response&.error || @response&.body&.to_s
23
+ end
24
+
25
+ sig { returns(T.nilable(T::Hash[Symbol, String])) }
26
+ def http_headers
27
+ @response&.headers
28
+ end
29
+
30
+ sig { returns(T.nilable(Integer)) }
31
+ def http_status
32
+ @response&.http_status
33
+ end
34
+
35
+ sig { returns(T.nilable(String)) }
36
+ def url
37
+ @response&.url&.to_s
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,6 @@
1
+ # typed: strong
2
+ # frozen_string_literal: true
3
+
4
+ module DearInventory
5
+ class ValidationError < DearInventory::Error; end
6
+ end
@@ -0,0 +1,18 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ module DearInventory
5
+ class DateTime
6
+ extend T::Sig
7
+
8
+ sig { params(date: T.any(Date, Time)).void }
9
+ def initialize(date)
10
+ @date = T.let(date, T.any(Date, Time))
11
+ end
12
+
13
+ sig { returns(String) }
14
+ def to_s
15
+ @date.strftime("%FT%T%:z")
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,57 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ module DearInventory
5
+ class EndpointClass
6
+ extend T::Sig
7
+
8
+ sig do
9
+ params(
10
+ class_type: String,
11
+ resource_class: T.class_of(DearInventory::Resource),
12
+ endpoint: T.nilable(String)
13
+ ).returns(
14
+ T.nilable(T.class_of(DearInventory::Parameters))
15
+ )
16
+ end
17
+ def self.call(class_type:, resource_class:, endpoint:)
18
+ new(
19
+ class_type: class_type,
20
+ resource_class: resource_class,
21
+ endpoint: endpoint
22
+ ).call
23
+ end
24
+
25
+ sig do
26
+ params(
27
+ class_type: String,
28
+ resource_class: T.class_of(DearInventory::Resource),
29
+ endpoint: T.nilable(String)
30
+ ).void
31
+ end
32
+ def initialize(class_type:, resource_class:, endpoint:)
33
+ @class_type = T.let(class_type, String)
34
+ @resource_class = T.let(resource_class, T.untyped)
35
+ @endpoint = T.let(endpoint || "Index", String)
36
+ @class_name = T.let(nil, T.nilable(String))
37
+ end
38
+
39
+ sig { returns(T.nilable(T.class_of(DearInventory::Parameters))) }
40
+ def call
41
+ Object.const_get(class_name) if Object.const_defined?(class_name)
42
+ end
43
+
44
+ private
45
+
46
+ sig { returns(String) }
47
+ def class_name
48
+ @class_name ||= begin
49
+ name = ["DearInventory"]
50
+ name << @class_type
51
+ name << @resource_class.name.split("::").last
52
+ name << @endpoint
53
+ name.join("::")
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,19 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ module DearInventory
5
+ module IsASubclass
6
+ extend T::Sig
7
+
8
+ sig { params(comparison_class: T.untyped).returns(T::Boolean) }
9
+ def is_a?(comparison_class)
10
+ return true if super
11
+
12
+ if T.unsafe(self).class == Class
13
+ return T.unsafe(self).ancestors.include?(comparison_class)
14
+ end
15
+
16
+ false
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,98 @@
1
+ # typed: true
2
+ # frozen_string_literal: true
3
+
4
+ require "json"
5
+
6
+ module DearInventory
7
+ class Model
8
+ extend T::Sig
9
+ extend T::Helpers
10
+ abstract!
11
+
12
+ extend DearInventory::IsASubclass
13
+
14
+ sig do
15
+ params(
16
+ fields: T::Hash[
17
+ Symbol,
18
+ T::Hash[Symbol, T.any(Symbol, T.class_of(DearInventory::Model))]
19
+ ]
20
+ ).void
21
+ end
22
+ def self.fields(fields)
23
+ if const_defined?(:FIELDS, false)
24
+ fields = remove_const(:FIELDS).merge(fields)
25
+ end
26
+ const_set(:FIELDS, fields.freeze)
27
+
28
+ enumerate_fields do |_, specifications|
29
+ __send__(:attr_reader, specifications[:name])
30
+ end
31
+ end
32
+
33
+ sig { void }
34
+ def self.enumerate_fields
35
+ const_get(:FIELDS).each do |response_name, specifications|
36
+ yield(response_name, specifications)
37
+ end
38
+ end
39
+
40
+ sig do
41
+ params(values: T.nilable(T::Hash[String, T.untyped])).void
42
+ end
43
+ def initialize(values)
44
+ return if values.nil?
45
+
46
+ self.class.enumerate_fields do |response_name, specifications|
47
+ value = field_value(response_name, T.must(values), specifications)
48
+ instance_variable_set(:"@#{specifications[:name]}", value)
49
+ end
50
+ end
51
+
52
+ private
53
+
54
+ sig do
55
+ params(
56
+ response_name: Symbol,
57
+ values:
58
+ T::Hash[String, T.untyped],
59
+ specifications:
60
+ T::Hash[Symbol, T.any(Symbol, T.class_of(DearInventory::Model))]
61
+ ).returns(
62
+ T.nilable(
63
+ T.any(
64
+ String, Numeric, T::Boolean,
65
+ DearInventory::Model, T::Array[DearInventory::Model]
66
+ )
67
+ )
68
+ )
69
+ end
70
+ def field_value(response_name, values, specifications)
71
+ model = specifications[:model]
72
+ value = values[response_name.to_s]
73
+
74
+ case specifications[:type]
75
+ when :Array
76
+ initialize_array_values_in_models(value, model)
77
+ when :Hash
78
+ model.new(value)
79
+ else
80
+ value
81
+ end
82
+ end
83
+
84
+ sig do
85
+ params(
86
+ array: T.nilable(T::Array[T::Hash[String, T.untyped]]),
87
+ model: T.class_of(DearInventory::Model)
88
+ ).returns(T.nilable(T::Array[DearInventory::Model]))
89
+ end
90
+ def initialize_array_values_in_models(array, model)
91
+ return if array.nil?
92
+
93
+ array.each_with_object([]) do |values, records|
94
+ records << model.new(values)
95
+ end
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,53 @@
1
+ # typed: strong
2
+ # frozen_string_literal: true
3
+
4
+ module DearInventory
5
+ module Models
6
+ class AdditionalAttributes < DearInventory::Model
7
+ extend T::Sig
8
+
9
+ fields({
10
+ AdditionalAttribute1: {
11
+ name: :additional_attribute_1,
12
+ type: :String,
13
+ },
14
+ AdditionalAttribute2: {
15
+ name: :additional_attribute_2,
16
+ type: :String,
17
+ },
18
+ AdditionalAttribute3: {
19
+ name: :additional_attribute_3,
20
+ type: :String,
21
+ },
22
+ AdditionalAttribute4: {
23
+ name: :additional_attribute_4,
24
+ type: :String,
25
+ },
26
+ AdditionalAttribute5: {
27
+ name: :additional_attribute_5,
28
+ type: :String,
29
+ },
30
+ AdditionalAttribute6: {
31
+ name: :additional_attribute_6,
32
+ type: :String,
33
+ },
34
+ AdditionalAttribute7: {
35
+ name: :additional_attribute_7,
36
+ type: :String,
37
+ },
38
+ AdditionalAttribute8: {
39
+ name: :additional_attribute_8,
40
+ type: :String,
41
+ },
42
+ AdditionalAttribute9: {
43
+ name: :additional_attribute_9,
44
+ type: :String,
45
+ },
46
+ AdditionalAttribute10: {
47
+ name: :additional_attribute_10,
48
+ type: :String,
49
+ },
50
+ })
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,45 @@
1
+ # typed: strong
2
+ # frozen_string_literal: true
3
+
4
+ module DearInventory
5
+ module Models
6
+ class AdditionalCharge < DearInventory::Model
7
+ extend T::Sig
8
+
9
+ fields({
10
+ Description: {
11
+ name: :description,
12
+ type: :String,
13
+ },
14
+ Price: {
15
+ name: :price,
16
+ type: :Numeric,
17
+ },
18
+ Quantity: {
19
+ name: :quantity,
20
+ type: :Numeric,
21
+ },
22
+ Discount: {
23
+ name: :discount,
24
+ type: :Numeric,
25
+ },
26
+ Tax: {
27
+ name: :tax,
28
+ type: :Numeric,
29
+ },
30
+ Total: {
31
+ name: :total,
32
+ type: :Numeric,
33
+ },
34
+ TaxRule: {
35
+ name: :tax_rule,
36
+ type: :String,
37
+ },
38
+ Comment: {
39
+ name: :comment,
40
+ type: :String,
41
+ },
42
+ })
43
+ end
44
+ end
45
+ end