Skip to content

Instantly share code, notes, and snippets.

@tvdeyen
Created July 3, 2012 18:56
Show Gist options
  • Save tvdeyen/3041942 to your computer and use it in GitHub Desktop.
Save tvdeyen/3041942 to your computer and use it in GitHub Desktop.
Spree tax calculation patch
StateMachine::Machine.ignore_method_conflicts = true
module Spree
Order.class_eval do
# customize the checkout state machine
Order.state_machines[:state] = StateMachine::Machine.new(Order, :initial => 'cart') do
event :next do
transition :from => 'cart', :to => 'address'
transition :from => 'address', :to => 'delivery'
transition :from => 'delivery', :to => 'payment', :if => :payment_required?
transition :from => 'delivery', :to => 'confirm'
transition :from => 'payment', :to => 'confirm'
transition :from => 'confirm', :to => 'complete'
end
event :cancel do
transition :to => 'canceled', :if => :allow_cancel?
end
event :return do
transition :to => 'returned', :from => 'awaiting_return'
end
event :resume do
transition :to => 'resumed', :from => 'canceled', :if => :allow_resume?
end
event :authorize_return do
transition :to => 'awaiting_return'
end
before_transition :to => 'complete' do |order|
begin
order.process_payments!
rescue Core::GatewayError
if Spree::Config[:allow_checkout_on_gateway_error]
true
else
false
end
end
end
before_transition :to => ['delivery'] do |order|
order.shipments.each { |s| s.destroy unless s.shipping_method.available_to_order?(order) }
end
# updating tax because of promotions
before_transition :to => 'confirm', :do => :create_tax_charge!
after_transition :to => 'complete', :do => :finalize!
after_transition :to => 'delivery', :do => :create_tax_charge!
after_transition :to => 'payment', :do => :create_shipment!
after_transition :to => 'resumed', :do => :after_resume
after_transition :to => 'canceled', :do => :after_cancel
end
# Updates the following Order total values:
#
# +payment_total+ The total value of all finalized Payments (NOTE: non-finalized Payments are excluded)
# +item_total+ The total value of all LineItems
# +adjustment_total+ The total value of all adjustments (promotions, credits, etc.)
# +total+ The so-called "order total." This is equivalent to +item_total+ plus +adjustment_total+.
def update_totals
# update_adjustments
self.payment_total = payments.completed.map(&:amount).sum
self.item_total = line_items.map(&:amount).sum
# Only use shipping and promotions for adjustment
self.adjustment_total = adjustments.shipping.eligible.map(&:amount).sum
self.adjustment_total += adjustments.promotion.eligible.map(&:amount).sum
self.total = item_total + adjustment_total
end
end
end
module Spree
TaxRate.class_eval do
# Creates necessary tax adjustments for the order.
def adjust(order)
label = "#{tax_category.name} #{amount * 100}%"
if self.included_in_price
if Zone.default_tax.contains? order.tax_zone
amount = 0
order.line_items.each do |line_item|
amount += calculator.compute(line_item)
end
if order.adjustments.promotion.eligible.any?
factor = order.adjustments.promotion.eligible.map(&:amount).sum.abs / order.item_total
amount = amount - ( amount * factor )
amount = BigDecimal.new(amount.to_s).round(2, BigDecimal::ROUND_HALF_UP)
end
return if amount == 0
order.adjustments.create(:amount => amount,
:source => order,
:originator => self,
:locked => true,
:label => label)
else
amount = -1 * calculator.compute(order)
label = I18n.t(:refund) + label
order.adjustments.create(:amount => amount,
:source => order,
:originator => self,
:locked => true,
:label => label)
end
else
create_adjustment(label, order, order)
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment