dear_inventory 0.7.5 → 1.0.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 (80) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +15 -0
  3. data/README.md +70 -18
  4. data/dear_inventory.gemspec +1 -1
  5. data/docs/resources/advanced_purchase.md +25 -0
  6. data/docs/resources/customer.md +31 -0
  7. data/docs/resources/product.md +37 -0
  8. data/docs/resources/purchase.md +89 -0
  9. data/docs/resources/sale.md +89 -0
  10. data/lib/dear_inventory.rb +20 -8
  11. data/lib/dear_inventory/config.rb +17 -6
  12. data/lib/dear_inventory/errors/api_limit.rb +6 -0
  13. data/lib/dear_inventory/errors/no_more_pages.rb +6 -0
  14. data/lib/dear_inventory/lib/endpoint_class.rb +1 -1
  15. data/lib/dear_inventory/lib/request.rb +45 -8
  16. data/lib/dear_inventory/lib/strings/urlize.rb +18 -0
  17. data/lib/dear_inventory/model.rb +22 -9
  18. data/lib/dear_inventory/models/advanced_purchase.rb +176 -0
  19. data/lib/dear_inventory/models/customer.rb +1 -1
  20. data/lib/dear_inventory/models/customers.rb +1 -1
  21. data/lib/dear_inventory/models/products.rb +1 -1
  22. data/lib/dear_inventory/models/{purchase_list.rb → purchases.rb} +12 -2
  23. data/lib/dear_inventory/models/purchases/additional_charge.rb +1 -1
  24. data/lib/dear_inventory/models/purchases/advanced/credit_note.rb +21 -0
  25. data/lib/dear_inventory/models/purchases/advanced/invoice.rb +68 -0
  26. data/lib/dear_inventory/models/purchases/advanced/manual_journal.rb +21 -0
  27. data/lib/dear_inventory/models/purchases/advanced/put_away.rb +34 -0
  28. data/lib/dear_inventory/models/purchases/advanced/put_away_line.rb +21 -0
  29. data/lib/dear_inventory/models/purchases/advanced/stock.rb +30 -0
  30. data/lib/dear_inventory/models/purchases/advanced/stock_line.rb +61 -0
  31. data/lib/dear_inventory/models/purchases/credit_note.rb +1 -1
  32. data/lib/dear_inventory/models/purchases/inventory_movement.rb +1 -1
  33. data/lib/dear_inventory/models/purchases/invoice.rb +1 -1
  34. data/lib/dear_inventory/models/purchases/invoice_additional_charge.rb +1 -1
  35. data/lib/dear_inventory/models/purchases/invoice_line.rb +1 -1
  36. data/lib/dear_inventory/models/purchases/line.rb +1 -1
  37. data/lib/dear_inventory/models/purchases/manual_journal.rb +1 -1
  38. data/lib/dear_inventory/models/purchases/manual_journal_line.rb +1 -1
  39. data/lib/dear_inventory/models/purchases/order.rb +1 -1
  40. data/lib/dear_inventory/models/purchases/payment_line.rb +51 -0
  41. data/lib/dear_inventory/models/purchases/stock.rb +1 -1
  42. data/lib/dear_inventory/models/purchases/stock_line.rb +1 -1
  43. data/lib/dear_inventory/models/purchases/unstock_line.rb +1 -1
  44. data/lib/dear_inventory/models/{purchase_lists.rb → purchases_results.rb} +4 -4
  45. data/lib/dear_inventory/models/{sale_list.rb → sales.rb} +7 -2
  46. data/lib/dear_inventory/models/sales/additional_charge.rb +1 -1
  47. data/lib/dear_inventory/models/sales/credit_note.rb +1 -1
  48. data/lib/dear_inventory/models/sales/fulfilment.rb +1 -1
  49. data/lib/dear_inventory/models/sales/fulfilments/pick_pack.rb +1 -1
  50. data/lib/dear_inventory/models/sales/fulfilments/pick_pack_line.rb +1 -1
  51. data/lib/dear_inventory/models/sales/fulfilments/ship.rb +1 -1
  52. data/lib/dear_inventory/models/sales/fulfilments/ship_line.rb +1 -1
  53. data/lib/dear_inventory/models/sales/invoice.rb +1 -1
  54. data/lib/dear_inventory/models/sales/invoice_additional_charge.rb +1 -1
  55. data/lib/dear_inventory/models/sales/invoice_line.rb +1 -1
  56. data/lib/dear_inventory/models/sales/line.rb +1 -1
  57. data/lib/dear_inventory/models/sales/manual_journal.rb +1 -1
  58. data/lib/dear_inventory/models/sales/manual_journal_line.rb +1 -1
  59. data/lib/dear_inventory/models/sales/order.rb +1 -1
  60. data/lib/dear_inventory/models/sales/payment_line.rb +1 -1
  61. data/lib/dear_inventory/models/sales/quote.rb +1 -1
  62. data/lib/dear_inventory/models/{sale_lists.rb → sales_results.rb} +4 -4
  63. data/lib/dear_inventory/parameters/advanced_purchase/show.rb +25 -0
  64. data/lib/dear_inventory/parameters/purchase/index.rb +65 -6
  65. data/lib/dear_inventory/parameters/purchase/show.rb +25 -0
  66. data/lib/dear_inventory/parameters/sale/index.rb +95 -11
  67. data/lib/dear_inventory/parameters/sale/show.rb +35 -0
  68. data/lib/dear_inventory/resource.rb +8 -11
  69. data/lib/dear_inventory/resources/{purchase_list.rb → advanced_purchase.rb} +8 -5
  70. data/lib/dear_inventory/resources/customer.rb +2 -0
  71. data/lib/dear_inventory/resources/product.rb +2 -0
  72. data/lib/dear_inventory/resources/purchase.rb +38 -2
  73. data/lib/dear_inventory/resources/sale.rb +38 -2
  74. data/lib/dear_inventory/response.rb +118 -17
  75. data/lib/dear_inventory/version.rb +1 -1
  76. data/sorbet/rbi/hidden-definitions/hidden.rbi +0 -4
  77. metadata +29 -12
  78. data/lib/dear_inventory/parameters/purchase_list/index.rb +0 -84
  79. data/lib/dear_inventory/parameters/sale_list/index.rb +0 -119
  80. data/lib/dear_inventory/resources/sale_list.rb +0 -24
