# AGPLv3 sysmocom s.f.m.c. GmbH module Spree class Calculator::SysmocomValueCalculator < Calculator def self.description I18n.t(:sysmocom_value_based) end ZONE1 = { "BE" => 1, "BG" => 1, "DK" => 1, "EE" => 1, "FI" => 1, "FR" => 1, "GR" => 1, "GB" => 1, "IE" => 1, "IT" => 1, "LV" => 1, "LU" => 1, "MT" => 1, "MC" => 1, "NL" => 1, "AT" => 1, "PL" => 1, "PT" => 1, "RO" => 1, "SE" => 1, "SK" => 1, "SI" => 1, "ES" => 1, "CZ" => 1, "HU" => 1, "CY" => 1 }.freeze() ZONE2 = { #"Älandinseln (Finnland)" "AD" => 1, "AL" => 1, "BY" => 1, #Berg Athos "BA" => 1, #Campione d'Italia Italien #Ceuta..Spanien "FO" => 1, "GE" => 1, "GI" => 1, "IS" => 1, #Kanalinseln (Großbritannien) #Kanarische Inseln (Spanien) #Kosovo "HR" => 1, "LI" => 1, #Livigno "MK" => 1, "MD" => 1, #Melila (Spanien) #Montenegro "NO" => 1, "CH" => 1, "RU" => 1, "SM" => 1, "RS" => 1, "TR" => 1, "UA" => 1, "VA" => 1, }.freeze ZONE3 = { "EG" => 1, "DZ" => 1, "AM" => 1, "AZ" => 1, "IL" => 1, "JO" => 1, "CA" => 1, "KZ" => 1, "LB" => 1, "LY" => 1, "MA" => 1, #Palästinensische Gebiete "PM" => 1, "SY" => 1, "TN" => 1, "US" => 1, }.freeze def packages_price(value, limit, price_each) price = 0 rest = value # It is intended that a package reaching the limit is counted twice # Also a zero value should still be one package. while rest >= 0 do price += price_each rest -= limit end price end def price_germany(value) # 6 Euro and up to 500 Euro in Value for a 2kg package # http://www.dhl.de/dhl-paket return packages_price(value, 500, 6.0) end def price_package_zone1(value) # 17 Euro and up to 500 Euro in value for a 5kg package or # 2kg registered parcel with 35 Euro of value... # http://www.dhl.de/de/paket/pakete-versenden/weltweit-versenden/paket.html if value < 35 return packages_price(value, 35, 12) else return packages_price(value, 500, 17.0) end end def price_package_zone2(value) # 5kg package # TODO: for the last item we could check for 74.11 again if value < 74.11 return packages_price(value, 74.11, 32) else return packages_price(value, 500, 38) end end def price_package_zone3(value) # 5kg package # TODO see zone2 if value < 74.11 return packages_price(value, 74.11, 38) else return packages_price(value, 500, 54) end end def price_package_zone4(value) if value < 74.11 return packages_price(value, 74.11, 44) else return packages_price(value, 500, 66) end 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) iso_code = extract_iso_code(object) # Go through the zones by name... if iso_code == 'DE' return price_germany(shipping_value) elsif ZONE1.has_key?(iso_code) return price_package_zone1(shipping_value) elsif ZONE2.has_key?(iso_code) return price_package_zone2(shipping_value) elsif ZONE3.has_key?(iso_code) return price_package_zone3(shipping_value) else return price_package_zone4(shipping_value) end end end end