summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/super_good/solidus_taxjar.rb1
-rw-r--r--lib/super_good/solidus_taxjar/api.rb49
-rw-r--r--spec/super_good/solidus_taxjar/api_spec.rb118
3 files changed, 168 insertions, 0 deletions
diff --git a/lib/super_good/solidus_taxjar.rb b/lib/super_good/solidus_taxjar.rb
index 6553213..40df3ec 100644
--- a/lib/super_good/solidus_taxjar.rb
+++ b/lib/super_good/solidus_taxjar.rb
@@ -8,4 +8,5 @@ module SuperGood
end
require "super_good/solidus_taxjar/version"
+require "super_good/solidus_taxjar/api"
require "super_good/solidus_taxjar/tax_calculator"
diff --git a/lib/super_good/solidus_taxjar/api.rb b/lib/super_good/solidus_taxjar/api.rb
new file mode 100644
index 0000000..5434aab
--- /dev/null
+++ b/lib/super_good/solidus_taxjar/api.rb
@@ -0,0 +1,49 @@
+module SuperGood
+ module SolidusTaxJar
+ class API
+ def self.default_taxjar_client
+ ::Taxjar::Client.new(
+ api_key: ENV.fetch("TAXJAR_API_KEY"),
+ api_url: 'https://api.sandbox.taxjar.com'
+ )
+ end
+
+ def initialize(taxjar_client: Client.default_taxjar_client)
+ @taxjar_client = taxjar_client
+ end
+
+ def order_tax_for(order)
+ taxjar_client.tax_for_order order_params(order)
+ end
+
+ private
+
+ attr_reader :taxjar_client
+
+ def order_params(order)
+ ship_address = order.ship_address
+
+ {
+ to_country: ship_address.country.iso,
+ to_zip: ship_address.zipcode,
+ to_city: ship_address.city,
+ to_state: ship_address&.state&.abbr || ship_address.state_name,
+ to_street: ship_address.address1,
+
+ amount: order.item_total,
+ shipping: order.shipment_total,
+
+ line_items: order.line_items.map do |line_item|
+ {
+ id: line_item.id,
+ quantity: line_item.quantity,
+ unit_price: line_item.price,
+ discount: -line_item.adjustment_total,
+ product_tax_code: line_item.tax_category&.tax_code
+ }
+ end
+ }
+ end
+ end
+ end
+end
diff --git a/spec/super_good/solidus_taxjar/api_spec.rb b/spec/super_good/solidus_taxjar/api_spec.rb
new file mode 100644
index 0000000..ce49dd3
--- /dev/null
+++ b/spec/super_good/solidus_taxjar/api_spec.rb
@@ -0,0 +1,118 @@
+require 'spec_helper'
+
+RSpec.describe SuperGood::SolidusTaxJar::API do
+ describe "#order_tax_for" do
+ subject { api.order_tax_for order }
+
+ let(:api) do
+ described_class.new(taxjar_client: dummy_client)
+ end
+
+ let(:dummy_client) do
+ instance_double ::Taxjar::Client
+ end
+
+ let(:order) do
+ Spree::Order.create!(
+ item_total: 28.00,
+ shipment_total: 3.01,
+ ship_address: ship_address,
+ line_items: [line_item]
+ )
+ end
+
+ let(:ship_address) do
+ Spree::Address.create!(
+ country: country_us,
+ state: state_california,
+ zipcode: "90210",
+ city: "Los Angeles",
+ address1: "475 N Beverly Dr",
+
+ first_name: "Chuck",
+ last_name: "Schuldiner",
+ phone: "1-250-555-4444"
+ )
+ end
+
+ let(:country_us) do
+ Spree::Country.create!(
+ iso_name: "UNITED STATES",
+ iso: "US",
+ iso3: "USA",
+ name: "United States",
+ numcode: 840,
+ states_required: true
+ )
+ end
+
+ let(:state_california) do
+ Spree::State.create!(
+ country: country_us,
+ name: "California",
+ abbr: "CA"
+ )
+ end
+
+ let(:line_item) do
+ Spree::LineItem.new(
+ variant: variant,
+ price: 10,
+ quantity: 3,
+ adjustment_total: -2
+ )
+ end
+
+ let(:variant) do
+ Spree::Variant.create!(
+ product: product,
+ price: 10
+ )
+ end
+
+ let(:product) do
+ Spree::Product.create!(
+ name: "Product Name",
+ shipping_category: shipping_category,
+ tax_category: Spree::TaxCategory.first,
+ master: master_variant,
+ variants: [master_variant]
+ )
+ end
+
+ let(:shipping_category) do
+ Spree::ShippingCategory.create!(name: "Default Category")
+ end
+
+ let(:master_variant) do
+ Spree::Variant.new(
+ is_master: true,
+ price: 10
+ )
+ end
+
+ before do
+
+ allow(dummy_client).to receive(:tax_for_order).with(
+ to_country: "US",
+ to_zip: "90210",
+ to_city: "Los Angeles",
+ to_state: "CA",
+ to_street: "475 N Beverly Dr",
+
+ amount: 28.00,
+ shipping: 3.01,
+
+ line_items: [{
+ id: order.line_items.first.id,
+ quantity: 3,
+ unit_price: 10.00,
+ discount: 2.00,
+ product_tax_code: "A_GEN_TAX"
+ }]
+ ).and_return({ some_kind_of: "response" })
+ end
+
+ it { is_expected.to eq({ some_kind_of: "response" }) }
+ end
+end