@@ -8,6 +8,8 @@ require "dear_inventory/config"
8
8
  require "dear_inventory/environment"
9
9
 
10
10
  require "dear_inventory/error"
11
+ require "dear_inventory/errors/api_limit"
12
+ require "dear_inventory/errors/no_more_pages"
11
13
  require "dear_inventory/errors/not_paginated"
12
14
  require "dear_inventory/errors/validation"
13
15
 
@@ -18,6 +20,7 @@ require "dear_inventory/lib/endpoint_class"
18
20
  require "dear_inventory/lib/date_time"
19
21
  require "dear_inventory/lib/is_a_subclass"
20
22
  require "dear_inventory/lib/request"
23
+ require "dear_inventory/lib/strings/urlize"
21
24
 
22
25
  require "dear_inventory/model"
23
26
  require "dear_inventory/models/additional_attributes"
@@ -29,8 +32,8 @@ require "dear_inventory/models/customers/address"
29
32
  require "dear_inventory/models/customers/contact"
30
33
  require "dear_inventory/models/inventory_movement"
31
34
  require "dear_inventory/models/products/movement"
32
- require "dear_inventory/models/purchase_list"
33
- require "dear_inventory/models/purchase_lists"
35
+ require "dear_inventory/models/purchases"
36
+ require "dear_inventory/models/purchases_results"
34
37
  require "dear_inventory/models/purchases/additional_charge"
35
38
  require "dear_inventory/models/purchases/inventory_movement"
36
39
  require "dear_inventory/models/purchases/invoice_additional_charge"
@@ -38,11 +41,11 @@ require "dear_inventory/models/purchases/line"
38
41
  require "dear_inventory/models/purchases/invoice_line"
39
42
  require "dear_inventory/models/purchases/manual_journal_line"
40
43
  require "dear_inventory/models/purchases/manual_journal"
44
+ require "dear_inventory/models/purchases/payment_line"
41
45
  require "dear_inventory/models/purchases/stock_line"
