Class: Spree::OrderShipping

Inherits:
Object
  • Object
show all
Defined in:
app/models/spree/order_shipping.rb

Overview

A service layer that handles generating Carton objects when inventory units are actually shipped. It also takes care of things like updating order and shipment states and delivering shipment emails as needed.

Instance Method Summary collapse

Constructor Details

#initialize(order) ⇒ OrderShipping



5
6
7
# File 'app/models/spree/order_shipping.rb', line 5

def initialize(order)
  @order = order
end

Instance Method Details

#ship(inventory_units:, stock_location:, address:, shipping_method:, shipped_at: Time.current, external_number: nil, tracking_number: nil, suppress_mailer: false) ⇒ Object

Generate a carton from the supplied inventory units and marks those units as shipped. Also sends shipment emails if appropriate and updates shipment_states for associated orders.



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'app/models/spree/order_shipping.rb', line 43

def ship(inventory_units:, stock_location:, address:, shipping_method:,
         shipped_at: Time.current, external_number: nil, tracking_number: nil, suppress_mailer: false)

  carton = nil

  Spree::InventoryUnit.transaction do
    inventory_units.each(&:ship!)

    carton = Spree::Carton.create!(
      stock_location: stock_location,
      address: address,
      shipping_method: shipping_method,
      inventory_units: inventory_units,
      shipped_at: shipped_at,
      external_number: external_number,
      tracking: tracking_number
    )
  end

  inventory_units.map(&:shipment).uniq.each do |shipment|
    # Temporarily propagate the tracking number to the shipment as well
    # TODO: Remove tracking numbers from shipments.
    shipment.update_attributes!(tracking: tracking_number)

    next unless shipment.inventory_units.reload.all? { |iu| iu.shipped? || iu.canceled? }
    # TODO: make OrderShipping#ship_shipment call Shipment#ship! rather than
    # having Shipment#ship! call OrderShipping#ship_shipment. We only really
    # need this `update_columns` for the specs, until we make that change.
    shipment.update_columns(state: 'shipped', shipped_at: Time.current)
  end

  send_shipment_emails(carton) if stock_location.fulfillable? && !suppress_mailer # e.g. digital gift cards that aren't actually shipped
  @order.recalculate

  carton
end

#ship_shipment(shipment, external_number: nil, tracking_number: nil, suppress_mailer: false) ⇒ Object

A shortcut method that ships all inventory units in a shipment in a single carton. See also #ship.



16
17
18
19
20
21
22
23
24
25
26
27
28
29
# File 'app/models/spree/order_shipping.rb', line 16

def ship_shipment(shipment, external_number: nil, tracking_number: nil, suppress_mailer: false)
  ship(
    inventory_units: shipment.inventory_units.shippable,
    stock_location: shipment.stock_location,
    address: shipment.order.ship_address,
    shipping_method: shipment.shipping_method,
    shipped_at: Time.current,
    external_number: external_number,
    # TODO: Remove the `|| shipment.tracking` once Shipment#ship! is called by
    # OrderShipping#ship rather than vice versa
    tracking_number: tracking_number || shipment.tracking,
    suppress_mailer: suppress_mailer
  )
end