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



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

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

#after_cancelObject



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

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

#after_resumeObject



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

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

#backordered?Boolean

Returns:

  • (Boolean)


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

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.



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

def cost
  adjustment ? adjustment.amount : 0
end

#currencyObject



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

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



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

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



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

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

#display_item_costObject



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

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

#display_total_costObject



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

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

#editable_by?(user) ⇒ Boolean

Returns:

  • (Boolean)


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

def editable_by?(user)
  !shipped?
end

#finalize!Object



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

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

#include?(variant) ⇒ Boolean

Returns:

  • (Boolean)


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

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

#inventory_units_for(variant) ⇒ Object



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

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

#item_costObject



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

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

#line_itemsObject



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

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



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

def manifest
  inventory_units.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



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

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



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

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

#selected_shipping_rate_idObject



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

def selected_shipping_rate_id
  selected_shipping_rate.try(:id)
end

#selected_shipping_rate_id=(id) ⇒ Object



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

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



229
230
231
# File 'app/models/spree/shipment.rb', line 229

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

#shipped=(value) ⇒ Object



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

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

#shipping_methodObject



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

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

#to_packageObject



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

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



65
66
67
# File 'app/models/spree/shipment.rb', line 65

def to_param
  number
end

#total_costObject



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

def total_cost
  cost + item_cost
end

#tracking_urlObject



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

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.



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

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