42
46
  require "dear_inventory/models/purchases/stock"
43
47
  require "dear_inventory/models/purchases/unstock_line"
44
48
  require "dear_inventory/models/reorder_level"
45
- require "dear_inventory/models/sale_list"
46
49
  require "dear_inventory/models/sales/additional_charge"
47
50
  require "dear_inventory/models/sales/invoice_additional_charge"
48
51
  require "dear_inventory/models/sales/line"
@@ -60,7 +63,7 @@ require "dear_inventory/models/sales/fulfilments/pick_pack"
60
63
  require "dear_inventory/models/sales/fulfilments/ship_line"
61
64
  require "dear_inventory/models/sales/fulfilments/ship"
62
65
  require "dear_inventory/models/sales/fulfilment"
63
- require "dear_inventory/models/sale_lists"
66
+ require "dear_inventory/models/sales_results"
64
67
 
65
68
  require "dear_inventory/models/customer"
66
69
  require "dear_inventory/models/customers"
@@ -70,9 +73,18 @@ require "dear_inventory/models/purchases/credit_note"
70
73
  require "dear_inventory/models/purchases/invoice"
71
74
  require "dear_inventory/models/purchases/order"
72
75
  require "dear_inventory/models/purchase"
76
+ require "dear_inventory/models/purchases/advanced/credit_note"
77
+ require "dear_inventory/models/purchases/advanced/invoice"
78
+ require "dear_inventory/models/purchases/advanced/manual_journal"
79
+ require "dear_inventory/models/purchases/advanced/put_away_line"
80
+ require "dear_inventory/models/purchases/advanced/put_away"
81
+ require "dear_inventory/models/purchases/advanced/stock_line"
82
+ require "dear_inventory/models/purchases/advanced/stock"
83
+ require "dear_inventory/models/advanced_purchase"
73
84
  require "dear_inventory/models/sales/credit_note"
74
85
  require "dear_inventory/models/sales/invoice"
75
86
  require "dear_inventory/models/sale"
87
+ require "dear_inventory/models/sales"
76
88
  require "dear_inventory/models/request"
77
89
 
78
90
  require "dear_inventory/validator"
@@ -85,20 +97,20 @@ require "dear_inventory/validators/string"
85
97
  require "dear_inventory/validators/time"
86
98
 
87
99
  require "dear_inventory/parameters"
100
+ require "dear_inventory/parameters/advanced_purchase/show"
88
101
  require "dear_inventory/parameters/customer/index"
89
102
  require "dear_inventory/parameters/product/index"
90
103
  require "dear_inventory/parameters/purchase/index"
91
- require "dear_inventory/parameters/purchase_list/index"
104
+ require "dear_inventory/parameters/purchase/show"
92
105
  require "dear_inventory/parameters/sale/index"
93
- require "dear_inventory/parameters/sale_list/index"
106
+ require "dear_inventory/parameters/sale/show"
94
107
 
95
108
  require "dear_inventory/resource"
109
+ require "dear_inventory/resources/advanced_purchase"
96
110
  require "dear_inventory/resources/customer"
97
111
  require "dear_inventory/resources/product"
98
112
  require "dear_inventory/resources/purchase"
99
- require "dear_inventory/resources/purchase_list"
100
113
  require "dear_inventory/resources/sale"
101
- require "dear_inventory/resources/sale_list"
102
114
 
103
115
  require "dear_inventory/response"
104
116
 
@@ -1,10 +1,27 @@
1
1
  # typed: ignore
2
2
  # frozen_string_literal: true
3
3
 
4
+ require "logger"
5
+
4
6
  module DearInventory
5
7
  class Config
6
8
  extend T::Sig
7
9
 
10
+ sig { returns(T.nilable(String)) }
11
+ attr_accessor :account_id
12
+
13
+ sig { returns(T.nilable(String)) }
14
+ attr_accessor :key
15
+
16
+ sig { returns(T.untyped) }
17
+ attr_accessor :logger
18
+
19
+ sig { void }
20
+ def initialize
21
+ @logger = Logger.new(STDOUT)
22
+ @logger.level = Logger::WARN
23
+ end
24
+
8
25
  sig { returns(DearInventory::Environment.class) }
9
26
  def environment
