change invoice layout to include amount for each relevant tax rate

This commit is contained in:
Pierre de Lacroix
2016-12-15 23:26:09 +01:00
committed by Rob Harrington
parent a079a64cbe
commit 2d2792225a
9 changed files with 129 additions and 43 deletions

View File

@@ -43,6 +43,16 @@ module CheckoutHelper
Spree::Money.new order.total_tax, currency: order.currency
end
def display_checkout_taxes_hash(order)
order.tax_adjustment_totals.each_with_object(Hash.new) do |(tax_rate, tax_value), acc|
acc[number_to_percentage(tax_rate.amount * 100, :precision => 1)] = Spree::Money.new tax_value, currency: order.currency
end
end
def display_line_item_tax_rates(line_item)
line_item.tax_rates.map { |tr| number_to_percentage(tr.amount * 100, :precision => 1) }.join(", ")
end
def display_checkout_total_less_tax(order)
Spree::Money.new order.total - order.total_tax, currency: order.currency
end

View File

@@ -20,6 +20,18 @@ Spree::Address.class_eval do
filtered_address.compact.join(', ')
end
def address_part1
address_part1 = [address1, address2]
filtered_address = address_part1.select{ |field| !field.nil? && field != '' }
filtered_address.compact.join(', ')
end
def address_part2
address_part2= [city, zipcode, state.andand.name]
filtered_address = address_part2.select{ |field| !field.nil? && field != '' }
filtered_address.compact.join(', ')
end
private
def touch_enterprise

View File

@@ -4,6 +4,7 @@ module Spree
# So we don't need the option `dependent: :destroy` as long as
# AdjustmentMetadata has no destroy logic itself.
has_one :metadata, class_name: 'AdjustmentMetadata'
belongs_to :tax_rate, foreign_key: 'originator_id', conditions: "spree_adjustments.originator_type = 'Spree::TaxRate'"
scope :enterprise_fee, where(originator_type: 'EnterpriseFee')
scope :billable_period, where(source_type: 'BillablePeriod')

View File

@@ -3,6 +3,7 @@ require 'open_food_network/variant_and_line_item_naming'
Spree::LineItem.class_eval do
include OpenFoodNetwork::VariantAndLineItemNaming
has_and_belongs_to_many :option_values, join_table: 'spree_option_values_line_items', class_name: 'Spree::OptionValue'
has_many :tax_adjustments, class_name: "Adjustment", conditions: "spree_adjustments.originator_type = 'Spree::TaxRate'", as: :adjustable
attr_accessible :max_quantity, :final_weight_volume, :price
attr_accessible :final_weight_volume, :price, :as => :api
@@ -56,6 +57,10 @@ Spree::LineItem.class_eval do
adjustments.included_tax.sum(&:included_tax)
end
def tax_rates
product.tax_category.tax_rates
end
def price_with_adjustments
# EnterpriseFee#create_locked_adjustment applies adjustments on line items to their parent order,
# so line_item.adjustments returns an empty array

View File

@@ -227,6 +227,22 @@ Spree::Order.class_eval do
(adjustments + price_adjustments).sum &:included_tax
end
def tax_adjustments
adjustments.with_tax +
line_items.includes(:tax_adjustments).map {|li| li.tax_adjustments}.flatten
end
def tax_adjustment_totals
Hash[tax_adjustments.group_by(&:label).map do |label, adjustments|
[adjustments.first.originator, adjustments.sum(&:amount)]
end]
end
# Uses the first associated tax to determine if taxes are included in price
def has_taxes_included
not line_items.with_tax.empty?
end
def account_invoice?
distributor_id == Spree::Config.accounts_distributor_id
end

View File

@@ -2,13 +2,15 @@
%thead
%tr
%th{:align => "left"}
%h4= t(:invoice_column_item)
%h5= t(:invoice_column_item)
%th{:align => "right", :width => "15%"}
%h4= t(:invoice_column_qty)
%h5= t(:invoice_column_qty)
%th{:align => "right", :width => "15%"}
%h4= @order.total_tax > 0 ? t(:invoice_column_tax) : ""
%h5= @order.has_taxes_included ? t(:invoice_column_unit_price_with_taxes) : t(:invoice_column_unit_price_without_taxes)
%th{:align => "right", :width => "15%"}
%h4= t(:invoice_column_price)
%h5= @order.has_taxes_included ? t(:invoice_column_price_with_taxes) : t(:invoice_column_price_without_taxes)
%th{:align => "right", :width => "15%"}
%h5= @order.total_tax > 0 ? t(:invoice_column_tax_rate) : ""
%tbody
- @order.line_items.sort_by{ |li| li.product.name }.each do |item|
%tr
@@ -17,9 +19,11 @@
%td{:align => "right"}
= item.quantity
%td{:align => "right"}
= item.included_tax > 0 ? item.display_included_tax : ""
= item.single_display_amount_with_adjustments
%td{:align => "right"}
= item.display_amount_with_adjustments
%td{:align => "right"}
= display_line_item_tax_rates(item)
- checkout_adjustments_for(@order, exclude: [:line_item]).reject{ |a| a.amount == 0 }.reverse_each do |adjustment|
%tr
%td
@@ -32,19 +36,20 @@
= adjustment.display_amount
%tfoot
%tr
%td{:align => "right", :colspan => "3"}
%strong= @order.has_taxes_included ? t(:total_incl_tax) : t(:total_excl_tax)
%td{:align => "right", :colspan => "2"}
%strong GST Total:
%td{:align => "right", :colspan => "2"}
%strong= display_checkout_tax_total(@order)
%strong= @order.has_taxes_included ? @order.display_total : display_checkout_total_less_tax(@order)
- display_checkout_taxes_hash(@order).each do |tax_rate, tax_value|
%tr
%td{:align => "right", :colspan => "3"}
= t(:tax_total, rate: tax_rate)
%td{:align => "right", :colspan => "2"}
= tax_value
%tr
%td{:align => "right", :colspan => "3"}
= @order.has_taxes_included ? t(:total_excl_tax) : t(:total_incl_tax)
%td{:align => "right", :colspan => "2"}
%strong Total (Excl. GST):
%td{:align => "right", :colspan => "2"}
%strong= display_checkout_total_less_tax(@order)
%tr
%td{:align => "right", :colspan => "2"}
%strong Total (Incl. GST):
%td{:align => "right", :colspan => "2"}
%strong= @order.display_total
= @order.has_taxes_included ? display_checkout_total_less_tax(@order) : @order.display_total
%p
 

