Class: Shipping::Package

Inherits:
Object
  • Object
show all
Defined in:
app/services/shipping/package.rb

Overview

Physical package dimensions, weight, and declared value for rate shopping.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(grams_or_ounces, dimensions, options = {}) ⇒ Package

Package.new(100, [10, 20, 30], :units => :metric)
Package.new(Mass.new(100, :grams), [10, 20, 30].map {|m| Length.new(m, :centimetres)})
Package.new(100.grams, [10, 20, 30].map(&:centimetres))

Parameters:

  • grams_or_ounces (Numeric, Mass)

    package weight (bare numerics are grams, or ounces with :units => :imperial)

  • dimensions (Array)

    package dimensions (bare numerics are centimetres, or inches with :units => :imperial)

  • options (Hash) (defaults to: {})

    package attributes

Options Hash (options):

  • units (Symbol)

    unit system for bare numerics (:imperial or :metric)

  • value (Numeric, Money)

    declared value of the package contents

  • currency (String)

    currency of :value (inferred from a Money value when omitted)

  • cylinder (Boolean)

    whether the package is a cylinder (alias: tube)

  • tube (Boolean)

    alias for cylinder

  • pallet (Boolean)

    whether the package ships on a pallet

  • crate (Boolean)

    whether the package ships in a crate

  • container_code (String)

    SSCC or other container code

  • shipment_id (Integer)

    id of the shipment this package belongs to

  • nmfc_code (String)

    NMFC freight class code

  • flat_rate_package_type (String)

    carrier flat-rate package type



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'app/services/shipping/package.rb', line 28

def initialize(grams_or_ounces, dimensions, options = {})
  options = self.class.default_options.update(options) if self.class.default_options
  options.symbolize_keys!
  @options = options

  @dimensions = [dimensions].flatten.reject(&:nil?)

  imperial = (options[:units] == :imperial) ||
             [grams_or_ounces, *dimensions].all? { |m| m.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)

  if @dimensions.blank?
    @dimensions = [Length.new(0, (imperial ? :inches : :centimetres))] * 3
  else
    process_dimensions
  end

  @value = Package.dollars_from(options[:value])
  @currency = options[:currency] || (options[:value].currency if options[:value].respond_to?(:currency))
  @cylinder = options[:cylinder] || options[:tube] ? true : false
  @pallet = options[:pallet] ? true : false
  @crate = options[:crate] ? true : false
  @container_code = options[:container_code]
  @shipment_id = options[:shipment_id]
  @nmfc_code = options[:nmfc_code]
  @flat_rate_package_type = options[:flat_rate_package_type]
end

Instance Attribute Details

#container_codeObject (readonly)

Returns the value of attribute container_code.



9
10
11
# File 'app/services/shipping/package.rb', line 9

def container_code
  @container_code
end

#currencyObject (readonly)

Returns the value of attribute currency.



9
10
11
# File 'app/services/shipping/package.rb', line 9

def currency
  @currency
end

#flat_rate_package_typeObject (readonly)

Returns the value of attribute flat_rate_package_type.



9
10
11
# File 'app/services/shipping/package.rb', line 9

def flat_rate_package_type
  @flat_rate_package_type
end

#nmfc_codeObject (readonly)

Returns the value of attribute nmfc_code.



9
10
11
# File 'app/services/shipping/package.rb', line 9

def nmfc_code
  @nmfc_code
end

#optionsObject (readonly)

Returns the value of attribute options.



9
10
11
# File 'app/services/shipping/package.rb', line 9

def options
  @options
end

#shipment_idObject (readonly)

Returns the value of attribute shipment_id.



9
10
11
# File 'app/services/shipping/package.rb', line 9

def shipment_id
  @shipment_id
end

#valueObject (readonly)

Returns the value of attribute value.



9
10
11
# File 'app/services/shipping/package.rb', line 9

def value
  @value
end

Class Method Details

.dollars_from(money) ⇒ Float?

Converts a money value to a dollar amount.

Parameters:

  • money (Money, Numeric, nil)

    the value to convert

Returns:

  • (Float, nil)

    the value in dollars



151
152
153
154
155
156
157
158
159
# File 'app/services/shipping/package.rb', line 151

def self.dollars_from(money)
  return nil if money.nil?

  if money.respond_to?(:dollars)
    money.dollars
  else
    money.to_f.round(2)
  end
end

Instance Method Details

#centimetres(measurement = nil) ⇒ Array<Numeric>, Numeric Also known as: cm

