# 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 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 # we choose pricing between 2kg and 5gk def price_germany(value) return packages_price(value, 500, 6.0) end # We assume a 5kg package in all zones below def price_package_zone1(value) return packages_price(value, 500, 17.0) end def price_package_zone2(value) return packages_price(value, 500, 29) end def price_package_zone3(value) return packages_price(value, 500, 30) end def price_package_zone4(value) return packages_price(value, 500, 33) end def price_package_zone5(value) return packages_price(value, 500, 38) end def price_package_zone6(value) return packages_price(value, 500, 40) end def price_package_zone7(value) return packages_price(value, 500, 60) end def price_package_zone8(value) return packages_price(value, 500, 63) 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) elsif ZONE4.has_key?(iso_code) return price_package_zone4(shipping_value) elsif ZONE5.has_key?(iso_code) return price_package_zone5(shipping_value) elsif ZONE6.has_key?(iso_code) return price_package_zone6(shipping_value) elsif ZONE7.has_key?(iso_code) return price_package_zone7(shipping_value) else return price_package_zone8(shipping_value) end end end end