Class: Spree::LineItem
- Inherits:
-
Object
- Object
- Spree::LineItem
- Extended by:
- DisplayMoney
- Includes:
- Metadata, Metafields
- Defined in:
- app/models/spree/line_item.rb
Constant Summary collapse
- DB_INTEGER_MAX =
(2**31) - 1
Instance Attribute Summary collapse
-
#target_shipment ⇒ Object
Returns the value of attribute target_shipment.
Instance Method Summary collapse
-
#amount ⇒ BigDecimal
(also: #subtotal)
Returns the amount (price * quantity) of the line item.
-
#any_shipped? ⇒ Boolean
returns true if any of the inventory units are shipped.
-
#compare_at_amount ⇒ BigDecimal
Returns the compare at amount (compare at price * quantity) of the line item.
- #copy_price ⇒ Object
- #copy_tax_category ⇒ Object
- #discounted_price ⇒ Object
-
#final_amount ⇒ BigDecimal
(also: #total)
Returns the final amount of the line item.
-
#fully_shipped? ⇒ Boolean
returns true if all of the inventory units are shipped.
-
#insufficient_stock? ⇒ Boolean
Returns true if the line item has insufficient stock.
-
#item_weight ⇒ BigDecimal
Returns the weight of the line item.
-
#maximum_quantity ⇒ Integer
Returns the maximum quantity that can be added to the line item.
- #options=(options = {}) ⇒ Object
-
#recalculate_price ⇒ void
Recalculates and persists the price based on the current quantity and pricing context This is used for volume-based pricing and other price list rules.
-
#shipping_cost ⇒ BigDecimal
Returns the shipping cost for the line item.
-
#sufficient_stock? ⇒ Boolean
Returns true if the line item has sufficient stock.
-
#tax_total ⇒ BigDecimal
returns the total tax amount.
-
#taxable_amount ⇒ BigDecimal
(also: #discounted_amount)
Returns the taxable amount (amount + taxable adjustment total) of the line item.
-
#taxable_basis ⇒ BigDecimal
Returns the amount this line item is taxed on: the discounted amount reduced further by the line item's proportional share of any whole-order promotions, which are adjustments on the order itself and therefore not part of
taxable_adjustment_total. -
#thumbnail ⇒ Spree::Asset?
Returns the thumbnail image for this line item Prefers variant primary media, falls back to product primary media.
- #update_price ⇒ Object
-
#with_digital_assets? ⇒ Boolean
Returns true if the line item variant has digital assets.
Methods included from DisplayMoney
Methods included from Metadata
#metadata, #metadata=, #public_metadata=
Instance Attribute Details
#target_shipment ⇒ Object
Returns the value of attribute target_shipment.
69 70 71 |
# File 'app/models/spree/line_item.rb', line 69 def target_shipment @target_shipment end |
Instance Method Details
#amount ⇒ BigDecimal Also known as: subtotal
Returns the amount (price * quantity) of the line item
119 120 121 |
# File 'app/models/spree/line_item.rb', line 119 def amount price * quantity end |
#any_shipped? ⇒ Boolean
returns true if any of the inventory units are shipped
210 211 212 |
# File 'app/models/spree/line_item.rb', line 210 def any_shipped? inventory_units.any?(&:shipped?) end |
#compare_at_amount ⇒ BigDecimal
Returns the compare at amount (compare at price * quantity) of the line item
126 127 128 |
# File 'app/models/spree/line_item.rb', line 126 def compare_at_amount (variant.compare_at_amount_in(currency) || 0) * quantity end |
#copy_price ⇒ Object
78 79 80 81 82 83 84 |
# File 'app/models/spree/line_item.rb', line 78 def copy_price if variant update_price if price.nil? self.cost_price = variant.cost_price if cost_price.nil? self.currency = order.currency if currency.nil? end end |
#copy_tax_category ⇒ Object
94 95 96 |
# File 'app/models/spree/line_item.rb', line 94 def copy_tax_category self.tax_category = variant.tax_category if variant end |
#discounted_price ⇒ Object
110 111 112 113 114 |
# File 'app/models/spree/line_item.rb', line 110 def discounted_price return price if quantity.zero? price - (promo_total.abs / quantity) end |
#final_amount ⇒ BigDecimal Also known as: total
Returns the final amount of the line item
175 176 177 |
# File 'app/models/spree/line_item.rb', line 175 def final_amount amount + adjustment_total end |
#fully_shipped? ⇒ Boolean
returns true if all of the inventory units are shipped
217 218 219 |
# File 'app/models/spree/line_item.rb', line 217 def fully_shipped? inventory_units.all?(&:shipped?) end |
#insufficient_stock? ⇒ Boolean
Returns true if the line item has insufficient stock
203 204 205 |
# File 'app/models/spree/line_item.rb', line 203 def insufficient_stock? !sufficient_stock? end |
#item_weight ⇒ BigDecimal
Returns the weight of the line item
182 183 184 |
# File 'app/models/spree/line_item.rb', line 182 def item_weight variant.weight * quantity end |
#maximum_quantity ⇒ Integer
Returns the maximum quantity that can be added to the line item
262 263 264 |
# File 'app/models/spree/line_item.rb', line 262 def maximum_quantity @maximum_quantity ||= variant.backorderable? ? DB_INTEGER_MAX : variant.total_on_hand end |
#options=(options = {}) ⇒ Object
248 249 250 251 252 253 254 255 256 257 |
# File 'app/models/spree/line_item.rb', line 248 def ( = {}) return unless .present? opts = .dup # we will be deleting from the hash, so leave the caller's copy intact currency = opts.delete(:currency) || order.try(:currency) update_price_from_modifier(currency, opts) assign_attributes opts end |
#recalculate_price ⇒ void
This method returns an undefined value.
Recalculates and persists the price based on the current quantity and pricing context This is used for volume-based pricing and other price list rules
276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 |
# File 'app/models/spree/line_item.rb', line 276 def recalculate_price context = Spree::Pricing::Context.from_order(variant, order, quantity: quantity) currency_price = variant.price_for(context) return unless currency_price.present? new_price = currency_price.price_including_vat_for(tax_zone: tax_zone) return unless new_price.present? new_price_list_id = currency_price.price_list_id # Only update if price or price list changed if new_price != price || new_price_list_id != price_list_id update_columns(price: new_price, price_list_id: new_price_list_id, updated_at: Time.current) end end |
#shipping_cost ⇒ BigDecimal
Returns the shipping cost for the line item
224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 |
# File 'app/models/spree/line_item.rb', line 224 def shipping_cost shipments.sum do |shipment| # Skip cancelled shipments return BigDecimal('0') if shipment.canceled? # Skip shipments with no cost/zero cost return BigDecimal('0') if shipment.cost.zero? # Get total inventory units in this shipment total_units = shipment.inventory_units # Calculate proportional shipping cost return BigDecimal('0') if total_units.empty? # Get all inventory units in this shipment for this line item line_item_units = shipment.inventory_units.find_all { |unit| unit.line_item_id == id }.count # Calculate proportional shipping cost return BigDecimal('0') if line_item_units.zero? shipment.cost * (line_item_units.to_d / total_units.count) end end |
#sufficient_stock? ⇒ Boolean
Returns true if the line item has sufficient stock
The order's own active stock reservations are excluded from the availability check — a customer's own checkout hold must not make their own line item look out of stock.
196 197 198 |
# File 'app/models/spree/line_item.rb', line 196 def sufficient_stock? Spree::Stock::Quantifier.new(variant, excluded_order: order).can_supply?(quantity) end |
#tax_total ⇒ BigDecimal
returns the total tax amount
142 143 144 |
# File 'app/models/spree/line_item.rb', line 142 def tax_total included_tax_total + additional_tax_total end |
#taxable_amount ⇒ BigDecimal Also known as: discounted_amount
Returns the taxable amount (amount + taxable adjustment total) of the line item
135 136 137 |
# File 'app/models/spree/line_item.rb', line 135 def taxable_amount amount + taxable_adjustment_total end |
#taxable_basis ⇒ BigDecimal
Returns the amount this line item is taxed on: the discounted amount
reduced further by the line item's proportional share of any
whole-order promotions, which are adjustments on the order itself and
therefore not part of taxable_adjustment_total. Never negative.
155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 |
# File 'app/models/spree/line_item.rb', line 155 def taxable_basis basis = taxable_amount return basis if basis <= 0 order_discount = order.order_level_promo_total return basis if order_discount.zero? # summed in SQL so the allocation uses the persisted adjustment totals # of all line items, not a possibly stale cached association items_total = order.line_items.reorder(nil).pick( Arel.sql('COALESCE(SUM(price * quantity + taxable_adjustment_total), 0)') ) return basis if items_total <= 0 [basis + (order_discount * basis / items_total), BigDecimal(0)].max end |
#thumbnail ⇒ Spree::Asset?
Returns the thumbnail image for this line item Prefers variant primary media, falls back to product primary media
61 62 63 |
# File 'app/models/spree/line_item.rb', line 61 def thumbnail variant.primary_media || product.primary_media end |
#update_price ⇒ Object
86 87 88 89 90 91 92 |
# File 'app/models/spree/line_item.rb', line 86 def update_price context = Spree::Pricing::Context.from_order(variant, order, quantity: quantity) currency_price = variant.price_for(context) self.price = currency_price.price_including_vat_for(tax_zone: tax_zone) if currency_price.present? self.price_list_id = currency_price.price_list_id if currency_price.present? end |
#with_digital_assets? ⇒ Boolean
Returns true if the line item variant has digital assets
269 270 271 |
# File 'app/models/spree/line_item.rb', line 269 def with_digital_assets? variant.with_digital_assets? end |