Returns the package dimensions in centimetres.

Parameters:

  • measurement (Symbol, Integer, nil) (defaults to: nil)

    a specific dimension to measure (see #measure)

Returns:

  • (Array<Numeric>, Numeric)

    all dimensions in centimetres, or the requested measurement



123
124
125
126
# File 'app/services/shipping/package.rb', line 123

def centimetres(measurement = nil)
  @centimetres ||= @dimensions.map { |m| m.in_centimetres.amount }
  measurement.nil? ? @centimetres : measure(measurement, @centimetres)
end

#crate?Boolean

Returns whether the package ships in a crate.

Returns:

  • (Boolean)

    whether the package ships in a crate



65
66
67
# File 'app/services/shipping/package.rb', line 65

def crate?
  @crate
end

#cylinder?Boolean Also known as: tube?

Returns whether the package is a cylinder (tube).

Returns:

  • (Boolean)

    whether the package is a cylinder (tube)



70
71
72
# File 'app/services/shipping/package.rb', line 70

def cylinder?
  @cylinder
end

#grams(options = {}) ⇒ Numeric Also known as: g

Returns the package weight in grams.

Parameters:

  • options (Hash) (defaults to: {})

    weight options (see #weight)

Options Hash (options):

  • type (Symbol)

    weight type: :actual (default), :volumetric/:dimensional, or :billable

Returns:

  • (Numeric)

    the package weight in grams



86
87
88
# File 'app/services/shipping/package.rb', line 86

def grams(options = {})
  weight(options).in_grams.amount
end

#inches(measurement = nil) ⇒ Array<Numeric>, Numeric Also known as: in

Returns the package dimensions in inches.

Parameters:

  • measurement (Symbol, Integer, nil) (defaults to: nil)

    a specific dimension to measure (see #measure)

Returns:

  • (Array<Numeric>, Numeric)

    all dimensions in inches, or the requested measurement



113
114
115
116
# File 'app/services/shipping/package.rb', line 113

def inches(measurement = nil)
  @inches ||= @dimensions.map { |m| m.in_inches.amount }
  measurement.nil? ? @inches : measure(measurement, @inches)
end

#kilograms(options = {}) ⇒ Numeric Also known as: kg, kgs

Returns the package weight in kilograms.

Parameters:

  • options (Hash) (defaults to: {})

    weight options (see #weight)

Options Hash (options):

  • type (Symbol)

    weight type: :actual (default), :volumetric/:dimensional, or :billable

Returns:

  • (Numeric)

    the package weight in kilograms



103
104
105
# File 'app/services/shipping/package.rb', line 103

def kilograms(options = {})
  weight(options).in_kilograms.amount
end

#ounces(options = {}) ⇒ Numeric Also known as: oz

Returns the package weight in ounces.

Parameters:

  • options (Hash) (defaults to: {})

    weight options (see #weight)

Options Hash (options):

  • type (Symbol)

    weight type: :actual (default), :volumetric/:dimensional, or :billable

Returns:

  • (Numeric)

    the package weight in ounces



78
79
80
# File 'app/services/shipping/package.rb', line 78

def ounces(options = {})
  weight(options).in_ounces.amount
end

#pallet?Boolean

Returns whether the package ships on a pallet.

Returns:

  • (Boolean)

    whether the package ships on a pallet



60
61
62
# File 'app/services/shipping/package.rb', line 60

def pallet?
  @pallet
end

#pounds(options = {}) ⇒ Numeric Also known as: lb, lbs

Returns the package weight in pounds.

Parameters:

  • options (Hash) (defaults to: {})

    weight options (see #weight)

Options Hash (options):

  • type (Symbol)

    weight type: :actual (default), :volumetric/:dimensional, or :billable

Returns:

  • (Numeric)

    the package weight in pounds



94
95
96
# File 'app/services/shipping/package.rb', line 94

def pounds(options = {})
  weight(options).in_pounds.amount
end

#weight(options = {}) ⇒ Mass Also known as: mass

Returns the package weight.

Parameters:

  • options (Hash) (defaults to: {})

    weight options

Options Hash (options):

  • type (Symbol)

    weight type: :actual (default), :volumetric/:dimensional, or :billable (the greater of actual and volumetric)

Returns:

  • (Mass)

    the package weight



132
133
134
135
136
137
138
139
140
141
142
143
144
# File 'app/services/shipping/package.rb', line 132

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