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|