module SolidusMe class MelhorEnvio SHIPPING_METHODS = [ { name: "Correios PAC", carrier: "Correios", service_level: "PAC", external_id: 1 }, { name: "Correios SEDEX", carrier: "Correios", service_level: "SEDEX", external_id: 2 }, { name: "Correios Mini Envios", carrier: "Correios", service_level: "Mini Envios", external_id: 17 }, { name: "Jadlog .Package", carrier: "Jadlog", service_level: ".Package", external_id: 3 }, { name: "Jadlog .Com", carrier: "Jadlog", service_level: ".Com", external_id: 4 } ] attr_accessor :package, :shipping_methods def initialize(package, shipping_methods) @package = package @shipping_methods = shipping_methods end def self.generate_code external_id (self.name.underscore + "_#{external_id}").downcase end def self.install SHIPPING_METHODS.each do |provider_method| Spree::ShippingMethod.find_or_create_by(code: generate_code(provider_method[:external_id])) do |shipping_method| shipping_method.name = provider_method[:name] shipping_method.carrier = provider_method[:carrier] shipping_method.service_level = provider_method[:service_level] shipping_method.code = generate_code(provider_method[:external_id]) shipping_method.calculator = Spree::Calculator::Shipping::FlatRate.create shipping_method.shipping_categories = [Spree::ShippingCategory.first] shipping_method.available_to_users = false shipping_method.provider_id = SolidusTecEstimator::Provider.find_by(class_name: self.to_s).id end end end def shipping_rates @me_account = Account.first return [] if @me_account.blank? @me_account.check_token @me_client = MeApi::Client.new(@me_account.access_token) 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.compact shipping_rates end private def get_rates_from_melhor_envio(package) price = package.contents.map { |content| content.price }.sum weight = package.weight zipcode = package.order.ship_address.zipcode available_shipping_method_codes = @shipping_methods.pluck(:code) rates = @me_client.rates( from: @me_account.postal_code_from, to: zipcode, weight_kg: (weight / 1000.00), contents_value_brl: price ) rates.select { |rate| rate.price > 0 && available_shipping_method_codes.include?(self.class.generate_code(rate.id)) } rescue [] end def build_shipping_rate(melhor_envio_rate, package) return unless melhor_envio_rate.max_delivery_time shipping_method = Spree::ShippingMethod.find_by(code: self.class.generate_code(melhor_envio_rate.id)) estimate_prose = "Chegará em até #{ActionController::Base.helpers.pluralize(melhor_envio_rate.max_delivery_time, "dia", plural: "dias")} úteis" Spree::ShippingRate.new( shipment: package.shipment, shipping_method: shipping_method, cost: melhor_envio_rate.price, min_delivery_time: melhor_envio_rate.min_delivery_time.business_days.from_now, max_delivery_time: melhor_envio_rate.max_delivery_time.business_days.from_now, estimate_prose: estimate_prose, expires_in: Time.now + 2.hours ) end end end