Class: ActiveShipping::ShipmentPacker

Inherits:
Object
  • Object
show all
Defined in:
lib/active_shipping/shipment_packer.rb

Defined Under Namespace

Classes: ExcessPackageQuantity, OverweightItem

Constant Summary collapse

EXCESS_PACKAGE_QUANTITY_THRESHOLD =
10_000

Class Method Summary collapse

Class Method Details

.pack(items, dimensions, maximum_weight, currency) ⇒ Object



16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/active_shipping/shipment_packer.rb', line 16

def pack(items, dimensions, maximum_weight, currency)
  return [] if items.empty?
  packages = []
  items.map!(&:symbolize_keys)

  # Naive in that it assumes weight is equally distributed across all items
  # Should raise early enough in most cases
  validate_total_weight(items, maximum_weight)
  items_to_pack = items.map(&:dup).sort_by! { |i| i[:grams].to_i }

  state = :package_empty
  while state != :packing_finished
    case state
    when :package_empty
      package_weight, package_value = 0, 0
      state = :filling_package
    when :filling_package
      validate_package_quantity(packages.count)

      items_to_pack.each do |item|
        quantity = determine_fillable_quantity_for_package(item, maximum_weight, package_weight)
        package_weight += item_weight(quantity, item[:grams])
        package_value += item_value(quantity, item[:price])
        item[:quantity] = item[:quantity].to_i - quantity
      end

      items_to_pack.reject! { |i| i[:quantity].to_i == 0 }
      state = :package_full
    when :package_full
      packages << ActiveShipping::Package.new(package_weight, dimensions, value: package_value, currency: currency)
      state = items_to_pack.any? ? :package_empty : :packing_finished
    end
  end

  packages
end