View File

@@ -4,38 +4,46 @@
%tbody
%tr{ valign: "top" }
%td{ :align => "left", colspan: 3 }
%h6= "Issued on: #{Time.zone.now.strftime("%F")}"
%tr{ valign: "top" }
%td{ :align => "left" }
%h4
= t('.tax_invoice')
= "#{@order.number}"
%td{width: "10%" }
 
%td{ :align => "right" }
%h4= @order.order_cycle.andand.name
= t(:tax_invoice)
%tr{ valign: "top" }
%td{ :align => "left" }
%strong= "From: #{@order.distributor.name}"
- if @order.distributor.abn.present?
%br
= "ABN: #{@order.distributor.abn}"
%td{ :align => "left", colspan: 3 }
%strong= @order.distributor.name
%br
= @order.distributor.address.full_address
= @order.distributor.address.address_part1
%br
= @order.distributor.address.address_part2
%br
= @order.distributor.email
%td{width: "10%" }
 
%td{ :align => "right" }
%strong= "To: #{@order.ship_address.full_name}"
- if @order.distributor.phone.present?
%br
= @order.distributor.phone
- if @order.distributor.abn.present?
%br
= "#{t :abn} #{@order.distributor.abn}"
- if @order.distributor.acn.present?
%br
= "#{t :acn} #{@order.distributor.acn}"
%tr{ valign: "top" }
%td{ :align => "right", colspan: 3 }
%strong= @order.ship_address.full_name
- if @order.customer.code.present?
%br
= "Code: #{@order.customer.code}"
%br
= @order.ship_address.full_address
= @order.ship_address.address_part1
%br
= "#{@order.customer.email},"
= "#{@order.bill_address.phone}"
= @order.ship_address.address_part2
%tr{ valign: "top" }
%td{ :align => "left", colspan: 3 }
= t :invoice_issued_on
= l Time.zone.now.to_date
%br
= t :date_of_transaction
= l @order.completed_at.to_date
%br
= t :order_number
= @order.number
= render 'spree/admin/orders/invoice_table'

View File

@@ -531,8 +531,20 @@ en:
# Printable Invoice Columns
invoice_column_item: "Item"
invoice_column_qty: "Qty"
invoice_column_tax: "GST"
invoice_column_price: "Price"
invoice_column_unit_price_with_taxes: "Unit price (Incl. GST)"
invoice_column_unit_price_without_taxes: "Unit price (Excl. GST)"
invoice_column_price_with_taxes: "Total price (Incl. GST)"
invoice_column_price_without_taxes: "Total price (Excl. GST)"
invoice_column_tax_rate: "Tax rate"
tax_invoice: "TAX INVOICE"
tax_total: "GST Total (%{rate}):"
total_excl_tax: "Total (Excl. GST):"
total_incl_tax: "Total (Incl. GST):"
abn: "ABN:"
acn: "ACN:"
invoice_issued_on: "Invoice issued on:"
order_number: "Invoice number:"
date_of_transaction: "Date of transaction:"
logo: "Logo (640x130)" #FIXME
logo_mobile: "Mobile logo (75x26)" #FIXME

View File

@@ -484,8 +484,25 @@ fr:
require_customer_html: "Veuillez %{contact} %{enterprise} pour devenir membre."
invoice_column_item: "Produit"
invoice_column_qty: "Qté"
invoice_column_tax: "TVA"
invoice_column_price: "Prix"
invoice_column_unit_price_with_taxes: "Prix unitaire (TTC)"
invoice_column_unit_price_without_taxes: "Prix unitaire (HT)"
invoice_column_price_with_taxes: "Prix total (TTC)"
invoice_column_price_without_taxes: "Prix total (HT)"
invoice_column_tax_rate: "Taux TVA"
tax_invoice: "FACTURE"
tax_total: "Total TVA (%{rate}) :"
total_excl_tax: "Total HT :"
total_incl_tax: "Total TTC :"
abn: "SIRET :"
acn: "n° TVA :"
invoice_issued_on: "Facture éditée le :"
order_number: "Numéro de facture :"
date_of_transaction: "Date de la transaction :"
number:
percentage:
format:
format: "%n %"
logo: "Logo (640x130)"
logo_mobile: "Logo smartphone (75x26)"
logo_mobile_svg: "Logo smartphone (SVG)"
@@ -689,7 +706,7 @@ fr:
email_payment_paid: RÉGLÉ
email_payment_not_paid: NON RÉGLÉ
email_payment_summary: Résumé du paiement
email_payment_method: "Payer via :"
email_payment_method: "Moyen de paiement :"
email_shipping_delivery_details: Détails de livraison
email_shipping_delivery_time: "Livré le:"
email_shipping_delivery_address: "Adresse de livraison:"