summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/super_good/solidus_taxjar/tax_calculator.rb48
-rw-r--r--spec/super_good/solidus_taxjar/tax_calculator_spec.rb89
2 files changed, 121 insertions, 16 deletions
diff --git a/lib/super_good/solidus_taxjar/tax_calculator.rb b/lib/super_good/solidus_taxjar/tax_calculator.rb
index e2a398e..e498da0 100644
--- a/lib/super_good/solidus_taxjar/tax_calculator.rb
+++ b/lib/super_good/solidus_taxjar/tax_calculator.rb
@@ -1,28 +1,60 @@
module SuperGood
module SolidusTaxJar
class TaxCalculator
- def initialize(order)
+ def self.default_api
+ ::SuperGood::SolidusTaxJar::API.new
+ end
+
+ def initialize(order, api: self.class.default_api)
@order = order
+ @api = api
end
def calculate
+ return no_tax if order.tax_address.empty?
+ return no_tax unless taxjar_breakdown
+
Spree::Tax::OrderTax.new(
order_id: order.id,
- line_item_taxes: line_item_rates,
- shipment_taxes: shipment_rates
+ line_item_taxes: line_item_taxes,
+ shipment_taxes: []
)
end
private
- attr_reader :order
+ attr_reader :order, :api
+
+ def line_item_taxes
+ taxjar_breakdown.line_items.map do |line_item|
+ Spree::Tax::ItemTax.new(
+ item_id: line_item.id.to_i,
+ label: "Sales Tax",
+ tax_rate: tax_rate,
+ amount: line_item.tax_collectable,
+ included_in_price: false
+ )
+ end
+ end
+
+ def taxjar_breakdown
+ @taxjar_breakdown ||= taxjar_tax.breakdown
+ end
+
+ def taxjar_tax
+ @taxjar_taxes ||= api.tax_for(order)
+ end
- def line_item_rates
- []
+ def no_tax
+ Spree::Tax::OrderTax.new(
+ order_id: order.id,
+ line_item_taxes: [],
+ shipment_taxes: []
+ )
end
- def shipment_rates
- []
+ def tax_rate
+ Spree::TaxRate.find_by(name: "Sales Tax")
end
end
end
diff --git a/spec/super_good/solidus_taxjar/tax_calculator_spec.rb b/spec/super_good/solidus_taxjar/tax_calculator_spec.rb
index eaf810c..02140da 100644
--- a/spec/super_good/solidus_taxjar/tax_calculator_spec.rb
+++ b/spec/super_good/solidus_taxjar/tax_calculator_spec.rb
@@ -1,21 +1,94 @@
require 'spec_helper'
-RSpec.describe SuperGood::SolidusTaxJar::TaxCalculator do
+RSpec.describe ::SuperGood::SolidusTaxJar::TaxCalculator do
describe "#calculate" do
subject { calculator.calculate }
- let(:calculator) { described_class.new(order) }
+ let(:calculator) { described_class.new(order, api: dummy_api) }
+
+ let(:dummy_api) do
+ instance_double ::SuperGood::SolidusTaxJar::API
+ end
let(:order) do
- Spree::Order.new(
- id: 10
+ ::Spree::Order.new(
+ id: 10,
+ store: store,
+ ship_address: address
+ )
+ end
+
+ let(:store) do
+ ::Spree::Store.new(
+ name: "Default Store",
+ url: "https://store.example.com",
+ code: "store",
+ mail_from_address: "contact@example.com",
+ cart_tax_country_iso: "US"
)
end
- it "returns the taxes" do
- expect(subject.order_id).to eq order.id
- expect(subject.line_item_taxes).to be_empty
- expect(subject.shipment_taxes).to be_empty
+ context "when the order has an empty tax address" do
+ let(:address) { nil }
+
+ it "returns no taxes" do
+ expect(subject.order_id).to eq order.id
+ expect(subject.shipment_taxes).to be_empty
+ expect(subject.line_item_taxes).to be_empty
+ end
+ end
+
+ context "when the order has a non-empty tax address" do
+ let(:address) { ::Spree::Address.new(first_name: "Ronnie James") }
+
+ before do
+ allow(dummy_api).to receive(:tax_for).with(order).and_return(
+ instance_double(::Taxjar::Tax, breakdown: breakdown)
+ )
+ end
+
+ context "and there is a breakdown" do
+ let!(:tax_rate) do
+ ::Spree::TaxRate.create!(
+ name: "Sales Tax",
+ amount: 0.5,
+ calculator: ::Spree::Calculator.new
+ )
+ end
+
+ let(:breakdown) do
+ instance_double ::Taxjar::Breakdown, line_items: [taxjar_line_item]
+ end
+
+ let(:taxjar_line_item) do
+ instance_double ::Taxjar::BreakdownLineItem, id: "33", tax_collectable: 6.66
+ end
+
+ it "returns the taxes" do
+ expect(subject.order_id).to eq order.id
+ expect(subject.shipment_taxes).to be_empty
+ expect(subject.line_item_taxes.length).to eq 1
+
+ item_tax = subject.line_item_taxes.first
+ aggregate_failures do
+ expect(item_tax.item_id).to eq 33
+ expect(item_tax.label).to eq "Sales Tax"
+ expect(item_tax.tax_rate).to eq tax_rate
+ expect(item_tax.amount).to eq 6.66
+ expect(item_tax.included_in_price).to eq false
+ end
+ end
+ end
+
+ context "and there is not a breakdown" do
+ let(:breakdown) { nil }
+
+ it "returns no taxes" do
+ expect(subject.order_id).to eq order.id
+ expect(subject.shipment_taxes).to be_empty
+ expect(subject.line_item_taxes).to be_empty
+ end
+ end
end
end
end