super_good-solidus_taxjar 0.18.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (127) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +58 -0
  3. data/CHANGELOG.md +118 -5
  4. data/Gemfile +28 -10
  5. data/README.md +300 -45
  6. data/Rakefile +3 -0
  7. data/app/controllers/spree/admin/taxjar_settings_controller.rb +93 -0
  8. data/app/controllers/spree/admin/taxjar_transactions_controller.rb +37 -0
  9. data/app/controllers/spree/admin/transaction_sync_batches_controller.rb +18 -0
  10. data/app/jobs/super_good/solidus_taxjar/backfill_transaction_sync_batch_job.rb +23 -0
  11. data/app/jobs/super_good/solidus_taxjar/replace_transaction_job.rb +26 -0
  12. data/app/jobs/super_good/solidus_taxjar/report_transaction_job.rb +22 -0
  13. data/app/models/super_good/solidus_taxjar/configuration.rb +27 -0
  14. data/app/models/super_good/solidus_taxjar/order_transaction.rb +16 -0
  15. data/app/models/super_good/solidus_taxjar/refund_transaction.rb +13 -0
  16. data/app/models/super_good/solidus_taxjar/transaction_sync_batch.rb +11 -0
  17. data/app/models/super_good/solidus_taxjar/transaction_sync_log.rb +8 -0
  18. data/app/overrides/spree/admin/orders_controller_override.rb +12 -0
  19. data/app/overrides/spree/admin/shared/_order_submenu/add_taxjar_sync_history_tab.html.erb.deface +6 -0
  20. data/app/overrides/spree/admin/shared/_order_summary/add_taxjar_reported_at.html.erb.deface +30 -0
  21. data/app/overrides/spree/admin/shared/_taxes_tabs/add_configuration_menu_items.html.erb.deface +5 -0
  22. data/app/overrides/super_good/solidus_taxjar/spree/order_override.rb +21 -0
  23. data/app/views/spree/admin/orders/taxjar_transactions.html.erb +4 -0
  24. data/app/views/spree/admin/shared/_transaction_sync_log_table.html.erb +35 -0
  25. data/app/views/spree/admin/taxjar_settings/_nexus_regions.html.erb +23 -0
  26. data/app/views/spree/admin/taxjar_settings/_tax_categories.html.erb +41 -0
  27. data/app/views/spree/admin/taxjar_settings/edit.html.erb +17 -0
  28. data/app/views/spree/admin/taxjar_settings/edit_no_api_key.html.erb +21 -0
  29. data/app/views/spree/admin/transaction_sync_batches/index.html.erb +50 -0
  30. data/app/views/spree/admin/transaction_sync_batches/show.html.erb +7 -0
  31. data/bin/console +2 -0
  32. data/bin/rails-engine +1 -1
  33. data/bin/sandbox +43 -36
  34. data/bin/setup +3 -3
  35. data/config/routes.rb +19 -0
  36. data/db/migrate/20210908205201_create_taxjar_order_transactions.rb +16 -0
  37. data/db/migrate/20211008175113_create_taxjar_refund_transaction.rb +15 -0
  38. data/db/migrate/20211008183858_add_transaction_date_to_order_transaction.rb +5 -0
  39. data/db/migrate/20211119143354_create_configuration.rb +8 -0
  40. data/db/migrate/20220405213958_create_transaction_sync_batches.rb +7 -0
  41. data/db/migrate/20220405215225_create_transaction_sync_logs.rb +14 -0
  42. data/db/migrate/20220908181655_add_dates_to_transaction_sync_batch.rb +6 -0
  43. data/db/migrate/20220912182210_allow_null_transaction_sync_batches_on_logs.rb +5 -0
  44. data/db/migrate/20230320211309_add_refund_transaction_to_sync_logs.rb +5 -0
  45. data/lib/generators/super_good/solidus_taxjar/install/install_generator.rb +68 -0
  46. data/lib/super_good/engine.rb +2 -0
  47. data/lib/super_good/solidus_taxjar/addresses.rb +3 -3
  48. data/lib/super_good/solidus_taxjar/api.rb +45 -9
  49. data/lib/super_good/solidus_taxjar/api_params.rb +93 -26
  50. data/lib/super_good/solidus_taxjar/backfill_transactions.rb +11 -0
  51. data/lib/super_good/solidus_taxjar/cached_api.rb +23 -0
  52. data/lib/super_good/solidus_taxjar/calculator_helper.rb +34 -5
  53. data/lib/super_good/solidus_taxjar/discount_calculator.rb +1 -1
  54. data/lib/super_good/solidus_taxjar/overrides/request_override.rb +15 -0
  55. data/lib/super_good/solidus_taxjar/reportable.rb +91 -0
  56. data/lib/super_good/solidus_taxjar/reporting.rb +44 -0
  57. data/lib/super_good/solidus_taxjar/spree/legacy_reporting_subscriber.rb +41 -0
  58. data/lib/super_good/solidus_taxjar/spree/reporting_subscriber.rb +40 -0
  59. data/lib/super_good/solidus_taxjar/tax_calculator.rb +10 -4
  60. data/lib/super_good/solidus_taxjar/testing_support/factories/address_factory.rb +11 -0
  61. data/lib/super_good/solidus_taxjar/testing_support/factories/configuration_factory.rb +11 -0
  62. data/lib/super_good/solidus_taxjar/testing_support/factories/order_transaction_factory.rb +22 -0
  63. data/lib/super_good/solidus_taxjar/testing_support/factories/refund_transaction_factory.rb +7 -0
  64. data/lib/super_good/solidus_taxjar/testing_support/factories/transaction_sync_batch_factory.rb +9 -0
  65. data/lib/super_good/solidus_taxjar/testing_support/factories/transaction_sync_log_factory.rb +18 -0
  66. data/lib/super_good/solidus_taxjar/transaction_id_generator.rb +45 -0
  67. data/lib/super_good/solidus_taxjar/version.rb +1 -1
  68. data/lib/super_good/solidus_taxjar.rb +30 -3
  69. data/spec/features/spree/admin/backfill_transactions_spec.rb +138 -0
  70. data/spec/features/spree/admin/refund_spec.rb +167 -0
  71. data/spec/features/spree/admin/reporting_to_taxjar_spec.rb +156 -0
  72. data/spec/features/spree/admin/taxjar_settings_spec.rb +90 -0
  73. data/spec/features/spree/checkout_spec.rb +58 -0
  74. data/spec/fixtures/cassettes/Admin_TaxJar_Settings/GET_sync_nexus_regions/Taxjar_API_token_is_not_set/doesn_t_make_a_request_for_the_nexus_regions.yml +57 -0
  75. data/spec/fixtures/cassettes/Admin_TaxJar_Settings/GET_sync_tax_categories/Taxjar_API_token_is_not_set/doesn_t_make_a_request_for_the_tax_categories.yml +57 -0
  76. data/spec/fixtures/cassettes/Admin_TaxJar_Settings/Taxjar_settings_tab/Taxjar_API_token_is_set/shows_the_settings_page.yml +2437 -0
  77. data/spec/fixtures/cassettes/Admin_TaxJar_Settings/Taxjar_settings_tab/Taxjar_API_token_isn_t_set/doesn_t_show_any_other_TaxJar_features.yml +57 -0
  78. data/spec/fixtures/cassettes/Admin_TaxJar_Settings/Taxjar_settings_tab/Taxjar_API_token_isn_t_set/shows_a_descriptive_error_message.yml +57 -0
  79. data/spec/fixtures/cassettes/Admin_TaxJar_Settings/Taxjar_settings_tab/Taxjar_reporting_is_enabled/shows_that_reporting_is_enabled.yml +2382 -0
  80. data/spec/fixtures/cassettes/Admin_TaxJar_Settings/Taxjar_settings_tab/order_is_shipped/the_user_backfills_their_transactions.yml +2511 -0
  81. data/spec/fixtures/cassettes/Admin_TaxJar_Settings/Taxjar_settings_tab/the_user_navigates_to_the_TaxJar_Settings.yml +2382 -0
  82. data/spec/fixtures/cassettes/Admin_Transaction_Sync_Batches/user_has_a_shipped_order/starts_a_transaction_backfill.yml +370 -0
  83. data/spec/fixtures/cassettes/Reporting_orders_to_TaxJar/shipping_a_complete_and_paid_order.yml +310 -0
  84. data/spec/fixtures/cassettes/Reporting_orders_to_TaxJar/updating_an_order_which_was_not_reported_due_to_failure/it_reports_the_order_instead_of_trying_to_replace_it.yml +794 -0
  85. data/spec/fixtures/cassettes/Reporting_orders_to_TaxJar/with_an_order_with_invalid_zipcode/retry_of_a_previously_failed_transaction_sync.yml +418 -0
  86. data/spec/fixtures/cassettes/Spree_Admin_TransactionSyncBatchesController/_create/creates_a_batch.yml +250 -0
  87. data/spec/fixtures/cassettes/Spree_Admin_TransactionSyncBatchesController/_create/creates_a_log_in_the_batch_with_an_order.yml +250 -0
  88. data/spec/fixtures/cassettes/Spree_Admin_TransactionSyncBatchesController/_create/user_supplies_a_start_date/creates_a_batch.yml +250 -0
  89. data/spec/fixtures/cassettes/Spree_Admin_TransactionSyncBatchesController/_create/user_supplies_a_start_date/user_supplies_start_and_end_date/creates_a_batch.yml +250 -0
  90. data/spec/fixtures/cassettes/SuperGood_SolidusTaxjar_CalculatorHelper/_taxable_address_/when_taxable_address_check_returns_true/with_US_address/when_the_address_is_not_within_a_nexus_region/1_3_2_2_2_1.yml +58 -0
  91. data/spec/fixtures/cassettes/SuperGood_SolidusTaxjar_CalculatorHelper/_taxable_address_/when_taxable_address_check_returns_true/with_US_address/when_the_address_is_within_a_nexus_region/1_3_2_2_1_1.yml +58 -0
  92. data/spec/fixtures/cassettes/SuperGood_SolidusTaxjar_Reporting/_refund_and_create_transaction/when_Taxjar_cannot_create_a_refund_transaction/doesn_t_create_a_new_transaction.yml +393 -0
  93. data/spec/fixtures/cassettes/SuperGood_SolidusTaxjar_Reporting/_refund_and_create_transaction/when_Taxjar_cannot_create_a_refund_transaction/raises_an_error.yml +393 -0
  94. data/spec/fixtures/cassettes/Taxjar_API_Request/logging_is_disabled/doesn_t_call_the_logger.yml +158 -0
  95. data/spec/fixtures/cassettes/Taxjar_API_Request/logging_is_enabled/calls_the_logger.yml +158 -0
  96. data/spec/fixtures/cassettes/features/spree/admin/checkout.yml +238 -0
  97. data/spec/fixtures/cassettes/features/spree/admin/refund.yml +1162 -0
  98. data/spec/jobs/super_good/solidus_taxjar/backfill_transaction_sync_batch_job_spec.rb +117 -0
  99. data/spec/jobs/super_good/solidus_taxjar/replace_transaction_job_spec.rb +95 -0
  100. data/spec/jobs/super_good/solidus_taxjar/report_transaction_job_spec.rb +76 -0
  101. data/spec/models/super_good/solidus_taxjar/configuration_spec.rb +79 -0
  102. data/spec/models/super_good/solidus_taxjar/order_transaction_spec.rb +36 -0
  103. data/spec/models/super_good/solidus_taxjar/transaction_sync_batch_spec.rb +48 -0
  104. data/spec/requests/spree/admin/order_request_spec.rb +121 -0
  105. data/spec/requests/spree/admin/taxjar_settings_request_spec.rb +198 -0
  106. data/spec/requests/spree/admin/taxjar_transactions_request_spec.rb +62 -0
  107. data/spec/requests/spree/admin/transaction_sync_batches_request_spec.rb +82 -0
  108. data/spec/spec_helper.rb +47 -4
  109. data/spec/subscribers/super_good/solidus_taxjar/spree/reporting_subscriber_spec.rb +278 -0
  110. data/spec/super_good/solidus_taxjar/addresses_spec.rb +0 -14
  111. data/spec/super_good/solidus_taxjar/api_params_spec.rb +284 -80
  112. data/spec/super_good/solidus_taxjar/api_spec.rb +168 -28
  113. data/spec/super_good/solidus_taxjar/backfill_transactions_spec.rb +24 -0
  114. data/spec/super_good/solidus_taxjar/cached_api_spec.rb +58 -0
  115. data/spec/super_good/solidus_taxjar/calculator_helper_spec.rb +131 -0
  116. data/spec/super_good/solidus_taxjar/discount_calculator_spec.rb +19 -2
  117. data/spec/super_good/solidus_taxjar/reportable_spec.rb +194 -0
  118. data/spec/super_good/solidus_taxjar/reporting_spec.rb +243 -0
  119. data/spec/super_good/solidus_taxjar/tax_calculator_spec.rb +19 -19
  120. data/spec/super_good/solidus_taxjar/tax_rate_calculator_spec.rb +8 -3
  121. data/spec/super_good/solidus_taxjar/transaction_id_generator_spec.rb +77 -0
  122. data/spec/super_good/solidus_taxjar_spec.rb +99 -0
  123. data/spec/support/checkoutable_store_shared_context.rb +19 -0
  124. data/spec/support/solidus_events_helper.rb +26 -0
  125. data/spec/taxjar/api/request_spec.rb +52 -0
  126. data/super_good-solidus_taxjar.gemspec +4 -3
  127. metadata +176 -14
