Class: Spree::ItemAdjustments
- Inherits:
-
Object
- Object
- Spree::ItemAdjustments
- Includes:
- ActiveSupport::Callbacks
- Defined in:
- app/models/spree/item_adjustments.rb
Overview
Manage (recalculate) item (LineItem or Shipment) adjustments
Instance Attribute Summary collapse
-
#item ⇒ Object
readonly
Returns the value of attribute item.
Instance Method Summary collapse
- #best_promotion_adjustment ⇒ Object
-
#choose_best_promotion_adjustment ⇒ Object
Picks one (and only one) promotion to be eligible for this order This promotion provides the most discount, and if two promotions have the same amount, then it will pick the latest one.
-
#initialize(item) ⇒ ItemAdjustments
constructor
A new instance of ItemAdjustments.
- #update ⇒ Object
-
#update_adjustments ⇒ Object
TODO this should be probably the place to calculate proper item taxes values after promotions are applied.
Constructor Details
#initialize(item) ⇒ ItemAdjustments
Returns a new instance of ItemAdjustments.
10 11 12 13 14 15 |
# File 'app/models/spree/item_adjustments.rb', line 10 def initialize(item) @item = item # Don't attempt to reload the item from the DB if it's not there @item.reload if @item.instance_of?(Shipment) && @item.persisted? end |
Instance Attribute Details
#item ⇒ Object (readonly)
Returns the value of attribute item.
6 7 8 |
# File 'app/models/spree/item_adjustments.rb', line 6 def item @item end |
Instance Method Details
#best_promotion_adjustment ⇒ Object
78 79 80 |
# File 'app/models/spree/item_adjustments.rb', line 78 def best_promotion_adjustment @best_promotion_adjustment ||= adjustments.promotion.eligible.reorder("amount ASC, created_at DESC, id DESC").first end |
#choose_best_promotion_adjustment ⇒ Object
Picks one (and only one) promotion to be eligible for this order This promotion provides the most discount, and if two promotions have the same amount, then it will pick the latest one.
71 72 73 74 75 76 |
# File 'app/models/spree/item_adjustments.rb', line 71 def choose_best_promotion_adjustment if best_promotion_adjustment other_promotions = self.adjustments.promotion.where("id NOT IN (?)", best_promotion_adjustment.id) other_promotions.update_all(:eligible => false) end end |
#update ⇒ Object
17 18 19 20 |
# File 'app/models/spree/item_adjustments.rb', line 17 def update update_adjustments if item.persisted? item end |
#update_adjustments ⇒ Object
TODO this should be probably the place to calculate proper item taxes values after promotions are applied
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 |
# File 'app/models/spree/item_adjustments.rb', line 24 def update_adjustments # 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 effect the eventual total price. # # Additional tax adjustments are the opposite; effecting the final total. promo_total = 0 run_callbacks :promo_adjustments do promotion_total = adjustments.promotion.reload.map do |adjustment| adjustment.update!(@item) end.compact.sum unless promotion_total == 0 choose_best_promotion_adjustment end promo_total = best_promotion_adjustment.try(:amount).to_f end included_tax_total = 0 additional_tax_total = 0 run_callbacks :tax_adjustments do tax = (item.respond_to?(:all_adjustments) ? item.all_adjustments : item.adjustments).tax included_tax_total = tax.included.reload.map(&:update!).compact.sum additional_tax_total = tax.additional.reload.map(&:update!).compact.sum end item.update_columns( :promo_total => promo_total, :included_tax_total => included_tax_total, :additional_tax_total => additional_tax_total, :adjustment_total => promo_total + additional_tax_total, :updated_at => Time.now, ) end |