10
27
  DearInventory::Environment
@@ -15,12 +32,6 @@ module DearInventory
15
32
  DearInventory::Environment.set(value)
16
33
  end
17
34
 
18
- sig { returns(T.nilable(String)) }
19
- attr_accessor :account_id
20
-
21
- sig { returns(T.nilable(String)) }
22
- attr_accessor :key
23
-
24
35
  sig { params(param: Symbol).returns(String) }
25
36
  def require(param)
26
37
  value = public_send(param)
@@ -0,0 +1,6 @@
1
+ # typed: strong
2
+ # frozen_string_literal: true
3
+
4
+ module DearInventory
5
+ class APILimitError < DearInventory::Error; end
6
+ end
@@ -0,0 +1,6 @@
1
+ # typed: strong
2
+ # frozen_string_literal: true
3
+
4
+ module DearInventory
5
+ class NoMorePagesError < Error; end
6
+ end
@@ -49,7 +49,7 @@ module DearInventory
49
49
  name = ["DearInventory"]
50
50
  name << @class_type
51
51
  name << @resource_class.name.split("::").last
52
- name << @endpoint
52
+ name << @endpoint.split("_").map(&:capitalize).join
53
53
  name.join("::")
54
54
  end
55
55
  end
@@ -6,18 +6,25 @@ module DearInventory
6
6
  extend T::Sig
7
7
 
8
8
  sig do
9
- params(parameters: DearInventory::Models::Request).
10
- returns(DearInventory::Response)
9
+ params(
10
+ parameters: DearInventory::Models::Request,
11
+ num_previous_records: Integer
12
+ ).returns(DearInventory::Response)
11
13
  end
12
- def self.call(parameters)
13
- new(parameters).call
14
+ def self.call(parameters, num_previous_records: 0)
15
+ new(parameters, num_previous_records: num_previous_records).call
14
16
  end
15
17
 
16
18
  sig do
17
- params(parameters: DearInventory::Models::Request).void
19
+ params(
20
+ parameters: DearInventory::Models::Request,
21
+ num_previous_records: Integer
22
+ ).void
18
23
  end
19
- def initialize(parameters)
20
- @parameters = parameters
24
+ def initialize(parameters, num_previous_records: 0)
25
+ @parameters = T.let(parameters, DearInventory::Models::Request)
26
+ @num_previous_records = T.let(num_previous_records, Integer)
27
+ @retries = T.let(0, Integer)
21
28
  end
22
29
 
23
30
  sig { returns(DearInventory::Response) }
@@ -28,8 +35,11 @@ module DearInventory
28
35
 
29
36
  DearInventory::Response.new(
30
37
  response: response,
31
- request: @parameters
38
+ request: @parameters,
39
+ num_previous_records: @num_previous_records
32
40
  )
41
+ rescue DearInventory::APILimitError, HTTP::ConnectionError => e
42
+ retry_request(e)
33
43
  end
34
44
 
35
45
  private
@@ -54,5 +64,32 @@ module DearInventory
54
64
  { json: params.to_h }
55
65
  end
56
66
  end
67
+
68
+ ERROR_MESSAGE_PREFIXES = T.let(
69
+ {
70
+ DearInventory::APILimitError => "The API request limit was reached",
71
+ HTTP::ConnectionError => "There was an error connecting to the API",
72
+ }.freeze,
73
+ T::Hash[T.class_of(StandardError), String]
74
+ )
75
+ MAX_RETRIES = T.let(4, Integer)
76
+ RETRY_DELAY = T.let(5, Integer)
77
+
78
+ sig { params(error: StandardError).returns(DearInventory::Response) }
79
+ def retry_request(error)
80
+ @retries += 1
81
+ raise if @retries >= MAX_RETRIES
82
+
83
+ message_prefix = ERROR_MESSAGE_PREFIXES[error.class]
84
+ retry_time = @retries * RETRY_DELAY
85
+
86
+ DearInventory.config.logger.warn(
87
+ "#{message_prefix} while fetching #{@parameters.uri}. " \
88
+ "The request will be tried again in #{retry_time} seconds"
89
+ )
90
+
91
+ sleep(retry_time)
92
+ call
93
+ end
57
94
  end
58
95
  end