@@ -10,8 +10,6 @@ RSpec.describe SuperGood::SolidusTaxjar::Addresses do
10
10
  address1: "475 North Beverly Drive",
11
11
  city: "Los Angeles",
12
12
  country: country_us,
13
- first_name: "Chuck",
14
- last_name: "Schuldiner",
15
13
  phone: "1-250-555-4444",
16
14
  state: state_california,
17
15
  zipcode: "90210"
@@ -79,8 +77,6 @@ RSpec.describe SuperGood::SolidusTaxjar::Addresses do
79
77
  address1: "475 N Beverly Dr",
80
78
  city: "Beverly Hills",
81
79
  country: country_us,
82
- first_name: "Chuck",
83
- last_name: "Schuldiner",
84
80
  phone: "1-250-555-4444",
85
81
  state: state_california,
86
82
  zipcode: "90210-4606"
@@ -123,8 +119,6 @@ RSpec.describe SuperGood::SolidusTaxjar::Addresses do
123
119
  address1: "475 N Beverly Dr",
124
120
  city: "Beverly Hills",
125
121
  country: country_us,
126
- first_name: "Chuck",
127
- last_name: "Schuldiner",
128
122
  phone: "1-250-555-4444",
129
123
  state: state_california,
130
124
  zipcode: "90210-4606"
