dear_inventory 0.7.5 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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