valken-shipping 2.1.2 → 3.0.0.pre
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/app/models/workarea/shipping.decorator +18 -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 +20 -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/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: 146a3ad0dd1b020312bcf880257b2d080cadd3bdfcb6205c1a63a79247ea080f
|
|
4
|
+
data.tar.gz: 02edb837e0c27d4fba3ebce3f2e9545dd896c67f11dd00c865768144147977ea
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ff8e88fc94268f6ea84ff2eb1d0d01ca4ea0f39609f92492feec006a9a01ea1e3fe9f2b4aaf50afa59badb0d1c9df3501f98bd468302c6b43be4e5a3065d90a7
|
|
7
|
+
data.tar.gz: 67a511096848ef71c7a422d56342e63908f118b20f71ed5dc0196156c68355e2d8e3e537f36d13368c272920fb50c3f7dcfb8cf6fc82a6fd343fc8c4d678f64a
|
|
@@ -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
|
-
|
|
85
|
-
# If the carrier is ups then it will print ups data...or if carrier is fedex then prinnt fedex data...
|
|
86
|
-
# else if it is not both then choose cheapest price.
|
|
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
|
|
92
|
-
end
|
|
93
57
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
@ups_options ||= get_options(Workarea.config.gateways.ups_carrier, Workarea.config.shipping_rates)
|
|
58
|
+
shipping_options.unshift(get_free_shipping) if is_free_ship
|
|
59
|
+
shipping_options
|
|
97
60
|
end
|
|
98
61
|
|
|
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,
|
|
70
|
+
price: Money.new(0.0, Money.default_currency.to_s),
|
|
128
71
|
tax_code: "TAX01"
|
|
129
72
|
)
|
|
130
73
|
end
|
|
131
74
|
|
|
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"),
|
|
154
|
-
tax_code: "TAX01"
|
|
155
|
-
)
|
|
156
|
-
end
|
|
157
|
-
|
|
158
|
-
def get_shipping_for_special_region
|
|
159
|
-
puts "weight_convertion",weight_convertion
|
|
160
|
-
weight_price = 0
|
|
161
|
-
case weight_convertion
|
|
162
|
-
when 0..50
|
|
163
|
-
weight_price = 50
|
|
164
|
-
when 50..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
|
|
@@ -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,20 @@ 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
|
+
(total_weight_lb / Workarea.config.max_weight_per_pack).ceil
|
|
18
|
+
end
|
|
19
|
+
|
|
6
20
|
def find_shipping_sku(sku)
|
|
7
21
|
shipping_skus.detect { |s| s.id == sku } || Shipping::Sku.new(id: sku, weight: find_sku_weight(sku))
|
|
8
22
|
end
|
|
@@ -10,16 +24,20 @@ module Workarea
|
|
|
10
24
|
def find_sku_weight(sku)
|
|
11
25
|
product_by_sku = Catalog::Product.find_by_sku(sku).variants
|
|
12
26
|
sku_data = product_by_sku.detect {|variant| variant.sku == sku }
|
|
13
|
-
sku_weight = is_pounds(sku_data) ?
|
|
27
|
+
sku_weight = is_pounds(sku_data) ? convert_to_oz(sku_data.weight || 0) : (sku_data.weight || 0)
|
|
14
28
|
sku_weight
|
|
15
29
|
end
|
|
16
30
|
|
|
17
|
-
def
|
|
31
|
+
def convert_to_oz(weight)
|
|
18
32
|
unit = Measured::Weight.new(weight, :lb)
|
|
19
33
|
ounce_unit = unit.convert_to(:oz)
|
|
20
34
|
ounce_unit.value
|
|
21
35
|
end
|
|
22
36
|
|
|
37
|
+
def total_weight_lb
|
|
38
|
+
@total_weight_lb ||= Measured::Weight.new(total_weight, :oz).convert_to(:lb).value
|
|
39
|
+
end
|
|
40
|
+
|
|
23
41
|
def is_pounds(sku_data)
|
|
24
42
|
sku_data.weight_unit == "lb"
|
|
25
43
|
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'
|
|
@@ -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.0.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: []
|