@@ -143,8 +137,6 @@ RSpec.describe SuperGood::SolidusTaxjar::Addresses do
143
137
  address1: "475 North Beverly Drive",
144
138
  city: "Los Angeles",
145
139
  country: country_us,
146
- first_name: "Chuck",
147
- last_name: "Schuldiner",
148
140
  phone: "1-250-555-4444",
149
141
  state: state_california,
150
142
  zipcode: "90210"
@@ -212,8 +204,6 @@ RSpec.describe SuperGood::SolidusTaxjar::Addresses do
212
204
  address1: "475 N Beverly Dr",
213
205
  city: "Beverly Hills",
214
206
  country: country_us,
215
- first_name: "Chuck",
216
- last_name: "Schuldiner",
217
207
  phone: "1-250-555-4444",
218
208
  state: state_california,
219
209
  zipcode: "90210-4606"
@@ -264,8 +254,6 @@ RSpec.describe SuperGood::SolidusTaxjar::Addresses do
264
254
  address1: "475 N Beverly Dr",
265
255
  city: "Beverly Hills",
266
256
  country: country_us,
267
- first_name: "Chuck",
268
- last_name: "Schuldiner",
269
257
  phone: "1-250-555-4444",
270
258
  state: state_california,
271
259
  zipcode: "90210-4606"
