valken-shipping 2.0.9 → 3.0.1.pre
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/models/workarea/shipping.decorator +39 -222
- data/app/models/workarea/shipping/rate.decorator +12 -0
- data/app/models/workarea/shipping/rate_lookup.decorator +36 -0
- data/app/models/workarea/shipping/service.decorator +50 -0
- data/app/models/workarea/shipping_option.decorator +15 -0
- data/app/services/workarea/packaging.decorator +22 -2
- data/app/views/workarea/admin/shipping_services/_addtional_service_fields.html.haml +6 -0
- data/app/views/workarea/admin/shipping_services/edit.html.haml +79 -0
- data/app/views/workarea/admin/shipping_services/new.html.haml +65 -0
- data/config/initializers/appends.rb +4 -0
- data/config/initializers/shipping_configuration.rb +2 -1
- data/config/initializers/workarea.rb +3 -10
- data/lib/active_shipping/carriers/valken.rb +90 -0
- data/lib/valken/shipping.rb +5 -8
- data/lib/valken/shipping/version.rb +1 -1
- metadata +16 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a1513e4c5c0a38b69af9f422bb6312fe996faa0928dd089d42c7288a31887a28
|
4
|
+
data.tar.gz: 1af97c1da52c7408dfbe7289a4d5754f5fb41ad4c2ead8ddc76049812f26a6ee
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5d8150fc9f6cf02f0046882a65d5bdd07a5f375245834ae6474493bcfee8611f10dfff7e9a438cccc17860e897171b2046120f09aa4a97b4c337678438f5bbe7
|
7
|
+
data.tar.gz: 83c7a5f7e96bc89543c3a73552f2d20841b78e76d380f65f0d72e1b4cf963b20bfbb1b39d1a7149418506f67e0df5bc1ed712add24ba5ca4224cef47c88d327a
|
@@ -37,85 +37,28 @@ module Workarea
|
|
37
37
|
carrier_data = []
|
38
38
|
|
39
39
|
packaging = Packaging.new(order, shipping)
|
40
|
-
return [] if packaging.packages.blank?
|
40
|
+
return [] if packaging.packages.blank? || address.blank?
|
41
41
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
else
|
57
|
-
return []
|
58
|
-
end
|
59
|
-
|
60
|
-
carrier_data.flatten.reverse
|
61
|
-
end
|
62
|
-
|
63
|
-
def get_final_shipping_options(rates)
|
64
|
-
options = []
|
65
|
-
|
66
|
-
if is_ground
|
67
|
-
ground_rate = rates.detect{|rate| rate.service_code == "GROUND_HOME_DELIVERY" || rate.service_code == "03" }
|
68
|
-
return [] if ground_rate.blank?
|
69
|
-
|
70
|
-
description = "#{ground_rate.delivery_date.strftime('%A, %B %d, %Y')}"
|
71
|
-
days_to_deliver = (ground_rate.delivery_date - Date.today).to_i
|
72
|
-
|
73
|
-
label = Workarea.config.shipping_rates[(days_to_deliver - 1)]
|
74
|
-
return options.push(create_shipping_options(ground_rate, label, description))
|
75
|
-
end
|
76
|
-
|
77
|
-
rates.each_with_index do |rate, index|
|
78
|
-
description = "#{rate.delivery_date.strftime('%A, %B %d, %Y')}"
|
79
|
-
label = Workarea.config.shipping_rates[index]
|
80
|
-
options.push(create_shipping_options(rate, label, description))
|
42
|
+
shipping_option = Workarea.config.gateways.shipping
|
43
|
+
origin = ActiveShipping::Location.new(Workarea.config.shipping_origin)
|
44
|
+
response = shipping_option.find_rates(
|
45
|
+
origin,
|
46
|
+
address.to_active_shipping,
|
47
|
+
packaging.packages,
|
48
|
+
{
|
49
|
+
ground: is_ground,
|
50
|
+
special_region: is_special_region?,
|
51
|
+
free_shipping: is_free_ship
|
52
|
+
}
|
53
|
+
)
|
54
|
+
shipping_options = response.rates.sort_by(&:price).map do |rate|
|
55
|
+
ShippingOption.from_rate_estimate(rate)
|
81
56
|
end
|
82
|
-
options
|
83
|
-
end
|
84
57
|
|
85
|
-
|
86
|
-
|
87
|
-
def collect_carrier_data
|
88
|
-
return get_ups_data
|
89
|
-
# Temporarily disabling fedex and cheaper
|
90
|
-
# return get_fedex_data if is_fedex
|
91
|
-
# return get_none_data unless is_ups && is_fedex
|
58
|
+
shipping_options.unshift(get_free_shipping) if is_free_ship
|
59
|
+
shipping_options
|
92
60
|
end
|
93
61
|
|
94
|
-
# UPS data.
|
95
|
-
def get_ups_data
|
96
|
-
@ups_options ||= get_options(Workarea.config.gateways.ups_carrier, Workarea.config.shipping_rates)
|
97
|
-
end
|
98
|
-
|
99
|
-
# FedEx data.
|
100
|
-
def get_fedex_data
|
101
|
-
@fedex_response ||= get_options(Workarea.config.gateways.fedex_carrier, Workarea.config.shipping_rates)
|
102
|
-
end
|
103
|
-
|
104
|
-
# If the product is not ups or fedex then it will choose the cheapest price among ups and fedex annd print the value.
|
105
|
-
def get_none_data
|
106
|
-
return [] if get_ups_data.blank? || get_fedex_data.blank?
|
107
|
-
final_options = []
|
108
|
-
temp_options = get_fedex_data + get_ups_data
|
109
|
-
return [] unless temp_options.any?
|
110
|
-
|
111
|
-
delivery_dates = temp_options.map(&:delivery_date).uniq.sort
|
112
|
-
delivery_dates.each_with_index do |date, index|
|
113
|
-
selected_rates = temp_options.select {|rate| rate.delivery_date == date}
|
114
|
-
final_options.push(selected_rates.sort_by(&:price).first)
|
115
|
-
end
|
116
|
-
return final_options
|
117
|
-
|
118
|
-
end
|
119
62
|
|
120
63
|
# Free shipping option.
|
121
64
|
def get_free_shipping
|
@@ -124,158 +67,11 @@ module Workarea
|
|
124
67
|
name: "Valken Economy",
|
125
68
|
sub_name: "5 - 9 Business Days",
|
126
69
|
service_code: "Free",
|
127
|
-
price: Money.new(0.0,
|
128
|
-
tax_code: "TAX01"
|
129
|
-
)
|
130
|
-
end
|
131
|
-
|
132
|
-
# Calculating the ltl shipping rates based on the conditions.
|
133
|
-
def get_ltl_shipping
|
134
|
-
weight_price = 0
|
135
|
-
case weight_convertion
|
136
|
-
when 0..2
|
137
|
-
weight_price = 5
|
138
|
-
when 2..15
|
139
|
-
weight_price = 15
|
140
|
-
when 15..200
|
141
|
-
weight_price = (1 * weight_convertion)
|
142
|
-
when 200..2500
|
143
|
-
weight_price = 200
|
144
|
-
else
|
145
|
-
weight_price = ((weight_convertion / 2500).ceil()) * 200
|
146
|
-
end
|
147
|
-
|
148
|
-
ShippingOption.new(
|
149
|
-
carrier: "LTL Shipping",
|
150
|
-
name: "Valken Standard",
|
151
|
-
sub_name: "3 - 5 Business Days",
|
152
|
-
service_code: "LTL01",
|
153
|
-
price: Money.new(weight_price * 100, "USD"),
|
70
|
+
price: Money.new(0.0, Money.default_currency.to_s),
|
154
71
|
tax_code: "TAX01"
|
155
72
|
)
|
156
73
|
end
|
157
74
|
|
158
|
-
def get_shipping_for_special_region
|
159
|
-
puts "weight_convertion",weight_convertion
|
160
|
-
weight_price = 0
|
161
|
-
case weight_convertion
|
162
|
-
when 0..15
|
163
|
-
weight_price = 50
|
164
|
-
when 15..200
|
165
|
-
weight_price = (1 * weight_convertion)
|
166
|
-
when 200..2500
|
167
|
-
weight_price = 200
|
168
|
-
else
|
169
|
-
weight_price = ((weight_convertion / 2500).ceil()) * 200
|
170
|
-
end
|
171
|
-
|
172
|
-
ShippingOption.new(
|
173
|
-
carrier: "LTL Shipping",
|
174
|
-
name: "Valken Standard",
|
175
|
-
sub_name: "3 - 5 Business Days",
|
176
|
-
service_code: "LTL01",
|
177
|
-
price: Money.new(weight_price * 100, "USD"),
|
178
|
-
tax_code: "TAX01"
|
179
|
-
)
|
180
|
-
end
|
181
|
-
|
182
|
-
# Returns the total weight.
|
183
|
-
def weight_convertion
|
184
|
-
packaging = Packaging.new(order, shipping)
|
185
|
-
return 0 if packaging.packages.blank?
|
186
|
-
full_weight = 0
|
187
|
-
packaging.packages.each do |item_package|
|
188
|
-
new_weight = item_package.weight.convert_to(:lb)
|
189
|
-
full_weight += new_weight.value
|
190
|
-
end
|
191
|
-
full_weight
|
192
|
-
end
|
193
|
-
|
194
|
-
# 1. Sending a call to carrier and get shipping rates
|
195
|
-
# 2. Based on service codes in config, filter the shipping rates
|
196
|
-
# 3. If error, return empty array
|
197
|
-
def get_options(carrier, service_code)
|
198
|
-
packaging = Packaging.new(order, shipping)
|
199
|
-
return [] if @shipping.address.blank? || packaging.packages.blank?
|
200
|
-
shipping_option = carrier || Workarea.config.gateways.shipping
|
201
|
-
|
202
|
-
origin = ActiveShipping::Location.new(Workarea.config.shipping_origin)
|
203
|
-
begin
|
204
|
-
response = shipping_option.find_rates(
|
205
|
-
origin,
|
206
|
-
@shipping.address.to_active_shipping,
|
207
|
-
packaging.packages
|
208
|
-
)
|
209
|
-
if carrier.class == ActiveShipping::Workarea
|
210
|
-
response.rates.sort_by(&:price).map do |rate|
|
211
|
-
ShippingOption.from_rate_estimate(rate)
|
212
|
-
end
|
213
|
-
else
|
214
|
-
filter_shipping_rates(response.rates, service_code)
|
215
|
-
end
|
216
|
-
rescue ActiveShipping::ResponseError => e
|
217
|
-
@error = e
|
218
|
-
return []
|
219
|
-
end
|
220
|
-
end
|
221
|
-
|
222
|
-
# Sort rates by delevry date and pick 1st three rates
|
223
|
-
# Find cheapest rate for those three rates
|
224
|
-
# Push all the cheap option for 1, 2, & 3 days into an array and return
|
225
|
-
def filter_shipping_rates(rates, service_code)
|
226
|
-
filtered_rates = []
|
227
|
-
# find and sort all delivery dates and pick 1st three
|
228
|
-
all_delivery_dates = rates.map { |rate| rate.delivery_date }
|
229
|
-
# sorting the uniq delivery dates and reversing those delivery dates.
|
230
|
-
uniq_delivery_dates = all_delivery_dates.compact.sort.uniq[0..2]
|
231
|
-
|
232
|
-
# removing overnight. Assuming the 3rd option is always overnight
|
233
|
-
uniq_delivery_dates.pop if uniq_delivery_dates.length == 3
|
234
|
-
|
235
|
-
# For each delivery dates, find cheapest rates and create shipping option and push
|
236
|
-
uniq_delivery_dates.each_with_index do |date, index|
|
237
|
-
selected_rates = rates.select {|rate| rate.delivery_date.present? && rate.delivery_date == date}
|
238
|
-
cheap_rate = selected_rates.sort_by(&:price).first
|
239
|
-
description = "#{cheap_rate.delivery_date.strftime('%A, %B %d, %Y')}"
|
240
|
-
|
241
|
-
filtered_rates.push(cheap_rate)
|
242
|
-
end
|
243
|
-
filtered_rates
|
244
|
-
end
|
245
|
-
|
246
|
-
# creating a ShippingOption
|
247
|
-
def create_shipping_options(rate, rate_label = nil, description = nil)
|
248
|
-
ShippingOption.new(
|
249
|
-
carrier: rate.carrier,
|
250
|
-
name: rate_label.keys.join || rate.service_name,
|
251
|
-
sub_name: rate_label.values.join,
|
252
|
-
service_code: rate.service_code,
|
253
|
-
description: description,
|
254
|
-
delivery_date: rate.delivery_date,
|
255
|
-
price: Money.new(rate.price, rate.currency),
|
256
|
-
tax_code: Shipping::Service.find_tax_code(
|
257
|
-
rate.carrier,
|
258
|
-
rate.service_name
|
259
|
-
)
|
260
|
-
)
|
261
|
-
end
|
262
|
-
|
263
|
-
# Selecting the shipping carrier based on order items
|
264
|
-
#
|
265
|
-
# If the product is type hazmat then it returns ups...or if product is type gun then it returns fedex
|
266
|
-
# else if product is not both type then it returns none
|
267
|
-
def is_fedex
|
268
|
-
carrier_type_attribute = Workarea.config.shipping_attributes[:carrier_type]
|
269
|
-
product_carrier_type = product_details.map{ |item| item[:en][carrier_type_attribute] }.flatten
|
270
|
-
product_carrier_type.include?("FEDEX")
|
271
|
-
end
|
272
|
-
|
273
|
-
def is_ups
|
274
|
-
carrier_type_attribute = Workarea.config.shipping_attributes[:carrier_type]
|
275
|
-
product_carrier_type = product_details.map{ |item| item[:en][carrier_type_attribute] }.flatten
|
276
|
-
product_carrier_type.include?("UPS")
|
277
|
-
end
|
278
|
-
|
279
75
|
def is_ground
|
280
76
|
ground_ship_attribute = Workarea.config.shipping_attributes[:ground_shipping_only]
|
281
77
|
product_carrier_type = product_details.map{ |item| item[:en][ground_ship_attribute] }.flatten
|
@@ -286,6 +82,27 @@ module Workarea
|
|
286
82
|
Workarea.config.special_region.include?(@shipping.address.region)
|
287
83
|
end
|
288
84
|
|
85
|
+
# if any of the product is NO FREE SHIPPING = TRUE then return false
|
86
|
+
# if free shipping config is then return true
|
87
|
+
# if user applies free shipping promo code then return true
|
88
|
+
def is_free_ship
|
89
|
+
free_ship_attribute = Workarea.config.shipping_attributes[:no_free_shipping]
|
90
|
+
product_carrier_type = product_details.map{ |item| item[:en][free_ship_attribute] }.flatten
|
91
|
+
return false if product_carrier_type.include?("true")
|
92
|
+
|
93
|
+
return true if Workarea.config.show_free_shipping
|
94
|
+
|
95
|
+
test_order = order.clone
|
96
|
+
test_shipping = shipping.clone
|
97
|
+
test_shipping.apply_shipping_service(get_free_shipping.to_h)
|
98
|
+
|
99
|
+
price_adjustments = Pricing.find_shipping_discounts(
|
100
|
+
test_order,
|
101
|
+
test_shipping
|
102
|
+
)
|
103
|
+
return price_adjustments.present? && price_adjustments.any?
|
104
|
+
end
|
105
|
+
|
289
106
|
def product_details
|
290
107
|
# product_attributes = @order.items.map(&:product_attributes)
|
291
108
|
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module Workarea
|
2
|
+
decorate Shipping::Rate, with: :valken_shipping do
|
3
|
+
decorated do
|
4
|
+
field :tier_weight_min, type: Float
|
5
|
+
field :tier_weight_max, type: Float
|
6
|
+
end
|
7
|
+
|
8
|
+
def weight_tiered?
|
9
|
+
!tier_weight_min.nil? || !tier_weight_max.nil?
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Workarea
|
2
|
+
decorate Shipping::RateLookup, with: :valken_shipping do
|
3
|
+
|
4
|
+
def total_weight
|
5
|
+
full_weight = 0
|
6
|
+
packages.each do |item_package|
|
7
|
+
new_weight = item_package.weight.convert_to(:lb)
|
8
|
+
full_weight += new_weight.value
|
9
|
+
end
|
10
|
+
full_weight
|
11
|
+
end
|
12
|
+
|
13
|
+
def response
|
14
|
+
ActiveShipping::RateResponse.new(
|
15
|
+
true, # success
|
16
|
+
'success', # message
|
17
|
+
{}, # params
|
18
|
+
rates: valid_services.map do |service|
|
19
|
+
total = service.find_rate(subtotal, total_weight).try(:price)
|
20
|
+
next unless total.present?
|
21
|
+
|
22
|
+
ActiveShipping::RateEstimate.new(
|
23
|
+
origin,
|
24
|
+
destination,
|
25
|
+
service.carrier,
|
26
|
+
service.name,
|
27
|
+
description: service.description,
|
28
|
+
service_code: service.service_code,
|
29
|
+
total_price: total.cents,
|
30
|
+
currency: total.currency.to_s
|
31
|
+
)
|
32
|
+
end.compact
|
33
|
+
)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module Workarea
|
2
|
+
decorate Shipping::Service, with: :valken_shipping do
|
3
|
+
decorated do
|
4
|
+
field :description, type: String
|
5
|
+
end
|
6
|
+
|
7
|
+
def find_rate(price = 0.to_m, weight = 0)
|
8
|
+
if tiered? && weight_tiered?
|
9
|
+
rates.detect do |rate|
|
10
|
+
(rate.tier_min.nil? || rate.tier_min <= price) &&
|
11
|
+
(rate.tier_max.nil? || rate.tier_max >= price) &&
|
12
|
+
(rate.tier_weight_min.nil? || rate.tier_weight_min <= weight) &&
|
13
|
+
(rate.tier_weight_max.nil? || rate.tier_weight_max >= weight)
|
14
|
+
end
|
15
|
+
elsif weight_tiered?
|
16
|
+
rates.detect do |rate|
|
17
|
+
(rate.tier_weight_min.nil? || rate.tier_weight_min <= weight) &&
|
18
|
+
(rate.tier_weight_max.nil? || rate.tier_weight_max >= weight)
|
19
|
+
end
|
20
|
+
elsif tiered?
|
21
|
+
rates.detect do |rate|
|
22
|
+
(rate.tier_min.nil? || rate.tier_min <= price) &&
|
23
|
+
(rate.tier_max.nil? || rate.tier_max >= price)
|
24
|
+
end
|
25
|
+
else
|
26
|
+
rates.first
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def tiered?
|
31
|
+
rates.any?(&:tiered?)
|
32
|
+
end
|
33
|
+
|
34
|
+
def weight_tiered?
|
35
|
+
rates.any?(&:weight_tiered?)
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
def rate_tiering
|
40
|
+
non_tiered_rates = rates.reject(&:tiered?).reject(&:weight_tiered?)
|
41
|
+
|
42
|
+
if non_tiered_rates.length > 1
|
43
|
+
errors.add(
|
44
|
+
:rates,
|
45
|
+
I18n.t('workarea.errors.messages.exceeds_non_tiered_rate_limit')
|
46
|
+
)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -5,6 +5,21 @@ module Workarea
|
|
5
5
|
end
|
6
6
|
|
7
7
|
class_methods do
|
8
|
+
def from_rate_estimate(rate)
|
9
|
+
new(
|
10
|
+
carrier: rate.carrier,
|
11
|
+
name: rate.service_name,
|
12
|
+
service_code: rate.service_code,
|
13
|
+
price: Money.new(rate.price, rate.currency),
|
14
|
+
tax_code: Shipping::Service.find_tax_code(
|
15
|
+
rate.carrier,
|
16
|
+
rate.service_name
|
17
|
+
),
|
18
|
+
sub_name: rate.description,
|
19
|
+
description: rate.delivery_date&.strftime('%A, %B %d, %Y'),
|
20
|
+
delivery_date: rate.delivery_date
|
21
|
+
)
|
22
|
+
end
|
8
23
|
end
|
9
24
|
end
|
10
25
|
end
|
@@ -3,6 +3,22 @@ module Workarea
|
|
3
3
|
decorated do
|
4
4
|
end
|
5
5
|
|
6
|
+
def packages
|
7
|
+
Array(1..no_of_packs).map do |i|
|
8
|
+
ActiveShipping::Package.new(
|
9
|
+
Measured::Weight.new(total_weight_lb/no_of_packs, :lb),
|
10
|
+
total_dimensions,
|
11
|
+
Workarea.config.shipping_options.merge(value: total_value)
|
12
|
+
)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def no_of_packs
|
17
|
+
packs_count = (total_weight_lb / Workarea.config.max_weight_per_pack).ceil
|
18
|
+
|
19
|
+
return packs_count == 0 ? 1 : packs_count
|
20
|
+
end
|
21
|
+
|
6
22
|
def find_shipping_sku(sku)
|
7
23
|
shipping_skus.detect { |s| s.id == sku } || Shipping::Sku.new(id: sku, weight: find_sku_weight(sku))
|
8
24
|
end
|
@@ -10,16 +26,20 @@ module Workarea
|
|
10
26
|
def find_sku_weight(sku)
|
11
27
|
product_by_sku = Catalog::Product.find_by_sku(sku).variants
|
12
28
|
sku_data = product_by_sku.detect {|variant| variant.sku == sku }
|
13
|
-
sku_weight = is_pounds(sku_data) ?
|
29
|
+
sku_weight = is_pounds(sku_data) ? convert_to_oz(sku_data.weight || 1) : (sku_data.weight || 1)
|
14
30
|
sku_weight
|
15
31
|
end
|
16
32
|
|
17
|
-
def
|
33
|
+
def convert_to_oz(weight)
|
18
34
|
unit = Measured::Weight.new(weight, :lb)
|
19
35
|
ounce_unit = unit.convert_to(:oz)
|
20
36
|
ounce_unit.value
|
21
37
|
end
|
22
38
|
|
39
|
+
def total_weight_lb
|
40
|
+
@total_weight_lb ||= Measured::Weight.new(total_weight, :oz).convert_to(:lb).value
|
41
|
+
end
|
42
|
+
|
23
43
|
def is_pounds(sku_data)
|
24
44
|
sku_data.weight_unit == "lb"
|
25
45
|
end
|
@@ -0,0 +1,6 @@
|
|
1
|
+
.property
|
2
|
+
= label_tag 'service_description', "Carrier Name", class: 'property__name'
|
3
|
+
= text_field_tag "service[carrier]", @service.carrier, class: 'text-box'
|
4
|
+
.property
|
5
|
+
= label_tag 'service_description', "Description", class: 'property__name'
|
6
|
+
= text_field_tag "service[description]", @service.description, class: 'text-box'
|
@@ -0,0 +1,79 @@
|
|
1
|
+
- @page_title = t('workarea.admin.shipping_services.edit.title', service: @service.name)
|
2
|
+
|
3
|
+
.view
|
4
|
+
.view__header
|
5
|
+
.grid.grid--middle.grid--center
|
6
|
+
.grid__cell.grid__cell--50
|
7
|
+
.view__heading
|
8
|
+
= link_to_index_for(@service)
|
9
|
+
%h1= @service.name
|
10
|
+
|
11
|
+
.view__container
|
12
|
+
- if @service.errors.present?
|
13
|
+
- @service.errors.full_messages.each do |message|
|
14
|
+
= render_message 'error', message
|
15
|
+
|
16
|
+
= form_tag shipping_service_path(@service), method: :patch, id: 'shipping_service_form', data: { unsaved_changes: '' } do
|
17
|
+
|
18
|
+
.section
|
19
|
+
|
20
|
+
.property.property--required
|
21
|
+
= label_tag 'service_name', t('workarea.admin.fields.name'), class: 'property__name'
|
22
|
+
= text_field_tag 'service[name]', @service.name, class: 'text-box text-box--i18n', required: true
|
23
|
+
|
24
|
+
.property
|
25
|
+
= label_tag 'service_tax_code', t('workarea.admin.fields.tax_code'), class: 'property__name'
|
26
|
+
= text_field_tag 'service[tax_code]', @service.tax_code, class: 'text-box'
|
27
|
+
|
28
|
+
.property
|
29
|
+
= label_tag 'service_service_code', t('workarea.admin.fields.service_code'), class: 'property__name'
|
30
|
+
= text_field_tag 'service[service_code]', @service.service_code, class: 'text-box'
|
31
|
+
|
32
|
+
.property
|
33
|
+
= label_tag 'service_country', t('workarea.admin.fields.country'), class: 'property__name'
|
34
|
+
= select_tag "service[country]", options_for_select(country_options, @service.country.try(:alpha2)), prompt: t('workarea.admin.shipping_services.options.not_specified')
|
35
|
+
|
36
|
+
.property
|
37
|
+
= label_tag 'service_regions', t('workarea.admin.fields.regions'), class: 'property__name'
|
38
|
+
= text_field_tag "service[regions_list]", @service.regions_list, class: 'text-box'
|
39
|
+
%span.property__note= t('workarea.admin.shipping_services.regions_note')
|
40
|
+
|
41
|
+
= append_partials('admin.shipping_service_fields', service: @service)
|
42
|
+
|
43
|
+
.section
|
44
|
+
|
45
|
+
%h2= t('workarea.admin.shipping_services.shipping_rates.title')
|
46
|
+
|
47
|
+
%table
|
48
|
+
%thead
|
49
|
+
%tr
|
50
|
+
%th= t('workarea.admin.shipping_services.shipping_rates.price')
|
51
|
+
%th= "Min Weight (lb)"
|
52
|
+
%th= "Max Weight (lb)"
|
53
|
+
%th= t('workarea.admin.shipping_services.shipping_rates.min_value')
|
54
|
+
%th= t('workarea.admin.shipping_services.shipping_rates.max_value')
|
55
|
+
%th= t('workarea.admin.actions.remove')
|
56
|
+
%tbody
|
57
|
+
- @service.rates.each do |rate|
|
58
|
+
%tr
|
59
|
+
%td=text_field_tag "rates[#{rate.id}][price]", rate.price, class: 'text-box'
|
60
|
+
%td= text_field_tag "rates[#{rate.id}][tier_weight_min]", rate.tier_weight_min, class: 'text-box'
|
61
|
+
%td= text_field_tag "rates[#{rate.id}][tier_weight_max]", rate.tier_weight_max, class: 'text-box'
|
62
|
+
%td= text_field_tag "rates[#{rate.id}][tier_min]", rate.tier_min, class: 'text-box'
|
63
|
+
%td= text_field_tag "rates[#{rate.id}][tier_max]", rate.tier_max, class: 'text-box'
|
64
|
+
%td= check_box_tag 'rates_to_remove[]', rate.id
|
65
|
+
%tr{ data: { cloneable_row: '' } }
|
66
|
+
%td= text_field_tag 'new_rates[][price]', '', placeholder: 'New Price Tier', class: 'text-box'
|
67
|
+
%td= text_field_tag 'new_rates[][tier_weight_min]', '', placeholder: 'Min Weight Value', class: 'text-box'
|
68
|
+
%td= text_field_tag 'new_rates[][tier_weight_max]', '', placeholder: 'Max Weight Value', class: 'text-box'
|
69
|
+
%td= text_field_tag 'new_rates[][tier_min]', '', placeholder: 'Min Value', class: 'text-box'
|
70
|
+
%td= text_field_tag 'new_rates[][tier_min]', '', placeholder: 'Min Value', class: 'text-box'
|
71
|
+
%td
|
72
|
+
|
73
|
+
.workflow-bar
|
74
|
+
.grid
|
75
|
+
.grid__cell.grid__cell--50
|
76
|
+
= link_to t('workarea.admin.actions.delete'), shipping_service_path(@service), class: 'workflow-bar__button workflow-bar__button--delete', data: { method: 'delete', confirm: t('workarea.admin.actions.delete_confirmation') }
|
77
|
+
.grid__cell.grid__cell--50
|
78
|
+
.align-right
|
79
|
+
= button_tag t('workarea.admin.shipping_services.edit.button'), value: 'save_shipping_service', class: 'workflow-bar__button workflow-bar__button--update'
|
@@ -0,0 +1,65 @@
|
|
1
|
+
- @page_title = t('workarea.admin.shipping_services.new.title')
|
2
|
+
|
3
|
+
.view
|
4
|
+
.view__header
|
5
|
+
.grid.grid--middle.grid--center
|
6
|
+
.grid__cell.grid__cell--50
|
7
|
+
.view__heading
|
8
|
+
= link_to_index_for(@service)
|
9
|
+
%h1= t('workarea.admin.shipping_services.new.title')
|
10
|
+
|
11
|
+
.view__container
|
12
|
+
- if @service.errors.present?
|
13
|
+
- @service.errors.full_messages.each do |message|
|
14
|
+
= render_message 'error', message
|
15
|
+
|
16
|
+
= form_tag shipping_services_path(@service), method: :post, id: 'shipping_service_form', data: { unsaved_changes: '' } do
|
17
|
+
|
18
|
+
.section
|
19
|
+
|
20
|
+
.property.property--required
|
21
|
+
= label_tag 'service_name', t('workarea.admin.fields.name'), class: 'property__name'
|
22
|
+
= text_field_tag 'service[name]', @service.name, class: 'text-box text-box--i18n', required: true
|
23
|
+
|
24
|
+
.property
|
25
|
+
= label_tag 'service_tax_code', t('workarea.admin.fields.tax_code'), class: 'property__name'
|
26
|
+
= text_field_tag 'service[tax_code]', @service.tax_code, class: 'text-box'
|
27
|
+
|
28
|
+
.property
|
29
|
+
= label_tag 'service_service_code', t('workarea.admin.fields.service_code'), class: 'property__name'
|
30
|
+
= text_field_tag 'service[service_code]', @service.service_code, class: 'text-box'
|
31
|
+
|
32
|
+
.property
|
33
|
+
= label_tag 'service_country', t('workarea.admin.fields.country'), class: 'property__name'
|
34
|
+
= select_tag "service[country]", options_for_select(country_options, @service.country.try(:alpha2)), prompt: t('workarea.admin.shipping_services.options.not_specified')
|
35
|
+
|
36
|
+
.property
|
37
|
+
= label_tag 'service_regions', t('workarea.admin.fields.regions'), class: 'property__name'
|
38
|
+
= text_field_tag "service[regions_list]", @service.regions_list, class: 'text-box'
|
39
|
+
%span.property__note= t('workarea.admin.shipping_services.regions_note')
|
40
|
+
|
41
|
+
= append_partials('admin.shipping_service_fields', service: @service)
|
42
|
+
|
43
|
+
.section
|
44
|
+
|
45
|
+
%h2= t('workarea.admin.shipping_services.shipping_rates.title')
|
46
|
+
|
47
|
+
%table
|
48
|
+
%thead
|
49
|
+
%tr
|
50
|
+
%th= t('workarea.admin.shipping_services.shipping_rates.price')
|
51
|
+
%th= "Min Weight (lb)"
|
52
|
+
%th= "Max Weight (lb)"
|
53
|
+
%th= t('workarea.admin.shipping_services.shipping_rates.min_value')
|
54
|
+
%th= t('workarea.admin.shipping_services.shipping_rates.max_value')
|
55
|
+
%tbody
|
56
|
+
%tr{ data: { cloneable_row: '' } }
|
57
|
+
%td= text_field_tag 'new_rates[][price]', '', placeholder: 'New Price Tier', class: 'text-box', title: 'New Price Tier'
|
58
|
+
%td= text_field_tag 'new_rates[][tier_weight_min]', '', placeholder: 'Min Weight Value', class: 'text-box'
|
59
|
+
%td= text_field_tag 'new_rates[][tier_weight_max]', '', placeholder: 'Max Weight Value', class: 'text-box'
|
60
|
+
%td= text_field_tag 'new_rates[][tier_min]', '', placeholder: 'Min Value', class: 'text-box', title: 'Min Value'
|
61
|
+
%td= text_field_tag 'new_rates[][tier_max]', '', placeholder: 'Max Value', class: 'text-box', title: 'Max Value'
|
62
|
+
|
63
|
+
.workflow-bar
|
64
|
+
.grid.grid--auto.grid--right.grid--middle
|
65
|
+
.grid__cell= button_tag t('workarea.admin.shipping_services.new.create_shipping_service'), value: 'create_shipping_service', class: 'workflow-bar__button workflow-bar__button--create'
|
@@ -5,7 +5,8 @@ Workarea::Configuration.define_fields do
|
|
5
5
|
default: {
|
6
6
|
'usa_only' => 'usa only',
|
7
7
|
'carrier_type' => 'Type',
|
8
|
-
'ground_shipping_only' => 'ground shipping only'
|
8
|
+
'ground_shipping_only' => 'ground shipping only',
|
9
|
+
'no_free_shipping' => 'no free shipping'
|
9
10
|
},
|
10
11
|
description: 'Mapping of product details keys with shipping logic. Note: This maps only the keys not the values.'
|
11
12
|
|
@@ -1,17 +1,10 @@
|
|
1
1
|
Workarea.configure do |config|
|
2
2
|
|
3
|
-
config.countries = [Country['US']]
|
3
|
+
config.countries = [Country['US'], Country['CA']]
|
4
4
|
|
5
5
|
ActiveShipping::Carriers.register :UPS, 'active_shipping/carriers/ups'
|
6
|
+
ActiveShipping::Carriers.register :VALKEN, 'active_shipping/carriers/valken'
|
6
7
|
|
7
|
-
config.
|
8
|
-
|
9
|
-
config.shipping_rates = [
|
10
|
-
{"Valken Overnight" => "Overnight"},
|
11
|
-
{"Valken Express 2-Day" => "2 Business Days"},
|
12
|
-
{"Valken Express 3-Day" => "3 Business Days"}
|
13
|
-
]
|
14
|
-
config.ups_options = {"12"=> "Valken Express 3-Day", "01"=> "Valken Overnight", "02"=> "Valken Express 2-Day"}
|
15
|
-
config.fedex_options = {"STANDARD_OVERNIGHT"=> "Valken Overnight", "FEDEX_2_DAY"=> "Valken Express 2-Day", "GROUND_HOME_DELIVERY"=> "Valken Express 3-Day"}
|
8
|
+
config.max_weight_per_pack = 150
|
16
9
|
end
|
17
10
|
Valken::Shipping.auto_initialize_gateway
|
@@ -0,0 +1,90 @@
|
|
1
|
+
require 'active_shipping'
|
2
|
+
|
3
|
+
module ActiveShipping
|
4
|
+
class VALKEN < UPS
|
5
|
+
|
6
|
+
def find_rates(origin, destination, packages, options = {})
|
7
|
+
return get_workarea_rates(origin, destination, packages, options) if options[:ground]
|
8
|
+
super
|
9
|
+
end
|
10
|
+
|
11
|
+
def parse_rate_response(origin, destination, packages, response, options = {})
|
12
|
+
xml = build_document(response, 'RatingServiceSelectionResponse')
|
13
|
+
success = response_success?(xml)
|
14
|
+
message = response_message(xml)
|
15
|
+
filtered_rates = []
|
16
|
+
if success
|
17
|
+
rate_estimates = xml.root.css('> RatedShipment').map do |rated_shipment|
|
18
|
+
service_code = rated_shipment.at('Service/Code').text
|
19
|
+
days_to_delivery = rated_shipment.at('GuaranteedDaysToDelivery').text.to_i
|
20
|
+
days_to_delivery = nil if days_to_delivery == 0
|
21
|
+
warning_messages = rate_warning_messages(rated_shipment)
|
22
|
+
RateEstimate.new(origin, destination, @@name, service_name_for(origin, service_code),
|
23
|
+
total_price: rated_shipment.at('TotalCharges/MonetaryValue').text.to_f,
|
24
|
+
insurance_price: rated_shipment.at('ServiceOptionsCharges/MonetaryValue').text.to_f,
|
25
|
+
currency: rated_shipment.at('TotalCharges/CurrencyCode').text,
|
26
|
+
service_code: service_code,
|
27
|
+
packages: packages,
|
28
|
+
delivery_range: [timestamp_from_business_day(days_to_delivery)],
|
29
|
+
negotiated_rate: rated_shipment.at('NegotiatedRates/NetSummaryCharges/GrandTotal/MonetaryValue').try(:text).to_f,
|
30
|
+
messages: warning_messages
|
31
|
+
)
|
32
|
+
end
|
33
|
+
filtered_rates = filter_rates(rate_estimates)
|
34
|
+
end
|
35
|
+
|
36
|
+
workarea_rates = get_workarea_services(origin, destination, packages, options).rates
|
37
|
+
if message == "Failure: Maximum number of packages exceeded (200)"
|
38
|
+
RateResponse.new(true, "Only workarea shipping service", {}, rates: workarea_rates, xml: "", request: "")
|
39
|
+
else
|
40
|
+
RateResponse.new(success, message, Hash.from_xml(response).values.first, rates:(filtered_rates + workarea_rates).flatten, xml: response, request: last_request)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def get_workarea_services(*args)
|
45
|
+
::Workarea::Shipping::RateLookup.new(*args).response
|
46
|
+
end
|
47
|
+
|
48
|
+
def filter_rates(rates)
|
49
|
+
filtered_rates = []
|
50
|
+
# find and sort all delivery dates and pick 1st three
|
51
|
+
all_delivery_dates = rates.map { |rate| rate.delivery_date }
|
52
|
+
# sorting the uniq delivery dates and reversing those delivery dates.
|
53
|
+
uniq_delivery_dates = all_delivery_dates.compact.sort.uniq[0..2]
|
54
|
+
|
55
|
+
# For each delivery dates, find cheapest rates and create shipping option and push
|
56
|
+
uniq_delivery_dates.each_with_index do |date, index|
|
57
|
+
selected_rates = rates.select {|rate| rate.delivery_date.present? && rate.delivery_date == date}
|
58
|
+
cheap_rate = selected_rates.sort_by(&:price).first
|
59
|
+
filtered_rates.push(cheap_rate)
|
60
|
+
end
|
61
|
+
|
62
|
+
if filtered_rates[-1].present?
|
63
|
+
filtered_rates[-1].service_name = "Valken Express 3-Day"
|
64
|
+
filtered_rates[-1].description = "3 Business Days"
|
65
|
+
end
|
66
|
+
|
67
|
+
if filtered_rates[-2].present?
|
68
|
+
filtered_rates[-2].service_name = "Valken Express 2-Day"
|
69
|
+
filtered_rates[-2].description = "2 Business Days"
|
70
|
+
end
|
71
|
+
|
72
|
+
if filtered_rates[-3].present?
|
73
|
+
filtered_rates[-3].service_name = "Valken Overnight"
|
74
|
+
filtered_rates[-3].description = "Overnight"
|
75
|
+
end
|
76
|
+
|
77
|
+
return filtered_rates
|
78
|
+
end
|
79
|
+
|
80
|
+
def weight_convertion(packages)
|
81
|
+
full_weight = 0
|
82
|
+
packages.each do |item_package|
|
83
|
+
new_weight = item_package.weight.convert_to(:lb)
|
84
|
+
full_weight += new_weight.value
|
85
|
+
end
|
86
|
+
full_weight
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
90
|
+
end
|
data/lib/valken/shipping.rb
CHANGED
@@ -24,18 +24,15 @@ module Valken
|
|
24
24
|
Workarea.config.gateways.fedex_carrier = gateway
|
25
25
|
end
|
26
26
|
|
27
|
-
def self.auto_initialize_gateway
|
28
|
-
if ups_credentials.present? &&
|
27
|
+
def self.auto_initialize_gateway
|
28
|
+
if ups_credentials.present? && !Workarea.config.default_shipping
|
29
29
|
if Rails.env.test?
|
30
|
-
|
31
|
-
self.fedex_gateway = ActiveShipping::Workarea.new
|
30
|
+
Workarea.config.gateways.shipping = ActiveShipping::Workarea.new
|
32
31
|
else
|
33
|
-
|
34
|
-
self.fedex_gateway = ActiveShipping::FedEx.new fedex_credentials
|
32
|
+
Workarea.config.gateways.shipping = ActiveShipping::VALKEN.new ups_credentials
|
35
33
|
end
|
36
34
|
else
|
37
|
-
|
38
|
-
self.fedex_gateway = ActiveShipping::Workarea.new
|
35
|
+
Workarea.config.gateways.shipping = ActiveShipping::Workarea.new
|
39
36
|
end
|
40
37
|
end
|
41
38
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: valken-shipping
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 3.0.1.pre
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- sushmitha02
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-12-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -44,11 +44,19 @@ files:
|
|
44
44
|
- app/helpers/workarea/addresses_helper.rb
|
45
45
|
- app/models/workarea/checkout/shipping_options.decorator
|
46
46
|
- app/models/workarea/shipping.decorator
|
47
|
+
- app/models/workarea/shipping/rate.decorator
|
48
|
+
- app/models/workarea/shipping/rate_lookup.decorator
|
49
|
+
- app/models/workarea/shipping/service.decorator
|
47
50
|
- app/models/workarea/shipping_option.decorator
|
48
51
|
- app/services/workarea/packaging.decorator
|
52
|
+
- app/views/workarea/admin/shipping_services/_addtional_service_fields.html.haml
|
53
|
+
- app/views/workarea/admin/shipping_services/edit.html.haml
|
54
|
+
- app/views/workarea/admin/shipping_services/new.html.haml
|
55
|
+
- config/initializers/appends.rb
|
49
56
|
- config/initializers/shipping_configuration.rb
|
50
57
|
- config/initializers/workarea.rb
|
51
58
|
- config/routes.rb
|
59
|
+
- lib/active_shipping/carriers/valken.rb
|
52
60
|
- lib/tasks/valken/shipping_tasks.rake
|
53
61
|
- lib/valken/shipping.rb
|
54
62
|
- lib/valken/shipping/engine.rb
|
@@ -57,7 +65,7 @@ homepage: https://github.com/sushmitha02
|
|
57
65
|
licenses:
|
58
66
|
- MIT
|
59
67
|
metadata: {}
|
60
|
-
post_install_message:
|
68
|
+
post_install_message:
|
61
69
|
rdoc_options: []
|
62
70
|
require_paths:
|
63
71
|
- lib
|
@@ -68,12 +76,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
68
76
|
version: '0'
|
69
77
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
70
78
|
requirements:
|
71
|
-
- - "
|
79
|
+
- - ">"
|
72
80
|
- !ruby/object:Gem::Version
|
73
|
-
version:
|
81
|
+
version: 1.3.1
|
74
82
|
requirements: []
|
75
|
-
rubygems_version: 3.0.
|
76
|
-
signing_key:
|
83
|
+
rubygems_version: 3.0.3
|
84
|
+
signing_key:
|
77
85
|
specification_version: 4
|
78
86
|
summary: shipping options
|
79
87
|
test_files: []
|