Class: Spree::ItemAdjustments

Inherits:
Object
  • Object
show all
Defined in:
app/models/spree/item_adjustments.rb

Overview

Manage (recalculate) item (LineItem or Shipment) adjustments

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(item) ⇒ ItemAdjustments

Returns a new instance of ItemAdjustments.

Parameters:



7
8
9
# File 'app/models/spree/item_adjustments.rb', line 7

def initialize(item)
  @item = item
end

Instance Attribute Details

#itemObject (readonly)

Returns the value of attribute item.



4
5
6
# File 'app/models/spree/item_adjustments.rb', line 4

def item
  @item
end

Instance Method Details

#updateObject

Update the item’s adjustments and totals

If the item is an Order, this will update and select the best promotion adjustment.

If it is a LineItem or Shipment, it will update and select the best promotion adjustment, update tax adjustments, update cancellation adjustments, and then update the total fields (promo_total, included_tax_total, additional_tax_total, and adjustment_total) on the item.

This is a noop if the item is not persisted.



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'app/models/spree/item_adjustments.rb', line 23

def update
  return @item unless item.persisted?

  # Promotion adjustments must be applied first, then tax adjustments.
  # This fits the criteria for VAT tax as outlined here:
  # http://www.hmrc.gov.uk/vat/managing/charging/discounts-etc.htm#1
  #
  # It also fits the criteria for sales tax as outlined here:
  # http://www.boe.ca.gov/formspubs/pub113/
  #
  # Tax adjustments come in not one but *two* exciting flavours:
  # Included & additional

  # Included tax adjustments are those which are included in the price.
  # These ones should not affect the eventual total price.
  #
  # Additional tax adjustments are the opposite, affecting the final total.

  promotion_adjustments = adjustments.select(&:promotion?)
  promotion_adjustments.each(&:update!)

  promo_total = PromotionChooser.new(promotion_adjustments).update

  # Calculating the totals for the order here would be incorrect. Order's
  # totals are the sum of the adjustments on all child models, as well as
  # its own.
  #
  # We want to select the best promotion for the order, but the remainder
  # of the calculations here are done in the OrderUpdater instead.
  return if Spree::Order === item

  @item.promo_total = promo_total

  tax = adjustments.select(&:tax?)

  @item.included_tax_total = tax.select(&:included?).map(&:update!).compact.sum
  @item.additional_tax_total = tax.reject(&:included?).map(&:update!).compact.sum

  item_cancellation_total = adjustments.select(&:cancellation?).map(&:update!).compact.sum

  @item.adjustment_total = @item.promo_total + @item.additional_tax_total + item_cancellation_total

  @item.update_columns(
    :promo_total => @item.promo_total,
    :included_tax_total => @item.included_tax_total,
    :additional_tax_total => @item.additional_tax_total,
    :adjustment_total => @item.adjustment_total,
    :updated_at => Time.now,
  ) if @item.changed?

  @item
end