@@ -275,8 +263,6 @@ RSpec.describe SuperGood::SolidusTaxjar::Addresses do
275
263
  address1: "473 N Beverly Dr",
276
264
  city: "Phoenix",
277
265
  country: country_us,
278
- first_name: "Chuck",
279
- last_name: "Schuldiner",
280
266
  phone: "1-250-555-4444",
281
267
  state: state_arizona,
282
268
  zipcode: "90213-1234"
@@ -2,24 +2,27 @@ require "spec_helper"
2
2
 
3
3
  RSpec.describe SuperGood::SolidusTaxjar::ApiParams do
4
4
  let(:order) do
5
- Spree::Order.create!(
6
- additional_tax_total: BigDecimal("9.87"),
7
- item_total: BigDecimal("28.00"),
8
- line_items: [line_item],
5
+ create(:order,
9
6
  number: "R111222333",
10
7
  ship_address: ship_address,
11
- shipment_total: BigDecimal("3.01"),
8
+ line_items: line_items_attributes.map { |attributes| build(:line_item, attributes) },
12
9
  store: store,
13
- total: order_total,
14
- user_id: 12345
15
- ).tap do |order|
16
- order.update! completed_at: DateTime.new(2018, 3, 6, 12, 10, 33)
17
- end
10
+ shipments: [shipment],
11
+ user_id: 12345,
12
+ completed_at: DateTime.new(2018, 3, 6, 12, 10, 33),
13
+ payments: payments).tap do |order|
14
+ order.update_columns(additional_tax_total: 9.87, item_total: 28.00, total: order_total)
15
+ order.line_items.each_with_index do |line_item, idx|
16
+ line_item.update_columns(line_items_attributes[idx])
17
+ end
18
+ end
18
19
  end
19
20
  let(:order_total) { BigDecimal("123.45") }
21
+ let(:payments) { build_list(:payment, 1, :completed, amount: 110.45) }
20
22
 
