Module: Models::ShipMeasurable

Extended by:
ActiveSupport::Concern
Includes:
Memery
Included in:
Delivery, ShipQuotable, StandaloneDelivery
Defined in:
app/concerns/models/ship_measurable.rb

Overview

Aggregate shipping measurements for an order: picks the best available
shipment set (complete > packed > suggested) and derives weight, volume,
freight class, and carton/pallet/crate counts from it.

Instance Method Summary collapse

Instance Method Details

#cartons_totalInteger

Number of carton shipments in the current shipment set.

Returns:

  • (Integer)


78
79
80
# File 'app/concerns/models/ship_measurable.rb', line 78

def cartons_total
  shipment_set.cartons.size
end

#crates_totalInteger

Number of crate shipments in the current shipment set.

Returns:

  • (Integer)


92
93
94
# File 'app/concerns/models/ship_measurable.rb', line 92

def crates_total
  shipment_set.crates.size
end

#pallets_totalInteger

Number of pallet (and palleted-crate) shipments in the current set.

Returns:

  • (Integer)


85
86
87
# File 'app/concerns/models/ship_measurable.rb', line 85

def pallets_total
  shipment_set.where(container_type: %i[pallet palleted_crate]).count
end

#ship_freight_class_from_shipmentsInteger?

Freight class derived from pounds-per-cubic-foot density, via
Shipping::UpsFreight::FREIGHT_CLASS_BY_PCF. Nil when weight or volume
is unavailable.

Returns:

  • (Integer, nil)


60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'app/concerns/models/ship_measurable.rb', line 60

def ship_freight_class_from_shipments
  return unless (swfs = ship_weight_from_shipments)
  return unless (svs = ship_volume_from_shipments_in_cubic_feet)

  pcf = swfs / svs
  freight_class = nil
  Shipping::UpsFreight::FREIGHT_CLASS_BY_PCF.each do |fc, pcf_limits|
    if pcf >= pcf_limits[:lower] && pcf < pcf_limits[:upper]
      freight_class = fc.to_i
      break
    end
  end
  freight_class
end

#ship_volume_from_shipmentsBigDecimal?

Total volume (cubic inches) across the shipments used for measurement;
nil when any shipment lacks a volume.

Returns:

  • (BigDecimal, nil)


42
43
44
45
46
# File 'app/concerns/models/ship_measurable.rb', line 42

def ship_volume_from_shipments
  vol = nil
  vol = shipments_for_measure.sum(&:volume) if shipments_for_measure.present? && shipments_for_measure.all?(&:volume)
  vol
end

#ship_volume_from_shipments_in_cubic_feetFloat?

Shipment volume converted from cubic inches to cubic feet.

Returns:

  • (Float, nil)


51
52
53
# File 'app/concerns/models/ship_measurable.rb', line 51

def ship_volume_from_shipments_in_cubic_feet
  (svs = ship_volume_from_shipments) ? svs / 1728.0 : nil
end

#ship_weight_from_shipmentsBigDecimal

Total weight across the shipments used for measurement.

Returns:

  • (BigDecimal)


34
35
36
# File 'app/concerns/models/ship_measurable.rb', line 34

def ship_weight_from_shipments
  shipments_for_measure.sum(:weight)
end

#shipment_setActiveRecord::Relation<Shipment>

Shipments in complete/awaiting_label stage take precedence over packed shipments which take precedence over suggested shipments

Returns:



15
16
17
18
19
# File 'app/concerns/models/ship_measurable.rb', line 15

def shipment_set
  shipments.where(state: %w[awaiting_label label_complete manually_complete]).presence ||
    shipments.packed.presence ||
    shipments.suggested
end

#shipments_for_measureActiveRecord::Relation<Shipment>

TODO:

Once pallets are defined with boxes, use the pallet weight and volume

Returns the shipments to use for measurements. Cartons are used by default, unless none are defined then we'll use the pallet

Returns:

  • (ActiveRecord::Relation<Shipment>)

    top-level shipments only



25
26
27
28
# File 'app/concerns/models/ship_measurable.rb', line 25

def shipments_for_measure
  # We only use top level shipments, ie shipments that are not contained in other shipments/pallets
  shipment_set.top_level
end