Skip to content

Commit

Permalink
Replaced ship_amount and tax_amount with a flexible system of charges. [
Browse files Browse the repository at this point in the history
spree#499 state:resolved milestone:0.8.99]
  • Loading branch information
schof committed Jun 25, 2009
1 parent 0112563 commit 0f12041
Show file tree
Hide file tree
Showing 28 changed files with 269 additions and 140 deletions.
10 changes: 7 additions & 3 deletions app/controllers/checkouts_controller.rb
Expand Up @@ -30,9 +30,9 @@ def update
end

success.wants.js do
render :json => { :order_total => number_to_currency(@order.total),
:ship_amount => number_to_currency(@order.ship_amount),
:tax_amount => number_to_currency(@order.tax_amount),
@order.reload
render :json => { :order_total => number_to_currency(@order.total),
:charges => charge_hash,
:available_methods => rate_hash}.to_json,
:layout => false
end
Expand Down Expand Up @@ -74,5 +74,9 @@ def rate_hash
:name => ship_method.name,
:rate => number_to_currency(ship_method.calculate_shipping(fake_shipment)) }
end
end

def charge_hash
Hash[*@order.charges.collect { |c| [c.description, number_to_currency(c.amount)] }.flatten]
end
end
4 changes: 2 additions & 2 deletions app/helpers/spree/base_helper.rb
Expand Up @@ -31,10 +31,10 @@ def order_price(order, options={})
options.reverse_merge! :format_as_currency => true, :show_vat_text => true

# overwrite show_vat_text if show_price_inc_vat is false
options[:show_vat_text] = Spree::Tax::Config[:show_price_inc_vat]
options[:show_vat_text] = Spree::Config[:show_price_inc_vat]

amount = order.item_total
amount += Spree::VatCalculator.calculate_tax(order) if Spree::Tax::Config[:show_price_inc_vat]
amount += Spree::VatCalculator.calculate_tax(order) if Spree::Config[:show_price_inc_vat]

options.delete(:format_as_currency) ? number_to_currency(amount) : amount
end
Expand Down
7 changes: 7 additions & 0 deletions app/models/charge.rb
@@ -0,0 +1,7 @@
class Charge < ActiveRecord::Base
belongs_to :order
acts_as_list :scope => :order

validates_presence_of :amount
validates_presence_of :description
end
25 changes: 22 additions & 3 deletions app/models/checkout.rb
@@ -1,6 +1,6 @@
class Checkout < ActiveRecord::Base
after_update :update_order_totals
class Checkout < ActiveRecord::Base
before_save :authorize_creditcard
after_save :update_charges
belongs_to :order
belongs_to :shipping_method
belongs_to :bill_address, :foreign_key => "bill_address_id", :class_name => "Address"
Expand All @@ -17,7 +17,26 @@ def authorize_creditcard
return unless cc.valid? and cc.authorize(order.total)
order.complete
end
def update_order_totals
def update_charges
# update shipping (if applicable)
if shipping_method
ship_charge = order.shipping_charges.first
ship_charge ||= order.shipping_charges.build
ship_charge.amount = shipping_method.calculate_shipping(Shipment.new(:order => order, :address => ship_address))
ship_charge.description = "#{I18n.t(:shipping)} (#{shipping_method.name})"
ship_charge.save
end
# update tax (if applicable)
tax_amount = order.calculate_tax
if tax_amount > 0
tax_charge = order.tax_charges.first
tax_charge ||= order.tax_charges.build(:description => I18n.t(:tax))
tax_charge.amount = tax_amount
tax_charge.save
end

order.reload
order.update_totals
order.save
end
end
47 changes: 22 additions & 25 deletions app/models/order.rb
@@ -1,7 +1,7 @@
class Order < ActiveRecord::Base
before_save :update_line_items
before_create :generate_token
before_create :create_checkout
before_save :update_line_items, :update_totals
after_create :create_checkout

has_many :line_items, :dependent => :destroy, :attributes => true
has_many :inventory_units
Expand All @@ -13,14 +13,15 @@ class Order < ActiveRecord::Base
has_one :checkout
has_one :bill_address, :through => :checkout
has_one :ship_address, :through => :checkout

has_many :charges, :order => :position
has_many :shipping_charges
has_many :tax_charges

delegate :email, :to => :checkout
delegate :ip_address, :to => :checkout
delegate :special_instructions, :to => :checkout

validates_associated :line_items, :message => "are not valid"
validates_numericality_of :tax_amount
validates_numericality_of :ship_amount
validates_numericality_of :item_total
validates_numericality_of :total

Expand All @@ -32,7 +33,7 @@ class Order < ActiveRecord::Base
make_permalink :field => :number

# attr_accessible is a nightmare with attachment_fu, so use attr_protected instead.
attr_protected :ship_amount, :tax_amount, :item_total, :total, :user, :number, :ip_address, :checkout_complete, :state, :token
attr_protected :charge_total, :item_total, :total, :user, :number, :state, :token

def to_param
self.number if self.number
Expand Down Expand Up @@ -138,10 +139,14 @@ def item_total
self.item_total = tot
end

def total
self.total = self.item_total + self.ship_amount + self.tax_amount
end

def ship_total
shipping_charges.inject(0) { |sum, charge| charge.amount + 0 }
end

def tax_total
tax_charges.inject(0) { |sum, charge| charge.amount + 0 }
end

# convenience method since many stores will not allow user to create multiple shipments
def shipment
shipments.last
Expand Down Expand Up @@ -172,16 +177,9 @@ def shipping_methods
ShippingMethod.all.select { |method| method.zone.include?(ship_address) && method.available?(self) }
end

def update_totals
# finalize order totals
tmp_shipment = shipment || Shipment.new(:order => self, :address => checkout.ship_address)
if checkout.shipping_method
self.ship_amount = checkout.shipping_method.calculate_shipping(tmp_shipment) if checkout.ship_address
else
self.ship_amount = 0
end
self.tax_amount = calculate_tax
save!
def update_totals
self.charge_total = self.charges.inject(0) { |sum, charge| charge.amount + sum }
self.total = self.item_total + self.charge_total
end

def calculate_tax
Expand All @@ -204,14 +202,13 @@ def complete_order
shipments.build(:address => ship_address, :shipping_method => checkout.shipping_method)
checkout.update_attribute(:completed_at, Time.now)
InventoryUnit.sell_units(self)
#update_totals
save_result = save!
if email
OrderMailer.deliver_confirm(self)
end
save_result
end
end

def cancel_order
restock_inventory
OrderMailer.deliver_cancel(self)
Expand All @@ -234,6 +231,6 @@ def generate_token
end

def create_checkout
self.checkout = Checkout.create unless self.checkout
end
self.checkout = Checkout.create(:order => self) unless self.checkout
end
end
10 changes: 5 additions & 5 deletions app/models/shipment.rb
Expand Up @@ -4,7 +4,7 @@ class Shipment < ActiveRecord::Base
belongs_to :address

before_create :generate_shipment_number
after_save :recalculate_tax
# after_save :recalculate_tax
after_save :transition_order

attr_accessor :special_instructions
Expand Down Expand Up @@ -41,8 +41,8 @@ def transition_order
order.state_events.create(:name => I18n.t('ship'), :user => current_user, :previous_state => order.state_was)
end

def recalculate_tax
return unless order && order.respond_to?(:calculate_tax)
order.update_attribute("tax_amount", order.calculate_tax)
end
# def recalculate_tax
# return unless order && order.respond_to?(:calculate_tax)
# order.update_attribute("tax_amount", order.calculate_tax)
# end
end
2 changes: 2 additions & 0 deletions app/models/shipping_charge.rb
@@ -0,0 +1,2 @@
class ShippingCharge < Charge
end
2 changes: 2 additions & 0 deletions app/models/tax_charge.rb
@@ -0,0 +1,2 @@
class TaxCharge < Charge
end
2 changes: 1 addition & 1 deletion app/views/admin/orders/show.html.erb
Expand Up @@ -5,7 +5,7 @@

<%= render :partial => 'admin/shared/order_tabs', :locals => {:current => "Order Details"} %>
<%= render :partial => 'admin/shared/order_details', :locals => {:order => @order} -%>
<%= render :partial => 'shared/order_details', :locals => {:order => @order} -%>
<% if @order.bill_address %>
<div class='adr'>
Expand Down
36 changes: 0 additions & 36 deletions app/views/admin/shared/_order_details.html.erb

This file was deleted.

2 changes: 1 addition & 1 deletion app/views/admin/tax_rates/index.html.erb
Expand Up @@ -6,7 +6,7 @@
</ul>
<br class='clear' />
</div>
<h1><%=t("ext_tax_calculator_tax_rates") %></h1>
<h1><%=t("tax_rates") %></h1>
<table class="index">
<thead>
<th><%=t("zone")%></th>
Expand Down
5 changes: 3 additions & 2 deletions app/views/order_mailer/cancel.html.erb
Expand Up @@ -10,6 +10,7 @@ Order Summary [CANCELED]
<% end -%>
============================================================
Subtotal: <%= number_to_currency @order.item_total %>
Tax: <%= number_to_currency @order.tax_amount %>
Shipping: <%= number_to_currency @order.ship_amount %>
<% @order.charges.each do |charge| %>
<%= "#{charge.description}: #{number_to_currency charge.amount}"%>
<% end %>
Order Total: <%= number_to_currency @order.total %>
5 changes: 3 additions & 2 deletions app/views/order_mailer/confirm.html.erb
Expand Up @@ -10,8 +10,9 @@ Order Summary
<% end -%>
============================================================
Subtotal: <%= number_to_currency @order.item_total %>
Tax: <%= number_to_currency @order.tax_amount %>
Shipping: <%= number_to_currency @order.ship_amount %>
<% @order.charges.each do |charge| %>
<%= "#{charge.description}: #{number_to_currency charge.amount}"%>
<% end %>
Order Total: <%= number_to_currency @order.total %>


Expand Down
4 changes: 2 additions & 2 deletions app/views/orders/_google_order.html.erb
Expand Up @@ -10,8 +10,8 @@
"<%= order.number %>", //Order Number
"", //Affiliation
"<%= order.total %>", //Order total
"<%= order.tax_amount %>", //Tax Amount
"<%= order.ship_amount %>", //Ship Amount
"<%= order.tax_charges.sum(:amount).to_s %>", //Tax Amount
"<%= order.shipping_charges.sum(:amount).to_s %>", //Ship Amount
"", //City
"", //State
"" //Country
Expand Down
74 changes: 38 additions & 36 deletions app/views/shared/_order_details.html.erb
@@ -1,36 +1,38 @@
<table class="order-summary">
<tr>
<th><%= t('item_description') %></th>
<th class="price"><%= t('price') %></th>
<th class="qty"><%= t('qty') %></th>
<th class="total_display"><span><%= t('total') %></span></th>
</tr>
<% @order.line_items.each do |item| %>
<tr >
<td width="300"><%=item.variant.product.name-%> <%= "(" + variant_options(item.variant) + ")" unless item.variant .option_values.empty? %></td>
<td valign="top"><%= number_to_currency item.price -%></td>
<td valign="top"><%=item.quantity-%></td>
<td valign="top" class="total_display"><span><%= number_to_currency (item.price * item.quantity)-%></span></td>
</tr>
<% end %>
<tr id="subtotal-row">
<td colspan="3"><b><%= t('subtotal') %>:</b></td>
<td class="total_display"><span><%= number_to_currency @order.item_total -%></span></td>
</tr>
<tr>
<td colspan="3"><b><%= t('tax') %>:</b></td>
<td class="total_display"><span id="tax_amount"><%= number_to_currency @order.tax_amount -%></span></td>
</tr>
<tr>
<td colspan="3"><b><%= t('shipping') %>:</b>
<% if @order.shipment && @order.shipment.shipping_method %>
<span id="ship_method">(<%= @order.shipment.shipping_method.name %>)</span>
<% end %>
</td>
<td class="total_display"><span id="ship_amount"><%= number_to_currency @order.ship_amount -%></span></td>
</tr>
<tr>
<td colspan="3"><b><%= t('order_total') %>:</b></td>
<td class="total_display"><span id="order_total"><%= number_to_currency @order.total -%></span></td>
</tr>
</table>
<table class="index">
<tbody id='line-items'>
<tr>
<th><%= t('item_description') %></th>
<th class="price"><%= t('price') %></th>
<th class="qty"><%= t('qty') %></th>
<th class="total_display"><span><%= t('total') %></span></th>
</tr>
<% @order.line_items.each do |item| %>
<tr >
<td width="300"><%=item.variant.product.name-%> <%= "(" + variant_options(item.variant) + ")" unless item.variant .option_values.empty? %></td>
<td valign="top"><%= number_to_currency item.price -%></td>
<td valign="top"><%=item.quantity-%></td>
<td valign="top" class="total_display"><span><%= number_to_currency (item.price * item.quantity)-%></span></td>
</tr>
<% end %>
</tbody>
<tbody id='subtotal'>
<tr class="total" id="subtotal-row">
<td colspan="3"><b><%= t('subtotal') %>:</b></td>
<td class="total_display"><span><%= number_to_currency @order.item_total -%></span></td>
</tr>
</tbody>
<tbody id="order-charges">
<% order.charges.each do |charge| %>
<tr class="total">
<td colspan="3"><strong><%= charge.description %></strong></td>
<td class="total_display"><span><%= number_to_currency charge.amount -%></span></td>
</tr>
<% end %>
</tbody>
<tbody id='order-total'>
<tr class="total">
<td colspan="3"><b><%= t('order_total') %>:</b></td>
<td class="total_display"><span id="order_total"><%= number_to_currency @order.total -%></span></td>
</tr>
</tbody>
</table>
2 changes: 0 additions & 2 deletions config/locales/en-US.yml
Expand Up @@ -46,10 +46,8 @@ en-US:
ip_address: "IP Address"
item_total: "Item Total"
number: Number
ship_amount: "Ship Amount"
special_instructions: "Special Instructions"
state: State
tax_amount: "Tax Amount"
total: Total
product:
available_on: "Available On"
Expand Down

0 comments on commit 0f12041

Please sign in to comment.