Class: Shipping::Container

Inherits:
Object
  • Object
show all
Includes:
ActiveModel::API, ActiveModel::Attributes
Defined in:
app/services/shipping/container.rb

Overview

Package PORO

Defined Under Namespace

Classes: InvalidPackageDimensions

Constant Summary collapse

DIM_WEIGHT_DIVISOR =

Choose UPS's dimensional weight divisor (also Purolator's ground divisor) which can represent the generic/standard value

139
LARGE_PACKAGE_THRESHOLD =

Choose UPS's threshold (also Purolator's threshold) which can represent the generic/standard value

130
LARGE_PACKAGE_MIN_WEIGHT =

Choose UPS's minimum weight for large packages which can represent the generic/standard value

90
CLOSE_TO_PERCENT_THRESHOLD =

Default percentage to use to decide if one package is close to another in terms of dimensions and weight

20.0
CLOSE_TO_MIN_DIM_DELTA =

Minimum absolute difference (inches) to count as a real discrepancy

2.0
CLOSE_TO_MIN_WEIGHT_DELTA =

Minimum absolute difference (lbs) to count as a real discrepancy

2.0

Instance Method Summary collapse

Constructor Details

#initialize(length:, width:, height:, weight: nil, container_type: Shipment.container_types.keys.first, flat_rate_package_type: nil) ⇒ Container

Returns a new instance of Container.



22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'app/services/shipping/container.rb', line 22

def initialize(length:, width:, height:, weight: nil, container_type: Shipment.container_types.keys.first, flat_rate_package_type: nil)
  super()
  # Make sure we get everything in a sort order
  raise InvalidPackageDimensions.new unless length && width && height
  self.length, self.width, self.height = *[length,width,height].sort.reverse
  self.weight = weight.to_f.positive? ? weight : 0.1 #Because we always need a weight
  # 1 in will be our unit minimum dimension
  self.length = 1 if self.length < 1
  self.width = 1 if self.width < 1
  self.height = 1 if self.height < 1
  self.container_type = container_type
  self.flat_rate_package_type = flat_rate_package_type
end

Instance Method Details

#add_content(item_id, quantity) ⇒ Object



36
37
38
# File 'app/services/shipping/container.rb', line 36

def add_content(item_id, quantity)
  contents << Shipping::PackageContent.new(item_id: item_id, quantity: quantity)
end

#billable_weightObject



68
69
70
71
72
# File 'app/services/shipping/container.rb', line 68

def billable_weight
  weights = [dimensional_weight, weight]
  weights << LARGE_PACKAGE_MIN_WEIGHT if large_package_surcharge?
  weights.max.ceil
end

#close_to?(package_to_compare:, percent_threshold: nil, exclude_weight: false) ⇒ Boolean

Returns:

  • (Boolean)


78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'app/services/shipping/container.rb', line 78

def close_to?(package_to_compare:, percent_threshold: nil, exclude_weight: false)
  res = true
  percent_threshold ||= CLOSE_TO_PERCENT_THRESHOLD
  dim_syms_to_check = [:length, :width, :height]
  dim_syms_to_check += [:weight] unless exclude_weight
  dim_syms_to_check.each do |dim_sym|
    dim = send(dim_sym)
    compare_dim = package_to_compare.send(dim_sym)
    abs_delta = (dim - compare_dim).abs
    min_delta = dim_sym == :weight ? CLOSE_TO_MIN_WEIGHT_DELTA : CLOSE_TO_MIN_DIM_DELTA
    next if abs_delta < min_delta

    discrepancy_percent = dim.zero? ? 100.0 : 100.0 * abs_delta / dim
    Rails.logger.debug("Shipping::Container close_to? percent_threshold: #{percent_threshold}%, compare_dim: #{compare_dim}, discrepancy_percent: #{discrepancy_percent}%")
    if discrepancy_percent > percent_threshold
      res = false
    end
  end
  res
end

#cubic_sizeObject



52
53
54
# File 'app/services/shipping/container.rb', line 52

def cubic_size
  length * width * height
end

#cubic_size_in_ftObject



56
57
58
# File 'app/services/shipping/container.rb', line 56

def cubic_size_in_ft
  cubic_size / 1728.0
end

#dimensional_weightObject



64
65
66
# File 'app/services/shipping/container.rb', line 64

def dimensional_weight
  ( rounded_cubic_size / DIM_WEIGHT_DIVISOR ).ceil #round up
end

#girthObject



40
41
42
# File 'app/services/shipping/container.rb', line 40

def girth
  2.0*(width+height)
end

#large_package_surcharge?Boolean

Returns:

  • (Boolean)


74
75
76
# File 'app/services/shipping/container.rb', line 74

def large_package_surcharge?
  length_plus_girth > LARGE_PACKAGE_THRESHOLD
end

#length_plus_girthObject



44
45
46
# File 'app/services/shipping/container.rb', line 44

def length_plus_girth
  (length + girth).ceil
end

#rounded_cubic_sizeObject



48
49
50
# File 'app/services/shipping/container.rb', line 48

def rounded_cubic_size
  length.round * width.round * height.round
end

#surfaceObject



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

def surface
  2 * ((length * height) + (width * height))
end