lib/active_shipping/shipping/package.rb in active_shipping-0.9.15 vs lib/active_shipping/shipping/package.rb in active_shipping-0.10.0
- old
+ new
@@ -1,7 +1,82 @@
module ActiveMerchant #:nodoc:
module Shipping #:nodoc:
+ # A package item is a unique item(s) that is physically in a package.
+ # A single package can have many items. This is only required
+ # for shipping methods (label creation) right now.
+ class PackageItem
+ include Quantified
+
+ attr_reader :sku, :hs_code, :value, :name, :weight, :quantity, :options
+
+ def initialize(name, grams_or_ounces, value, quantity, options = {})
+ @name = name
+
+ imperial = (options[:units] == :imperial) ||
+ (grams_or_ounces.respond_to?(:unit) && m.unit.to_sym == :imperial)
+
+ @unit_system = imperial ? :imperial : :metric
+
+ @weight = attribute_from_metric_or_imperial(grams_or_ounces, Mass, :grams, :ounces)
+
+ @value = Package.cents_from(value)
+ @quantity = quantity > 0 ? quantity : 1
+
+ @sku = options[:sku]
+ @hs_code = options[:hs_code]
+ @options = options
+ end
+
+ def weight(options = {})
+ case options[:type]
+ when nil, :actual
+ @weight
+ when :volumetric, :dimensional
+ @volumetric_weight ||= begin
+ m = Mass.new((centimetres(:box_volume) / 6.0), :grams)
+ @unit_system == :imperial ? m.in_ounces : m
+ end
+ when :billable
+ [ weight, weight(:type => :volumetric) ].max
+ end
+ end
+ alias_method :mass, :weight
+
+ def ounces(options={})
+ weight(options).in_ounces.amount
+ end
+ alias_method :oz, :ounces
+
+ def grams(options={})
+ weight(options).in_grams.amount
+ end
+ alias_method :g, :grams
+
+ def pounds(options={})
+ weight(options).in_pounds.amount
+ end
+ alias_method :lb, :pounds
+ alias_method :lbs, :pounds
+
+ def kilograms(options={})
+ weight(options).in_kilograms.amount
+ end
+ alias_method :kg, :kilograms
+ alias_method :kgs, :kilograms
+
+ private
+
+ def attribute_from_metric_or_imperial(obj, klass, metric_unit, imperial_unit)
+ if obj.is_a?(klass)
+ return value
+ else
+ return klass.new(obj, (@unit_system == :imperial ? imperial_unit : metric_unit))
+ end
+ end
+
+ end
+
class Package
include Quantified
cattr_accessor :default_options
attr_reader :options, :value, :currency
@@ -13,30 +88,54 @@
options = @@default_options.update(options) if @@default_options
options.symbolize_keys!
@options = options
@dimensions = [dimensions].flatten.reject {|d| d.nil?}
+
imperial = (options[:units] == :imperial) ||
- ([grams_or_ounces, *dimensions].all? {|m| m.respond_to?(:unit) && m.unit.to_sym == :imperial})
+ ([grams_or_ounces, *dimensions].all? {|m| m.respond_to?(:unit) && m.unit.to_sym == :imperial})
- @unit_system = imperial ? :imperial : :metric
+ weight_imperial = dimensions_imperial = imperial if options.include?(:units)
+
+ if options.include?(:weight_units)
+ weight_imperial = (options[:weight_units] == :imperial) ||
+ (grams_or_ounces.respond_to?(:unit) && m.unit.to_sym == :imperial)
+ end
+
+ if options.include?(:dim_units)
+ dimensions_imperial = (options[:dim_units] == :imperial) ||
+ (dimensions && dimensions.all? {|m| m.respond_to?(:unit) && m.unit.to_sym == :imperial})
+ end
- @weight = attribute_from_metric_or_imperial(grams_or_ounces, Mass, :grams, :ounces)
+ @weight_unit_system = weight_imperial ? :imperial : :metric
+ @dimensions_unit_system = dimensions_imperial ? :imperial : :metric
+ @weight = attribute_from_metric_or_imperial(grams_or_ounces, Mass, @weight_unit_system, :grams, :ounces)
+
if @dimensions.blank?
- @dimensions = [Length.new(0, (imperial ? :inches : :centimetres))] * 3
+ @dimensions = [Length.new(0, (dimensions_imperial ? :inches : :centimetres))] * 3
else
process_dimensions
end
@value = Package.cents_from(options[:value])
@currency = options[:currency] || (options[:value].currency if options[:value].respond_to?(:currency))
@cylinder = (options[:cylinder] || options[:tube]) ? true : false
@gift = options[:gift] ? true : false
+ @oversized = options[:oversized] ? true : false
+ @unpackaged = options[:unpackaged] ? true : false
end
+ def unpackaged?
+ @unpackaged
+ end
+
+ def oversized?
+ @oversized
+ end
+
def cylinder?
@cylinder
end
alias_method :tube?, :cylinder?
@@ -81,11 +180,11 @@
when nil, :actual
@weight
when :volumetric, :dimensional
@volumetric_weight ||= begin
m = Mass.new((centimetres(:box_volume) / 6.0), :grams)
- @unit_system == :imperial ? m.in_ounces : m
+ @weight_unit_system == :imperial ? m.in_ounces : m
end
when :billable
[ weight, weight(:type => :volumetric) ].max
end
end
@@ -106,16 +205,16 @@
end
end
end
private
-
- def attribute_from_metric_or_imperial(obj, klass, metric_unit, imperial_unit)
+
+ def attribute_from_metric_or_imperial(obj, klass, unit_system, metric_unit, imperial_unit)
if obj.is_a?(klass)
- return value
+ return obj
else
- return klass.new(obj, (@unit_system == :imperial ? imperial_unit : metric_unit))
+ return klass.new(obj, (unit_system == :imperial ? imperial_unit : metric_unit))
end
end
def measure(measurement, ary)
case measurement
@@ -130,10 +229,10 @@
end
end
def process_dimensions
@dimensions = @dimensions.map do |l|
- attribute_from_metric_or_imperial(l, Length, :centimetres, :inches)
+ attribute_from_metric_or_imperial(l, Length, @dimensions_unit_system, :centimetres, :inches)
end.sort
# [1,2] => [1,1,2]
# [5] => [5,5,5]
# etc..
2.downto(@dimensions.length) do |n|