freight_kit 0.1.17 → 0.1.18
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/Gemfile.lock +43 -47
- data/VERSION +1 -1
- data/lib/freight_kit/carrier.rb +55 -21
- data/lib/freight_kit/tariff/overlength_rule.rb +33 -0
- data/lib/freight_kit/tariff.rb +4 -14
- metadata +7 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a388e3b699bfd3954ee2505e18db4d202af11dfba48c1c64643c0331f52a4a63
|
|
4
|
+
data.tar.gz: db547dada7eb6f6f65980ea8004b18210cae4e90e27022d194a513c3184c56b0
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 76be478d726587dda86efd0aa86cf758daee9537f16f65dafd3227ecc128bf3915dbc1bc5eeb403b21099247629d43f5962fc35b2ced934a7f98837ac8500941
|
|
7
|
+
data.tar.gz: 689dbeed18ddd0929e360a9ec232cea1916dcb47575e2567092ef141b9ff67cc069d1ba28c6969692cb293e7a2932bf75f1b364feb188f9b4d1aa5de9f2ade98
|
data/Gemfile.lock
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
freight_kit (0.1.
|
|
4
|
+
freight_kit (0.1.17)
|
|
5
5
|
active_utils (>= 3.3.1, < 3.7.0)
|
|
6
6
|
activemodel (>= 7.1, < 8.1.4)
|
|
7
7
|
activesupport (>= 7.1, < 8.1.4)
|
|
@@ -39,21 +39,20 @@ GEM
|
|
|
39
39
|
mutex_m
|
|
40
40
|
securerandom (>= 0.3)
|
|
41
41
|
tzinfo (~> 2.0)
|
|
42
|
-
addressable (2.
|
|
43
|
-
public_suffix (>= 2.0.2, <
|
|
44
|
-
akami (1.3.
|
|
45
|
-
base64
|
|
42
|
+
addressable (2.8.5)
|
|
43
|
+
public_suffix (>= 2.0.2, < 6.0)
|
|
44
|
+
akami (1.3.1)
|
|
46
45
|
gyoku (>= 0.4.0)
|
|
47
46
|
nokogiri
|
|
48
|
-
ast (2.4.
|
|
47
|
+
ast (2.4.3)
|
|
49
48
|
base64 (0.3.0)
|
|
50
49
|
benchmark (0.5.0)
|
|
51
|
-
bigdecimal (
|
|
52
|
-
builder (3.
|
|
50
|
+
bigdecimal (4.1.2)
|
|
51
|
+
builder (3.2.4)
|
|
53
52
|
business_time (0.13.0)
|
|
54
53
|
activesupport (>= 3.2.0)
|
|
55
54
|
tzinfo
|
|
56
|
-
concurrent-ruby (1.
|
|
55
|
+
concurrent-ruby (1.2.2)
|
|
57
56
|
connection_pool (3.0.2)
|
|
58
57
|
csv (3.3.5)
|
|
59
58
|
date (3.5.1)
|
|
@@ -61,7 +60,7 @@ GEM
|
|
|
61
60
|
drb (2.2.3)
|
|
62
61
|
faker (3.8.0)
|
|
63
62
|
i18n (>= 1.8.11, < 2)
|
|
64
|
-
faraday (2.14.
|
|
63
|
+
faraday (2.14.3)
|
|
65
64
|
faraday-net_http (>= 2.0, < 3.5)
|
|
66
65
|
json
|
|
67
66
|
logger
|
|
@@ -78,12 +77,12 @@ GEM
|
|
|
78
77
|
mutex_m
|
|
79
78
|
nkf
|
|
80
79
|
rack (>= 2.0, < 4)
|
|
81
|
-
i18n (1.14.
|
|
80
|
+
i18n (1.14.1)
|
|
82
81
|
concurrent-ruby (~> 1.0)
|
|
83
|
-
json (2.
|
|
84
|
-
language_server-protocol (3.17.0.
|
|
82
|
+
json (2.21.1)
|
|
83
|
+
language_server-protocol (3.17.0.6)
|
|
85
84
|
logger (1.7.0)
|
|
86
|
-
mail (2.9.
|
|
85
|
+
mail (2.9.1)
|
|
87
86
|
logger
|
|
88
87
|
mini_mime (>= 0.1.1)
|
|
89
88
|
net-imap
|
|
@@ -95,15 +94,13 @@ GEM
|
|
|
95
94
|
nokogiri (~> 1)
|
|
96
95
|
rake
|
|
97
96
|
mini_mime (1.1.5)
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
multi_xml (0.7.1)
|
|
102
|
-
bigdecimal (~> 3.1)
|
|
97
|
+
mini_portile2 (2.8.4)
|
|
98
|
+
minitest (5.15.0)
|
|
99
|
+
multi_xml (0.6.0)
|
|
103
100
|
mutex_m (0.3.0)
|
|
104
101
|
net-http (0.9.1)
|
|
105
102
|
uri (>= 0.11.1)
|
|
106
|
-
net-imap (0.6.4)
|
|
103
|
+
net-imap (0.6.4.1)
|
|
107
104
|
date
|
|
108
105
|
net-protocol
|
|
109
106
|
net-pop (0.1.2)
|
|
@@ -112,14 +109,14 @@ GEM
|
|
|
112
109
|
timeout
|
|
113
110
|
net-smtp (0.5.1)
|
|
114
111
|
net-protocol
|
|
115
|
-
nkf (0.
|
|
116
|
-
nokogiri (1.
|
|
112
|
+
nkf (0.3.0)
|
|
113
|
+
nokogiri (1.13.10)
|
|
114
|
+
mini_portile2 (~> 2.8.0)
|
|
117
115
|
racc (~> 1.4)
|
|
118
|
-
nori (2.
|
|
119
|
-
bigdecimal
|
|
116
|
+
nori (2.6.0)
|
|
120
117
|
observer (0.1.2)
|
|
121
|
-
parallel (1.
|
|
122
|
-
parser (3.3.
|
|
118
|
+
parallel (1.28.0)
|
|
119
|
+
parser (3.3.12.0)
|
|
123
120
|
ast (~> 2.4.1)
|
|
124
121
|
racc
|
|
125
122
|
pkg-config (1.6.5)
|
|
@@ -127,15 +124,15 @@ GEM
|
|
|
127
124
|
activesupport (>= 7.1, < 8.1.4)
|
|
128
125
|
csv (~> 3.3)
|
|
129
126
|
prism (1.9.0)
|
|
130
|
-
public_suffix (
|
|
131
|
-
racc (1.
|
|
132
|
-
rack (3.
|
|
127
|
+
public_suffix (5.0.3)
|
|
128
|
+
racc (1.7.1)
|
|
129
|
+
rack (3.0.8)
|
|
133
130
|
rainbow (3.1.1)
|
|
134
131
|
rake (13.4.2)
|
|
135
132
|
redcarpet (3.6.0)
|
|
136
|
-
regexp_parser (2.
|
|
137
|
-
rexml (3.
|
|
138
|
-
rmagick (7.0.
|
|
133
|
+
regexp_parser (2.8.1)
|
|
134
|
+
rexml (3.2.6)
|
|
135
|
+
rmagick (7.0.5)
|
|
139
136
|
observer (~> 0.1)
|
|
140
137
|
pkg-config (~> 1.4)
|
|
141
138
|
rspec (3.12.0)
|
|
@@ -162,10 +159,11 @@ GEM
|
|
|
162
159
|
rubocop-ast (>= 1.31.1, < 2.0)
|
|
163
160
|
ruby-progressbar (~> 1.7)
|
|
164
161
|
unicode-display_width (>= 2.4.0, < 3.0)
|
|
165
|
-
rubocop-ast (1.
|
|
166
|
-
parser (>= 3.3.
|
|
167
|
-
|
|
168
|
-
|
|
162
|
+
rubocop-ast (1.50.0)
|
|
163
|
+
parser (>= 3.3.7.2)
|
|
164
|
+
prism (~> 1.7)
|
|
165
|
+
rubocop-graphql (1.5.4)
|
|
166
|
+
rubocop (>= 1.50, < 2)
|
|
169
167
|
rubocop-next (1.0.7)
|
|
170
168
|
rubocop (>= 1.56, < 1.65)
|
|
171
169
|
rubocop-graphql (>= 1.4, < 1.6)
|
|
@@ -173,14 +171,14 @@ GEM
|
|
|
173
171
|
rubocop-rake (~> 0.6.0)
|
|
174
172
|
rubocop-rspec (>= 2.23.2, < 3.1.0)
|
|
175
173
|
rubocop-shopify (>= 2.14, < 2.16)
|
|
176
|
-
rubocop-rails (2.25.
|
|
174
|
+
rubocop-rails (2.25.1)
|
|
177
175
|
activesupport (>= 4.2.0)
|
|
178
176
|
rack (>= 1.1)
|
|
179
177
|
rubocop (>= 1.33.0, < 2.0)
|
|
180
178
|
rubocop-ast (>= 1.31.1, < 2.0)
|
|
181
179
|
rubocop-rake (0.6.0)
|
|
182
180
|
rubocop (~> 1.0)
|
|
183
|
-
rubocop-rspec (3.0.
|
|
181
|
+
rubocop-rspec (3.0.5)
|
|
184
182
|
rubocop (~> 1.61)
|
|
185
183
|
rubocop-shopify (2.15.1)
|
|
186
184
|
rubocop (~> 1.51)
|
|
@@ -196,32 +194,30 @@ GEM
|
|
|
196
194
|
nori (~> 2.4)
|
|
197
195
|
wasabi (>= 5.1.0, < 6)
|
|
198
196
|
securerandom (0.4.1)
|
|
199
|
-
selenium-webdriver (4.
|
|
197
|
+
selenium-webdriver (4.12.0)
|
|
200
198
|
rexml (~> 3.2, >= 3.2.5)
|
|
201
199
|
rubyzip (>= 1.2.2, < 3.0)
|
|
202
200
|
websocket (~> 1.0)
|
|
203
201
|
timeout (0.6.1)
|
|
204
202
|
tzinfo (2.0.6)
|
|
205
203
|
concurrent-ruby (~> 1.0)
|
|
206
|
-
tzinfo-data (1.2023.
|
|
204
|
+
tzinfo-data (1.2023.4)
|
|
207
205
|
tzinfo (>= 1.0.0)
|
|
208
|
-
unicode-display_width (2.
|
|
206
|
+
unicode-display_width (2.6.0)
|
|
209
207
|
uri (1.1.1)
|
|
210
208
|
wasabi (5.1.0)
|
|
211
209
|
addressable
|
|
212
210
|
faraday (>= 1.9, < 3)
|
|
213
211
|
nokogiri (>= 1.13.9)
|
|
214
|
-
watir (7.
|
|
212
|
+
watir (7.1.0)
|
|
215
213
|
regexp_parser (>= 1.2, < 3)
|
|
216
|
-
selenium-webdriver (~> 4.
|
|
217
|
-
websocket (1.2.
|
|
214
|
+
selenium-webdriver (~> 4.0)
|
|
215
|
+
websocket (1.2.9)
|
|
218
216
|
yard (0.9.34)
|
|
219
|
-
zeitwerk (2.
|
|
217
|
+
zeitwerk (2.8.2)
|
|
220
218
|
|
|
221
219
|
PLATFORMS
|
|
222
220
|
arm64-darwin-22
|
|
223
|
-
arm64-darwin-23
|
|
224
|
-
arm64-darwin-24
|
|
225
221
|
arm64-darwin-25
|
|
226
222
|
|
|
227
223
|
DEPENDENCIES
|
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.1.
|
|
1
|
+
0.1.18
|
data/lib/freight_kit/carrier.rb
CHANGED
|
@@ -353,21 +353,44 @@ module FreightKit
|
|
|
353
353
|
raise NotImplementedError, "#valid_pro is not supported by #{self.class.name}."
|
|
354
354
|
end
|
|
355
355
|
|
|
356
|
-
|
|
357
|
-
|
|
356
|
+
# The package's longest horizontal dimension (length or width), as a
|
|
357
|
+
# Measured::Length so comparisons stay unit-agnostic.
|
|
358
|
+
#
|
|
359
|
+
# @param package [FreightKit::Package]
|
|
360
|
+
# @return [Measured::Length]
|
|
361
|
+
def longest_dimension(package)
|
|
362
|
+
[
|
|
363
|
+
Measured::Length.new(package.length(:inches), :inches),
|
|
364
|
+
Measured::Length.new(package.width(:inches), :inches),
|
|
365
|
+
].max
|
|
366
|
+
end
|
|
358
367
|
|
|
359
|
-
|
|
368
|
+
# @param package [FreightKit::Package]
|
|
369
|
+
# @return [Boolean] whether the package is long enough to incur overlength fees.
|
|
370
|
+
def overlength?(package) = longest_dimension(package) >= self.class.minimum_length_for_overlength_fees
|
|
360
371
|
|
|
361
|
-
|
|
362
|
-
|
|
372
|
+
def overlength_fee(tariff, package)
|
|
373
|
+
overlength_rule = overlength_rule_for(tariff, package)
|
|
374
|
+
return 0 if overlength_rule.nil?
|
|
363
375
|
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
376
|
+
package.quantity * overlength_rule.fee_cents
|
|
377
|
+
end
|
|
378
|
+
|
|
379
|
+
# Returns the overlength rule from +tariff+ that applies to +package+, or
|
|
380
|
+
# +nil+ when the package is not overlength, or no configured rule covers it.
|
|
381
|
+
#
|
|
382
|
+
# This is the single source of truth for "does a rule cover this package?"
|
|
383
|
+
# shared by {#overlength_fee} and {#validate_packages} so the two can never
|
|
384
|
+
# disagree (e.g. a package quoting $0 overlength while also being treated as
|
|
385
|
+
# serviceable).
|
|
386
|
+
#
|
|
387
|
+
# @param tariff [FreightKit::Tariff, nil]
|
|
388
|
+
# @param package [FreightKit::Package]
|
|
389
|
+
# @return [FreightKit::Tariff::OverlengthRule, nil]
|
|
390
|
+
def overlength_rule_for(tariff, package)
|
|
391
|
+
return unless tariff.is_a?(FreightKit::Tariff) && overlength?(package)
|
|
369
392
|
|
|
370
|
-
|
|
393
|
+
tariff.overlength_rules.find { |overlength_rule| overlength_rule.cover?(longest_dimension(package)) }
|
|
371
394
|
end
|
|
372
395
|
|
|
373
396
|
# Determine whether the carrier will accept the packages based on credentials and/or tariff.
|
|
@@ -389,19 +412,30 @@ module FreightKit
|
|
|
389
412
|
message << "items must weigh #{max_weight_pounds.to_f} lbs or less"
|
|
390
413
|
end
|
|
391
414
|
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
415
|
+
# Carriers that don't quote overlength fees via their API rely on the
|
|
416
|
+
# tariff to price them. Fail closed rather than silently under-quoting: a
|
|
417
|
+
# missing, empty, or non-covering tariff for an overlength package must
|
|
418
|
+
# make the carrier unserviceable. We key off rule *coverage* (via
|
|
419
|
+
# #overlength_rule_for) rather than the tariff object's mere presence,
|
|
420
|
+
# because a present-but-empty FreightKit::Tariff is not `blank?` and would
|
|
421
|
+
# otherwise slip past this check.
|
|
422
|
+
if self.class.overlength_fees_require_tariff?
|
|
423
|
+
missing_dimensions = packages.any? do |package|
|
|
424
|
+
[
|
|
425
|
+
package.height(:inches),
|
|
426
|
+
package.length(:inches),
|
|
427
|
+
package.width(:inches),
|
|
428
|
+
].any?(&:zero?)
|
|
429
|
+
end
|
|
430
|
+
|
|
431
|
+
uncovered_overlength = packages.any? do |package|
|
|
432
|
+
overlength?(package) && overlength_rule_for(tariff, package).nil?
|
|
433
|
+
end
|
|
396
434
|
|
|
397
435
|
if missing_dimensions
|
|
398
436
|
message << 'item dimensions are required'
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
if packages.map { |p| [p.width(:inches), p.length(:inches)].max }.max >= max_length_inches
|
|
403
|
-
message << 'tariff must be defined to calculate overlength fees'
|
|
404
|
-
end
|
|
437
|
+
elsif uncovered_overlength
|
|
438
|
+
message << 'tariff must be defined to calculate overlength fees'
|
|
405
439
|
end
|
|
406
440
|
end
|
|
407
441
|
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module FreightKit
|
|
4
|
+
class Tariff
|
|
5
|
+
class OverlengthRule
|
|
6
|
+
attr_reader :fee_cents, :max_length, :min_length
|
|
7
|
+
|
|
8
|
+
def initialize(fee_cents:, max_length:, min_length:)
|
|
9
|
+
raise ArgumentError, 'overlength_rule[:fee_cents] must be an Integer' unless fee_cents.is_a?(Integer)
|
|
10
|
+
|
|
11
|
+
if max_length && !max_length.is_a?(Measured::Length)
|
|
12
|
+
raise ArgumentError, 'overlength_rule[:max_length] must be one of Measured::Length, NilClass'
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
unless min_length.is_a?(Measured::Length)
|
|
16
|
+
raise ArgumentError, 'overlength_rule[:min_length] must be a Measured::Length'
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
@fee_cents = fee_cents
|
|
20
|
+
@max_length = max_length
|
|
21
|
+
@min_length = min_length
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# @param length [Measured::Length] a package's longest dimension.
|
|
25
|
+
# @return [Boolean] whether this rule's length band covers the dimension.
|
|
26
|
+
def cover?(length)
|
|
27
|
+
return false if length < min_length
|
|
28
|
+
|
|
29
|
+
max_length.nil? || length <= max_length
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
data/lib/freight_kit/tariff.rb
CHANGED
|
@@ -8,22 +8,12 @@ module FreightKit
|
|
|
8
8
|
options.symbolize_keys!
|
|
9
9
|
@options = options
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
raise ArgumentError, 'overlength_rules must be an Array' unless
|
|
11
|
+
overlength_rules = options[:overlength_rules].presence || []
|
|
12
|
+
raise ArgumentError, 'overlength_rules must be an Array' unless overlength_rules.is_a?(Array)
|
|
13
13
|
|
|
14
|
-
@
|
|
15
|
-
|
|
16
|
-
raise ArgumentError, 'overlength_rule[:min_length] must be a Measured::Length'
|
|
17
|
-
elsif ![Measured::Length, NilClass].include?(overlength_rule[:max_length].class)
|
|
18
|
-
raise ArgumentError, 'overlength_rule[:max_length] must be one of Measured::Length, NilClass'
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
unless overlength_rule[:fee_cents].is_a?(Integer)
|
|
22
|
-
raise ArgumentError, 'overlength_rule[:fee_cents] must be an Integer'
|
|
23
|
-
end
|
|
14
|
+
@overlength_rules = overlength_rules.map do |overlength_rule|
|
|
15
|
+
overlength_rule.is_a?(OverlengthRule) ? overlength_rule : OverlengthRule.new(**overlength_rule)
|
|
24
16
|
end
|
|
25
|
-
|
|
26
|
-
@overlength_rules = @options[:overlength_rules]
|
|
27
17
|
end
|
|
28
18
|
end
|
|
29
19
|
end
|
metadata
CHANGED
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: freight_kit
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.18
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Third Party Transportation Systems LLC
|
|
8
8
|
- Brody Hoskins
|
|
9
9
|
- Sub Pop Records
|
|
10
10
|
- Shopify
|
|
11
|
+
autorequire:
|
|
11
12
|
bindir: bin
|
|
12
13
|
cert_chain: []
|
|
13
|
-
date:
|
|
14
|
+
date: 2026-07-23 00:00:00.000000000 Z
|
|
14
15
|
dependencies:
|
|
15
16
|
- !ruby/object:Gem::Dependency
|
|
16
17
|
name: faker
|
|
@@ -477,11 +478,13 @@ files:
|
|
|
477
478
|
- lib/freight_kit/platforms/the_great_information_factory.rb
|
|
478
479
|
- lib/freight_kit/shipment_packer.rb
|
|
479
480
|
- lib/freight_kit/tariff.rb
|
|
481
|
+
- lib/freight_kit/tariff/overlength_rule.rb
|
|
480
482
|
- service_type_symbols.txt
|
|
481
483
|
- shipment_event_symbols.txt
|
|
482
484
|
homepage: https://github.com/next-tms/freight_kit
|
|
483
485
|
licenses: []
|
|
484
486
|
metadata: {}
|
|
487
|
+
post_install_message:
|
|
485
488
|
rdoc_options: []
|
|
486
489
|
require_paths:
|
|
487
490
|
- lib
|
|
@@ -496,7 +499,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
496
499
|
- !ruby/object:Gem::Version
|
|
497
500
|
version: '0'
|
|
498
501
|
requirements: []
|
|
499
|
-
rubygems_version: 4.
|
|
502
|
+
rubygems_version: 3.4.10
|
|
503
|
+
signing_key:
|
|
500
504
|
specification_version: 4
|
|
501
505
|
summary: Freight carrier API and website abstraction library for transportation management
|
|
502
506
|
systems (TMS)
|