# AGPLv3 sysmocom s.f.m.c. GmbH module Spree class Calculator::SysmocomScBaseCalculator < Calculator def total_value_no_tax(o) item_total = o.line_items.map(&:amount).sum item_total end def total_weight(o) weight = 0 o.line_items.each do |li| weight += li.quantity * li.variant.weight end return weight 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 extract_dst_dadr(o) if o.kind_of?(Spree::Shipment) return o.address end return o.ship_address end def cbrt(x) return x ** (1.0/3) end def estimate_dimensions(weight_kg, density_kg_per_dm3) volume_dm3 = weight_kg.to_f / density_kg_per_dm3.to_f volume_cm3 = 1000.0 * volume_dm3 # assuming l=3x, w=2x, h1x -> x=6 x = cbrt(volume_cm3 / 6) return 3.0 * x, 2.0 * x, 1.0 * x end def sc_compute(carrier, service, object) # This could be more than an order but not right now weight = total_weight(object) dst = extract_dst_addr(object) length, width, height = estimate_dimensions(weight, 0.5) quote = Shipcloud::ShipmentQuote.create( carrier: carrier, service: service, to: { street: dst.address1, zip_code: dst.zipcode, city: dst.city, country: dst.country.iso, }, from: { street: "Alt-Moabit", street_no: "93", zip_code: "10559", city: "Berlin", country: "DE", }, package: { weight: weight, width: width, length: length, height: height, }, ) return quote.price end def available?(object) # use 'compute' to determine availability begin price = sc_compute(object) rescue => return false else return true end end end class Calculator::SysmocomScUpsStdCalculator < SysmocomScBaseCalculator def self.description I18n.t(:sysmocom_ups_standard) end def compute(object) return sc_compute('ups', 'standard') end end class Calculator::SysmocomScUpsExpressCalculator < SysmocomScBaseCalculator def self.description I18n.t(:sysmocom_ups_express) end def compute(object) return sc_compute('ups', 'one_day') end end class Calculator::SysmocomScUpsExpeditedCalculator < SysmocomScBaseCalculator def self.description I18n.t(:sysmocom_ups_expedited) end def compute(object) return sc_compute('ups', 'ups_expedited') end end end