Class: Shoppe::OrderItem

Inherits:
ActiveRecord::Base
  • Object
show all
Defined in:
app/models/shoppe/order_item.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.add_item(ordered_item, quantity = 1) ⇒ Shoppe::OrderItem

This allows you to add a product to the scoped order. For example Order.first.order_items.add_product(…). This will either increase the quantity of the value in the order or create a new item if one does not exist already.

Parameters:

  • ordered_item (Object)

    an object which implements the Shoppe::OrderableItem protocol

  • quantity (Fixnum) (defaults to: 1)

    the number of items to order

Returns:

Raises:



48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'app/models/shoppe/order_item.rb', line 48

def self.add_item(ordered_item, quantity = 1)
  raise Errors::UnorderableItem, :ordered_item => ordered_item unless ordered_item.orderable?
  transaction do
    if existing = self.where(:ordered_item_id => ordered_item.id, :ordered_item_type => ordered_item.class.to_s).first
      existing.increase!(quantity)
      existing
    else
      new_item = self.create(:ordered_item => ordered_item, :quantity => 0)
      new_item.increase!(quantity)
      new_item
    end
  end
end

Instance Method Details

#accept!Object

Trigger when the associated order is accepted



186
187
# File 'app/models/shoppe/order_item.rb', line 186

def accept!
end

#allocate_unallocated_stock!Object

Allocate any unallocated stock for this order item. There is no return value.



233
234
235
236
237
# File 'app/models/shoppe/order_item.rb', line 233

def allocate_unallocated_stock!
  if self.ordered_item.stock_control? && self.unallocated_stock != 0
    self.ordered_item.stock_level_adjustments.create!(:parent => self, :adjustment => 0 - self.unallocated_stock, :description => "Order ##{self.order.number}")
  end
end

#allocated_stockFixnum

How much stock has been allocated to this item?

Returns:

  • (Fixnum)


215
216
217
# File 'app/models/shoppe/order_item.rb', line 215

def allocated_stock
  0 - self.stock_level_adjustments.sum(:adjustment)
end

#cache_pricingObject

Cache the pricing for this order item



165
166
167
168
169
170
# File 'app/models/shoppe/order_item.rb', line 165

def cache_pricing
  write_attribute :weight, self.weight
  write_attribute :unit_price, self.unit_price
  write_attribute :unit_cost_price, self.unit_cost_price
  write_attribute :tax_rate, self.tax_rate
end

#cache_pricing!Object

Cache the pricing for this order item and save



173
174
175
176
# File 'app/models/shoppe/order_item.rb', line 173

def cache_pricing!
  cache_pricing
  save!
end

#confirm!Object

Trigger when the associated order is confirmed. It handles caching the values of the monetary items and allocating stock as appropriate.



180
181
182
183
# File 'app/models/shoppe/order_item.rb', line 180

def confirm!
  cache_pricing!
  allocate_unallocated_stock!
end

#decrease!(amount = 1) ⇒ Object

Decreases the quantity of items in the order by the number provided.

Parameters:

  • amount (Fixnum) (defaults to: 1)


93
94
95
96
97
98
99
# File 'app/models/shoppe/order_item.rb', line 93

def decrease!(amount = 1)
  transaction do
    self.quantity -= amount
    self.quantity == 0 ? self.destroy : self.save!
    self.order.remove_delivery_service_if_invalid
  end
end

#in_stock?Boolean

Do we have the stock needed to fulfil this order?

Returns:

  • (Boolean)


197
198
199
200
201
202
203
# File 'app/models/shoppe/order_item.rb', line 197

def in_stock?
  if self.ordered_item && self.ordered_item.stock_control?
    self.ordered_item.stock >= unallocated_stock
  else
    true
  end
end

#increase!(amount = 1) ⇒ Object

Increases the quantity of items in the order by the number provided. Will raise an error if we don’t have the stock to do this.

Parameters:

  • quantity (Fixnum)


79
80
81
82
83
84
85
86
87
88
# File 'app/models/shoppe/order_item.rb', line 79