@@ -0,0 +1,18 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ module Strings
5
+ class Urlize
6
+ extend T::Sig
7
+
8
+ sig { params(camel_cased_word: String).returns(String) }
9
+ def self.call(camel_cased_word)
10
+ return camel_cased_word unless /[A-Z_]/.match?(camel_cased_word)
11
+
12
+ camel_cased_word.
13
+ gsub(/([A-Z\d]+)([A-Z][a-z])/, '\1-\2').
14
+ gsub(/([a-z\d])([A-Z])/, '\1-\2').
15
+ downcase
16
+ end
17
+ end
18
+ end
@@ -20,13 +20,23 @@ module DearInventory
20
20
  ).void
21
21
  end
22
22
  def self.fields(fields)
23
- if ancestors[1].const_defined?(:FIELDS)
24
- fields = ancestors[1]::FIELDS.merge(fields)
23
+ ancestor = T.must(ancestors[1])
24
+ if ancestor.const_defined?(:FIELDS)
25
+ fields = ancestor.const_get(:FIELDS).merge(fields)
25
26
  end
26
27
  const_set(:FIELDS, fields.freeze)
27
28
 
29
+ define_readers
30
+ end
31
+
32
+ sig { void }
33
+ def self.define_readers
28
34
  enumerate_fields do |_, specifications|
29
35
  __send__(:attr_reader, specifications[:name])
36
+
37
+ if specifications[:type] == :ResultSet
38
+ alias_method :records, specifications[:name]
39
+ end
30
40
  end
31
41
  end
32
42
 
@@ -65,9 +75,6 @@ module DearInventory
65
75
 
66
76
  private
67
77
 
68
- # rubocop:disable Metrics/AbcSize
69
- # rubocop:disable Metrics/CyclomaticComplexity
70
- # rubocop:disable Metrics/MethodLength
71
78
  sig do
72
79
  params(
73
80
  response_name: Symbol,
@@ -83,23 +90,29 @@ module DearInventory
83
90
  T.nilable(T.class_of(DearInventory::Model))
84
91
  )
85
92
  value = values[response_name.to_s]
93
+ return if value == ""
86
94
 
87
- case specifications[:type]
95
+ format_value(value, specifications[:type], model)
96
+ end
97
+
98
+ # rubocop:disable Metrics/CyclomaticComplexity
99
+ # rubocop:disable Metrics/MethodLength
100
+ def format_value(value, type, model)
101
+ case type
102
+ when :Array, :ResultSet
103
+ initialize_array_values_in_models(value, T.must(model))
88
104
  when :BigDecimal
89
105
  value.to_d
90
106
  when :Date
91
107
  ::Date.parse(value) unless value.nil?
92
108
  when :DateTime
93
109
  ::DateTime.parse(value) unless value.nil?
94
- when :Array
95
- initialize_array_values_in_models(value, T.must(model))
96
110
  when :Hash
97
111
  T.must(model).new(value)
98
112
  else
99
113
  value
100
114
  end
101
115
  end
102
- # rubocop:enable Metrics/AbcSize
103
116
  # rubocop:enable Metrics/CyclomaticComplexity
104
117
  # rubocop:enable Metrics/MethodLength
105
118
 
