Skip to content

Commit

Permalink
Merge pull request #5492 from pacodelaluna/include-negative-tax-adjus…
Browse files Browse the repository at this point in the history
…tments-in-sales-report

Include adjustments with negative taxes on Sales Tax reports
  • Loading branch information
luisramos0 authored Jun 16, 2020
2 parents 6a31c56 + 6672cfd commit 01e27dd
Show file tree
Hide file tree
Showing 7 changed files with 133 additions and 85 deletions.
7 changes: 5 additions & 2 deletions app/helpers/checkout_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,11 @@ def display_checkout_tax_total(order)
end

def display_checkout_taxes_hash(order)
order.tax_adjustment_totals.each_with_object({}) do |(tax_rate, tax_amount), hash|
hash[number_to_percentage(tax_rate.amount * 100, precision: 1)] = Spree::Money.new tax_amount, currency: order.currency
totals = OrderTaxAdjustmentsFetcher.new(order).totals

totals.each_with_object({}) do |(tax_rate, tax_amount), hash|
hash[number_to_percentage(tax_rate.amount * 100, precision: 1)] =
Spree::Money.new tax_amount, currency: order.currency
end
end

Expand Down
2 changes: 1 addition & 1 deletion app/models/spree/adjustment_decorator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ module Spree
where(originator_type: 'Spree::TaxRate', adjustable_type: 'Spree::LineItem')
}

scope :with_tax, -> { where('spree_adjustments.included_tax > 0') }
scope :with_tax, -> { where('spree_adjustments.included_tax <> 0') }
scope :without_tax, -> { where('spree_adjustments.included_tax = 0') }
scope :payment_fee, -> { where(AdjustmentScopes::PAYMENT_FEE_SCOPE) }
scope :shipping, -> { where(AdjustmentScopes::SHIPPING_SCOPE) }
Expand Down
16 changes: 0 additions & 16 deletions app/models/spree/order_decorator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -312,22 +312,6 @@ def total_tax
(adjustments + price_adjustments).sum(&:included_tax)
end

def tax_adjustments
adjustments.with_tax +
line_items.includes(:adjustments).map { |li| li.adjustments.with_tax }.flatten
end

def tax_adjustment_totals
tax_adjustments.each_with_object({}) do |adjustment, hash|
tax_rates = TaxRateFinder.tax_rates_of(adjustment)
tax_rates_hash = Hash[tax_rates.collect do |tax_rate|
tax_amount = tax_rates.one? ? adjustment.included_tax : tax_rate.compute_tax(adjustment.amount)
[tax_rate, tax_amount]
end]
hash.update(tax_rates_hash) { |_tax_rate, amount1, amount2| amount1 + amount2 }
end
end

def price_adjustments
adjustments = []

Expand Down
55 changes: 55 additions & 0 deletions app/services/order_tax_adjustments_fetcher.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# frozen_string_literal: true

# This class will be used to get Tax Adjustments related to an order,
# and proceed basic calcultation over them.

class OrderTaxAdjustmentsFetcher
def initialize(order)
@order = order
end

def totals
all.each_with_object({}) do |adjustment, hash|
tax_rates_hash = tax_rates_hash(adjustment)
hash.update(tax_rates_hash) { |_tax_rate, amount1, amount2| amount1 + amount2 }
end
end

private

attr_reader :order

def all
Spree::Adjustment
.with_tax
.where(order_adjustments.or(line_item_adjustments))
.order('created_at ASC')
end

def order_adjustments
table[:adjustable_id].eq(order.id)
.and(table[:adjustable_type].eq('Spree::Order'))
end

def line_item_adjustments
table[:adjustable_id].eq(order.line_item_ids.join(','))
.and(table[:adjustable_type].eq('Spree::LineItem'))
end

def table
@table ||= Spree::Adjustment.arel_table
end

def tax_rates_hash(adjustment)
tax_rates = TaxRateFinder.tax_rates_of(adjustment)

Hash[tax_rates.collect do |tax_rate|
tax_amount = if tax_rates.one?
adjustment.included_tax
else
tax_rate.compute_tax(adjustment.amount)
end
[tax_rate, tax_amount]
end]
end
end
5 changes: 3 additions & 2 deletions lib/open_food_network/sales_tax_report.rb
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,9 @@ def table
when "tax_rates"
orders.map do |order|
[order.number, order.total - order.total_tax] +
relevant_rates.map { |rate| order.tax_adjustment_totals.fetch(rate, 0) } +
[order.total_tax, order.total]
relevant_rates.map { |rate|
OrderTaxAdjustmentsFetcher.new(order).totals.fetch(rate, 0)
} + [order.total_tax, order.total]
end
else
orders.map do |order|
Expand Down
64 changes: 0 additions & 64 deletions spec/models/spree/order_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -287,70 +287,6 @@
end
end

describe "getting a hash of all taxes" do
let(:zone) { create(:zone_with_member) }
let(:coordinator) { create(:distributor_enterprise, charges_sales_tax: true) }

let(:tax_rate10) { create(:tax_rate, included_in_price: true, calculator: Spree::Calculator::DefaultTax.new, amount: 0.1, zone: zone) }
let(:tax_rate15) { create(:tax_rate, included_in_price: true, calculator: Spree::Calculator::DefaultTax.new, amount: 0.15, zone: zone) }
let(:tax_rate20) { create(:tax_rate, included_in_price: true, calculator: Spree::Calculator::DefaultTax.new, amount: 0.2, zone: zone) }
let(:tax_rate25) { create(:tax_rate, included_in_price: true, calculator: Spree::Calculator::DefaultTax.new, amount: 0.25, zone: zone) }
let(:tax_category10) { create(:tax_category, tax_rates: [tax_rate10]) }
let(:tax_category15) { create(:tax_category, tax_rates: [tax_rate15]) }
let(:tax_category20) { create(:tax_category, tax_rates: [tax_rate20]) }
let(:tax_category25) { create(:tax_category, tax_rates: [tax_rate25]) }

