Skip to content

Instantly share code, notes, and snippets.

@geermc4
Created March 6, 2013 00:16
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save geermc4/5095653 to your computer and use it in GitHub Desktop.
Save geermc4/5095653 to your computer and use it in GitHub Desktop.
usps debug
o=Spree::Order.find_by_number("R672076841")
object=o
#'USPS Priority Mail' on my db
@carrier=Spree::ShippingMethod.find(16).calculator.carrier
if object.is_a?(Array)
order = object.first.order
elsif object.is_a?(Spree::Shipment)
order = object.order
else
order = object
end
origin= ActiveMerchant::Shipping::Location.new(
:country => Spree::ActiveShipping::Config[:origin_country],
:city => Spree::ActiveShipping::Config[:origin_city],
:state => Spree::ActiveShipping::Config[:origin_state],
:zip => Spree::ActiveShipping::Config[:origin_zip])
addr = order.ship_address
destination = ActiveMerchant::Shipping::Location.new(
:country => addr.country.iso,
:state => (addr.state ? addr.state.abbr : addr.state_name),
:city => addr.city,
:zip => addr.zipcode)
addr = order.ship_address
line_items_hash = Digest::MD5.hexdigest(order.line_items.map {|li| li.variant_id.to_s + "_" + li.quantity.to_s }.join("|"))
@cache_key = "#{@carrier.name}-#{order.number}-#{addr.country.iso}-#{addr.state ? addr.state.abbr : addr.state_name}-#{addr.city}-#{addr.zipcode}-#{line_items_hash}-#{I18n.locale}".gsub(" ","")
def packages(order)
units = Spree::ActiveShipping::Config[:units].to_sym
packages = []
weights = convert_order_to_weights_array(order)
max_weight = get_max_weight(order)
if max_weight <= 0
packages << ActiveMerchant::Shipping::Package.new(weights.sum, [], :units => units)
else
package_weight = 0
weights.each do |li_weight|
if package_weight + li_weight <= max_weight
package_weight += li_weight
else
packages << ActiveMerchant::Shipping::Package.new(package_weight, [], :units => units)
package_weight = li_weight
end
end
packages << ActiveMerchant::Shipping::Package.new(package_weight, [], :units => units) if package_weight > 0
end
packages
end
def convert_order_to_weights_array(order)
multiplier = Spree::ActiveShipping::Config[:unit_multiplier]
default_weight = Spree::ActiveShipping::Config[:default_weight]
max_weight = get_max_weight(order)
weights = order.line_items.map do |line_item|
item_weight = line_item.variant.weight.to_f
item_weight = default_weight if item_weight <= 0
item_weight *= multiplier
quantity = line_item.quantity
if max_weight <= 0
item_weight * quantity
elsif item_weight == 0
0
else
if item_weight < max_weight
max_quantity = (max_weight/item_weight).floor
if quantity < max_quantity
item_weight * quantity
else
new_items = []
while quantity > 0 do
new_quantity = [max_quantity, quantity].min
new_items << (item_weight * new_quantity)
quantity -= new_quantity
end
new_items
end
else
raise Spree::ShippingError.new("#{I18n.t(:shipping_error)}: The maximum per package weight for the selected service from the selected country is #{max_weight} ounces.")
end
end
end
weights.flatten.sort
end
def get_max_weight(order)
max_weight = max_weight_for_country(order.ship_address.country)
max_weight_per_package = Spree::ActiveShipping::Config[:max_weight_per_package] * Spree::ActiveShipping::Config[:unit_multiplier]
if max_weight == 0 and max_weight_per_package > 0
max_weight = max_weight_per_package
elsif max_weight > 0 and max_weight_per_package < max_weight and max_weight_per_package > 0
max_weight = max_weight_per_package
end
max_weight
end
def max_weight_for_country(country)
0
end
def retrieve_rates(origin, destination, packages)
begin
response = @carrier.find_rates(origin, destination, packages)
# turn this beastly array into a nice little hash
rates = response.rates.collect do |rate|
# decode html entities for xml-based APIs, ie Canada Post
if RUBY_VERSION.to_f < 1.9
service_name = Iconv.iconv('UTF-8//IGNORE', 'UTF-8', rate.service_name).first
else
service_name = rate.service_name.encode("UTF-8")
end
[CGI.unescapeHTML(service_name), rate.price]
end
rate_hash = Hash[*rates.flatten]
return rate_hash
rescue ActiveMerchant::ActiveMerchantError => e
if [ActiveMerchant::ResponseError, ActiveMerchant::Shipping::ResponseError].include?(e.class) && e.response.is_a?(ActiveMerchant::Shipping::Response)
params = e.response.params
if params.has_key?("Response") && params["Response"].has_key?("Error") && params["Response"]["Error"].has_key?("ErrorDescription")
message = params["Response"]["Error"]["ErrorDescription"]
# Canada Post specific error message
elsif params.has_key?("eparcel") && params["eparcel"].has_key?("error") && params["eparcel"]["error"].has_key?("statusMessage")
message = e.response.params["eparcel"]["error"]["statusMessage"]
else
message = e.message
end
else
message = e.message
end
error = Spree::ShippingError.new("#{I18n.t(:shipping_error)}: #{message}")
Rails.cache.write @cache_key, error #write error to cache to prevent constant re-lookups
raise error
end
end
rates_result = Rails.cache.fetch(@cache_key) do
order_packages = packages(order)
if order_packages.empty?
{}
else
retrieve_rates(origin, destination, order_packages)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment