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


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

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

#after_cancelObject


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

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

#after_resumeObject


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

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

#backordered?Boolean


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

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.


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

def cost
  adjustment ? adjustment.amount : 0
end

#currencyObject


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

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


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

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


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

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

#display_item_costObject


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

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

#display_total_costObject


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

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

#editable_by?(user) ⇒ Boolean


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

def editable_by?(user)
  !shipped?
end

#finalize!Object


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

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

#include?(variant) ⇒ Boolean


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

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

#inventory_units_for(variant) ⇒ Object


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

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

#item_costObject


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

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

#line_itemsObject


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

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


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

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


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

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


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

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

#selected_shipping_rate_idObject


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

def selected_shipping_rate_id
  selected_shipping_rate.try(:id)
end

#selected_shipping_rate_id=(id) ⇒ Object


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

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


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

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


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

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

#shipping_methodObject


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

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

#to_packageObject


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

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


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

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

#total_costObject


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

def total_cost
  cost + item_cost
end

#tracking_urlObject


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

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.


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

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