let(:variant) { create(:variant, product: create(:product, tax_category: tax_category10)) }
let(:enterprise_fee) { create(:enterprise_fee, enterprise: coordinator, tax_category: tax_category20, calculator: Spree::Calculator::FlatRate.new(preferred_amount: 48.0)) }
let(:additional_adjustment) { create(:adjustment, amount: 50.0, included_tax: tax_rate25.compute_tax(50.0)) }

let(:order_cycle) { create(:simple_order_cycle, coordinator: coordinator, coordinator_fees: [enterprise_fee], distributors: [coordinator], variants: [variant]) }
let(:line_item) { create(:line_item, variant: variant, price: 44.0) }
let(:order) do
create(
:order,
line_items: [line_item],
bill_address: create(:address),
order_cycle: order_cycle,
distributor: coordinator,
adjustments: [additional_adjustment]
)
end

before do
allow(Spree::Config).to receive(:shipment_inc_vat).and_return(true)
allow(Spree::Config).to receive(:shipping_tax_rate).and_return(tax_rate15.amount)
end

let(:shipping_method) { create(:shipping_method, calculator: Spree::Calculator::FlatRate.new(preferred_amount: 46.0)) }
let!(:shipment) { create(:shipment_with, :shipping_method, shipping_method: shipping_method, order: order) }

before do
order.create_tax_charge!
order.update_distribution_charge!
end

it "returns a hash with all 3 taxes" do
expect(order.tax_adjustment_totals.size).to eq(4)
end

it "contains tax on line_item" do
expect(order.tax_adjustment_totals[tax_rate10]).to eq(4.0)
end

it "contains tax on shipping_fee" do
expect(order.tax_adjustment_totals[tax_rate15]).to eq(6.0)
end

it "contains tax on enterprise_fee" do
expect(order.tax_adjustment_totals[tax_rate20]).to eq(8.0)
end

it "contains tax on order adjustment" do
expect(order.tax_adjustment_totals[tax_rate25]).to eq(10.0)
end
end

describe "setting the distributor" do
it "sets the distributor when no order cycle is set" do
d = create(:distributor_enterprise)
Expand Down
69 changes: 69 additions & 0 deletions spec/services/order_tax_adjustments_fetcher_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
require "spec_helper"

describe OrderTaxAdjustmentsFetcher do
describe "#totals" do
let(:zone) { create(:zone_with_member) }
let(:coordinator) { create(:distributor_enterprise, charges_sales_tax: true) }

let(:tax_rate10) { create(:tax_rate, included_in_price: true, calculator: Spree::Calculator::DefaultTax.new, amount: 0.1, zone: zone) }
let(:tax_rate15) { create(:tax_rate, included_in_price: true, calculator: Spree::Calculator::DefaultTax.new, amount: 0.15, zone: zone) }
let(:tax_rate20) { create(:tax_rate, included_in_price: true, calculator: Spree::Calculator::DefaultTax.new, amount: 0.2, zone: zone) }
let(:tax_rate25) { create(:tax_rate, included_in_price: true, calculator: Spree::Calculator::DefaultTax.new, amount: 0.25, zone: zone) }
let(:tax_category10) { create(:tax_category, tax_rates: [tax_rate10]) }
let(:tax_category15) { create(:tax_category, tax_rates: [tax_rate15]) }
let(:tax_category20) { create(:tax_category, tax_rates: [tax_rate20]) }
let(:tax_category25) { create(:tax_category, tax_rates: [tax_rate25]) }

let(:variant) { create(:variant, product: create(:product, tax_category: tax_category10)) }
let(:enterprise_fee) { create(:enterprise_fee, enterprise: coordinator, tax_category: tax_category20, calculator: Spree::Calculator::FlatRate.new(preferred_amount: 48.0)) }
let(:additional_adjustment) { create(:adjustment, amount: 50.0, included_tax: tax_rate25.compute_tax(50.0)) }

let(:order_cycle) { create(:simple_order_cycle, coordinator: coordinator, coordinator_fees: [enterprise_fee], distributors: [coordinator], variants: [variant]) }
let(:line_item) { create(:line_item, variant: variant, price: 44.0) }
let(:order) do
create(
:order,
line_items: [line_item],
bill_address: create(:address),
order_cycle: order_cycle,
distributor: coordinator,
adjustments: [additional_adjustment]
)
end

before do
allow(Spree::Config).to receive(:shipment_inc_vat).and_return(true)
allow(Spree::Config).to receive(:shipping_tax_rate).and_return(tax_rate15.amount)
end

let(:shipping_method) { create(:shipping_method, calculator: Spree::Calculator::FlatRate.new(preferred_amount: 46.0)) }
let!(:shipment) { create(:shipment_with, :shipping_method, shipping_method: shipping_method, order: order) }

before do
order.create_tax_charge!
order.update_distribution_charge!
end

subject { OrderTaxAdjustmentsFetcher.new(order).totals }

it "returns a hash with all 3 taxes" do
expect(subject.size).to eq(4)
end

it "contains tax on line_item" do
expect(subject[tax_rate10]).to eq(4.0)
end

it "contains tax on shipping_fee" do
expect(subject[tax_rate15]).to eq(6.0)
end

it "contains tax on enterprise_fee" do
expect(subject[tax_rate20]).to eq(8.0)
end

it "contains tax on order adjustment" do
expect(subject[tax_rate25]).to eq(10.0)
end
end
end

0 comments on commit 01e27dd

Please sign in to comment.