Class: Spree::Shipment

Inherits:
ActiveRecord::Base
  • Object
show all
Defined in:
app/models/spree/shipment.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#special_instructionsObject

Returns the value of attribute special_instructions.



18
19
20
# File 'app/models/spree/shipment.rb', line 18

def special_instructions
  @special_instructions
end

Instance Method Details

#add_shipping_method(shipping_method, selected = false) ⇒ Object



87
88
89
# File 'app/models/spree/shipment.rb', line 87

def add_shipping_method(shipping_method, selected = false)
  shipping_rates.create(shipping_method: shipping_method, selected: selected)
end

#after_cancelObject



179
180
181
# File 'app/models/spree/shipment.rb', line 179

def after_cancel
  manifest.each { |item| manifest_restock(item) }
end

#after_resumeObject



183
184
185
# File 'app/models/spree/shipment.rb', line 183

def after_resume
  manifest.each { |item| manifest_unstock(item) }
end

#backordered?Boolean

Returns:

  • (Boolean)


74
75
76
# File 'app/models/spree/shipment.rb', line 74

def backordered?
  inventory_units.any? { |inventory_unit| inventory_unit.backordered? }
end

#costObject Also known as: amount

The adjustment amount associated with this shipment (if any.) Returns only the first adjustment to match the shipment but there should never really be more than one.



126
127
128
# File 'app/models/spree/shipment.rb', line 126

def cost
  adjustment ? adjustment.amount : 0
end

#currencyObject



120
121
122
# File 'app/models/spree/shipment.rb', line 120

def currency
  order ? order.currency : Spree::Config[:currency]
end

#determine_state(order) ⇒ Object

Determines the appropriate state according to the following logic:

pending unless order is complete and order.payment_state is paid shipped if already shipped (ie. does not change the state) ready all other cases



202
203
204
205
206
207
208
# File 'app/models/spree/shipment.rb', line 202

def determine_state(order)
  return 'canceled' if order.canceled?
  return 'pending' unless order.can_ship?
  return 'pending' if inventory_units.any? &:backordered?
  return 'shipped' if state == 'shipped'
  order.paid? ? 'ready' : 'pending'
end

#display_costObject Also known as: display_amount



132
133
134
# File 'app/models/spree/shipment.rb', line 132

def display_cost
  Spree::Money.new(cost, { currency: currency })
end

#display_item_costObject



142
143
144
# File 'app/models/spree/shipment.rb', line 142

def display_item_cost
  Spree::Money.new(item_cost, { currency: currency })
end

#display_total_costObject



150
151
152
# File 'app/models/spree/shipment.rb', line 150

def display_total_cost
  Spree::Money.new(total_cost, { currency: currency })
end

#editable_by?(user) ⇒ Boolean

Returns:

  • (Boolean)


154
155
156
# File 'app/models/spree/shipment.rb', line 154

def editable_by?(user)
  !shipped?
end

#finalize!Object



174
175
176
177
# File 'app/models/spree/shipment.rb', line 174

def finalize!
  InventoryUnit.finalize_units!(inventory_units)
  manifest.each { |item| manifest_unstock(item) }
end

#include?(variant) ⇒ Boolean

Returns:

  • (Boolean)


214
215
216
# File 'app/models/spree/shipment.rb', line 214

def include?(variant)
  inventory_units_for(variant).present?
end

#inventory_units_for(variant) ⇒ Object



218
219
220
# File 'app/models/spree/shipment.rb', line 218

def inventory_units_for(variant)
  inventory_units.group_by(&:variant_id)[variant.id] || []
end

#item_costObject



138
139
140
# File 'app/models/spree/shipment.rb', line 138

def item_cost
  line_items.map(&:amount).sum
end

#line_itemsObject



166
167
168
169
170
171
172
# File 'app/models/spree/shipment.rb', line 166

def line_items
  if order.complete? and Spree::Config[:track_inventory_levels]
    order.line_items.select { |li| inventory_units.pluck(:variant_id).include?(li.variant_id) }
  else
    order.line_items
  end
end

#manifestObject



158
159
160
161
162
163
164
# File 'app/models/spree/shipment.rb', line 158

def manifest
  inventory_units.joins(:variant).includes(:variant).group_by(&:variant).map do |variant, units|
    states = {}
    units.group_by(&:state).each { |state, iu| states[state] = iu.count }
    OpenStruct.new(variant: variant, quantity: units.length, states: states)
  end
end

#refresh_ratesObject



105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'app/models/spree/shipment.rb', line 105

def refresh_rates
  return shipping_rates if shipped?

  self.shipping_rates = Stock::Estimator.new(order).shipping_rates(to_package)

  if shipping_method
    selected_rate = shipping_rates.detect { |rate|
      rate.shipping_method_id == shipping_method.id
    }
    self.selected_shipping_rate_id = selected_rate.id if selected_rate
  end

  shipping_rates
end

#selected_shipping_rateObject



91
92
93
# File 'app/models/spree/shipment.rb', line 91

def selected_shipping_rate
  shipping_rates.where(selected: true).first
end

#selected_shipping_rate_idObject



95
96
97
# File 'app/models/spree/shipment.rb', line 95

def selected_shipping_rate_id
  selected_shipping_rate.try(:id)
end

#selected_shipping_rate_id=(id) ⇒ Object



99
100
101
102
103
# File 'app/models/spree/shipment.rb', line 99

def selected_shipping_rate_id=(id)
  shipping_rates.update_all(selected: false)
  shipping_rates.update(id, selected: true)
  self.save!
end

#set_up_inventory(state, variant, order) ⇒ Object



230
231
232
233
234
235
# File 'app/models/spree/shipment.rb', line 230

def set_up_inventory(state, variant, order)
  self.inventory_units.create(
    { variant_id: variant.id, state: state, order_id: order.id },
    without_protection: true
  )
end

#shipped=(value) ⇒ Object



78
79
80
81
# File 'app/models/spree/shipment.rb', line 78

def shipped=(value)
  return unless value == '1' && shipped_at.nil?
  self.shipped_at = Time.now
end

#shipping_methodObject



83
84
85
# File 'app/models/spree/shipment.rb', line 83

def shipping_method
  selected_shipping_rate.try(:shipping_method) || shipping_rates.first.try(:shipping_method)
end

#to_packageObject



222
223
224
225
226
227
228
# File 'app/models/spree/shipment.rb', line 222

def to_package
  package = Stock::Package.new(stock_location, order)
  inventory_units.includes(:variant).each do |inventory_unit|
    package.add inventory_unit.variant, 1, inventory_unit.state_name
  end
  package
end

#to_paramObject



68
69
70
71
72
# File 'app/models/spree/shipment.rb', line 68

def to_param
  number if number
  generate_shipment_number unless number
  number.to_s.to_url.upcase
end

#total_costObject



146
147
148
# File 'app/models/spree/shipment.rb', line 146

def total_cost
  cost + item_cost
end

#tracking_urlObject



210
211
212
# File 'app/models/spree/shipment.rb', line 210

def tracking_url
  @tracking_url ||= shipping_method.build_tracking_url(tracking)
end

#update!(order) ⇒ Object

Updates various aspects of the Shipment while bypassing any callbacks. Note that this method takes an explicit reference to the Order object. This is necessary because the association actually has a stale (and unsaved) copy of the Order and so it will not yield the correct results.



190
191
192
193
194
195
# File 'app/models/spree/shipment.rb', line 190

def update!(order)
  old_state = state
  new_state = determine_state(order)
  update_column :state, new_state
  after_ship if new_state == 'shipped' and old_state != 'shipped'
end