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.



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

def special_instructions
  @special_instructions
end

Instance Method Details

#add_shipping_method(shipping_method, selected = false) ⇒ Object



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

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

#after_cancelObject



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

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

#after_resumeObject



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

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

#backordered?Boolean

Returns:

  • (Boolean)


71
72
73
# File 'app/models/spree/shipment.rb', line 71

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.



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

def cost
  adjustment ? adjustment.amount : 0
end

#currencyObject



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

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



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

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



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

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

#display_item_costObject



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

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

#display_total_costObject



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

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

#editable_by?(user) ⇒ Boolean

Returns:

  • (Boolean)


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

def editable_by?(user)
  !shipped?
end

#finalize!Object



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

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

#include?(variant) ⇒ Boolean

Returns:

  • (Boolean)


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

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

#inventory_units_for(variant) ⇒ Object



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

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

#item_costObject



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

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

#line_itemsObject



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

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

#manifestObject



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

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



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

def refresh_rates
  return shipping_rates if shipped?
  return [] unless can_get_rates?

  # StockEstimator.new assigment below will replace the current shipping_method
  original_shipping_method_id = shipping_method.try(:id)

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

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

  shipping_rates
end

#selected_shipping_rateObject



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

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

#selected_shipping_rate_idObject



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

def selected_shipping_rate_id
  selected_shipping_rate.try(:id)
end

#selected_shipping_rate_id=(id) ⇒ Object



96
97
98
99
100
# File 'app/models/spree/shipment.rb', line 96

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



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

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



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

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

#shipping_methodObject



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

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

#to_packageObject



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

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



67
68
69
# File 'app/models/spree/shipment.rb', line 67

def to_param
  number
end

#total_costObject



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

def total_cost
  cost + item_cost
end

#tracking_urlObject



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

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.



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

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