sysmocom_dhl/app/models/spree/calculator/sysmocom_value_calculator.rb

323 lines
6.8 KiB
Ruby
Raw Normal View History

# 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