def increase!(amount = 1)
  transaction do
    self.quantity += amount
    unless self.in_stock?
      raise Shoppe::Errors::NotEnoughStock, :ordered_item => self.ordered_item, :requested_stock => self.quantity
    end
    self.save!
    self.order.remove_delivery_service_if_invalid
  end
end

#orderShoppe::Order

The associated order

Returns:



9
# File 'app/models/shoppe/order_item.rb', line 9

belongs_to :order, :class_name => 'Shoppe::Order', :touch => true

#reject!Object

Trigged when the associated order is rejected..



190
191
192
# File 'app/models/shoppe/order_item.rb', line 190

def reject!
  self.stock_level_adjustments.destroy_all
end

#removeShoppe::OrderItem

Remove a product from an order. It will also ensure that the order’s custom delivery service is updated if appropriate.

Returns:



66
67
68
69
70
71
72
# File 'app/models/shoppe/order_item.rb', line 66

def remove
  transaction do
    self.destroy!
    self.order.remove_delivery_service_if_invalid
    self
  end
end

#sub_totalBigDecimal

The sub total for the product

Returns:

  • (BigDecimal)


153
154
155
# File 'app/models/shoppe/order_item.rb', line 153

def sub_total
  quantity * unit_price
end

#tax_amountBigDecimal

The total tax for the item

Returns:

  • (BigDecimal)


139
140
141
# File 'app/models/shoppe/order_item.rb', line 139

def tax_amount
  read_attribute(:tax_amount) || (self.sub_total / BigDecimal(100)) * self.tax_rate
end

#tax_rateBigDecimal

The tax rate for the item

Returns:

  • (BigDecimal)


132
133
134
# File 'app/models/shoppe/order_item.rb', line 132

def tax_rate
  read_attribute(:tax_rate) || ordered_item.try(:tax_rate).try(:rate_for, self.order) || BigDecimal(0)  
end

#totalBigDecimal

The total price including tax for the order line

Returns:

  • (BigDecimal)


160
161
162
# File 'app/models/shoppe/order_item.rb', line 160

def total
  tax_amount + sub_total
end

#total_costBigDecimal

The total cost for the product

Returns:

  • (BigDecimal)


146
147
148
# File 'app/models/shoppe/order_item.rb', line 146

def total_cost
  quantity * unit_cost_price
end

#total_weightBigDecimal

Return the total weight of the item

Returns:

  • (BigDecimal)


111
112
113
# File 'app/models/shoppe/order_item.rb', line 111

def total_weight
  quantity * weight
end

#unallocated_stockFixnum

How much stock remains to be allocated for this order?

Returns:

  • (Fixnum)


208
209
210
# File 'app/models/shoppe/order_item.rb', line 208

def unallocated_stock
  self.quantity - allocated_stock
end

#unit_cost_priceBigDecimal

The cost price for the item

Returns:

  • (BigDecimal)


125
126
127
# File 'app/models/shoppe/order_item.rb', line 125

def unit_cost_price
  read_attribute(:unit_cost_price) || ordered_item.try(:cost_price) || BigDecimal(0)
end

#unit_priceBigDecimal

The unit price for the item

Returns:

  • (BigDecimal)


118
119
120
# File 'app/models/shoppe/order_item.rb', line 118

def unit_price
  read_attribute(:unit_price) || ordered_item.try(:price) || BigDecimal(0)
end

#validate_stock_levelsObject

Validate the stock level against the product and update as appropriate. This method will be executed before an order is completed. If we have run out of this product, we will update the quantity to an appropriate level (or remove the order item) and return the object.



222
223
224
225
226
227
228
229
230
# File 'app/models/shoppe/order_item.rb', line 222

def validate_stock_levels
  if in_stock?
    false
  else
    self.quantity = self.ordered_item.stock
    self.quantity == 0 ? self.destroy : self.save!
    self
  end
end

#weightBigDecimal

The total weight of the item

Returns:

  • (BigDecimal)


104
105
106
# File 'app/models/shoppe/order_item.rb', line 104

def weight
  read_attribute(:weight) || ordered_item.try(:weight) || BigDecimal(0)
end