Created
March 6, 2013 00:16
-
-
Save geermc4/5095653 to your computer and use it in GitHub Desktop.
usps debug
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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