323 lines
6.8 KiB
Ruby
323 lines
6.8 KiB
Ruby
# AGPLv3 sysmocom s.f.m.c. GmbH
|
|
|
|
module Spree
|
|
class Calculator::SysmocomValueCalculator < Calculator
|
|
|
|
def self.description
|
|
I18n.t(:sysmocom_value_based)
|
|
end
|
|
|
|
ZONE1 = {
|
|
"AT" => 1,
|
|
"BE" => 1,
|
|
"BG" => 1,
|
|
"HR" => 1,
|
|
"CZ" => 1,
|
|
"DK" => 1,
|
|
"EE" => 1,
|
|
"FI" => 1,
|
|
"FR" => 1,
|
|
"GR" => 1,
|
|
"HU" => 1,
|
|
"IE" => 1,
|
|
"IT" => 1,
|
|
"LV" => 1,
|
|
"LT" => 1,
|
|
"LU" => 1,
|
|
"MT" => 1,
|
|
"MC" => 1,
|
|
"NL" => 1,
|
|
"PL" => 1,
|
|
"PT" => 1,
|
|
"RO" => 1,
|
|
"SK" => 1,
|
|
"SI" => 1,
|
|
"ES" => 1,
|
|
"SE" => 1,
|
|
"GB" => 1
|
|
}.freeze()
|
|
|
|
ZONE2 = {
|
|
"CH" => 1
|
|
}.freeze()
|
|
|
|
ZONE3 = {
|
|
"AL" => 1,
|
|
"AD" => 1,
|
|
"BY" => 1,
|
|
"BA" => 1,
|
|
"CY" => 1,
|
|
"FO" => 1,
|
|
"GE" => 1,
|
|
"GI" => 1,
|
|
"GL" => 1,
|
|
"GG" => 1,
|
|
"VA" => 1,
|
|
"IS" => 1,
|
|
"JE" => 1,
|
|
"KZ" => 1,
|
|
"LI" => 1,
|
|
"MK" => 1,
|
|
"MD" => 1,
|
|
"ME" => 1,
|
|
"NO" => 1,
|
|
"SM" => 1,
|
|
"RS" => 1,
|
|
"TR" => 1,
|
|
"UA" => 1,
|
|
"AX" => 1
|
|
}.freeze
|
|
|
|
ZONE4 = {
|
|
"RU" => 1
|
|
}.freeze()
|
|
|
|
ZONE5 = {
|
|
"US" => 1
|
|
}.freeze()
|
|
|
|
ZONE6 = {
|
|
"DZ" => 1,
|
|
"AM" => 1,
|
|
"AZ" => 1,
|
|
"CA" => 1,
|
|
"EG" => 1,
|
|
"IL" => 1,
|
|
"JO" => 1,
|
|
"KZ" => 1,
|
|
"LB" => 1,
|
|
"LY" => 1,
|
|
"MA" => 1,
|
|
"PS" => 1,
|
|
"PM" => 1,
|
|
"SY" => 1,
|
|
"TN" => 1
|
|
}.freeze()
|
|
|
|
ZONE7 = {
|
|
"CN" => 1
|
|
}.freeze()
|
|
|
|
def total_weight(o)
|
|
weight = 0
|
|
o.line_items.each do |li|
|
|
weight += li.quantity + li.variant.weight
|
|
end
|
|
return weight
|
|
end
|
|
|
|
def insurance_cost_intl(value)
|
|
# Service Hoeherversicherung International stand 1.1.2019
|
|
if value <= 500
|
|
return 0
|
|
elsif value <= 1000
|
|
return 14
|
|
elsif value <= 2000
|
|
return 28
|
|
elsif value <= 3000
|
|
return 42
|
|
elsif value <= 4000
|
|
return 56
|
|
elsif value <= 5000
|
|
return 70
|
|
else
|
|
return 99999
|
|
end
|
|
# maximum insured value 5000 EUR
|
|
end
|
|
|
|
def insurance_cost_DE(value)
|
|
if value <= 500
|
|
return 0
|
|
elsif value <= 2500
|
|
return 6
|
|
elsif value <= 25000
|
|
return 18
|
|
else
|
|
return 99999
|
|
end
|
|
end
|
|
|
|
# we choose pricing between 2kg and 5kg
|
|
def price_germany(value, weight)
|
|
if weight < 2000
|
|
price = 4.99
|
|
elsif weight < 5000
|
|
price = 5.99
|
|
elsif weight < 10000
|
|
price = 8.49
|
|
elsif weight < 31500
|
|
price = 16.49
|
|
else
|
|
price = 99999
|
|
end
|
|
return price + insurance_cost_DE(value)
|
|
end
|
|
|
|
# We assume a 5kg package in all zones below
|
|
def price_package_zone1(value, weight)
|
|
if weight < 2000
|
|
price = 13.99
|
|
elsif weight < 5000
|
|
price = 15.99
|
|
elsif weight < 10000
|
|
price = 20.99
|
|
elsif weight < 20000
|
|
price = 21.99
|
|
elsif weight < 31500
|
|
price = 44.99
|
|
else
|
|
price = 99999
|
|
end
|
|
return price + insurance_cost_intl(value)
|
|
end
|
|
|
|
def price_package_zone2(value, weight)
|
|
if weight < 5000
|
|
price = 26.90
|
|
elsif weight < 10000
|
|
price = 34.99
|
|
elsif weight < 20000
|
|
price = 48.99
|
|
elsif weight < 31500
|
|
price = 55.99
|
|
else
|
|
price = 99999
|
|
end
|
|
return price + insurance_cost_intl(value)
|
|
end
|
|
|
|
def price_package_zone3(value, weight)
|
|
if weight < 5000
|
|
price = 29.99
|
|
elsif weight < 10000
|
|
price = 37.99
|
|
elsif weight < 20000
|
|
price = 52.99
|
|
elsif weight < 31500
|
|
price = 60.99
|
|
else
|
|
price = 99999
|
|
end
|
|
return price + insurance_cost_intl(value)
|
|
end
|
|
|
|
def price_package_zone4(value, weight)
|
|
if weight < 5000
|
|
price = 30.99
|
|
elsif weight < 10000
|
|
price = 37.99
|
|
elsif weight < 20000
|
|
price = 54.99
|
|
else
|
|
price = 99999
|
|
end
|
|
return price + insurance_cost_intl(value)
|
|
end
|
|
|
|
def price_package_zone5(value, weight)
|
|
if weight < 5000
|
|
price = 36.99
|
|
elsif weight < 10000
|
|
price = 53.99
|
|
elsif weight < 20000
|
|
price = 75.99
|
|
elsif weight < 31500
|
|
price = 105.99
|
|
else
|
|
price = 99999
|
|
end
|
|
return price + insurance_cost_intl(value)
|
|
end
|
|
|
|
def price_package_zone6(value, weight)
|
|
if weight < 5000
|
|
price = 37.99
|
|
elsif weight < 10000
|
|
price = 51.99
|
|
elsif weight < 20000
|
|
price = 71.99
|
|
elsif weight < 31500
|
|
price = 98.99
|
|
else
|
|
price = 99999
|
|
end
|
|
return price + insurance_cost_intl(value)
|
|
end
|
|
|
|
def price_package_zone7(value, weight)
|
|
if weight < 5000
|
|
price = 42.99
|
|
elsif weight < 10000
|
|
price = 58.99
|
|
elsif weight < 20000
|
|
price = 94.99
|
|
elsif weight < 31500
|
|
price = 125.99
|
|
else
|
|
price = 99999
|
|
end
|
|
return price + insurance_cost_intl(value)
|
|
end
|
|
|
|
def price_package_zone8(value, weight)
|
|
if weight < 5000
|
|
price = 45.99
|
|
elsif weight < 10000
|
|
price = 61.99
|
|
elsif weight < 20000
|
|
price = 100.99
|
|
elsif weight < 31500
|
|
price = 131.99
|
|
else
|
|
price = 99999
|
|
end
|
|
return price + insurance_cost_intl(value)
|
|
end
|
|
|
|
|
|
def total_value_no_tax(o)
|
|
item_total = o.line_items.map(&:amount).sum
|
|
item_total
|
|
end
|
|
|
|
def extract_iso_code(o)
|
|
if o.kind_of?(Spree::Shipment)
|
|
return o.address.country.iso
|
|
end
|
|
return o.ship_address.country.iso
|
|
end
|
|
|
|
def compute(object)
|
|
# This could be more than an order but not right now
|
|
shipping_value = total_value_no_tax(object)
|
|
weight = total_weight(object)
|
|
iso_code = extract_iso_code(object)
|
|
|
|
# Go through the zones by name...
|
|
if iso_code == 'DE'
|
|
return price_germany(shipping_value, weight)
|
|
elsif ZONE1.has_key?(iso_code)
|
|
return price_package_zone1(shipping_value, weight)
|
|
elsif ZONE2.has_key?(iso_code)
|
|
return price_package_zone2(shipping_value, weight)
|
|
elsif ZONE3.has_key?(iso_code)
|
|
return price_package_zone3(shipping_value, weight)
|
|
elsif ZONE4.has_key?(iso_code)
|
|
return price_package_zone4(shipping_value, weight)
|
|
elsif ZONE5.has_key?(iso_code)
|
|
return price_package_zone5(shipping_value, weight)
|
|
elsif ZONE6.has_key?(iso_code)
|
|
return price_package_zone6(shipping_value, weight)
|
|
elsif ZONE7.has_key?(iso_code)
|
|
return price_package_zone7(shipping_value, weight)
|
|
else
|
|
return price_package_zone8(shipping_value, weight)
|
|
end
|
|
end
|
|
|
|
end
|
|
end
|
|
|
|
|