Class: Spree::TaxRate
- Inherits:
-
ActiveRecord::Base
- Object
- ActiveRecord::Base
- Spree::TaxRate
- Includes:
- Core::CalculatedAdjustments
- Defined in:
- app/models/spree/tax_rate.rb
Class Method Summary collapse
- .adjust(order, items) ⇒ Object
-
.default ⇒ Object
For Vat the default rate is the rate that is configured for the default category It is needed for every price calculation (as all customer facing prices include vat ) The function returns the actual amount, which may be 0 in case of wrong setup, but is never nil.
-
.match(order) ⇒ Object
Gets the array of TaxRates appropriate for the specified order.
-
.store_pre_tax_amount(item, rates) ⇒ Object
Pre-tax amounts must be stored so that we can calculate correct rate amounts in the future.
Instance Method Summary collapse
-
#adjust(order, item) ⇒ Object
Creates necessary tax adjustments for the order.
-
#compute_amount(item) ⇒ Object
This method is used by Adjustment#update to recalculate the cost.
Methods included from Core::CalculatedAdjustments
Class Method Details
.adjust(order, items) ⇒ Object
51 52 53 54 55 56 57 58 59 60 61 62 63 |
# File 'app/models/spree/tax_rate.rb', line 51 def self.adjust(order, items) rates = self.match(order) tax_categories = rates.map(&:tax_category) relevant_items = items.select { |item| tax_categories.include?(item.tax_category) } relevant_items.each do |item| item.adjustments.tax.delete_all relevant_rates = rates.select { |rate| rate.tax_category == item.tax_category } store_pre_tax_amount(item, relevant_rates) relevant_rates.each do |rate| rate.adjust(order, item) end end end |
.default ⇒ Object
For Vat the default rate is the rate that is configured for the default category It is needed for every price calculation (as all customer facing prices include vat ) The function returns the actual amount, which may be 0 in case of wrong setup, but is never nil
68 69 70 71 72 73 74 75 76 |
# File 'app/models/spree/tax_rate.rb', line 68 def self.default category = TaxCategory.includes(:tax_rates).where(is_default: true).first return 0 unless category address ||= Address.new(country_id: Spree::Config[:default_country_id]) rate = category.tax_rates.detect { |rate| rate.zone.include? address }.try(:amount) rate || 0 end |
.match(order) ⇒ Object
Gets the array of TaxRates appropriate for the specified order
27 28 29 30 31 32 33 |
# File 'app/models/spree/tax_rate.rb', line 27 def self.match(order) return [] unless order.tax_zone all.select do |rate| (!rate.included_in_price && (rate.zone == order.tax_zone || rate.zone.contains?(order.tax_zone) || (order.tax_address.nil? && rate.zone.default_tax))) || rate.included_in_price end end |
.store_pre_tax_amount(item, rates) ⇒ Object
Pre-tax amounts must be stored so that we can calculate correct rate amounts in the future. For example: github.com/spree/spree/issues/4318#issuecomment-34723428
38 39 40 41 42 43 44 45 46 47 48 49 |
# File 'app/models/spree/tax_rate.rb', line 38 def self.store_pre_tax_amount(item, rates) if rates.any? { |r| r.included_in_price } case item when Spree::LineItem item_amount = item.discounted_amount when Spree::Shipment item_amount = item.discounted_cost end pre_tax_amount = item_amount / (1 + rates.map(&:amount).sum) item.update_column(:pre_tax_amount, pre_tax_amount) end end |
Instance Method Details
#adjust(order, item) ⇒ Object
Creates necessary tax adjustments for the order.
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
# File 'app/models/spree/tax_rate.rb', line 79 def adjust(order, item) amount = calculator.compute(item) return if amount == 0 included = included_in_price && Zone.default_tax.contains?(item.order.tax_zone) if amount < 0 label = Spree.t(:refund) + ' ' + create_label end self.adjustments.create!({ :adjustable => item, :amount => amount, :order => order, :label => label || create_label, :included => included }) end |
#compute_amount(item) ⇒ Object
This method is used by Adjustment#update to recalculate the cost.
100 101 102 103 104 105 106 107 108 109 110 111 |
# File 'app/models/spree/tax_rate.rb', line 100 def compute_amount(item) if included_in_price if Zone.default_tax.contains? item.order.tax_zone calculator.compute(item) else # In this case, it's a refund. calculator.compute(item) * - 1 end else calculator.compute(item) end end |