valken-shipping 2.0.8 → 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 +41 -192
- 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/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: 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,81 +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
|
-
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))
|
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)
|
77
56
|
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
|
85
|
-
# Temporarily disabling fedex and cheaper
|
86
|
-
# return get_fedex_data if is_fedex
|
87
|
-
# return get_none_data unless is_ups && is_fedex
|
88
|
-
end
|
89
57
|
|
90
|
-
|
91
|
-
|
92
|
-
@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
|
93
60
|
end
|
94
61
|
|
95
|
-
# FedEx data.
|
96
|
-
def get_fedex_data
|
97
|
-
@fedex_response ||= get_options(Workarea.config.gateways.fedex_carrier, Workarea.config.shipping_rates)
|
98
|
-
end
|
99
|
-
|
100
|
-
# If the product is not ups or fedex then it will choose the cheapest price among ups and fedex annd print the value.
|
101
|
-
def get_none_data
|
102
|
-
return [] if get_ups_data.blank? || get_fedex_data.blank?
|
103
|
-
final_options = []
|
104
|
-
temp_options = get_fedex_data + get_ups_data
|
105
|
-
return [] unless temp_options.any?
|
106
|
-
|
107
|
-
delivery_dates = temp_options.map(&:delivery_date).uniq.sort
|
108
|
-
delivery_dates.each_with_index do |date, index|
|
109
|
-
selected_rates = temp_options.select {|rate| rate.delivery_date == date}
|
110
|
-
final_options.push(selected_rates.sort_by(&:price).first)
|
111
|
-
end
|
112
|
-
return final_options
|
113
|
-
|
114
|
-
end
|
115
62
|
|
116
63
|
# Free shipping option.
|
117
64
|
def get_free_shipping
|
@@ -120,140 +67,42 @@ module Workarea
|
|
120
67
|
name: "Valken Economy",
|
121
68
|
sub_name: "5 - 9 Business Days",
|
122
69
|
service_code: "Free",
|
123
|
-
price: Money.new(0.0,
|
70
|
+
price: Money.new(0.0, Money.default_currency.to_s),
|
124
71
|
tax_code: "TAX01"
|
125
72
|
)
|
126
73
|
end
|
127
74
|
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
when 0..2
|
133
|
-
weight_price = 5
|
134
|
-
when 2..15
|
135
|
-
weight_price = 15
|
136
|
-
when 15..200
|
137
|
-
weight_price = (1 * weight_convertion)
|
138
|
-
when 200..2500
|
139
|
-
weight_price = 200
|
140
|
-
else
|
141
|
-
weight_price = ((weight_convertion / 2500).ceil()) * 200
|
142
|
-
end
|
143
|
-
|
144
|
-
ShippingOption.new(
|
145
|
-
carrier: "LTL Shipping",
|
146
|
-
name: "Valken Standard",
|
147
|
-
sub_name: "3 - 5 Business Days",
|
148
|
-
service_code: "LTL01",
|
149
|
-
price: Money.new(weight_price * 100, "USD"),
|
150
|
-
tax_code: "TAX01"
|
151
|
-
)
|
75
|
+
def is_ground
|
76
|
+
ground_ship_attribute = Workarea.config.shipping_attributes[:ground_shipping_only]
|
77
|
+
product_carrier_type = product_details.map{ |item| item[:en][ground_ship_attribute] }.flatten
|
78
|
+
product_carrier_type.include?("true")
|
152
79
|
end
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
packaging = Packaging.new(order, shipping)
|
157
|
-
return 0 if packaging.packages.blank?
|
158
|
-
full_weight = 0
|
159
|
-
packaging.packages.each do |item_package|
|
160
|
-
new_weight = item_package.weight.convert_to(:lb)
|
161
|
-
full_weight += new_weight.value
|
162
|
-
end
|
163
|
-
full_weight
|
80
|
+
|
81
|
+
def is_special_region?
|
82
|
+
Workarea.config.special_region.include?(@shipping.address.region)
|
164
83
|
end
|
165
84
|
|
166
|
-
#
|
167
|
-
#
|
168
|
-
#
|
169
|
-
def
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
origin = ActiveShipping::Location.new(Workarea.config.shipping_origin)
|
175
|
-
begin
|
176
|
-
response = shipping_option.find_rates(
|
177
|
-
origin,
|
178
|
-
@shipping.address.to_active_shipping,
|
179
|
-
packaging.packages
|
180
|
-
)
|
181
|
-
if carrier.class == ActiveShipping::Workarea
|
182
|
-
response.rates.sort_by(&:price).map do |rate|
|
183
|
-
ShippingOption.from_rate_estimate(rate)
|
184
|
-
end
|
185
|
-
else
|
186
|
-
filter_shipping_rates(response.rates, service_code)
|
187
|
-
end
|
188
|
-
rescue ActiveShipping::ResponseError => e
|
189
|
-
@error = e
|
190
|
-
return []
|
191
|
-
end
|
192
|
-
end
|
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")
|
193
92
|
|
194
|
-
|
195
|
-
# Find cheapest rate for those three rates
|
196
|
-
# Push all the cheap option for 1, 2, & 3 days into an array and return
|
197
|
-
def filter_shipping_rates(rates, service_code)
|
198
|
-
filtered_rates = []
|
199
|
-
# find and sort all delivery dates and pick 1st three
|
200
|
-
all_delivery_dates = rates.map { |rate| rate.delivery_date }
|
201
|
-
# sorting the uniq delivery dates and reversing those delivery dates.
|
202
|
-
uniq_delivery_dates = all_delivery_dates.compact.sort.uniq[0..2]
|
203
|
-
|
204
|
-
# removing overnight. Assuming the 3rd option is always overnight
|
205
|
-
uniq_delivery_dates.pop if uniq_delivery_dates.length == 3
|
93
|
+
return true if Workarea.config.show_free_shipping
|
206
94
|
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
cheap_rate = selected_rates.sort_by(&:price).first
|
211
|
-
description = "#{cheap_rate.delivery_date.strftime('%A, %B %d, %Y')}"
|
95
|
+
test_order = order.clone
|
96
|
+
test_shipping = shipping.clone
|
97
|
+
test_shipping.apply_shipping_service(get_free_shipping.to_h)
|
212
98
|
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
# creating a ShippingOption
|
219
|
-
def create_shipping_options(rate, rate_label = nil, description = nil)
|
220
|
-
ShippingOption.new(
|
221
|
-
carrier: rate.carrier,
|
222
|
-
name: rate_label.keys.join || rate.service_name,
|
223
|
-
sub_name: rate_label.values.join,
|
224
|
-
service_code: rate.service_code,
|
225
|
-
description: description,
|
226
|
-
delivery_date: rate.delivery_date,
|
227
|
-
price: Money.new(rate.price, rate.currency),
|
228
|
-
tax_code: Shipping::Service.find_tax_code(
|
229
|
-
rate.carrier,
|
230
|
-
rate.service_name
|
231
|
-
)
|
232
|
-
)
|
233
|
-
end
|
234
|
-
|
235
|
-
# Selecting the shipping carrier based on order items
|
236
|
-
#
|
237
|
-
# If the product is type hazmat then it returns ups...or if product is type gun then it returns fedex
|
238
|
-
# else if product is not both type then it returns none
|
239
|
-
def is_fedex
|
240
|
-
carrier_type_attribute = Workarea.config.shipping_attributes[:carrier_type]
|
241
|
-
product_carrier_type = product_details.map{ |item| item[:en][carrier_type_attribute] }.flatten
|
242
|
-
product_carrier_type.include?("FEDEX")
|
243
|
-
end
|
244
|
-
|
245
|
-
def is_ups
|
246
|
-
carrier_type_attribute = Workarea.config.shipping_attributes[:carrier_type]
|
247
|
-
product_carrier_type = product_details.map{ |item| item[:en][carrier_type_attribute] }.flatten
|
248
|
-
product_carrier_type.include?("UPS")
|
99
|
+
price_adjustments = Pricing.find_shipping_discounts(
|
100
|
+
test_order,
|
101
|
+
test_shipping
|
102
|
+
)
|
103
|
+
return price_adjustments.present? && price_adjustments.any?
|
249
104
|
end
|
250
105
|
|
251
|
-
def is_ground
|
252
|
-
ground_ship_attribute = Workarea.config.shipping_attributes[:ground_shipping_only]
|
253
|
-
product_carrier_type = product_details.map{ |item| item[:en][ground_ship_attribute] }.flatten
|
254
|
-
product_carrier_type.include?("true")
|
255
|
-
end
|
256
|
-
|
257
106
|
def product_details
|
258
107
|
# product_attributes = @order.items.map(&:product_attributes)
|
259
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,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'
|
@@ -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.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: []
|