workarea-valken-shipping 2.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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 230124e4ac5db27cfd29ae6ab6a71d79342365a0510fcf3c9c5677d72588e229
4
+ data.tar.gz: 60cd8040bc385b9b7de3ccfbae148f8662ff3756ff51ae8eef7efdfaac968f71
5
+ SHA512:
6
+ metadata.gz: c2fcd56f5131127418c269eef0322ccdc0dbd4b18eb17f6da5a2c57ab0deaae60b0a53192e87d834da77ffe8adcb561e9e6c95a5b1b10dd46c52e8ff1d9c5558
7
+ data.tar.gz: 800918f479596701f9a0c2d13884a3e94c781ad4e95047780a8c8cf30d2a4e14714bc5e19d61f0d0b0d646317e9dc43b54dd15c3cf68541400dd0f276fd9887e
@@ -0,0 +1,20 @@
1
+ Copyright 2020 sushmitha02
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,28 @@
1
+ # Valken::Shipping
2
+ Short description and motivation.
3
+
4
+ ## Usage
5
+ How to use my plugin.
6
+
7
+ ## Installation
8
+ Add this line to your application's Gemfile:
9
+
10
+ ```ruby
11
+ gem 'valken-shipping'
12
+ ```
13
+
14
+ And then execute:
15
+ ```bash
16
+ $ bundle
17
+ ```
18
+
19
+ Or install it yourself as:
20
+ ```bash
21
+ $ gem install valken-shipping
22
+ ```
23
+
24
+ ## Contributing
25
+ Contribution directions go here.
26
+
27
+ ## License
28
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
@@ -0,0 +1,29 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ require 'rdoc/task'
8
+
9
+ RDoc::Task.new(:rdoc) do |rdoc|
10
+ rdoc.rdoc_dir = 'rdoc'
11
+ rdoc.title = 'Valken::Shipping'
12
+ rdoc.options << '--line-numbers'
13
+ rdoc.rdoc_files.include('README.md')
14
+ rdoc.rdoc_files.include('lib/**/*.rb')
15
+ end
16
+
17
+ load 'rails/tasks/statistics.rake'
18
+
19
+ require 'bundler/gem_tasks'
20
+
21
+ require 'rake/testtask'
22
+
23
+ Rake::TestTask.new(:test) do |t|
24
+ t.libs << 'test'
25
+ t.pattern = 'test/**/*_test.rb'
26
+ t.verbose = false
27
+ end
28
+
29
+ task default: :test
@@ -0,0 +1,59 @@
1
+ module Workarea
2
+ module AddressesHelper
3
+ def country_options
4
+ return [[Country['US'].name, Country['US'].alpha2]] if is_usa_only?
5
+ Workarea.config.countries.map do |country|
6
+ [country.name, country.alpha2]
7
+ end
8
+ end
9
+
10
+ def region_options
11
+ @region_options ||= Workarea.config.countries.reduce([]) do |memo, country|
12
+ regions = country.subdivisions
13
+ .map { |id, region| [region.translations[I18n.locale.to_s] || region.name, id] }
14
+ .sort_by { |name, id| name || id }
15
+
16
+ memo << [country.name, regions]
17
+ memo
18
+ end
19
+ end
20
+
21
+ def is_usa_only?
22
+
23
+ orders = current_order rescue nil
24
+ return false if orders.blank? || orders.items.blank?
25
+
26
+ usa_only_attribute = Workarea.config.shipping_attributes[:usa_only]
27
+ product_attributes = orders.items.map(&:product_attributes)
28
+ return product_attributes.map{ |item| item[:details][:en][usa_only_attribute] }.flatten.include?("true")
29
+ end
30
+
31
+ def formatted_address(address)
32
+ pieces = {
33
+ recipient: "#{address.first_name} #{address.last_name}\n#{address.company}".strip,
34
+ street: "#{address.street} #{address.street_2}".strip,
35
+ city: address.city,
36
+ region: address.region_name,
37
+ region_short: address.region,
38
+ postalcode: address.postal_code,
39
+ country: address.country.alpha2
40
+ }
41
+
42
+ address_format = address.country.address_format || Country['US'].address_format
43
+ result = pieces.reduce(address_format) do |memo, (name, value)|
44
+ memo.gsub(/{{#{name}}}/, html_escape(value.to_s))
45
+ end
46
+
47
+ if address.phone_number.present?
48
+ formatted_phone = number_to_phone(
49
+ address.phone_number,
50
+ extension: address.phone_extension
51
+ )
52
+
53
+ result << "\n#{formatted_phone}"
54
+ end
55
+
56
+ result.gsub(/\n/, tag(:br)).html_safe
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,16 @@
1
+ module Workarea
2
+ decorate Checkout::ShippingOptions, with: :valken do
3
+ decorated do
4
+ class NoAvailableShippingOption < RuntimeError; end
5
+ end
6
+
7
+ def all_options
8
+ @all_options ||=
9
+ begin
10
+ packaging = Packaging.new(order, shipping)
11
+ shipping.find_method_options(order, shipping)
12
+ end
13
+ end
14
+
15
+ end
16
+ end
@@ -0,0 +1,262 @@
1
+ module Workarea
2
+ decorate Shipping, with: :valken do
3
+ decorated do
4
+ field :tracking_number, type: String
5
+ end
6
+
7
+ class_methods do
8
+ end
9
+
10
+ def order
11
+ @order
12
+ end
13
+
14
+ def shipping
15
+ @shipping
16
+ end
17
+
18
+
19
+ def default_options(packages)
20
+ return [] if address.blank? || packages.blank?
21
+ shipping_option = Workarea.config.gateways.shipping
22
+
23
+ origin = ActiveShipping::Location.new(Workarea.config.shipping_origin)
24
+ response = shipping_option.find_rates(
25
+ origin,
26
+ address.to_active_shipping,
27
+ packages
28
+ )
29
+ response.rates.sort_by(&:price).map do |rate|
30
+ ShippingOption.from_rate_estimate(rate)
31
+ end
32
+ end
33
+
34
+ def find_method_options(order, shipping)
35
+ @order ||= order
36
+ @shipping ||= shipping
37
+ carrier_data = []
38
+
39
+ packaging = Packaging.new(order, shipping)
40
+ return [] if packaging.packages.blank?
41
+
42
+ return default_options(packaging.packages) if Workarea.config.gateways.ups_carrier.class == ActiveShipping::Workarea
43
+
44
+ shipping_options_api = get_final_shipping_options(collect_carrier_data)
45
+ return [] if @error.present?
46
+
47
+ carrier_data.push(shipping_options_api) if shipping_options_api.present? && shipping_options_api.any?
48
+
49
+ if Workarea.config.gateways.ups_carrier.class != ActiveShipping::Workarea
50
+ carrier_data.push(get_ltl_shipping)
51
+ carrier_data.push(get_free_shipping) if Workarea.config.show_free_shipping
52
+ else
53
+ return []
54
+ end
55
+
56
+ carrier_data.flatten.reverse
57
+ end
58
+
59
+ def get_final_shipping_options(rates)
60
+ options = []
61
+
62
+ if is_ground
63
+ ground_rate = rates.detect{|rate| rate.service_code == "GROUND_HOME_DELIVERY" || rate.service_code == "03" }
64
+ return [] if ground_rate.blank?
65
+
66
+ description = "#{ground_rate.delivery_date.strftime('%A, %B %d, %Y')}"
67
+ days_to_deliver = (ground_rate.delivery_date - Date.today).to_i
68
+
69
+ label = Workarea.config.shipping_rates[(days_to_deliver - 1)]
70
+ return options.push(create_shipping_options(ground_rate, label, description))
71
+ end
72
+
73
+ rates.each_with_index do |rate, index|
74
+ description = "#{rate.delivery_date.strftime('%A, %B %d, %Y')}"
75
+ label = Workarea.config.shipping_rates[index]
76
+ options.push(create_shipping_options(rate, label, description))
77
+ end
78
+ options
79
+ end
80
+
81
+ # If the carrier is ups then it will print ups data...or if carrier is fedex then prinnt fedex data...
82
+ # else if it is not both then choose cheapest price.
83
+ def collect_carrier_data
84
+ return get_ups_data if is_ups
85
+ return get_fedex_data if is_fedex
86
+ return get_none_data unless is_ups && is_fedex
87
+ end
88
+
89
+ # UPS data.
90
+ def get_ups_data
91
+ @ups_options ||= get_options(Workarea.config.gateways.ups_carrier, Workarea.config.shipping_rates)
92
+ end
93
+
94
+ # FedEx data.
95
+ def get_fedex_data
96
+ @fedex_response ||= get_options(Workarea.config.gateways.fedex_carrier, Workarea.config.shipping_rates)
97
+ end
98
+
99
+ # If the product is not ups or fedex then it will choose the cheapest price among ups and fedex annd print the value.
100
+ def get_none_data
101
+ return [] if get_ups_data.blank? || get_fedex_data.blank?
102
+ final_options = []
103
+ temp_options = get_fedex_data + get_ups_data
104
+ return [] unless temp_options.any?
105
+
106
+ delivery_dates = temp_options.map(&:delivery_date).uniq.sort
107
+ delivery_dates.each_with_index do |date, index|
108
+ selected_rates = temp_options.select {|rate| rate.delivery_date == date}
109
+ final_options.push(selected_rates.sort_by(&:price).first)
110
+ end
111
+ return final_options
112
+
113
+ end
114
+
115
+ # Free shipping option.
116
+ def get_free_shipping
117
+ ShippingOption.new(
118
+ carrier: "Free Shipping",
119
+ name: "Valken Economy",
120
+ sub_name: "5 - 9 Business Days",
121
+ service_code: "Free",
122
+ price: Money.new(0.0, "USD"),
123
+ tax_code: "TAX01"
124
+ )
125
+ end
126
+
127
+ # Calculating the ltl shipping rates based on the conditions.
128
+ def get_ltl_shipping
129
+ weight_price = 0
130
+ case weight_convertion
131
+ when 0..2
132
+ weight_price = 5
133
+ when 2..15
134
+ weight_price = 15
135
+ when 15..200
136
+ weight_price = (1 * weight_convertion)
137
+ when 200..2500
138
+ weight_price = 200
139
+ else
140
+ weight_price = ((weight_convertion / 2500).ceil()) * 200
141
+ end
142
+
143
+ ShippingOption.new(
144
+ carrier: "LTL Shipping",
145
+ name: "Valken Standard",
146
+ sub_name: "3 - 5 Business Days",
147
+ service_code: "LTL01",
148
+ price: Money.new(weight_price * 100, "USD"),
149
+ tax_code: "TAX01"
150
+ )
151
+ end
152
+
153
+ # Returns the total weight.
154
+ def weight_convertion
155
+ packaging = Packaging.new(order, shipping)
156
+ return 0 if packaging.packages.blank?
157
+ full_weight = 0
158
+ packaging.packages.each do |item_package|
159
+ new_weight = item_package.weight.convert_to(:lb)
160
+ full_weight += new_weight.value
161
+ end
162
+ full_weight
163
+ end
164
+
165
+ # 1. Sending a call to carrier and get shipping rates
166
+ # 2. Based on service codes in config, filter the shipping rates
167
+ # 3. If error, return empty array
168
+ def get_options(carrier, service_code)
169
+ packaging = Packaging.new(order, shipping)
170
+ return [] if @shipping.address.blank? || packaging.packages.blank?
171
+ shipping_option = carrier || Workarea.config.gateways.shipping
172
+
173
+ origin = ActiveShipping::Location.new(Workarea.config.shipping_origin)
174
+ begin
175
+ response = shipping_option.find_rates(
176
+ origin,
177
+ @shipping.address.to_active_shipping,
178
+ packaging.packages
179
+ )
180
+ if carrier.class == ActiveShipping::Workarea
181
+ response.rates.sort_by(&:price).map do |rate|
182
+ ShippingOption.from_rate_estimate(rate)
183
+ end
184
+ else
185
+ filter_shipping_rates(response.rates, service_code)
186
+ end
187
+ rescue ActiveShipping::ResponseError => e
188
+ @error = e
189
+ return []
190
+ end
191
+ end
192
+
193
+ # Sort rates by delevry date and pick 1st three rates
194
+ # Find cheapest rate for those three rates
195
+ # Push all the cheap option for 1, 2, & 3 days into an array and return
196
+ def filter_shipping_rates(rates, service_code)
197
+ filtered_rates = []
198
+ # find and sort all delivery dates and pick 1st three
199
+ all_delivery_dates = rates.map { |rate| rate.delivery_date }
200
+ # sorting the uniq delivery dates and reversing those delivery dates.
201
+ uniq_delivery_dates = all_delivery_dates.compact.sort.uniq[0..2]
202
+
203
+ # removing overnight. Assuming the 3rd option is always overnight
204
+ uniq_delivery_dates.pop if uniq_delivery_dates.length == 3
205
+
206
+ # For each delivery dates, find cheapest rates and create shipping option and push
207
+ uniq_delivery_dates.each_with_index do |date, index|
208
+ selected_rates = rates.select {|rate| rate.delivery_date.present? && rate.delivery_date == date}
209
+ cheap_rate = selected_rates.sort_by(&:price).first
210
+ description = "#{cheap_rate.delivery_date.strftime('%A, %B %d, %Y')}"
211
+
212
+ filtered_rates.push(cheap_rate)
213
+ end
214
+ filtered_rates
215
+ end
216
+
217
+ # creating a ShippingOption
218
+ def create_shipping_options(rate, rate_label = nil, description = nil)
219
+ ShippingOption.new(
220
+ carrier: rate.carrier,
221
+ name: rate_label.keys.join || rate.service_name,
222
+ sub_name: rate_label.values.join,
223
+ service_code: rate.service_code,
224
+ description: description,
225
+ delivery_date: rate.delivery_date,
226
+ price: Money.new(rate.price, rate.currency),
227
+ tax_code: Shipping::Service.find_tax_code(
228
+ rate.carrier,
229
+ rate.service_name
230
+ )
231
+ )
232
+ end
233
+
234
+ # Selecting the shipping carrier based on order items
235
+ #
236
+ # If the product is type hazmat then it returns ups...or if product is type gun then it returns fedex
237
+ # else if product is not both type then it returns none
238
+ def is_fedex
239
+ carrier_type_attribute = Workarea.config.shipping_attributes[:carrier_type]
240
+ product_carrier_type = product_details.map{ |item| item[:en][carrier_type_attribute] }.flatten
241
+ product_carrier_type.include?("FEDEX")
242
+ end
243
+
244
+ def is_ups
245
+ carrier_type_attribute = Workarea.config.shipping_attributes[:carrier_type]
246
+ product_carrier_type = product_details.map{ |item| item[:en][carrier_type_attribute] }.flatten
247
+ product_carrier_type.include?("UPS")
248
+ end
249
+
250
+ def is_ground
251
+ ground_ship_attribute = Workarea.config.shipping_attributes[:ground_shipping_only]
252
+ product_carrier_type = product_details.map{ |item| item[:en][ground_ship_attribute] }.flatten
253
+ product_carrier_type.include?("true")
254
+ end
255
+
256
+ def product_details
257
+ # product_attributes = @order.items.map(&:product_attributes)
258
+
259
+ @product_details ||= Catalog::Product.in(id: @order.items.to_a.map(&:product_id)).pluck(:details)
260
+ end
261
+ end
262
+ end
@@ -0,0 +1,10 @@
1
+ module Workarea
2
+ decorate ShippingOption, with: :valken do
3
+ decorated do
4
+ attr_reader :description, :sub_name, :delivery_date
5
+ end
6
+
7
+ class_methods do
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,27 @@
1
+ module Workarea
2
+ decorate Packaging, with: :valken do
3
+ decorated do
4
+ end
5
+
6
+ def find_shipping_sku(sku)
7
+ shipping_skus.detect { |s| s.id == sku } || Shipping::Sku.new(id: sku, weight: find_sku_weight(sku))
8
+ end
9
+
10
+ def find_sku_weight(sku)
11
+ product_by_sku = Catalog::Product.find_by_sku(sku).variants
12
+ sku_data = product_by_sku.detect {|variant| variant.sku == sku }
13
+ sku_weight = is_pounds(sku_data) ? convert_to_lb(sku_data.weight || 0) : (sku_data.weight || 0)
14
+ sku_weight
15
+ end
16
+
17
+ def convert_to_lb(weight)
18
+ unit = Measured::Weight.new(weight, :lb)
19
+ ounce_unit = unit.convert_to(:oz)
20
+ ounce_unit.value
21
+ end
22
+
23
+ def is_pounds(sku_data)
24
+ sku_data.weight_unit == "lb"
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,12 @@
1
+ Workarea::Configuration.define_fields do
2
+ fieldset 'Shipping', namespaced: false do
3
+ field 'Shipping Attributes',
4
+ type: :hash,
5
+ default: {
6
+ 'usa_only' => 'usa only',
7
+ 'carrier_type' => 'Type',
8
+ 'ground_shipping_only' => 'ground shipping only'
9
+ },
10
+ description: 'Mapping of product details keys with shipping logic. Note: This maps only the keys not the values.'
11
+ end
12
+ end
@@ -0,0 +1,14 @@
1
+ Workarea.configure do |config|
2
+ ActiveShipping::Carriers.register :UPS, 'active_shipping/carriers/ups'
3
+
4
+ config.weight_table = {"2": 5, "15": 15, "200": 1, "2500": 200}
5
+
6
+ config.shipping_rates = [
7
+ {"Valken Overnight" => "Overnight"},
8
+ {"Valken Express 2-Day" => "2 Business Days"},
9
+ {"Valken Express 3-Day" => "3 Business Days"}
10
+ ]
11
+ config.ups_options = {"12"=> "Valken Express 3-Day", "01"=> "Valken Overnight", "02"=> "Valken Express 2-Day"}
12
+ config.fedex_options = {"STANDARD_OVERNIGHT"=> "Valken Overnight", "FEDEX_2_DAY"=> "Valken Express 2-Day", "GROUND_HOME_DELIVERY"=> "Valken Express 3-Day"}
13
+ end
14
+ Valken::Shipping.auto_initialize_gateway
@@ -0,0 +1,2 @@
1
+ Rails.application.routes.draw do
2
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :valken_shipping do
3
+ # # Task goes here
4
+ # end
@@ -0,0 +1,42 @@
1
+ require 'workarea'
2
+ require 'workarea/storefront'
3
+ require 'workarea/admin'
4
+ require "valken/shipping/engine"
5
+
6
+ module Valken
7
+ module Shipping
8
+
9
+ def self.ups_credentials
10
+ return {} unless Rails.application.secrets.ups_carrier.present?
11
+ Rails.application.secrets.ups_carrier.symbolize_keys
12
+ end
13
+
14
+ def self.fedex_credentials
15
+ return {} unless Rails.application.secrets.fedex_carrier.present?
16
+ Rails.application.secrets.fedex_carrier.symbolize_keys
17
+ end
18
+
19
+ def self.ups_gateway=(gateway)
20
+ Workarea.config.gateways.ups_carrier = gateway
21
+ end
22
+
23
+ def self.fedex_gateway=(gateway)
24
+ Workarea.config.gateways.fedex_carrier = gateway
25
+ end
26
+
27
+ def self.auto_initialize_gateway
28
+ if ups_credentials.present? && fedex_credentials.present?
29
+ if Rails.env.test?
30
+ self.ups_gateway = ActiveShipping::Workarea.new
31
+ self.fedex_gateway = ActiveShipping::Workarea.new
32
+ else
33
+ self.ups_gateway = ActiveShipping::UPS.new ups_credentials
34
+ self.fedex_gateway = ActiveShipping::FedEx.new fedex_credentials
35
+ end
36
+ else
37
+ self.ups_gateway = ActiveShipping::Workarea.new
38
+ self.fedex_gateway = ActiveShipping::Workarea.new
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,6 @@
1
+ module Valken
2
+ module Shipping
3
+ class Engine < ::Rails::Engine
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,5 @@
1
+ module Valken
2
+ module Shipping
3
+ VERSION = '2.0.0'
4
+ end
5
+ end
metadata ADDED
@@ -0,0 +1,79 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: workarea-valken-shipping
3
+ version: !ruby/object:Gem::Version
4
+ version: 2.0.0
5
+ platform: ruby
6
+ authors:
7
+ - sushmitha02
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-09-07 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 5.2.4
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 5.2.4.2
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: 5.2.4
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 5.2.4.2
33
+ description: Choosing multiple carrier shipping options
34
+ email:
35
+ - sushmitha.h@trikatechnologies.com
36
+ executables: []
37
+ extensions: []
38
+ extra_rdoc_files: []
39
+ files:
40
+ - MIT-LICENSE
41
+ - README.md
42
+ - Rakefile
43
+ - app/assets/config/valken_shipping_manifest.js
44
+ - app/helpers/workarea/addresses_helper.rb
45
+ - app/models/workarea/checkout/shipping_options.decorator
46
+ - app/models/workarea/shipping.decorator
47
+ - app/models/workarea/shipping_option.decorator
48
+ - app/services/workarea/packaging.decorator
49
+ - config/initializers/shipping_configuration.rb
50
+ - config/initializers/workarea.rb
51
+ - config/routes.rb
52
+ - lib/tasks/valken/shipping_tasks.rake
53
+ - lib/valken/shipping.rb
54
+ - lib/valken/shipping/engine.rb
55
+ - lib/valken/shipping/version.rb
56
+ homepage: https://github.com/sushmitha02
57
+ licenses:
58
+ - MIT
59
+ metadata: {}
60
+ post_install_message:
61
+ rdoc_options: []
62
+ require_paths:
63
+ - lib
64
+ required_ruby_version: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ required_rubygems_version: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ version: '0'
74
+ requirements: []
75
+ rubygems_version: 3.0.8
76
+ signing_key:
77
+ specification_version: 4
78
+ summary: shipping options
79
+ test_files: []