21
23
  let(:store) do
22
- Spree::Store.create!(
24
+ create(
25
+ :store,
23
26
  cart_tax_country_iso: "US",
24
27
  code: "store",
25
28
  mail_from_address: "contact@example.com",
@@ -28,58 +31,70 @@ RSpec.describe SuperGood::SolidusTaxjar::ApiParams do
28
31
  )
29
32
  end
30
33
 
31
- let(:ship_address) do
32
- Spree::Address.create!(
34
+ let!(:ship_address) do
35
+ create(
36
+ :address,
33
37
  address1: "475 N Beverly Dr",
38
+ address2: nil,
34
39
  city: "Los Angeles",
35
40
  country: country_us,
36
- first_name: "Chuck",
37
- last_name: "Schuldiner",
38
41
  phone: "1-250-555-4444",
39
- state: state_california,
42
+ state_code: "CA",
40
43
  zipcode: "90210"
41
44
  )
42
45
  end
43
46
 
44
47
  let(:country_us) do
45
- Spree::Country.create!(
46
- iso3: "USA",
48
+ create(
49
+ :country,
47
50
  iso: "US",
48
- iso_name: "UNITED STATES",
49
- name: "United States",
50
- numcode: 840,
51
51
  states_required: true
52
52
  )
53
53
  end
54
54
 
55
- let(:state_california) do
56
- Spree::State.create!(
57
- abbr: "CA",
58
- country: country_us,
59
- name: "California"
60
- )
55
+ let(:line_items_attributes) do
56
+ [
57
+ attributes_for(
58
+ :line_item,
59
+ additional_tax_total: 4,
60
+ price: 10,
61
+ promo_total: -2,
62
+ quantity: 3,
63
+ variant_id: variant.id
64
+ )
65
+ ]
61
66
  end
62
67
 
63
- let(:line_item) do
64
- Spree::LineItem.new(
65
- additional_tax_total: 4,
68
+ let(:variant) do
69
+ create(
70
+ :variant,
66
71
  price: 10,
67
- promo_total: -2,
68
- quantity: 3,
69
- variant: variant
72
+ product: product,
73
+ sku: "G00D-PR0DUCT",
74
+ option_values: [option_value]
70
75
  )
71
76
  end
72
77
 
73
- let(:variant) do
74
- Spree::Variant.create!(
75
- price: 10,
76
- product: product,
77
- sku: "G00D-PR0DUCT"
78
+ let(:option_value) do
79
+ create(
80
+ :option_value,
81
+ name: "Red",
82
+ presentation: "red",
83
+ option_type: option_type
84
+ )
85
+ end
86
+
87
+ let(:option_type) do
88
+ create(
89
+ :option_type,
90
+ name: "Color",
91
+ presentation: "color"
78
92
  )
79
93
  end
80
94
 
81
95
  let(:product) do
82
- Spree::Product.create!(
96
+ create(
97
+ :product,
83
98
  master: master_variant,
84
99
  name: "Product Name",
85
100
  shipping_category: shipping_category,
@@ -88,12 +103,11 @@ RSpec.describe SuperGood::SolidusTaxjar::ApiParams do
88
103
  )
89
104
  end
90
105
 
91
- let(:shipping_category) do
92
- Spree::ShippingCategory.create!(name: "Default Category")
93
- end
106
+ let(:shipping_category){ create(:shipping_category) }
94
107
 
95
108
  let(:tax_category) do
96
- Spree::TaxCategory.create!(
109
+ create(
110
+ :tax_category,
97
111
  is_default: true,
98
112
  name: "Default",
99
113
  tax_code: "A_GEN_TAX"
@@ -101,27 +115,52 @@ RSpec.describe SuperGood::SolidusTaxjar::ApiParams do
101
115
  end
102
116
 
103
117
  let(:master_variant) do
104
- Spree::Variant.new(
118
+ build(
119
+ :variant,
105
120
  is_master: true,
106
121
  price: 10
107
122
  )
108
123
  end
109
124
 
110
125
  let(:reimbursement) do
111
- Spree::Reimbursement.new(
126
+ build(
127
+ :reimbursement,
112
128
  number: "RI123123123",
113
129
  order: order,
114
130
  return_items: [
115
- Spree::ReturnItem.new(additional_tax_total: 0.33),
116
- Spree::ReturnItem.new(additional_tax_total: 33.0)
131
+ build(:return_item, additional_tax_total: 0.33),
132
+ build(:return_item, additional_tax_total: 33.0)
117
133
  ],
118
134
  total: 333.33
119
135
  )
120
136
  end
121
137
 
122
- describe "#order_params" do
138
+ let(:shipment) { create(:shipment, cost: BigDecimal("3.01")) }
139
+
140
+ before do
141
+ create :state, state_code: "CA"
142
+ create :state, state_code: "NY"
143
+
144
+
145
+ end
146
+
147
+ describe ".order_params" do
123
148
  subject { described_class.order_params(order) }
124
149
 
150
+ before do
151
+ # The discount calculator relies on the line item adjustments existing in
152
+ # order to calculate the correct discount amount for TaxJar.
153
+ create(
154
+ :adjustment,
155
+ order: order,
156
+ adjustable: order.line_items.first,
157
+ amount: line_items_attributes.first[:promo_total],
158
+ source_type: "Spree::Promotion::Action::CreateItemAdjustments",
159
+ label: "Promo",
160
+ finalized: true # Prevents this adjustment from being recalculated.
161
+ )
162
+ end
163
+
125
164
  it "returns params for fetching the tax for the order" do
126
165
  expect(subject).to eq(
127
166
  customer_id: "12345",
@@ -189,14 +228,17 @@ RSpec.describe SuperGood::SolidusTaxjar::ApiParams do
189
228
  end
190
229
 
191
230
  context "when the line item has zero quantity" do
192
- let(:line_item) do
193
- Spree::LineItem.new(
194
- additional_tax_total: 4,
195
- price: 10,
196
- promo_total: -2,
197
- quantity: 0,
198
- variant: variant
199
- )
231
+ let(:line_items_attributes) do
232
+ [
233
+ attributes_for(
234
+ :line_item,
235
+ additional_tax_total: 4,
236
+ price: 10,
237
+ promo_total: -2,
238
+ quantity: 0,
239
+ variant_id: variant.id
240
+ )
241
+ ]
200
242
  end
201
243
 
202
244
  it "excludes the line item" do
@@ -214,7 +256,7 @@ RSpec.describe SuperGood::SolidusTaxjar::ApiParams do
214
256
  end
215
257
  end
216
258
 
217
- describe "#address_params" do
259
+ describe ".address_params" do
218
260
  subject { described_class.address_params(ship_address) }
219
261
 
220
262
  it "returns params for fetching the tax info for that address" do
@@ -230,7 +272,7 @@ RSpec.describe SuperGood::SolidusTaxjar::ApiParams do
230
272
  end
231
273
  end
232
274
 
233
- describe "#tax_rate_address_params" do
275
+ describe ".tax_rate_address_params" do
234
276
  subject { described_class.tax_rate_address_params(ship_address) }
235
277
 
236
278
  it "returns params for fetching the tax rate for that address" do
@@ -248,17 +290,32 @@ RSpec.describe SuperGood::SolidusTaxjar::ApiParams do
248
290
  end
249
291
  end
250
292
 
251
- describe "#transaction_params" do
293
+ describe ".transaction_params" do
252
294
  subject { described_class.transaction_params(order) }
253
295
 
296
+ before do
297
+ # The discount calculator relies on the line item adjustments existing in
298
+ # order to calculate the correct discount amount for TaxJar.
299
+ create(
300
+ :adjustment,
301
+ order: order,
302
+ adjustable: order.line_items.first,
303
+ amount: line_items_attributes.first[:promo_total],
304
+ source_type: "Spree::Promotion::Action::CreateItemAdjustments",
305
+ label: "Promo",
306
+ finalized: true # Prevents this adjustment from being recalculated.
307
+ )
308
+ end
309
+
254
310
  it "returns params for creating/updating an order transaction" do
255
311
  expect(subject).to eq({
256
- amount: BigDecimal("113.58"),
312
+ amount: BigDecimal("100.58"),
257
313
  customer_id: "12345",
258
314
  line_items: [{
259
315
  discount: 2,
260
- id: line_item.id,
316
+ id: order.line_items.first.id,
261
317
  product_identifier: "G00D-PR0DUCT",
318
+ description: "Product Name - color: red",
262
319
  product_tax_code: "A_GEN_TAX",
263
320
  quantity: 3,
264
321
  sales_tax: 4,
@@ -278,6 +335,7 @@ RSpec.describe SuperGood::SolidusTaxjar::ApiParams do
278
335
 
279
336
  context "when the order is adjusted to 0" do
280
337
  let(:order_total) { BigDecimal("0") }
338
+ let(:payments) { [] }
281
339
 
282
340
  it "sends the order total as zero" do
283
341
  expect(subject[:amount]).to be_zero
@@ -290,8 +348,9 @@ RSpec.describe SuperGood::SolidusTaxjar::ApiParams do
290
348
  it "sends the sales tax on the line items as zero" do
291
349
  expect(subject[:line_items]).to contain_exactly({
292
350
  discount: 2,
293
- id: line_item.id,
351
+ id: order.line_items.first.id,
294
352
  product_identifier: "G00D-PR0DUCT",
353
+ description: "Product Name - color: red",
295
354
  product_tax_code: "A_GEN_TAX",
296
355
  quantity: 3,
297
356
  sales_tax: 0,
@@ -301,19 +360,22 @@ RSpec.describe SuperGood::SolidusTaxjar::ApiParams do
301
360
  end
302
361
 
303
362
  context "when the line item has 0 quantity" do
304
- let(:line_item) do
305
- Spree::LineItem.new(
306
- additional_tax_total: 4,
307
- price: 10,
308
- promo_total: -2,
309
- quantity: 0,
310
- variant: variant
311
- )
363
+ let(:line_items_attributes) do
364
+ [
365
+ attributes_for(
366
+ :line_item,
367
+ additional_tax_total: 4,
368
+ price: 10,
369
+ promo_total: -2,
370
+ quantity: 0,
371
+ variant_id: variant.id
372
+ )
373
+ ]
312
374
  end
313
375
 
314
376
  it "excludes the line item" do
315
377
  expect(subject).to eq({
316
- amount: BigDecimal("113.58"),
378
+ amount: BigDecimal("100.58"),
317
379
  customer_id: "12345",
318
380
  line_items: [],
319
381
  sales_tax: BigDecimal("9.87"),
@@ -328,6 +390,87 @@ RSpec.describe SuperGood::SolidusTaxjar::ApiParams do
328
390
  })
329
391
  end
330
392
  end
393
+
394
+ context "with an optional transaction_id specified" do
395
+ subject {
396
+ described_class.transaction_params(order, custom_transaction_id)
397
+ }
398
+
399
+ let(:custom_transaction_id) { "R0123456789" }
400
+
401
+ it "uses the specified transaction_id" do
402
+ expect(subject).to include(transaction_id: "R0123456789")
403
+ end
404
+ end
405
+
406
+ context "when all line items have been returned and reimbursed" do
407
+ let(:reimbursement_total) { 10 }
408
+ let(:reimbursement_tax) { 1.02 }
409
+
410
+ before do
411
+ reimbursement = create(:reimbursement)
412
+ reimbursement.return_items.first.update_columns(additional_tax_total: reimbursement_tax)
413
+ refund = create(:refund, reimbursement: reimbursement, payment: order.payments.first)
414
+ reimbursement.update_columns(order_id: order.id, total: reimbursement_total + reimbursement_tax)
415
+ order.line_items.first.inventory_units.update_all(state: "returned")
416
+ end
417
+
418
+ it "excludes returned line items" do
419
+ expect(subject).to match(hash_including({ line_items: [] }))
420
+ end
421
+
422
+ it "removes the reimbursed tax from the sales tax amount" do
423
+ expect(subject[:sales_tax]).to eq(9.87 - reimbursement_tax)
424
+ end
425
+
426
+ it "removes the reimbursements without tax from the total amount" do
427
+ expect(subject[:amount]).to eq(100.58 - reimbursement_total)
428
+ end
429
+ end
430
+
431
+ context "when some line items have been returned and reimbursed" do
432
+ let(:reimbursement_total) { 10 }
433
+ let(:reimbursement_tax) { 1.02 }
434
+
435
+ before do
436
+ reimbursement = create(:reimbursement)
437
+ reimbursement.return_items.first.update_columns(additional_tax_total: reimbursement_tax)
438
+ refund = create(:refund, reimbursement: reimbursement, payment: order.payments.first)
439
+ reimbursement.update_columns(order_id: order.id, total: reimbursement_total + reimbursement_tax)
440
+ first_inventory_unit = order.line_items.first.inventory_units.first
441
+ first_inventory_unit.update(state: "returned")
442
+ return_item = create(:return_item, amount: 34, additional_tax_total: reimbursement_tax / 4)
443
+ return_item.update_columns(inventory_unit_id: first_inventory_unit.id, reimbursement_id: reimbursement.id)
444
+ end
445
+
446
+ it "removes the reimbursed tax from the specific line item" do
447
+ expect(subject[:line_items].first[:sales_tax]).to eq(order.line_items.first.additional_tax_total - (reimbursement_tax / 4))
448
+ end
449
+ end
450
+
451
+
452
+ context "when a refund without a reimbursement exists" do
453
+ let(:refund_amount) { 10 }
454
+
455
+ before do
456
+ create(:refund, payment: order.payments.first, amount: refund_amount)
457
+ end
458
+
459
+ it "removes the orphaned refunds from the total amount" do
460
+ expect(subject[:amount]).to eq(100.58 - refund_amount)
461
+ end
462
+ end
463
+
464
+ context "part of a line item has been returned" do
465
+ before do
466
+ order.line_items.first.inventory_units.first.update(state: "returned")
467
+ order.line_items.first.inventory_units.second.update(state: "canceled")
468
+ end
469
+
470
+ it "adjusts the line item quanity" do
471
+ expect(subject).to match(hash_including({ line_items: [hash_including({quantity:1})] }))
472
+ end
473
+ end
331
474
  end
332
475
 
333
476
  describe "#refund_params" do
@@ -350,6 +493,44 @@ RSpec.describe SuperGood::SolidusTaxjar::ApiParams do
350
493
  end
351
494
  end
352
495
 
496
+ describe "#refund_transaction_params" do
497
+ subject { described_class.refund_transaction_params(order, taxjar_order) }
498
+
499
+ let(:taxjar_line_item) { {id: 1, quantity: 2, unit_price: 2.00, discount: 0.50, sales_tax: 0.80} }
500
+ let(:taxjar_order) {
501
+ Taxjar::Order.new(
502
+ transaction_id: "R111222333-1",
503
+ amount: 123.45,
504
+ sales_tax: 33.33,
505
+ shipping: 3.01,
506
+ line_items: [taxjar_line_item]
507
+ )
508
+ }
509
+
510
+ it "returns params for creating/updating a refund" do
511
+ expect(subject).to include({
512
+ amount: -123.45,
513
+ sales_tax: -33.33,
514
+ shipping: -3.01,
515
+ to_city: "Los Angeles",
516
+ to_country: "US",
517
+ to_state: "CA",
518
+ to_street: "475 N Beverly Dr",
519
+ to_zip: "90210",
520
+ transaction_date: "2018-03-06T12:10:33Z",
521
+ transaction_reference_id: "R111222333-1",
522
+ transaction_id: "R111222333-1-REFUND",
523
+ line_items: [{
524
+ id: 1,
525
+ quantity: 2,
526
+ unit_price: -2.00,
527
+ discount: -0.50,
528
+ sales_tax: -0.80
529
+ }]
530
+ })
531
+ end
532
+ end
533
+
353
534
  describe "#validate_address_params" do
354
535
  subject { described_class.validate_address_params(ship_address) }
355
536
 
@@ -364,26 +545,24 @@ RSpec.describe SuperGood::SolidusTaxjar::ApiParams do
364
545
  end
365
546
 
366
547
  context "with an address without a state" do
367
- let(:ship_address) do
368
- Spree::Address.create!(
548
+ let!(:ship_address) do
549
+ create(
550
+ :address,
369
551
  address1: "72 High St",
552
+ address2: nil,
370
553
  city: "Birmingham",
371
554
  country: country_uk,
372
- first_name: "Chuck",
373
- last_name: "Schuldiner",
374
555
  phone: "1-250-555-4444",
556
+ state: nil,
375
557
  state_name: "West Midlands",
376
558
  zipcode: "B4 7TA"
377
559
  )
378
560
  end
379
561
 
380
562
  let(:country_uk) do
381
- Spree::Country.create!(
382
- iso3: "GBR",
563
+ create(
564
+ :country,
383
565
  iso: "GB",
384
- iso_name: "UNITED KINGDOM",
385
- name: "United Kingdom",
386
- numcode: 826,
387
566
  states_required: false
388
567
  )
389
568
  end
@@ -398,5 +577,30 @@ RSpec.describe SuperGood::SolidusTaxjar::ApiParams do
398
577
  })
399
578
  end
400
579
  end
580
+
581
+ context "an address with address2" do
582
+ let!(:ship_address) do
583
+ create(
584
+ :address,
585
+ address1: "1 World Trade CTR",
586
+ address2: "STE 45A",
587
+ city: "New York",
588
+ country: country_us,
589
+ phone: "1-250-555-4444",
590
+ state_code: "NY",
591
+ zipcode: "10007"
592
+ )
593
+ end
594
+
595
+ it "concatenates address1 and address2 into the street parameter" do
596
+ expect(subject).to eq({
597
+ country: "US",
598
+ state: "NY",
599
+ zip: "10007",
600
+ city: "New York",
601
+ street: "1 World Trade CTR STE 45A"
602
+ })
603
+ end
604
+ end
401
605
  end
402
606
  end