module SolidusMe class ShippingEstimator def initialize store = Spree::Store.first @preferences = Preferences.new(store).preferences @me_client = MeApi::Client.new(@preferences[:access_token]) end def shipping_rates(package, _frontend_only = true) melhor_envio_rates = get_rates_from_melhor_envio(package) shipping_rates = melhor_envio_rates.map do |melhor_envio_rate| build_shipping_rate(melhor_envio_rate, package) end unless shipping_rates.empty? default_shipping_rate = Spree::Config.shipping_rate_selector_class.new(shipping_rates).find_default default_shipping_rate.selected = true end shipping_rates end private def get_rates_from_melhor_envio(package) begin weight = package.contents.map {|content| content.weight }.sum price = package.contents.map {|content| content.price }.sum zipcode = package.order.ship_address.zipcode services = @preferences[:services] || ["SEDEX", "PAC", "Mini Envios", ".Package", ".Com"] rates = @me_client.rates( from: @preferences[:postal_code_from], to: zipcode, weight_kg: (weight/1000), contents_value_brl: price ) rates.select { |rate| rate.price > 0 && services.include?(rate.service_name) } rescue [ OpenStruct.new({ price: 15.00, service_name: "", carrier_name: "Frete padrĂ£o", delivery_range: { min: 5, max: 5 } }) ] end end def build_shipping_rate(melhor_envio_rate, package) shipping_method = Spree::ShippingMethod.find_or_create_by( carrier: melhor_envio_rate.carrier_name, service_level: melhor_envio_rate.service_name, ) do |shipping_method| shipping_method.name = "#{melhor_envio_rate.carrier_name} #{melhor_envio_rate.service_name}" shipping_method.calculator = Spree::Calculator::Shipping::FlatRate.create shipping_method.shipping_categories = Spree::ShippingCategory.all shipping_method.available_to_users = true end Spree::ShippingRate.new( shipping_method: shipping_method, cost: melhor_envio_rate.price, min_delivery_time: melhor_envio_rate.delivery_range["min"], max_delivery_time: melhor_envio_rate.delivery_range["max"] ) end end end