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.
- checksums.yaml +4 -4
- data/.rubocop.yml +15 -0
- data/README.md +70 -18
- data/dear_inventory.gemspec +1 -1
- data/docs/resources/advanced_purchase.md +25 -0
- data/docs/resources/customer.md +31 -0
- data/docs/resources/product.md +37 -0
- data/docs/resources/purchase.md +89 -0
- data/docs/resources/sale.md +89 -0
- data/lib/dear_inventory.rb +20 -8
- data/lib/dear_inventory/config.rb +17 -6
- data/lib/dear_inventory/errors/api_limit.rb +6 -0
- data/lib/dear_inventory/errors/no_more_pages.rb +6 -0
- data/lib/dear_inventory/lib/endpoint_class.rb +1 -1
- data/lib/dear_inventory/lib/request.rb +45 -8
- data/lib/dear_inventory/lib/strings/urlize.rb +18 -0
- data/lib/dear_inventory/model.rb +22 -9
- data/lib/dear_inventory/models/advanced_purchase.rb +176 -0
- data/lib/dear_inventory/models/customer.rb +1 -1
- data/lib/dear_inventory/models/customers.rb +1 -1
- data/lib/dear_inventory/models/products.rb +1 -1
- data/lib/dear_inventory/models/{purchase_list.rb → purchases.rb} +12 -2
- data/lib/dear_inventory/models/purchases/additional_charge.rb +1 -1
- data/lib/dear_inventory/models/purchases/advanced/credit_note.rb +21 -0
- data/lib/dear_inventory/models/purchases/advanced/invoice.rb +68 -0
- data/lib/dear_inventory/models/purchases/advanced/manual_journal.rb +21 -0
- data/lib/dear_inventory/models/purchases/advanced/put_away.rb +34 -0
- data/lib/dear_inventory/models/purchases/advanced/put_away_line.rb +21 -0
- data/lib/dear_inventory/models/purchases/advanced/stock.rb +30 -0
- data/lib/dear_inventory/models/purchases/advanced/stock_line.rb +61 -0
- data/lib/dear_inventory/models/purchases/credit_note.rb +1 -1
- data/lib/dear_inventory/models/purchases/inventory_movement.rb +1 -1
- data/lib/dear_inventory/models/purchases/invoice.rb +1 -1
- data/lib/dear_inventory/models/purchases/invoice_additional_charge.rb +1 -1
- data/lib/dear_inventory/models/purchases/invoice_line.rb +1 -1
- data/lib/dear_inventory/models/purchases/line.rb +1 -1
- data/lib/dear_inventory/models/purchases/manual_journal.rb +1 -1
- data/lib/dear_inventory/models/purchases/manual_journal_line.rb +1 -1
- data/lib/dear_inventory/models/purchases/order.rb +1 -1
- data/lib/dear_inventory/models/purchases/payment_line.rb +51 -0
- data/lib/dear_inventory/models/purchases/stock.rb +1 -1
- data/lib/dear_inventory/models/purchases/stock_line.rb +1 -1
- data/lib/dear_inventory/models/purchases/unstock_line.rb +1 -1
- data/lib/dear_inventory/models/{purchase_lists.rb → purchases_results.rb} +4 -4
- data/lib/dear_inventory/models/{sale_list.rb → sales.rb} +7 -2
- data/lib/dear_inventory/models/sales/additional_charge.rb +1 -1
- data/lib/dear_inventory/models/sales/credit_note.rb +1 -1
- data/lib/dear_inventory/models/sales/fulfilment.rb +1 -1
- data/lib/dear_inventory/models/sales/fulfilments/pick_pack.rb +1 -1
- data/lib/dear_inventory/models/sales/fulfilments/pick_pack_line.rb +1 -1
- data/lib/dear_inventory/models/sales/fulfilments/ship.rb +1 -1
- data/lib/dear_inventory/models/sales/fulfilments/ship_line.rb +1 -1
- data/lib/dear_inventory/models/sales/invoice.rb +1 -1
- data/lib/dear_inventory/models/sales/invoice_additional_charge.rb +1 -1
- data/lib/dear_inventory/models/sales/invoice_line.rb +1 -1
- data/lib/dear_inventory/models/sales/line.rb +1 -1
- data/lib/dear_inventory/models/sales/manual_journal.rb +1 -1
- data/lib/dear_inventory/models/sales/manual_journal_line.rb +1 -1
- data/lib/dear_inventory/models/sales/order.rb +1 -1
- data/lib/dear_inventory/models/sales/payment_line.rb +1 -1
- data/lib/dear_inventory/models/sales/quote.rb +1 -1
- data/lib/dear_inventory/models/{sale_lists.rb → sales_results.rb} +4 -4
- data/lib/dear_inventory/parameters/advanced_purchase/show.rb +25 -0
- data/lib/dear_inventory/parameters/purchase/index.rb +65 -6
- data/lib/dear_inventory/parameters/purchase/show.rb +25 -0
- data/lib/dear_inventory/parameters/sale/index.rb +95 -11
- data/lib/dear_inventory/parameters/sale/show.rb +35 -0
- data/lib/dear_inventory/resource.rb +8 -11
- data/lib/dear_inventory/resources/{purchase_list.rb → advanced_purchase.rb} +8 -5
- data/lib/dear_inventory/resources/customer.rb +2 -0
- data/lib/dear_inventory/resources/product.rb +2 -0
- data/lib/dear_inventory/resources/purchase.rb +38 -2
- data/lib/dear_inventory/resources/sale.rb +38 -2
- data/lib/dear_inventory/response.rb +118 -17
- data/lib/dear_inventory/version.rb +1 -1
- data/sorbet/rbi/hidden-definitions/hidden.rbi +0 -4
- metadata +29 -12
- data/lib/dear_inventory/parameters/purchase_list/index.rb +0 -84
- data/lib/dear_inventory/parameters/sale_list/index.rb +0 -119
- data/lib/dear_inventory/resources/sale_list.rb +0 -24
@@ -0,0 +1,35 @@
|
|
1
|
+
# typed: strict
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module DearInventory
|
5
|
+
class Parameters
|
6
|
+
module Sale
|
7
|
+
class Show < DearInventory::Parameters
|
8
|
+
extend T::Sig
|
9
|
+
|
10
|
+
fields(
|
11
|
+
id: {
|
12
|
+
property: :ID,
|
13
|
+
type: :String,
|
14
|
+
required: true,
|
15
|
+
},
|
16
|
+
combine_additional_charges: {
|
17
|
+
property: :CombineAdditionalCharges,
|
18
|
+
type: :Boolean,
|
19
|
+
required: false,
|
20
|
+
},
|
21
|
+
hide_inventory_movements: {
|
22
|
+
property: :HideInventoryMovements,
|
23
|
+
type: :Boolean,
|
24
|
+
required: false,
|
25
|
+
},
|
26
|
+
include_transactions: {
|
27
|
+
property: :IncludeTransactions,
|
28
|
+
type: :Boolean,
|
29
|
+
required: false,
|
30
|
+
}
|
31
|
+
)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -15,28 +15,25 @@ module DearInventory
|
|
15
15
|
).returns(DearInventory::Response)
|
16
16
|
end
|
17
17
|
def request(action, model:, endpoint: nil, params: {})
|
18
|
-
uri = resource_uri(endpoint)
|
19
|
-
params = DearInventory::Parameters.convert(self.class, endpoint, params)
|
20
|
-
|
21
18
|
request = DearInventory::Models::Request.new(
|
22
19
|
action: action,
|
23
20
|
model: model,
|
24
|
-
params: params,
|
25
|
-
uri:
|
21
|
+
params: DearInventory::Parameters.convert(self.class, endpoint, params),
|
22
|
+
uri: resource_uri(endpoint)
|
26
23
|
)
|
27
24
|
DearInventory::Request.(request)
|
28
25
|
end
|
29
26
|
|
30
27
|
private
|
31
28
|
|
32
|
-
URI_BASE = "https://inventory.dearsystems.com/ExternalApi/v2"
|
29
|
+
URI_BASE = T.let("https://inventory.dearsystems.com/ExternalApi/v2", String)
|
33
30
|
|
34
|
-
sig { params(
|
35
|
-
def resource_uri(
|
31
|
+
sig { params(_endpoint: T.nilable(String)).returns(String) }
|
32
|
+
def resource_uri(_endpoint)
|
36
33
|
resource = T.must(self.class.name).split("::").last
|
37
|
-
|
38
|
-
|
39
|
-
|
34
|
+
camel_case = Strings::Urlize.(T.must(resource))
|
35
|
+
|
36
|
+
"#{URI_BASE}/#{camel_case}"
|
40
37
|
end
|
41
38
|
end
|
42
39
|
end
|
@@ -2,21 +2,24 @@
|
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
module DearInventory
|
5
|
-
class
|
5
|
+
class AdvancedPurchase < Resource
|
6
6
|
class << self
|
7
7
|
extend T::Sig
|
8
8
|
|
9
|
-
# Purchase
|
9
|
+
# Advanced Purchase
|
10
10
|
#
|
11
11
|
# @param params [Hash] URL query string parameters that conform to
|
12
|
-
# DearInventory::Parameters::
|
12
|
+
# DearInventory::Parameters::Purchase::ShowAdvanced
|
13
13
|
sig do
|
14
14
|
params(params: T::Hash[Symbol, T.untyped]).
|
15
15
|
returns(DearInventory::Response)
|
16
16
|
end
|
17
|
-
def
|
17
|
+
def show(params = {})
|
18
18
|
new.request(
|
19
|
-
:get,
|
19
|
+
:get,
|
20
|
+
endpoint: "show",
|
21
|
+
model: DearInventory::Models::AdvancedPurchase,
|
22
|
+
params: params
|
20
23
|
)
|
21
24
|
end
|
22
25
|
end
|
@@ -6,7 +6,7 @@ module DearInventory
|
|
6
6
|
class << self
|
7
7
|
extend T::Sig
|
8
8
|
|
9
|
-
#
|
9
|
+
# Purchases
|
10
10
|
#
|
11
11
|
# @param params [Hash] URL query string parameters that conform to
|
12
12
|
# DearInventory::Parameters::Purchase::Index
|
@@ -16,9 +16,45 @@ module DearInventory
|
|
16
16
|
end
|
17
17
|
def index(params = {})
|
18
18
|
new.request(
|
19
|
-
:get,
|
19
|
+
:get,
|
20
|
+
endpoint: "index",
|
21
|
+
model: DearInventory::Models::PurchasesResults,
|
22
|
+
params: params
|
23
|
+
)
|
24
|
+
end
|
25
|
+
|
26
|
+
alias call index
|
27
|
+
|
28
|
+
# Purchase
|
29
|
+
#
|
30
|
+
# @param params [Hash] URL query string parameters that conform to
|
31
|
+
# DearInventory::Parameters::Purchase::Show
|
32
|
+
sig do
|
33
|
+
params(params: T::Hash[Symbol, T.untyped]).
|
34
|
+
returns(DearInventory::Response)
|
35
|
+
end
|
36
|
+
def show(params = {})
|
37
|
+
new.request(
|
38
|
+
:get,
|
39
|
+
endpoint: "show",
|
40
|
+
model: DearInventory::Models::Purchase,
|
41
|
+
params: params
|
20
42
|
)
|
21
43
|
end
|
22
44
|
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
sig { params(endpoint: T.nilable(String)).returns(String) }
|
49
|
+
def resource_uri(endpoint)
|
50
|
+
suffix =
|
51
|
+
case endpoint
|
52
|
+
when "index"
|
53
|
+
"/purchaselist"
|
54
|
+
when "show"
|
55
|
+
"/purchase"
|
56
|
+
end
|
57
|
+
self.class.const_get(:URI_BASE) + suffix
|
58
|
+
end
|
23
59
|
end
|
24
60
|
end
|
@@ -6,7 +6,7 @@ module DearInventory
|
|
6
6
|
class << self
|
7
7
|
extend T::Sig
|
8
8
|
|
9
|
-
#
|
9
|
+
# Sales
|
10
10
|
#
|
11
11
|
# @param params [Hash] URL query string parameters that conform to
|
12
12
|
# DearInventory::Parameters::Sale::Index
|
@@ -15,7 +15,43 @@ module DearInventory
|
|
15
15
|
returns(DearInventory::Response)
|
16
16
|
end
|
17
17
|
def index(params = {})
|
18
|
-
new.request(
|
18
|
+
new.request(
|
19
|
+
:get,
|
20
|
+
endpoint: "index",
|
21
|
+
model: DearInventory::Models::SalesResults,
|
22
|
+
params: params
|
23
|
+
)
|
24
|
+
end
|
25
|
+
|
26
|
+
alias call index
|
27
|
+
|
28
|
+
# Sale
|
29
|
+
#
|
30
|
+
# @param params [Hash] URL query string parameters that conform to
|
31
|
+
# DearInventory::Parameters::Sale::Show
|
32
|
+
sig do
|
33
|
+
params(params: T::Hash[Symbol, T.untyped]).
|
34
|
+
returns(DearInventory::Response)
|
35
|
+
end
|
36
|
+
def show(params = {})
|
37
|
+
new.request(
|
38
|
+
:get,
|
39
|
+
endpoint: "show",
|
40
|
+
model: DearInventory::Models::Sale,
|
41
|
+
params: params
|
42
|
+
)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
sig { params(endpoint: T.nilable(String)).returns(String) }
|
49
|
+
def resource_uri(endpoint)
|
50
|
+
case endpoint
|
51
|
+
when "index"
|
52
|
+
self.class.const_get(:URI_BASE) + "/salelist"
|
53
|
+
when "show"
|
54
|
+
self.class.const_get(:URI_BASE) + "/sale"
|
19
55
|
end
|
20
56
|
end
|
21
57
|
end
|
@@ -11,28 +11,54 @@ module DearInventory
|
|
11
11
|
sig { returns(HTTP::Response) }
|
12
12
|
attr_reader :response
|
13
13
|
|
14
|
+
# rubocop:disable Metrics/AbcSize
|
15
|
+
# rubocop:disable Metrics/MethodLength
|
14
16
|
sig do
|
15
17
|
params(
|
16
18
|
request: DearInventory::Models::Request,
|
17
|
-
response: HTTP::Response
|
19
|
+
response: HTTP::Response,
|
20
|
+
num_previous_records: Integer
|
18
21
|
).void
|
19
22
|
end
|
20
|
-
def initialize(request:, response:)
|
23
|
+
def initialize(request:, response:, num_previous_records: 0)
|
21
24
|
@request = T.let(request, DearInventory::Models::Request)
|
22
25
|
@response = T.let(response, HTTP::Response)
|
26
|
+
@num_previous_records = T.let(num_previous_records, Integer)
|
27
|
+
|
28
|
+
@fields = T.let(nil, T.nilable(T::Array[Symbol]))
|
23
29
|
@http_status = T.let(nil, T.nilable(Integer))
|
24
|
-
@
|
30
|
+
@load_full_record = T.let(nil, T.nilable(T::Boolean))
|
31
|
+
@num_records_paged = T.let(nil, T.nilable(Integer))
|
25
32
|
@uri = T.let(nil, T.nilable(String))
|
26
33
|
|
27
|
-
assign_values
|
28
34
|
raise_error unless success?
|
35
|
+
|
36
|
+
body_copy = T.cast(body, T.nilable(T::Hash[String, T.untyped]))
|
37
|
+
@model = T.let(@request.model.new(body_copy), DearInventory::Model)
|
38
|
+
assign_values
|
39
|
+
end
|
40
|
+
# rubocop:enable Metrics/AbcSize
|
41
|
+
# rubocop:enable Metrics/MethodLength
|
42
|
+
|
43
|
+
sig { returns(T::Array[Symbol]) }
|
44
|
+
def fields
|
45
|
+
@fields ||= begin
|
46
|
+
values = @request.model.const_get(:FIELDS).values.map do |field|
|
47
|
+
field[:name]
|
48
|
+
end
|
49
|
+
values.unshift(:records) if @model.respond_to?(:records)
|
50
|
+
values
|
51
|
+
end
|
29
52
|
end
|
30
53
|
|
31
54
|
sig { returns(T.nilable(String)) }
|
32
55
|
def error
|
33
|
-
|
56
|
+
if body.respond_to?(:fetch)
|
57
|
+
body_copy = T.cast(body, T::Hash[String, T.untyped])
|
58
|
+
return body_copy.fetch("Exception", nil)
|
59
|
+
end
|
34
60
|
|
35
|
-
body
|
61
|
+
T.cast(body, T.nilable(String))
|
36
62
|
end
|
37
63
|
|
38
64
|
sig { returns(T::Hash[Symbol, String]) }
|
@@ -45,15 +71,54 @@ module DearInventory
|
|
45
71
|
@http_status ||= @response.status.code
|
46
72
|
end
|
47
73
|
|
74
|
+
sig { returns(T::Boolean) }
|
75
|
+
def paginated?
|
76
|
+
@model.respond_to?(:page)
|
77
|
+
end
|
78
|
+
|
79
|
+
sig { params(block: T.proc.params(arg0: DearInventory::Model).void).void }
|
80
|
+
def each(&block)
|
81
|
+
raise_not_paginated unless paginated?
|
82
|
+
|
83
|
+
response = self
|
84
|
+
loop do
|
85
|
+
iterate_over_records(response, block)
|
86
|
+
break unless response.next_page?
|
87
|
+
|
88
|
+
response = response.next_page
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
48
92
|
sig { returns(DearInventory::Response) }
|
49
93
|
def next_page
|
50
|
-
unless
|
51
|
-
|
52
|
-
end
|
94
|
+
raise_not_paginated unless paginated?
|
95
|
+
raise DearInventory::NoMorePagesError unless next_page?
|
53
96
|
|
54
97
|
request = @request.dup
|
55
98
|
T.unsafe(request.params).page = T.unsafe(@model).page + 1
|
56
|
-
|
99
|
+
|
100
|
+
DearInventory::Request.(request, num_previous_records: num_records_paged)
|
101
|
+
end
|
102
|
+
|
103
|
+
sig { returns(T::Boolean) }
|
104
|
+
def next_page?
|
105
|
+
raise_not_paginated unless paginated?
|
106
|
+
|
107
|
+
num_records_paged < T.unsafe(self).total
|
108
|
+
end
|
109
|
+
|
110
|
+
sig { returns(Integer) }
|
111
|
+
def num_records_paged
|
112
|
+
@num_records_paged ||= begin
|
113
|
+
raise_not_paginated unless paginated?
|
114
|
+
|
115
|
+
@num_previous_records + T.unsafe(self).records.count
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
sig { void }
|
120
|
+
def raise_not_paginated
|
121
|
+
raise DearInventory::NotPaginatedError.new(uri: uri)
|
57
122
|
end
|
58
123
|
|
59
124
|
sig { returns(T::Boolean) }
|
@@ -68,31 +133,67 @@ module DearInventory
|
|
68
133
|
|
69
134
|
protected
|
70
135
|
|
71
|
-
sig { returns(T.untyped) }
|
136
|
+
sig { returns(T.any(T::Hash[String, T.untyped], String)) }
|
72
137
|
def body
|
73
|
-
|
138
|
+
string_body = @response.body.to_s
|
139
|
+
JSON.parse(string_body)
|
140
|
+
rescue JSON::ParserError
|
141
|
+
string_body
|
74
142
|
end
|
75
143
|
|
76
144
|
private
|
77
145
|
|
78
146
|
sig { void }
|
79
147
|
def assign_values
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
148
|
+
fields.each { |field| define_alias_method(field) }
|
149
|
+
end
|
150
|
+
|
151
|
+
sig { params(method_name: Symbol).void }
|
152
|
+
def define_alias_method(method_name)
|
153
|
+
define_singleton_method(method_name) do
|
154
|
+
@model.public_send(method_name)
|
85
155
|
end
|
86
156
|
end
|
87
157
|
|
158
|
+
API_LIMIT_ERROR = T.let(
|
159
|
+
"You have reached 60 calls per 60 seconds API limit.", String
|
160
|
+
)
|
161
|
+
|
162
|
+
# rubocop:disable Metrics/AbcSize
|
88
163
|
sig { returns(DearInventory::Error) }
|
89
164
|
def raise_error
|
90
165
|
if http_status == 400
|
91
166
|
raise T.unsafe(DearInventory::BadRequestError).new(error, self)
|
92
167
|
end
|
93
168
|
|
169
|
+
if http_status == 503 && error == API_LIMIT_ERROR
|
170
|
+
raise T.unsafe(DearInventory::APILimitError)
|
171
|
+
end
|
172
|
+
|
94
173
|
raise T.unsafe(DearInventory::Error).
|
95
174
|
new("Unknown error (#{http_status}): #{error}")
|
96
175
|
end
|
176
|
+
# rubocop:enable Metrics/AbcSize
|
177
|
+
|
178
|
+
sig do
|
179
|
+
params(
|
180
|
+
response: DearInventory::Response,
|
181
|
+
block: T.proc.params(arg0: DearInventory::Model).void
|
182
|
+
).void
|
183
|
+
end
|
184
|
+
def iterate_over_records(response, block)
|
185
|
+
return if T.unsafe(response).records.nil?
|
186
|
+
|
187
|
+
T.unsafe(response).records.each do |record|
|
188
|
+
record = record.full_record if load_full_record?
|
189
|
+
block.call(record)
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
sig { returns(T::Boolean) }
|
194
|
+
def load_full_record?
|
195
|
+
@load_full_record ||=
|
196
|
+
T.unsafe(self).records.first.respond_to?(:full_record)
|
197
|
+
end
|
97
198
|
end
|
98
199
|
end
|
@@ -14376,10 +14376,6 @@ module Readline
|
|
14376
14376
|
def self.vi_editing_mode?(); end
|
14377
14377
|
end
|
14378
14378
|
|
14379
|
-
class Regexp
|
14380
|
-
def match?(*_); end
|
14381
|
-
end
|
14382
|
-
|
14383
14379
|
module Reline
|
14384
14380
|
def eof?(*args, &block); end
|
14385
14381
|
FILENAME_COMPLETION_PROC = ::T.let(nil, ::T.untyped)
|