physical 0.5.1 → 0.6.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/.yardopts +9 -0
- data/CHANGELOG.md +6 -0
- data/README.md +173 -36
- data/lib/physical/box.rb +37 -9
- data/lib/physical/cuboid.rb +42 -1
- data/lib/physical/item.rb +21 -3
- data/lib/physical/location.rb +91 -16
- data/lib/physical/package.rb +65 -4
- data/lib/physical/pallet.rb +31 -3
- data/lib/physical/shipment.rb +40 -8
- data/lib/physical/structure.rb +53 -4
- data/lib/physical/version.rb +1 -1
- data/physical.gemspec +5 -2
- metadata +49 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6ff0a2d8dd4662fd4642901ea536db815d6d51f318a2f6d8a66da1d32e5f7555
|
4
|
+
data.tar.gz: 991d0b406e3cadd1188fff3d84205467d9e47e93e81bfe4d3b6aa9db32e5f9a5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 15b3404acebb3c0d24d396cbcb66205c0d457148c5a1a5b08e2bf920a35d7e8e1edddf246707772337e08dc75c448dd3ec0bac0d49aeda26ef6a3a5ea07f92d2
|
7
|
+
data.tar.gz: 30e61b6929b17288830eee2e68967970895807c3d8695f189dd52fb31c783925245d2b6733d1e785fdef8800a1265fd9b316b1f23005e13c55d6bf59d6157056
|
data/.yardopts
ADDED
data/CHANGELOG.md
CHANGED
@@ -6,6 +6,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
6
6
|
|
7
7
|
## Unreleased
|
8
8
|
|
9
|
+
## [0.6.0] - 2025-08-14
|
10
|
+
|
11
|
+
### Changed
|
12
|
+
- Require Ruby >= 3.0
|
13
|
+
- Upgrade `measured` dependency to `~> 3.0` (bundled as 3.2.1)
|
14
|
+
|
9
15
|
## [0.5.1] - 2023-12-19
|
10
16
|
|
11
17
|
### Changed
|
data/README.md
CHANGED
@@ -1,20 +1,38 @@
|
|
1
1
|
# Physical
|
2
2
|
|
3
|
-
This is a small library to describe
|
3
|
+
This is a small library to describe packages (that could, potentially, be mailed) and
|
4
|
+
structures that store packages.
|
4
5
|
|
5
|
-
|
6
|
+
### Packages
|
6
7
|
|
7
|
-
|
8
|
-
It also has a `Set` of `Physical::Item`s that together make with the container make up everything
|
9
|
-
about the Package.
|
8
|
+
A `Physical::Package` represents a package. It has an ID, dimensions, and weight.
|
10
9
|
|
11
|
-
|
10
|
+
The `Package` takes its dimensions from its `container` object, usually a `Physical::Box`.
|
11
|
+
It also has a `Set` of `Physical::Item`s that together with the container make up everything
|
12
|
+
about the package.
|
12
13
|
|
13
|
-
|
14
|
-
of any void fill.
|
14
|
+
All containers are thought to be `Cuboid`: they have three dimensions and a weight.
|
15
15
|
|
16
|
-
|
17
|
-
|
16
|
+
The weight of a `Package` is the weight of its container plus the weight of all items plus
|
17
|
+
the weight of any void fill.
|
18
|
+
|
19
|
+
By default, the `Physical::Box` container is infinitely large. In order to limit the size
|
20
|
+
of the container, simply give it dimensions.
|
21
|
+
|
22
|
+
### Structures
|
23
|
+
|
24
|
+
A `Physical::Structure` represents a pallet, skid, rack, or some other collection of packages.
|
25
|
+
Similar to a `Package`, it has an ID, dimensions, and weight.
|
26
|
+
|
27
|
+
The `Structure` takes its dimensions from its `container` object, usually a `Physical::Pallet`.
|
28
|
+
It also has an `Array` of `Physical::Package`s that together with the container make up
|
29
|
+
everything about the structure.
|
30
|
+
|
31
|
+
The weight of a `Structure` is the weight of its container plus the weight of all packages.
|
32
|
+
Structures do not have void fill.
|
33
|
+
|
34
|
+
By default, the `Physical::Pallet` container is infinitely large. In order to limit the size
|
35
|
+
of the container, simply give it dimensions.
|
18
36
|
|
19
37
|
## Installation
|
20
38
|
|
@@ -34,9 +52,11 @@ Or install it yourself as:
|
|
34
52
|
|
35
53
|
## Usage
|
36
54
|
|
37
|
-
### Basic
|
55
|
+
### Basic package
|
38
56
|
|
39
|
-
A basic
|
57
|
+
A basic package has no items and is simply assigned a weight and dimensions. Weights must
|
58
|
+
be specified as `Measured::Weight` objects. Dimensions must be specified as an array of
|
59
|
+
`Measured::Length` objects.
|
40
60
|
|
41
61
|
```ruby
|
42
62
|
Physical::Package.new(
|
@@ -48,29 +68,34 @@ Physical::Package.new(
|
|
48
68
|
]
|
49
69
|
)
|
50
70
|
```
|
51
|
-
|
52
|
-
|
53
|
-
### Convenience methods
|
71
|
+
The package's weight and dimensions are retrieved using the `#weight` and `#dimensions`
|
72
|
+
attribute reader methods.
|
54
73
|
|
55
|
-
|
74
|
+
### Package dimensions
|
56
75
|
|
57
|
-
|
76
|
+
The length, width and height of a package are defined as the dimension array's first,
|
77
|
+
second, and third argument, respectively. For the package from the previous example,
|
78
|
+
`#length` will be 3 inches, `#width` will be 4 inches, and `#height` will be 5 inches.
|
58
79
|
|
59
|
-
|
80
|
+
### Packages with items
|
60
81
|
|
82
|
+
The following example is a somewhat more elaborate package: we know the items inside!
|
83
|
+
`Physical::Item` objects are `Cuboid`, so they have three dimensions and a weight. They also
|
84
|
+
have a `properties` hash that can hold things like any hazardous properties that might
|
85
|
+
impede shipping.
|
61
86
|
|
62
87
|
```ruby
|
63
|
-
|
88
|
+
item_one = Physical::Item.new(
|
64
89
|
id: '12345',
|
65
90
|
dimensions: [
|
66
91
|
Measured::Length(2, :inch),
|
67
92
|
Measured::Length(4, :inch),
|
68
93
|
Measured::Length(5, :inch)
|
69
94
|
],
|
70
|
-
weight: Measured::Weight(
|
95
|
+
weight: Measured::Weight(5, :g),
|
71
96
|
)
|
72
97
|
|
73
|
-
|
98
|
+
item_two = Physical::Item.new(
|
74
99
|
id: "54321",
|
75
100
|
dimensions: [
|
76
101
|
Measured::Length(1, :cm),
|
@@ -85,18 +110,22 @@ You can initialize a package with items as follows:
|
|
85
110
|
|
86
111
|
```ruby
|
87
112
|
package_with_items = Physical::Package.new(
|
88
|
-
items: [
|
113
|
+
items: [item_one, item_two]
|
89
114
|
)
|
90
115
|
```
|
91
116
|
|
92
|
-
This package has no defined container. This means we assume a box that is infinitely large, and
|
117
|
+
This package has no defined container. This means we assume a box that is infinitely large, and
|
118
|
+
that has zero weight. Thus the weight of this `package_with_items` will be 28 grams
|
119
|
+
(5 g + 23 g = 28 g).
|
93
120
|
|
94
|
-
### Packages with
|
121
|
+
### Packages with boxes
|
95
122
|
|
96
|
-
A package also has a
|
123
|
+
A package also has a container that wraps it. This container is assumed to be a `Cuboid`, too -
|
124
|
+
but one that has inner dimensions, and a weight that is it's own weight which must be added to
|
125
|
+
item weights in order to find out the total weight of a package.
|
97
126
|
|
98
127
|
```ruby
|
99
|
-
|
128
|
+
container = Physical::Box.new(
|
100
129
|
dimensions: [
|
101
130
|
Measured::Length(10, :cm),
|
102
131
|
Measured::Length(15, :cm),
|
@@ -111,22 +140,29 @@ my_carton = Physical::Box.new(
|
|
111
140
|
)
|
112
141
|
```
|
113
142
|
|
114
|
-
If you create a
|
143
|
+
If you create a container and omit the inner dimensions, we will assume that the container's inner
|
144
|
+
dimensions are equal to its outer dimensions. This will, in many cases, be good enough (but in some
|
145
|
+
cases you'll need the extra precision).
|
115
146
|
|
116
|
-
### Calculating
|
147
|
+
### Calculating void fill
|
117
148
|
|
118
|
-
For an elaborate package with a container box and items, we still cannot find out the full weight
|
149
|
+
For an elaborate package with a container box and items, we still cannot find out the full weight
|
150
|
+
of the package without taking into account void fill (styrofoam, bubble wrap or crumpled newspaper
|
151
|
+
maybe). We can instruct the package to fill up all the volume not used up by items with void fill.
|
152
|
+
You can pass the density as a `Measured::Weight` object that refers to the weight of 1 cubic
|
153
|
+
centimeter of void fill:
|
119
154
|
|
120
155
|
```ruby
|
121
156
|
package = Physical::Package.new(
|
122
157
|
id: "my_package",
|
123
|
-
container:
|
124
|
-
items: [
|
158
|
+
container: container,
|
159
|
+
items: [item_one, item_two],
|
125
160
|
void_fill_density: Measured::Weight(0.007, :g)
|
126
161
|
)
|
127
162
|
```
|
128
163
|
|
129
|
-
In this case, the package's weight will be slightly above the sum of
|
164
|
+
In this case, the package's weight will be slightly above the sum of container weight and the
|
165
|
+
sum of item weights, as we incorporate the approximate weight of the void fill material:
|
130
166
|
|
131
167
|
```ruby
|
132
168
|
package.weight
|
@@ -135,15 +171,115 @@ package.weight
|
|
135
171
|
package.remaining_volume
|
136
172
|
=> #<Measured::Volume: 1107.51744 #<Measured::Unit: ml (milliliter, millilitre, milliliters, millilitres) 1/1000 l>>
|
137
173
|
```
|
174
|
+
### Basic structure
|
175
|
+
|
176
|
+
A basic structure has no packages and is simply assigned a weight and dimensions. Weights must
|
177
|
+
be specified as `Measured::Weight` objects. Dimensions must be specified as an array of
|
178
|
+
`Measured::Length` objects.
|
179
|
+
|
180
|
+
```ruby
|
181
|
+
Physical::Structure.new(
|
182
|
+
weight: Measured::Weight(1, :pound),
|
183
|
+
dimensions: [
|
184
|
+
Measured::Length(48, :inch),
|
185
|
+
Measured::Length(48, :inch),
|
186
|
+
Measured::Length(96, :inch)
|
187
|
+
]
|
188
|
+
)
|
189
|
+
```
|
190
|
+
The structure's weight and dimensions are retrieved using the `#weight` and `#dimensions`
|
191
|
+
attribute reader methods.
|
192
|
+
|
193
|
+
### Structure dimensions
|
194
|
+
|
195
|
+
The length, width and height of a structure are defined as the dimension array's first,
|
196
|
+
second, and third argument, respectively. For the structure from the previous example,
|
197
|
+
`#length` will be 48 inches, `#width` will be 48 inches, and `#height` will be 96 inches
|
198
|
+
(the approximate dimensions of a pallet).
|
199
|
+
|
200
|
+
### Structures with packages
|
201
|
+
|
202
|
+
The following example is a somewhat more elaborate structure: we know the packages inside!
|
203
|
+
`Physical::Package` objects are `Cuboid`, so they have three dimensions and a weight. They also
|
204
|
+
have a `properties` hash that can hold things like any hazardous properties that might
|
205
|
+
impede shipping.
|
206
|
+
|
207
|
+
```ruby
|
208
|
+
package_one = Physical::Package.new(
|
209
|
+
id: '12345',
|
210
|
+
dimensions: [
|
211
|
+
Measured::Length(2, :inch),
|
212
|
+
Measured::Length(4, :inch),
|
213
|
+
Measured::Length(5, :inch)
|
214
|
+
],
|
215
|
+
weight: Measured::Weight(1, :kg),
|
216
|
+
)
|
217
|
+
|
218
|
+
package_two = Physical::Package.new(
|
219
|
+
id: "54321",
|
220
|
+
dimensions: [
|
221
|
+
Measured::Length(1, :cm),
|
222
|
+
Measured::Length(1, :cm),
|
223
|
+
Measured::Length(1, :cm)
|
224
|
+
],
|
225
|
+
weight: Measured::Weight(23, :g)
|
226
|
+
)
|
227
|
+
```
|
228
|
+
|
229
|
+
You can initialize a structure with packages as follows:
|
230
|
+
|
231
|
+
```ruby
|
232
|
+
structure_with_packages = Physical::Structure.new(
|
233
|
+
items: [package_one, package_two]
|
234
|
+
)
|
235
|
+
```
|
236
|
+
|
237
|
+
This structure has no defined container. This means we assume a pallet that is infinitely large,
|
238
|
+
and that has zero weight. Thus the weight of this `structure_with_packages` will be 1023 grams
|
239
|
+
(1 kg + 73 g = 1000 g + 23 g = 1023 g).
|
240
|
+
|
241
|
+
### Structures with pallets
|
242
|
+
|
243
|
+
A structure also has a container that wraps it. This container is assumed to be a `Cuboid`, too -
|
244
|
+
but one that has inner dimensions, and a weight that is it's own weight which must be added to
|
245
|
+
package weights in order to find out the total weight of a structure.
|
246
|
+
|
247
|
+
```ruby
|
248
|
+
container = Physical::Pallet.new(
|
249
|
+
dimensions: [
|
250
|
+
Measured::Length(10, :cm),
|
251
|
+
Measured::Length(15, :cm),
|
252
|
+
Measured::Length(15, :cm)
|
253
|
+
],
|
254
|
+
inner_dimensions: [
|
255
|
+
Measured::Length(9, :cm),
|
256
|
+
Measured::Length(14, :cm),
|
257
|
+
Measured::Length(14, :cm)
|
258
|
+
],
|
259
|
+
weight: Measured::Weight(350, :g),
|
260
|
+
)
|
261
|
+
```
|
262
|
+
|
263
|
+
If you create a container and omit the inner dimensions, we will assume that the container's inner
|
264
|
+
dimensions are equal to its outer dimensions. This will, in many cases, be good enough (but in some
|
265
|
+
cases you'll need the extra precision).
|
266
|
+
|
138
267
|
## Development
|
139
268
|
|
140
|
-
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to
|
269
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to
|
270
|
+
run the tests. You can also run `bin/console` for an interactive prompt that will allow you to
|
271
|
+
experiment.
|
141
272
|
|
142
|
-
To install this gem onto your local machine, run `bundle exec rake install`. To release a new
|
273
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new
|
274
|
+
version, update the version number in `version.rb`, and then run `bundle exec rake release`,
|
275
|
+
which will create a git tag for the version, push git commits and tags, and push the `.gem`
|
276
|
+
file to [rubygems.org](https://rubygems.org).
|
143
277
|
|
144
278
|
## Contributing
|
145
279
|
|
146
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/friendlycart/physical.
|
280
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/friendlycart/physical.
|
281
|
+
This project is intended to be a safe, welcoming space for collaboration, and contributors are
|
282
|
+
expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
|
147
283
|
|
148
284
|
## License
|
149
285
|
|
@@ -151,4 +287,5 @@ The gem is available as open source under the terms of the [MIT License](https:/
|
|
151
287
|
|
152
288
|
## Code of Conduct
|
153
289
|
|
154
|
-
Everyone interacting in the Physical project’s codebases, issue trackers, chat rooms and
|
290
|
+
Everyone interacting in the Physical project’s codebases, issue trackers, chat rooms and
|
291
|
+
mailing lists is expected to follow the [code of conduct](https://github.com/friendlycart/physical/blob/main/CODE_OF_CONDUCT.md).
|
data/lib/physical/box.rb
CHANGED
@@ -3,25 +3,52 @@
|
|
3
3
|
require 'measured'
|
4
4
|
|
5
5
|
module Physical
|
6
|
+
# Represents a physical box which items can be packed into.
|
6
7
|
class Box < Cuboid
|
8
|
+
# The default dimensions of this box when unspecified
|
7
9
|
DEFAULT_LENGTH = BigDecimal::INFINITY
|
10
|
+
|
11
|
+
# The default maximum weight of this box when unspecified
|
8
12
|
DEFAULT_MAX_WEIGHT = BigDecimal::INFINITY
|
9
13
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
14
|
+
# The inner length, width, and height of this box
|
15
|
+
# @return [Array<Measured::Length>]
|
16
|
+
attr_reader :inner_dimensions
|
17
|
+
|
18
|
+
# The inner length of this box
|
19
|
+
# @return [Measured::Length]
|
20
|
+
attr_reader :inner_length
|
21
|
+
|
22
|
+
# The inner width of this box
|
23
|
+
# @return [Measured::Length]
|
24
|
+
attr_reader :inner_width
|
25
|
+
|
26
|
+
# The inner height of this box
|
27
|
+
# @return [Measured::Length]
|
28
|
+
attr_reader :inner_height
|
29
|
+
|
30
|
+
# The maximum weight this box can handle
|
31
|
+
# @return [Measured::Weight]
|
32
|
+
attr_reader :max_weight
|
15
33
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
34
|
+
# @param [Hash] kwargs ID, dimensions, weight, and properties
|
35
|
+
# @option kwargs [String] :id a unique identifier for this box
|
36
|
+
# @option kwargs [Array<Measured::Length>] :dimensions the outer length, width, and height of this box
|
37
|
+
# @option kwargs [Array<Measured::Length>] :inner_dimensions the inner length, width, and height of this box
|
38
|
+
# @option kwargs [Measured::Weight] :weight the weight of the box itself (excluding what's inside)
|
39
|
+
# @option kwargs [Measured::Weight] :max_weight the maximum weight this box can handle
|
40
|
+
# @option kwargs [Hash] :properties additional custom properties for this box
|
41
|
+
def initialize(**kwargs)
|
42
|
+
inner_dimensions = kwargs.delete(:inner_dimensions) || []
|
43
|
+
max_weight = kwargs.delete(:max_weight) || Measured::Weight(DEFAULT_MAX_WEIGHT, :g)
|
44
|
+
super(**kwargs)
|
20
45
|
@inner_dimensions = fill_dimensions(Types::Dimensions[inner_dimensions])
|
21
46
|
@inner_length, @inner_width, @inner_height = *@inner_dimensions
|
22
47
|
@max_weight = Types::Weight[max_weight]
|
23
48
|
end
|
24
49
|
|
50
|
+
# Calculates and returns this box's volume based on the inner dimensions
|
51
|
+
# @return [Measured::Volume]
|
25
52
|
def inner_volume
|
26
53
|
Measured::Volume(
|
27
54
|
inner_dimensions.map { |d| d.convert_to(:cm).value }.reduce(1, &:*),
|
@@ -29,6 +56,7 @@ module Physical
|
|
29
56
|
)
|
30
57
|
end
|
31
58
|
|
59
|
+
# Returns true if the given item can fit inside this box
|
32
60
|
# @param [Physical::Item] item
|
33
61
|
# @return [Boolean]
|
34
62
|
def item_fits?(item)
|
data/lib/physical/cuboid.rb
CHANGED
@@ -3,11 +3,42 @@
|
|
3
3
|
require 'measured'
|
4
4
|
|
5
5
|
module Physical
|
6
|
+
# Represents a cube-shaped physical object with dimensions and weight.
|
6
7
|
class Cuboid
|
7
8
|
include PropertyReaders
|
8
9
|
|
9
|
-
|
10
|
+
# A unique identifier for this cuboid
|
11
|
+
# @return [String]
|
12
|
+
attr_reader :id
|
10
13
|
|
14
|
+
# The length, width, and height of this cuboid
|
15
|
+
# @return [Array<Measured::Length>]
|
16
|
+
attr_reader :dimensions
|
17
|
+
|
18
|
+
# The length of this cuboid
|
19
|
+
# @return <Measured::Length>
|
20
|
+
attr_reader :length
|
21
|
+
|
22
|
+
# The width of this cuboid
|
23
|
+
# @return <Measured::Length>
|
24
|
+
attr_reader :width
|
25
|
+
|
26
|
+
# The height of this cuboid
|
27
|
+
# @return <Measured::Length>
|
28
|
+
attr_reader :height
|
29
|
+
|
30
|
+
# The weight of the cuboid itself (excluding what's inside)
|
31
|
+
# @return [Measured::Weight]
|
32
|
+
attr_reader :weight
|
33
|
+
|
34
|
+
# Additional custom properties for this cuboid
|
35
|
+
# @return [Hash]
|
36
|
+
attr_reader :properties
|
37
|
+
|
38
|
+
# @param [String] id a unique identifier for this cuboid
|
39
|
+
# @param [Array<Measured::Length>] dimensions the length, width, and height of this cuboid
|
40
|
+
# @param [Measured::Weight] weight the weight of the cuboid itself (excluding what's inside)
|
41
|
+
# @param [Hash] properties additional custom properties for this cuboid
|
11
42
|
def initialize(id: nil, dimensions: [], weight: Measured::Weight(0, :g), properties: {})
|
12
43
|
@id = id || SecureRandom.uuid
|
13
44
|
@weight = Types::Weight[weight]
|
@@ -17,10 +48,14 @@ module Physical
|
|
17
48
|
@properties = properties
|
18
49
|
end
|
19
50
|
|
51
|
+
# Calculates and returns this cuboid's volume based on its dimensions.
|
52
|
+
# @return [Measured::Volume]
|
20
53
|
def volume
|
21
54
|
Measured::Volume(dimensions.map { |d| d.convert_to(:cm).value }.reduce(1, &:*), :ml)
|
22
55
|
end
|
23
56
|
|
57
|
+
# Calculates and returns this cuboid's density based on its volume and weight.
|
58
|
+
# @return [Measured::Density]
|
24
59
|
def density
|
25
60
|
return Measured::Density(Float::INFINITY, :g_ml) if volume.value.zero?
|
26
61
|
return Measured::Density(0.0, :g_ml) if volume.value.infinite?
|
@@ -28,6 +63,9 @@ module Physical
|
|
28
63
|
Measured::Density(weight.convert_to(:g).value / volume.convert_to(:ml).value, :g_ml)
|
29
64
|
end
|
30
65
|
|
66
|
+
# Returns true if the given object shares the same class and ID with this cuboid.
|
67
|
+
# @param [Object] other
|
68
|
+
# @return [Boolean]
|
31
69
|
def ==(other)
|
32
70
|
other.is_a?(self.class) &&
|
33
71
|
id == other&.id
|
@@ -35,6 +73,9 @@ module Physical
|
|
35
73
|
|
36
74
|
private
|
37
75
|
|
76
|
+
# Fills an array with dimensions or with default values if unspecified.
|
77
|
+
# @param [Array<Measured::Length>] dimensions
|
78
|
+
# @return [Array<Measured::Length>]
|
38
79
|
def fill_dimensions(dimensions)
|
39
80
|
dimensions.fill(dimensions.length..2) do |index|
|
40
81
|
@dimensions[index] || Measured::Length(self.class::DEFAULT_LENGTH, :cm)
|
data/lib/physical/item.rb
CHANGED
@@ -1,13 +1,31 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Physical
|
4
|
+
# Represents a physical item which can be packed into a box.
|
4
5
|
class Item < Cuboid
|
6
|
+
# The default dimensions of this item when unspecified
|
5
7
|
DEFAULT_LENGTH = 0
|
6
8
|
|
7
|
-
|
8
|
-
|
9
|
-
|
9
|
+
# The cost for this item
|
10
|
+
# @return [Money]
|
11
|
+
attr_reader :cost
|
10
12
|
|
13
|
+
# The SKU for this item
|
14
|
+
# @return [String]
|
15
|
+
attr_reader :sku
|
16
|
+
|
17
|
+
# A description for this item
|
18
|
+
# @return [String]
|
19
|
+
attr_reader :description
|
20
|
+
|
21
|
+
# @param [Hash] kwargs ID, dimensions, weight, and properties
|
22
|
+
# @option kwargs [String] :id a unique identifier for this item
|
23
|
+
# @option kwargs [Money] :cost the cost of this item
|
24
|
+
# @option kwargs [String] :sku the SKU for this item
|
25
|
+
# @option kwargs [String] :description a description for this item
|
26
|
+
# @option kwargs [Array<Measured::Length>] :dimensions the length, width, and height of this item
|
27
|
+
# @option kwargs [Measured::Weight] :weight the weight of this item
|
28
|
+
# @option kwargs [Hash] :properties additional custom properties for this item
|
11
29
|
def initialize(**kwargs)
|
12
30
|
@cost = Types::Money.optional[kwargs.delete(:cost)]
|
13
31
|
@sku = kwargs.delete(:sku)
|
data/lib/physical/location.rb
CHANGED
@@ -3,28 +3,93 @@
|
|
3
3
|
require 'carmen'
|
4
4
|
|
5
5
|
module Physical
|
6
|
+
# Represents a physical location.
|
6
7
|
class Location
|
7
8
|
include PropertyReaders
|
8
9
|
|
10
|
+
# Possible address types for this location
|
9
11
|
ADDRESS_TYPES = %w(residential commercial po_box).freeze
|
10
12
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
:city,
|
15
|
-
:name,
|
16
|
-
:address1,
|
17
|
-
:address2,
|
18
|
-
:address3,
|
19
|
-
:phone,
|
20
|
-
:fax,
|
21
|
-
:email,
|
22
|
-
:address_type,
|
23
|
-
:company_name,
|
24
|
-
:latitude,
|
25
|
-
:longitude,
|
26
|
-
:properties
|
13
|
+
# This location's country
|
14
|
+
# @return [Carmen::Country]
|
15
|
+
attr_reader :country
|
27
16
|
|
17
|
+
# This location's postal code
|
18
|
+
# @return [String]
|
19
|
+
attr_reader :zip
|
20
|
+
|
21
|
+
# This location's state or province
|
22
|
+
# @return [Carmen::Region]
|
23
|
+
attr_reader :region
|
24
|
+
|
25
|
+
# This location's city
|
26
|
+
# @return [String]
|
27
|
+
attr_reader :city
|
28
|
+
|
29
|
+
# This location's name (could be a person's name)
|
30
|
+
# @return [String]
|
31
|
+
attr_reader :name
|
32
|
+
|
33
|
+
# This location's address line 1
|
34
|
+
# @return [String]
|
35
|
+
attr_reader :address1
|
36
|
+
|
37
|
+
# This location's address line 2
|
38
|
+
# @return [String]
|
39
|
+
attr_reader :address2
|
40
|
+
|
41
|
+
# This location's address line 3
|
42
|
+
# @return [String]
|
43
|
+
attr_reader :address3
|
44
|
+
|
45
|
+
# This location's phone
|
46
|
+
# @return [String]
|
47
|
+
attr_reader :phone
|
48
|
+
|
49
|
+
# This location's fax
|
50
|
+
# @return [String]
|
51
|
+
attr_reader :fax
|
52
|
+
|
53
|
+
# This location's email
|
54
|
+
# @return [String]
|
55
|
+
attr_reader :email
|
56
|
+
|
57
|
+
# This location's address type (see {ADDRESS_TYPES})
|
58
|
+
# @return [String]
|
59
|
+
attr_reader :address_type
|
60
|
+
|
61
|
+
# This location's company name
|
62
|
+
# @return [String]
|
63
|
+
attr_reader :company_name
|
64
|
+
|
65
|
+
# This location's latitude
|
66
|
+
# @return [String]
|
67
|
+
attr_reader :latitude
|
68
|
+
|
69
|
+
# This location's longitude
|
70
|
+
# @return [String]
|
71
|
+
attr_reader :longitude
|
72
|
+
|
73
|
+
# Additional custom properties for this location
|
74
|
+
# @return [String]
|
75
|
+
attr_reader :properties
|
76
|
+
|
77
|
+
# @param [String] name the name of this location (could be a person's name)
|
78
|
+
# @param [String] company_name the name of the company at this location
|
79
|
+
# @param [String] address1 the first line of the address
|
80
|
+
# @param [String] address2 the second line of the address
|
81
|
+
# @param [String] address3 the third line of the address
|
82
|
+
# @param [String] city the city
|
83
|
+
# @param [String, Carmen::Region] region the state or province
|
84
|
+
# @param [String] zip the postal code
|
85
|
+
# @param [String, Carmen::Country] country the country
|
86
|
+
# @param [String] phone the phone number
|
87
|
+
# @param [String] fax the fax number
|
88
|
+
# @param [String] email the email address
|
89
|
+
# @param [String] address_type the type of address (see {ADDRESS_TYPES})
|
90
|
+
# @param [String] latitude the latitude at this location
|
91
|
+
# @param [String] longitude the longitude at this location
|
92
|
+
# @param [Hash] properties additional custom properties for this location
|
28
93
|
def initialize(
|
29
94
|
name: nil,
|
30
95
|
company_name: nil,
|
@@ -72,18 +137,26 @@ module Physical
|
|
72
137
|
@properties = properties
|
73
138
|
end
|
74
139
|
|
140
|
+
# Returns true if this location's address type is "residential"
|
141
|
+
# @return [Boolean]
|
75
142
|
def residential?
|
76
143
|
@address_type == 'residential'
|
77
144
|
end
|
78
145
|
|
146
|
+
# Returns true if this location's address type is "commercial"
|
147
|
+
# @return [Boolean]
|
79
148
|
def commercial?
|
80
149
|
@address_type == 'commercial'
|
81
150
|
end
|
82
151
|
|
152
|
+
# Returns true if this location's address type is "po_box"
|
153
|
+
# @return [Boolean]
|
83
154
|
def po_box?
|
84
155
|
@address_type == 'po_box'
|
85
156
|
end
|
86
157
|
|
158
|
+
# Returns a hash representation of this location.
|
159
|
+
# @return [Hash]
|
87
160
|
def to_hash
|
88
161
|
{
|
89
162
|
country: country&.code,
|
@@ -102,6 +175,8 @@ module Physical
|
|
102
175
|
}
|
103
176
|
end
|
104
177
|
|
178
|
+
# Returns true if the given object's class and {#to_hash} match this location.
|
179
|
+
# @return [Boolean]
|
105
180
|
def ==(other)
|
106
181
|
other.is_a?(self.class) &&
|
107
182
|
to_hash == other&.to_hash
|
data/lib/physical/package.rb
CHANGED
@@ -1,10 +1,46 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Physical
|
4
|
+
# Represents a physical package which has a container (box) and items.
|
4
5
|
class Package
|
5
6
|
extend Forwardable
|
6
|
-
attr_reader :id, :container, :items, :void_fill_density, :items_weight, :used_volume, :description
|
7
7
|
|
8
|
+
# A unique identifier for this package
|
9
|
+
# @return [String]
|
10
|
+
attr_reader :id
|
11
|
+
|
12
|
+
# The container ({Box}) for this package
|
13
|
+
# @return [Physical::Cuboid]
|
14
|
+
attr_reader :container
|
15
|
+
|
16
|
+
# The items contained by this package
|
17
|
+
# @return [Array<Physical::Item>]
|
18
|
+
attr_reader :items
|
19
|
+
|
20
|
+
# The density of the void fill in this package
|
21
|
+
# @return [Measured::Density]
|
22
|
+
attr_reader :void_fill_density
|
23
|
+
|
24
|
+
# The weight of the items in this package
|
25
|
+
# @return [Measured::Weight]
|
26
|
+
attr_reader :items_weight
|
27
|
+
|
28
|
+
# The total volume used by the items in this package
|
29
|
+
# @return [Measured::Volume]
|
30
|
+
attr_reader :used_volume
|
31
|
+
|
32
|
+
# The description for this package
|
33
|
+
# @return [String]
|
34
|
+
attr_reader :description
|
35
|
+
|
36
|
+
# @param [String] id a unique identifier for this package
|
37
|
+
# @param [Physical::Cuboid] container the container ({Box}) for this package
|
38
|
+
# @param [Array<Physical::Item>] items the items contained by this package
|
39
|
+
# @param [Measured::Density] void_fill_density the density of the void fill in this package
|
40
|
+
# @param [Array<Measured::Length>] dimensions the length, width, and height of this package's container
|
41
|
+
# @param [Measured::Weight] weight the weight of this package's container
|
42
|
+
# @param [String] description a description for this package
|
43
|
+
# @param [Hash] properties additional custom properties for this package's container
|
8
44
|
def initialize(id: nil, container: nil, items: [], void_fill_density: Measured::Density(0, :g_ml), dimensions: nil, weight: nil, description: nil, properties: {})
|
9
45
|
@id = id || SecureRandom.uuid
|
10
46
|
@void_fill_density = Types::Density[void_fill_density]
|
@@ -16,8 +52,22 @@ module Physical
|
|
16
52
|
@used_volume = @items.map(&:volume).reduce(Measured::Volume(0, :ml), &:+)
|
17
53
|
end
|
18
54
|
|
55
|
+
# @!attribute [r] dimensions
|
56
|
+
# The container's dimensions
|
57
|
+
# @!attribute [r] weight
|
58
|
+
# The container's weight
|
59
|
+
# @!attribute [r] length
|
60
|
+
# The container's length
|
61
|
+
# @!attribute [r] height
|
62
|
+
# The container's height
|
63
|
+
# @!attribute [r] properties
|
64
|
+
# The container's additional custom properties
|
65
|
+
# @!attribute [r] volume
|
66
|
+
# The container's volume
|
19
67
|
delegate [:dimensions, :width, :length, :height, :properties, :volume] => :container
|
20
68
|
|
69
|
+
# Adds an item to the package.
|
70
|
+
# @param [Physical::Item] other the item to add
|
21
71
|
def <<(other)
|
22
72
|
@items.add(other)
|
23
73
|
@items_weight += other.weight
|
@@ -25,6 +75,8 @@ module Physical
|
|
25
75
|
end
|
26
76
|
alias_method :add, :<<
|
27
77
|
|
78
|
+
# Removes an item from the package.
|
79
|
+
# @param [Physical::Item] other the item to remove
|
28
80
|
def >>(other)
|
29
81
|
@items.delete(other)
|
30
82
|
@items_weight -= other.weight
|
@@ -32,28 +84,37 @@ module Physical
|
|
32
84
|
end
|
33
85
|
alias_method :delete, :>>
|
34
86
|
|
87
|
+
# Sums container weight, items weight, and void fill weight and returns the total.
|
88
|
+
# @return [Measured::Weight]
|
35
89
|
def weight
|
36
90
|
container.weight + items_weight + void_fill_weight
|
37
91
|
end
|
38
92
|
|
39
|
-
#
|
40
|
-
#
|
41
|
-
#
|
93
|
+
# Sums and returns the cost from all items in this package. Item cost is
|
94
|
+
# optional, therefore we only return a sum if *all* items have a cost.
|
95
|
+
# Otherwise, nil is returned.
|
96
|
+
# @return [Money, nil]
|
42
97
|
def items_value
|
43
98
|
items_cost = items.map(&:cost)
|
44
99
|
items_cost.reduce(&:+) if items_cost.compact.size == items_cost.size
|
45
100
|
end
|
46
101
|
|
102
|
+
# Calculates and returns the weight of the void fill in this package.
|
103
|
+
# @return [Measured::Weight]
|
47
104
|
def void_fill_weight
|
48
105
|
return Measured::Weight(0, :g) if container.volume.value.infinite?
|
49
106
|
|
50
107
|
Measured::Weight(void_fill_density.convert_to(:g_ml).value * remaining_volume.convert_to(:ml).value, :g)
|
51
108
|
end
|
52
109
|
|
110
|
+
# Calculates and returns remaining volume in this package.
|
111
|
+
# @return [Measured::Volume]
|
53
112
|
def remaining_volume
|
54
113
|
container.inner_volume - used_volume
|
55
114
|
end
|
56
115
|
|
116
|
+
# Returns the density of this package based on its volume and weight.
|
117
|
+
# @return [Measured::Density]
|
57
118
|
def density
|
58
119
|
return Measured::Density(Float::INFINITY, :g_ml) if container.volume.value.zero?
|
59
120
|
return Measured::Density(0.0, :g_ml) if container.volume.value.infinite?
|
data/lib/physical/pallet.rb
CHANGED
@@ -3,24 +3,52 @@
|
|
3
3
|
require 'measured'
|
4
4
|
|
5
5
|
module Physical
|
6
|
+
# Represents a physical pallet which holds boxes.
|
6
7
|
class Pallet < Cuboid
|
8
|
+
# The default dimensions of this pallet when unspecified
|
7
9
|
DEFAULT_LENGTH = BigDecimal::INFINITY
|
10
|
+
|
11
|
+
# The default maximum weight of this pallet when unspecified
|
8
12
|
DEFAULT_MAX_WEIGHT = BigDecimal::INFINITY
|
9
13
|
|
14
|
+
# The maximum weight this pallet can handle
|
15
|
+
# @return [Measured::Weight]
|
10
16
|
attr_reader :max_weight
|
11
17
|
|
12
|
-
|
13
|
-
|
14
|
-
|
18
|
+
# @param [Hash] kwargs ID, dimensions, weight, and properties
|
19
|
+
# @option kwargs [String] :id a unique identifier for this pallet
|
20
|
+
# @option kwargs [Array<Measured::Length>] :dimensions the length, width, and height of this pallet
|
21
|
+
# @option kwargs [Measured::Weight] :weight the weight of the pallet itself (excluding what's on top)
|
22
|
+
# @option kwargs [Measured::Weight] :max_weight the maximum weight this pallet can handle
|
23
|
+
# @option kwargs [Hash] :properties additional custom properties for this pallet
|
24
|
+
def initialize(**kwargs)
|
25
|
+
max_weight = kwargs.delete(:max_weight) || Measured::Weight(DEFAULT_MAX_WEIGHT, :g)
|
26
|
+
super(**kwargs)
|
15
27
|
@max_weight = Types::Weight[max_weight]
|
16
28
|
end
|
17
29
|
|
30
|
+
# @!method volume
|
31
|
+
# @return [Measured::Volume] the volume of this pallet
|
18
32
|
alias_method :inner_volume, :volume
|
33
|
+
|
34
|
+
# @!method dimensions
|
35
|
+
# @return [Array<Measured::Length>] the dimensions of this pallet
|
19
36
|
alias_method :inner_dimensions, :dimensions
|
37
|
+
|
38
|
+
# @!method length
|
39
|
+
# @return [Measured::Length] the length of this pallet
|
20
40
|
alias_method :inner_length, :length
|
41
|
+
|
42
|
+
# @!method width
|
43
|
+
# @return [Measured::Length] the width of this pallet
|
21
44
|
alias_method :inner_width, :width
|
45
|
+
|
46
|
+
# @!method height
|
47
|
+
# @return [Measured::Length] the height of this pallet
|
22
48
|
alias_method :inner_height, :height
|
23
49
|
|
50
|
+
# Returns true if the given package can fit on the pallet. Checks package
|
51
|
+
# dimensions and weight against pallet dimensions and max weight.
|
24
52
|
# @param [Physical::Package] package
|
25
53
|
# @return [Boolean]
|
26
54
|
def package_fits?(package)
|
data/lib/physical/shipment.rb
CHANGED
@@ -1,16 +1,48 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Physical
|
4
|
+
# Represents a physical shipment containing structures and/or packages.
|
4
5
|
class Shipment
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
:service_code,
|
9
|
-
:pallets,
|
10
|
-
:structures,
|
11
|
-
:packages,
|
12
|
-
:options
|
6
|
+
# A unique identifier for this shipment
|
7
|
+
# @return [String]
|
8
|
+
attr_reader :id
|
13
9
|
|
10
|
+
# This shipment's origin location
|
11
|
+
# @return [Physical::Location]
|
12
|
+
attr_reader :origin
|
13
|
+
|
14
|
+
# This shipment's destination location
|
15
|
+
# @return [Physical::Location]
|
16
|
+
attr_reader :destination
|
17
|
+
|
18
|
+
# The shipment carrier's service code
|
19
|
+
# @return [String]
|
20
|
+
attr_reader :service_code
|
21
|
+
|
22
|
+
# This shipment's pallets (DEPRECATED: use {#structures} instead)
|
23
|
+
# @return [Array<Physical::Pallet>]
|
24
|
+
attr_reader :pallets
|
25
|
+
|
26
|
+
# This shipment's structures (pallets, skids, etc.) which hold packages
|
27
|
+
# @return [Array<Physical::Structure>]
|
28
|
+
attr_reader :structures
|
29
|
+
|
30
|
+
# This shipment's packages which hold items
|
31
|
+
# @return [Array<Physical::Package>]
|
32
|
+
attr_reader :packages
|
33
|
+
|
34
|
+
# Additional custom options for this shipment
|
35
|
+
# @return [Hash]
|
36
|
+
attr_reader :options
|
37
|
+
|
38
|
+
# @param [String] id a unique identifier for this shipment
|
39
|
+
# @param [Physical::Location] origin the shipment's origin location
|
40
|
+
# @param [Physical::Location] destination the shipment's destination location
|
41
|
+
# @param [String] service_code the shipment carrier's service code
|
42
|
+
# @param [Array<Physical::Pallet>] pallets the shipment's pallets (DEPRECATED: use `structures` instead)
|
43
|
+
# @param [Array<Physical::Structure>] structures the shipment's structures (pallets, skids, etc.) which hold packages
|
44
|
+
# @param [Array<Physical::Package>] packages the shipment's packages (boxes) which hold items
|
45
|
+
# @param [Hash] options additional custom options for this shipment
|
14
46
|
def initialize(id: nil, origin: nil, destination: nil, service_code: nil, pallets: [], structures: [], packages: [], options: {})
|
15
47
|
@id = id || SecureRandom.uuid
|
16
48
|
@origin = origin
|
data/lib/physical/structure.rb
CHANGED
@@ -1,10 +1,36 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Physical
|
4
|
+
# Represents a physical structure which has a container (pallet, skid, etc.) and packages.
|
4
5
|
class Structure
|
5
6
|
extend Forwardable
|
6
|
-
attr_reader :id, :container, :packages, :packages_weight, :used_volume
|
7
7
|
|
8
|
+
# A unique identifier for this structure
|
9
|
+
# @return [String]
|
10
|
+
attr_reader :id
|
11
|
+
|
12
|
+
# The container ({Pallet}) for this structure
|
13
|
+
# @return [Physical::Cuboid]
|
14
|
+
attr_reader :container
|
15
|
+
|
16
|
+
# The packages contained by this structure
|
17
|
+
# @return [Array<Physical::Package>]
|
18
|
+
attr_reader :packages
|
19
|
+
|
20
|
+
# The weight of the packages in this structure
|
21
|
+
# @return [Measured::Weight]
|
22
|
+
attr_reader :packages_weight
|
23
|
+
|
24
|
+
# The total volume used by the packages in this structure
|
25
|
+
# @return [Measured::Volume]
|
26
|
+
attr_reader :used_volume
|
27
|
+
|
28
|
+
# @param [String] id a unique identifier for this structure
|
29
|
+
# @param [Physical::Cuboid] container the container ({Pallet}) for this structure
|
30
|
+
# @param [Array<Physical::Package>] packages the packages contained by this structure
|
31
|
+
# @param [Array<Measured::Length>] dimensions the length, width, and height of this structure's container
|
32
|
+
# @param [Measured::Weight] weight the weight of this structure's container
|
33
|
+
# @param [Hash] properties additional custom properties for this package's container
|
8
34
|
def initialize(id: nil, container: nil, packages: [], dimensions: nil, weight: nil, properties: {})
|
9
35
|
@id = id || SecureRandom.uuid
|
10
36
|
@container = container || Physical::Pallet.new(dimensions: dimensions || [], weight: weight || Measured::Weight(0, :g), properties: properties)
|
@@ -14,8 +40,22 @@ module Physical
|
|
14
40
|
@used_volume = @packages.map(&:volume).reduce(Measured::Volume(0, :ml), &:+)
|
15
41
|
end
|
16
42
|
|
43
|
+
# @!attribute [r] dimensions
|
44
|
+
# The container's dimensions
|
45
|
+
# @!attribute [r] weight
|
46
|
+
# The container's weight
|
47
|
+
# @!attribute [r] length
|
48
|
+
# The container's length
|
49
|
+
# @!attribute [r] height
|
50
|
+
# The container's height
|
51
|
+
# @!attribute [r] properties
|
52
|
+
# The container's additional custom properties
|
53
|
+
# @!attribute [r] volume
|
54
|
+
# The container's volume
|
17
55
|
delegate [:dimensions, :width, :length, :height, :properties, :volume] => :container
|
18
56
|
|
57
|
+
# Adds a package to the structure.
|
58
|
+
# @param [Physical::Package] other the package to add
|
19
59
|
def <<(other)
|
20
60
|
@packages.add(other)
|
21
61
|
@packages_weight += other.weight
|
@@ -23,6 +63,8 @@ module Physical
|
|
23
63
|
end
|
24
64
|
alias_method :add, :<<
|
25
65
|
|
66
|
+
# Removes a package from the structure.
|
67
|
+
# @param [Physical::Package] other the package to remove
|
26
68
|
def >>(other)
|
27
69
|
@packages.delete(other)
|
28
70
|
@packages_weight -= other.weight
|
@@ -30,22 +72,29 @@ module Physical
|
|
30
72
|
end
|
31
73
|
alias_method :delete, :>>
|
32
74
|
|
75
|
+
# Sums container weight and packages weight and returns the total.
|
76
|
+
# @return [Measured::Weight]
|
33
77
|
def weight
|
34
78
|
container.weight + packages_weight
|
35
79
|
end
|
36
80
|
|
37
|
-
#
|
38
|
-
#
|
39
|
-
#
|
81
|
+
# Sums and returns the item cost from all packages in this structure.
|
82
|
+
# Item cost is optional, therefore we only return a sum if *all* packages
|
83
|
+
# return item cost. Otherwise, nil is returned.
|
84
|
+
# @return [Money, nil]
|
40
85
|
def packages_value
|
41
86
|
packages_cost = packages.map(&:items_value)
|
42
87
|
packages_cost.reduce(&:+) if packages_cost.compact.size == packages_cost.size
|
43
88
|
end
|
44
89
|
|
90
|
+
# Calculates and returns remaining volume in this structure.
|
91
|
+
# @return [Measured::Volume]
|
45
92
|
def remaining_volume
|
46
93
|
container.inner_volume - used_volume
|
47
94
|
end
|
48
95
|
|
96
|
+
# Returns the density of this structure based on its volume and weight.
|
97
|
+
# @return [Measured::Density]
|
49
98
|
def density
|
50
99
|
return Measured::Density(Float::INFINITY, :g_ml) if container.volume.value.zero?
|
51
100
|
return Measured::Density(0.0, :g_ml) if container.volume.value.infinite?
|
data/lib/physical/version.rb
CHANGED
data/physical.gemspec
CHANGED
@@ -19,17 +19,20 @@ Gem::Specification.new do |spec|
|
|
19
19
|
f.match(%r{^(spec)/})
|
20
20
|
end
|
21
21
|
spec.require_paths = ["lib"]
|
22
|
-
spec.required_ruby_version = '>=
|
22
|
+
spec.required_ruby_version = '>= 3.0'
|
23
23
|
spec.add_runtime_dependency "carmen", "~> 1.0"
|
24
24
|
spec.add_runtime_dependency "dry-types", "~> 1.5"
|
25
|
-
spec.add_runtime_dependency "measured", "~>
|
25
|
+
spec.add_runtime_dependency "measured", "~> 3.0"
|
26
26
|
spec.add_runtime_dependency "money", ">= 5"
|
27
27
|
|
28
28
|
spec.add_development_dependency "bundler", [">= 1.16", "< 3"]
|
29
29
|
spec.add_development_dependency "factory_bot", "~> 6.2"
|
30
|
+
spec.add_development_dependency "rack"
|
30
31
|
spec.add_development_dependency "rake", ">= 12.3.3"
|
31
32
|
spec.add_development_dependency "rspec", "~> 3.0"
|
32
33
|
spec.add_development_dependency "rspec_junit_formatter", "~> 0.4"
|
33
34
|
spec.add_development_dependency "rubocop"
|
34
35
|
spec.add_development_dependency "simplecov"
|
36
|
+
spec.add_development_dependency "webrick"
|
37
|
+
spec.add_development_dependency "yard"
|
35
38
|
end
|
metadata
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: physical
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Martin Meyerhoff
|
8
|
-
autorequire:
|
9
8
|
bindir: bin
|
10
9
|
cert_chain: []
|
11
|
-
date:
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
12
11
|
dependencies:
|
13
12
|
- !ruby/object:Gem::Dependency
|
14
13
|
name: carmen
|
@@ -44,14 +43,14 @@ dependencies:
|
|
44
43
|
requirements:
|
45
44
|
- - "~>"
|
46
45
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
46
|
+
version: '3.0'
|
48
47
|
type: :runtime
|
49
48
|
prerelease: false
|
50
49
|
version_requirements: !ruby/object:Gem::Requirement
|
51
50
|
requirements:
|
52
51
|
- - "~>"
|
53
52
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
53
|
+
version: '3.0'
|
55
54
|
- !ruby/object:Gem::Dependency
|
56
55
|
name: money
|
57
56
|
requirement: !ruby/object:Gem::Requirement
|
@@ -100,6 +99,20 @@ dependencies:
|
|
100
99
|
- - "~>"
|
101
100
|
- !ruby/object:Gem::Version
|
102
101
|
version: '6.2'
|
102
|
+
- !ruby/object:Gem::Dependency
|
103
|
+
name: rack
|
104
|
+
requirement: !ruby/object:Gem::Requirement
|
105
|
+
requirements:
|
106
|
+
- - ">="
|
107
|
+
- !ruby/object:Gem::Version
|
108
|
+
version: '0'
|
109
|
+
type: :development
|
110
|
+
prerelease: false
|
111
|
+
version_requirements: !ruby/object:Gem::Requirement
|
112
|
+
requirements:
|
113
|
+
- - ">="
|
114
|
+
- !ruby/object:Gem::Version
|
115
|
+
version: '0'
|
103
116
|
- !ruby/object:Gem::Dependency
|
104
117
|
name: rake
|
105
118
|
requirement: !ruby/object:Gem::Requirement
|
@@ -170,6 +183,34 @@ dependencies:
|
|
170
183
|
- - ">="
|
171
184
|
- !ruby/object:Gem::Version
|
172
185
|
version: '0'
|
186
|
+
- !ruby/object:Gem::Dependency
|
187
|
+
name: webrick
|
188
|
+
requirement: !ruby/object:Gem::Requirement
|
189
|
+
requirements:
|
190
|
+
- - ">="
|
191
|
+
- !ruby/object:Gem::Version
|
192
|
+
version: '0'
|
193
|
+
type: :development
|
194
|
+
prerelease: false
|
195
|
+
version_requirements: !ruby/object:Gem::Requirement
|
196
|
+
requirements:
|
197
|
+
- - ">="
|
198
|
+
- !ruby/object:Gem::Version
|
199
|
+
version: '0'
|
200
|
+
- !ruby/object:Gem::Dependency
|
201
|
+
name: yard
|
202
|
+
requirement: !ruby/object:Gem::Requirement
|
203
|
+
requirements:
|
204
|
+
- - ">="
|
205
|
+
- !ruby/object:Gem::Version
|
206
|
+
version: '0'
|
207
|
+
type: :development
|
208
|
+
prerelease: false
|
209
|
+
version_requirements: !ruby/object:Gem::Requirement
|
210
|
+
requirements:
|
211
|
+
- - ">="
|
212
|
+
- !ruby/object:Gem::Version
|
213
|
+
version: '0'
|
173
214
|
description: A package with boxes and items
|
174
215
|
email:
|
175
216
|
- mamhoff@gmail.com
|
@@ -183,6 +224,7 @@ files:
|
|
183
224
|
- ".rubocop-relaxed.yml"
|
184
225
|
- ".rubocop.yml"
|
185
226
|
- ".travis.yml"
|
227
|
+
- ".yardopts"
|
186
228
|
- CHANGELOG.md
|
187
229
|
- CODE_OF_CONDUCT.md
|
188
230
|
- Gemfile
|
@@ -220,7 +262,6 @@ homepage: https://github.com/friendlycart/physical
|
|
220
262
|
licenses:
|
221
263
|
- MIT
|
222
264
|
metadata: {}
|
223
|
-
post_install_message:
|
224
265
|
rdoc_options: []
|
225
266
|
require_paths:
|
226
267
|
- lib
|
@@ -228,15 +269,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
228
269
|
requirements:
|
229
270
|
- - ">="
|
230
271
|
- !ruby/object:Gem::Version
|
231
|
-
version: '
|
272
|
+
version: '3.0'
|
232
273
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
233
274
|
requirements:
|
234
275
|
- - ">="
|
235
276
|
- !ruby/object:Gem::Version
|
236
277
|
version: '0'
|
237
278
|
requirements: []
|
238
|
-
rubygems_version: 3.
|
239
|
-
signing_key:
|
279
|
+
rubygems_version: 3.7.1
|
240
280
|
specification_version: 4
|
241
281
|
summary: A facade to deal with physical packages
|
242
282
|
test_files: []
|