@@ -0,0 +1,176 @@
1
+ # typed: strong
2
+ # frozen_string_literal: true
3
+
4
+ module DearInventory
5
+ module Models
6
+ class AdvancedPurchase < DearInventory::Model
7
+ extend T::Sig
8
+
9
+ fields(
10
+ ID: {
11
+ name: :id,
12
+ type: :Guid,
13
+ },
14
+ SupplierID: {
15
+ name: :supplier_id,
16
+ type: :Guid,
17
+ },
18
+ Supplier: {
19
+ name: :supplier,
20
+ type: :String,
21
+ },
22
+ Contact: {
23
+ name: :contact,
24
+ type: :String,
25
+ },
26
+ Phone: {
27
+ name: :phone,
28
+ type: :String,
29
+ },
30
+ InventoryAccount: {
31
+ name: :inventory_account,
32
+ type: :String,
33
+ },
34
+ BlindReceipt: {
35
+ name: :blind_receipt,
36
+ type: :Boolean,
37
+ },
38
+ Approach: {
39
+ name: :approach,
40
+ type: :String,
41
+ },
42
+ BillingAddress: {
43
+ name: :billing_address,
44
+ type: :Hash,
45
+ model: DearInventory::Models::Address,
46
+ },
47
+ ShippingAddress: {
48
+ name: :shipping_address,
49
+ type: :Hash,
50
+ model: DearInventory::Models::Address,
51
+ },
52
+ BaseCurrency: {
53
+ name: :base_currency,
54
+ type: :String,
55
+ },
56
+ SupplierCurrency: {
57
+ name: :supplier_currency,
58
+ type: :String,
59
+ },
60
+ TaxRule: {
61
+ name: :tax_rule,
62
+ type: :String,
63
+ },
64
+ TaxCalculation: {
65
+ name: :tax_calculation,
66
+ type: :String,
67
+ },
68
+ Terms: {
69
+ name: :terms,
70
+ type: :String,
71
+ },
72
+ RequiredBy: {
73
+ name: :required_by,
74
+ type: :Date,
75
+ },
76
+ Location: {
77
+ name: :location,
78
+ type: :String,
79
+ },
80
+ Note: {
81
+ name: :note,
82
+ type: :String,
83
+ },
84
+ OrderNumber: {
85
+ name: :order_number,
86
+ type: :String,
87
+ },
88
+ OrderDate: {
89
+ name: :order_date,
90
+ type: :Date,
91
+ },
92
+ CombinedReceivingStatus: {
93
+ name: :combined_receiving_status,
94
+ type: :String,
95
+ },
96
+ CombinedInvoiceStatus: {
97
+ name: :combined_invoice_status,
98
+ type: :String,
99
+ },
100
+ CombinedPaymentStatus: {
101
+ name: :combined_payment_status,
102
+ type: :String,
103
+ },
104
+ Type: {
105
+ name: :type,
106
+ type: :String,
107
+ },
108
+ IsServiceOnly: {
109
+ name: :is_service_only,
110
+ type: :Boolean,
111
+ },
112
+ Status: {
113
+ name: :status,
114
+ type: :String,
115
+ },
116
+ RelatedDropShipSaleTask: {
117
+ name: :related_drop_ship_sale_task,
118
+ type: :Guid,
119
+ },
120
+ CurrencyRate: {
121
+ name: :currency_rate,
122
+ type: :Decimal,
123
+ },
124
+ LastUpdatedDate: {
125
+ name: :last_updated_date,
126
+ type: :DateTime,
127
+ },
128
+ Order: {
129
+ name: :order,
130
+ type: :Hash,
131
+ model: DearInventory::Models::Purchases::Order,
132
+ },
133
+ StockReceived: {
134
+ name: :stock_received,
135
+ type: :Array,
136
+ model: DearInventory::Models::Purchases::Advanced::Stock,
137
+ },
138
+ PutAway: {
139
+ name: :put_away,
140
+ type: :Array,
141
+ model: DearInventory::Models::Purchases::Advanced::PutAway,
142
+ },
143
+ Invoice: {
144
+ name: :invoice,
145
+ type: :Array,
146
+ model: DearInventory::Models::Purchases::Advanced::Invoice,
147
+ },
148
+ CreditNote: {
149
+ name: :credit_note,
150
+ type: :Array,
151
+ model: DearInventory::Models::Purchases::Advanced::CreditNote,
152
+ },
153
+ ManualJournals: {
154
+ name: :manual_journals,
155
+ type: :Array,
156
+ model: DearInventory::Models::Purchases::Advanced::ManualJournal,
157
+ },
158
+ AdditionalAttributes: {
159
+ name: :additional_attributes,
160
+ type: :Hash,
161
+ model: DearInventory::Models::AdditionalAttributes,
162
+ },
163
+ Attachments: {
164
+ name: :attachments,
165
+ type: :Array,
166
+ model: DearInventory::Models::Attachment,
167
+ },
168
+ InventoryMovements: {
169
+ name: :inventory_movements,
170
+ type: :Array,
171
+ model: DearInventory::Models::Purchases::InventoryMovement,
172
+ }
173
+ )
174
+ end
175
+ end
176
+ end