solidus_avatax 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +15 -0
- data/.rspec +1 -0
- data/.ruby-version +1 -0
- data/Gemfile +15 -0
- data/LICENSE +26 -0
- data/README.md +71 -0
- data/Rakefile +21 -0
- data/app/assets/javascripts/spree/frontend/solidus_avatax.js +1 -0
- data/app/assets/stylesheets/spree/frontend/solidus_avatax.css +1 -0
- data/app/models/spree/adjustment_decorator.rb +21 -0
- data/app/models/spree/order_contents_decorator.rb +26 -0
- data/app/models/spree/order_decorator.rb +43 -0
- data/app/models/spree/promotion_handler/coupon_decorator.rb +11 -0
- data/app/models/spree/reimbursement_decorator.rb +1 -0
- data/app/models/spree/tax_rate_decorator.rb +45 -0
- data/app/models/spree_avatax/calculator.rb +26 -0
- data/app/models/spree_avatax/return_invoice.rb +197 -0
- data/app/models/spree_avatax/sales_invoice.rb +157 -0
- data/app/models/spree_avatax/sales_shared.rb +211 -0
- data/app/models/spree_avatax/shared.rb +53 -0
- data/app/models/spree_avatax/short_ship_return_invoice.rb +133 -0
- data/app/models/spree_avatax/short_ship_return_invoice_inventory_unit.rb +11 -0
- data/bin/rails +7 -0
- data/circle.yml +6 -0
- data/config/locales/en.yml +5 -0
- data/db/migrate/20140122165618_add_avatax_response_at_to_orders.rb +5 -0
- data/db/migrate/20140214153139_add_avatax_invoice_at_to_orders.rb +5 -0
- data/db/migrate/20140617222244_close_all_tax_adjustments.rb +5 -0
- data/db/migrate/20140701144237_update_avatax_calculator_type.rb +17 -0
- data/db/migrate/20140801132302_create_spree_avatax_return_invoices.rb +19 -0
- data/db/migrate/20140903135132_create_spree_avatax_sales_orders.rb +15 -0
- data/db/migrate/20140903135357_create_spree_avatax_sales_invoices.rb +19 -0
- data/db/migrate/20140904171341_generate_uncommitted_sales_invoices.rb +31 -0
- data/db/migrate/20140911214414_add_transaction_id_to_sales_orders_and_sales_invoices.rb +6 -0
- data/db/migrate/20140911215422_add_canceled_at_and_cancel_transaction_id_to_sales_invoices.rb +6 -0
- data/db/migrate/20150427154942_create_spree_avatax_short_ship_return_invoices.rb +44 -0
- data/db/migrate/20150518172627_fix_avatax_short_ship_index.rb +30 -0
- data/lib/generators/solidus_avatax/install/install_generator.rb +31 -0
- data/lib/generators/solidus_avatax/install/templates/config/initializers/avatax.rb +18 -0
- data/lib/solidus_avatax.rb +4 -0
- data/lib/spree_avatax/config.rb +16 -0
- data/lib/spree_avatax/engine.rb +29 -0
- data/lib/spree_avatax/factories.rb +25 -0
- data/lib/tasks/commit_backfill.rake +119 -0
- data/lib/tasks/sales_invoice_backfill.rake +43 -0
- data/solidus_avatax.gemspec +34 -0
- data/spec/features/store_credits_spec.rb +92 -0
- data/spec/features/tax_calculation_spec.rb +75 -0
- data/spec/fixtures/vcr_cassettes/sales_invoice_gettax_with_discounts.yml +136 -0
- data/spec/fixtures/vcr_cassettes/sales_invoice_gettax_without_discounts.yml +136 -0
- data/spec/fixtures/vcr_cassettes/taxes_with_store_credits.yml +113 -0
- data/spec/models/spree/adjustment_spec.rb +23 -0
- data/spec/models/spree/order_contents_spec.rb +35 -0
- data/spec/models/spree/order_spec.rb +111 -0
- data/spec/models/spree/shipping_rate_spec.rb +23 -0
- data/spec/models/spree/tax_rate_spec.rb +40 -0
- data/spec/models/spree_avatax/calculator.rb +20 -0
- data/spec/models/spree_avatax/return_invoice_spec.rb +193 -0
- data/spec/models/spree_avatax/sales_invoice_spec.rb +491 -0
- data/spec/models/spree_avatax/sales_shared_spec.rb +47 -0
- data/spec/models/spree_avatax/shared_spec.rb +89 -0
- data/spec/models/spree_avatax/short_ship_return_invoice_spec.rb +181 -0
- data/spec/spec_helper.rb +85 -0
- data/spec/support/return_invoice_soap_responses.rb +117 -0
- data/spec/support/sales_invoice_soap_responses.rb +259 -0
- data/spec/support/short_ship_return_invoice_soap_responses.rb +178 -0
- data/spec/support/zone_support.rb +6 -0
- metadata +320 -0
@@ -0,0 +1,491 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe SpreeAvatax::SalesInvoice do
|
4
|
+
describe '.generate' do
|
5
|
+
subject do
|
6
|
+
SpreeAvatax::SalesInvoice.generate(order)
|
7
|
+
end
|
8
|
+
|
9
|
+
let(:order) do
|
10
|
+
create(:order_with_line_items,
|
11
|
+
line_items_count: 1,
|
12
|
+
ship_address: create(:address, {
|
13
|
+
address1: "1234 Way",
|
14
|
+
address2: "",
|
15
|
+
city: "New York",
|
16
|
+
state: state,
|
17
|
+
country: country,
|
18
|
+
zipcode: "10010",
|
19
|
+
phone: "1111111111",
|
20
|
+
}))
|
21
|
+
end
|
22
|
+
|
23
|
+
let(:line_item) { order.line_items.first }
|
24
|
+
let(:shipment) { order.shipments.first }
|
25
|
+
|
26
|
+
let(:country) { create(:country) }
|
27
|
+
let(:state) { create(:state, country: country, name: 'New York', abbr: 'NY') }
|
28
|
+
|
29
|
+
let(:expected_gettax_params) do
|
30
|
+
{
|
31
|
+
doccode: order.number,
|
32
|
+
customercode: order.email,
|
33
|
+
companycode: SpreeAvatax::Config.company_code,
|
34
|
+
|
35
|
+
doctype: SpreeAvatax::SalesInvoice::DOC_TYPE,
|
36
|
+
docdate: Date.today,
|
37
|
+
|
38
|
+
commit: false,
|
39
|
+
|
40
|
+
discount: order.avatax_order_adjustment_total.round(2).to_f,
|
41
|
+
|
42
|
+
addresses: [
|
43
|
+
{
|
44
|
+
addresscode: SpreeAvatax::SalesShared::DESTINATION_CODE,
|
45
|
+
line1: REXML::Text.normalize(order.ship_address.address1),
|
46
|
+
line2: REXML::Text.normalize(order.ship_address.address2),
|
47
|
+
city: REXML::Text.normalize(order.ship_address.city),
|
48
|
+
postalcode: REXML::Text.normalize(order.ship_address.zipcode),
|
49
|
+
},
|
50
|
+
],
|
51
|
+
|
52
|
+
lines: [
|
53
|
+
{ # line item
|
54
|
+
no: "Spree::LineItem-#{line_item.id}",
|
55
|
+
qty: line_item.quantity,
|
56
|
+
amount: line_item.discounted_amount.round(2).to_f,
|
57
|
+
origincodeline: SpreeAvatax::SalesShared::DESTINATION_CODE,
|
58
|
+
destinationcodeline: SpreeAvatax::SalesShared::DESTINATION_CODE,
|
59
|
+
|
60
|
+
description: expected_truncated_description,
|
61
|
+
|
62
|
+
itemcode: line_item.variant.sku,
|
63
|
+
taxcode: line_item.tax_category.tax_code,
|
64
|
+
discounted: true,
|
65
|
+
},
|
66
|
+
{ # shipping charge
|
67
|
+
no: "Spree::Shipment-#{shipment.id}",
|
68
|
+
qty: 1,
|
69
|
+
amount: shipment.discounted_amount.round(2).to_f,
|
70
|
+
origincodeline: SpreeAvatax::SalesShared::DESTINATION_CODE,
|
71
|
+
destinationcodeline: SpreeAvatax::SalesShared::DESTINATION_CODE,
|
72
|
+
|
73
|
+
description: SpreeAvatax::SalesShared::SHIPPING_DESCRIPTION,
|
74
|
+
|
75
|
+
taxcode: SpreeAvatax::SalesShared::SHIPPING_TAX_CODE,
|
76
|
+
discounted: false,
|
77
|
+
},
|
78
|
+
],
|
79
|
+
}
|
80
|
+
end
|
81
|
+
|
82
|
+
let(:expected_truncated_description) { line_item.variant.product.description.truncate(100) }
|
83
|
+
let(:gettax_response) { sales_invoice_gettax_response(order.number, line_item, shipment) }
|
84
|
+
let(:gettax_response_line_item_tax_line) { Array.wrap(gettax_response[:tax_lines][:tax_line]).first }
|
85
|
+
let(:gettax_response_shipment_tax_line) { Array.wrap(gettax_response[:tax_lines][:tax_line]).last }
|
86
|
+
let(:order_calculated_tax) do
|
87
|
+
BigDecimal.new(gettax_response[:total_tax])
|
88
|
+
end
|
89
|
+
let(:line_item_calculated_tax) do
|
90
|
+
BigDecimal.new(gettax_response_line_item_tax_line[:tax]).abs
|
91
|
+
end
|
92
|
+
let(:shipment_calculated_tax) do
|
93
|
+
BigDecimal.new(gettax_response_shipment_tax_line[:tax]).abs
|
94
|
+
end
|
95
|
+
|
96
|
+
let!(:gettax_stub) do
|
97
|
+
expect(SpreeAvatax::Shared.tax_svc)
|
98
|
+
.to receive(:gettax)
|
99
|
+
.with(expected_gettax_params)
|
100
|
+
.and_return(gettax_response)
|
101
|
+
end
|
102
|
+
|
103
|
+
it 'creates a sales invoice' do
|
104
|
+
expect {
|
105
|
+
subject
|
106
|
+
}.to change { SpreeAvatax::SalesInvoice.count }.by(1)
|
107
|
+
expect(order.avatax_sales_invoice).to eq SpreeAvatax::SalesInvoice.last
|
108
|
+
expect(order.avatax_sales_invoice.attributes).to include({
|
109
|
+
"transaction_id" => gettax_response[:transaction_id],
|
110
|
+
"doc_id" => gettax_response[:doc_id],
|
111
|
+
"doc_code" => gettax_response[:doc_code],
|
112
|
+
"doc_date" => gettax_response[:doc_date],
|
113
|
+
"pre_tax_total" => BigDecimal.new(gettax_response[:total_amount]),
|
114
|
+
"additional_tax_total" => BigDecimal.new(gettax_response[:total_tax]),
|
115
|
+
})
|
116
|
+
end
|
117
|
+
|
118
|
+
it 'persists the results to the order' do
|
119
|
+
expect {
|
120
|
+
subject
|
121
|
+
}.to change { order.reload.additional_tax_total }.from(0).to(order_calculated_tax)
|
122
|
+
end
|
123
|
+
|
124
|
+
it 'persists the results to the line items' do
|
125
|
+
expect {
|
126
|
+
subject
|
127
|
+
}.to change { line_item.reload.additional_tax_total }.from(0).to(line_item_calculated_tax)
|
128
|
+
end
|
129
|
+
|
130
|
+
it 'persists the results to the shipments' do
|
131
|
+
expect {
|
132
|
+
subject
|
133
|
+
}.to change { shipment.reload.additional_tax_total }.from(0).to(shipment_calculated_tax)
|
134
|
+
end
|
135
|
+
|
136
|
+
it "creates a line item adjustment" do
|
137
|
+
subject
|
138
|
+
expect(line_item.adjustments.tax.count).to eq 1
|
139
|
+
adjustment = line_item.adjustments.first
|
140
|
+
expect(adjustment.amount).to eq line_item_calculated_tax
|
141
|
+
expect(adjustment.source).to eq Spree::TaxRate.first
|
142
|
+
expect(adjustment.finalized).to eq true
|
143
|
+
end
|
144
|
+
|
145
|
+
it "creates a shipment adjustment" do
|
146
|
+
subject
|
147
|
+
expect(shipment.adjustments.tax.count).to eq 1
|
148
|
+
adjustment = shipment.adjustments.first
|
149
|
+
expect(adjustment.amount).to eq shipment_calculated_tax
|
150
|
+
expect(adjustment.source).to eq Spree::TaxRate.first
|
151
|
+
expect(adjustment.finalized).to eq true
|
152
|
+
end
|
153
|
+
|
154
|
+
context 'user input contains XML characters' do
|
155
|
+
let(:line1) { "<&line1>" }
|
156
|
+
let(:line2) { "<&line2>" }
|
157
|
+
let(:city) { "<&city>" }
|
158
|
+
let(:email) { "test&@test.com" }
|
159
|
+
let(:description) { "A description <wi>&/th xml characters" }
|
160
|
+
|
161
|
+
before(:each) do
|
162
|
+
ship_address = order.ship_address
|
163
|
+
ship_address.update_columns(address1: line1, address2: line2, city: city)
|
164
|
+
order.update_columns(email: email)
|
165
|
+
line_item.variant.product.update_columns(description: description)
|
166
|
+
end
|
167
|
+
|
168
|
+
let(:expected_gettax_params) do
|
169
|
+
super().tap do |params|
|
170
|
+
params[:addresses].first.merge!(line1: REXML::Text.normalize(line1), line2: REXML::Text.normalize(line2), city: REXML::Text.normalize(city))
|
171
|
+
params[:customercode] = REXML::Text.normalize(email)
|
172
|
+
params[:lines][0][:description] = REXML::Text.normalize(description)
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
it 'succeeds' do
|
177
|
+
subject
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
context 'when an error occurs' do
|
182
|
+
let(:error) { StandardError.new('just testing') }
|
183
|
+
let!(:gettax_stub) { }
|
184
|
+
let(:order) do
|
185
|
+
create(:order_with_line_items,
|
186
|
+
line_items_count: 2,
|
187
|
+
ship_address: create(:address, {
|
188
|
+
address1: "1234 Way",
|
189
|
+
address2: "",
|
190
|
+
city: "New York",
|
191
|
+
state: state,
|
192
|
+
country: country,
|
193
|
+
zipcode: "10010",
|
194
|
+
phone: "1111111111",
|
195
|
+
}))
|
196
|
+
end
|
197
|
+
|
198
|
+
before do
|
199
|
+
expect(SpreeAvatax::SalesShared)
|
200
|
+
.to receive(:get_tax)
|
201
|
+
.and_raise(error)
|
202
|
+
|
203
|
+
order.line_items.update_all(pre_tax_amount: nil)
|
204
|
+
order.reload
|
205
|
+
end
|
206
|
+
|
207
|
+
it 'sets the pre_tax_amount on each line item in the order' do
|
208
|
+
expect{ subject }.to raise_error(error)
|
209
|
+
expect(order.line_items.first.pre_tax_amount.to_f).to equal(order.line_items.first.discounted_amount.to_f)
|
210
|
+
expect(order.line_items.last.pre_tax_amount.to_f).to equal(order.line_items.last.discounted_amount.to_f)
|
211
|
+
end
|
212
|
+
|
213
|
+
it 'sets the pre_tax_amount on each shipment in the order' do
|
214
|
+
expect{ subject }.to raise_error(error)
|
215
|
+
expect(order.shipments.first.pre_tax_amount.to_f).to equal(order.shipments.first.discounted_amount.to_f)
|
216
|
+
end
|
217
|
+
|
218
|
+
context 'when an error_handler is not defined' do
|
219
|
+
it 'calls the handler instead of raising the original error' do
|
220
|
+
expect {
|
221
|
+
subject
|
222
|
+
}.to raise_error(error)
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
context 'when an error_handler is defined' do
|
227
|
+
let(:handler) { -> (o, e) { raise new_error } }
|
228
|
+
let(:new_error) { StandardError.new('just testing 2') }
|
229
|
+
|
230
|
+
before do
|
231
|
+
allow(SpreeAvatax::Config).to receive_messages(sales_invoice_generate_error_handler: handler)
|
232
|
+
end
|
233
|
+
|
234
|
+
it 'calls the handler instead of raising the original error' do
|
235
|
+
expect {
|
236
|
+
subject
|
237
|
+
}.to raise_error(new_error)
|
238
|
+
end
|
239
|
+
end
|
240
|
+
end
|
241
|
+
|
242
|
+
context 'when the response for a line item is missing' do
|
243
|
+
before do
|
244
|
+
gettax_response_line_item_tax_line[:no] = (line_item.id + 1).to_s
|
245
|
+
end
|
246
|
+
|
247
|
+
it 'raises InvalidApiResponse' do
|
248
|
+
expect {
|
249
|
+
subject
|
250
|
+
}.to raise_error(SpreeAvatax::SalesShared::InvalidApiResponse)
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|
254
|
+
context 'when an invoice already exists' do
|
255
|
+
context 'when the existing invoice is not committed' do
|
256
|
+
let!(:previous_sales_invoice) { create(:avatax_sales_invoice, order: order) }
|
257
|
+
|
258
|
+
it 'deletes the previous invoice' do
|
259
|
+
subject
|
260
|
+
expect(SpreeAvatax::SalesInvoice.find_by(id: previous_sales_invoice.id)).to be_nil
|
261
|
+
end
|
262
|
+
end
|
263
|
+
|
264
|
+
context 'when the existing invoice is committed' do
|
265
|
+
let!(:previous_sales_invoice) { create(:avatax_sales_invoice, order: order, committed_at: 1.day.ago) }
|
266
|
+
|
267
|
+
it 'raises an AlreadyCommittedError' do
|
268
|
+
expect {
|
269
|
+
subject
|
270
|
+
}.to raise_error(SpreeAvatax::SalesInvoice::AlreadyCommittedError)
|
271
|
+
end
|
272
|
+
end
|
273
|
+
end
|
274
|
+
|
275
|
+
describe 'when the description is too long' do
|
276
|
+
let(:description) { 'a'*1000 }
|
277
|
+
let(:expected_truncated_description) { description.truncate(100) }
|
278
|
+
|
279
|
+
before do
|
280
|
+
line_item.variant.product.update!(description: description)
|
281
|
+
end
|
282
|
+
|
283
|
+
it 'succeeds' do
|
284
|
+
subject # method expectation will fail if date isn't right
|
285
|
+
end
|
286
|
+
end
|
287
|
+
|
288
|
+
context 'when the order is not taxable' do
|
289
|
+
let(:order) { create(:order_with_line_items, ship_address: nil, line_items_count: 1) }
|
290
|
+
|
291
|
+
let!(:gettax_stub) { }
|
292
|
+
|
293
|
+
it 'does not create a sales invoice' do
|
294
|
+
expect {
|
295
|
+
subject
|
296
|
+
}.not_to change { SpreeAvatax::SalesInvoice.count }
|
297
|
+
expect(order.avatax_sales_invoice).to eq nil
|
298
|
+
end
|
299
|
+
|
300
|
+
it 'does not call avatax' do
|
301
|
+
expect(SpreeAvatax::Shared.tax_svc).to receive(:gettax).never
|
302
|
+
subject
|
303
|
+
end
|
304
|
+
end
|
305
|
+
|
306
|
+
context 'when the order is already completed' do
|
307
|
+
let(:order) { create(:completed_order_with_totals) }
|
308
|
+
|
309
|
+
let!(:gettax_stub) { }
|
310
|
+
|
311
|
+
it 'does not create a sales invoice' do
|
312
|
+
expect {
|
313
|
+
subject
|
314
|
+
}.not_to change { SpreeAvatax::SalesInvoice.count }
|
315
|
+
expect(order.avatax_sales_invoice).to eq nil
|
316
|
+
end
|
317
|
+
|
318
|
+
it 'does not call avatax' do
|
319
|
+
expect(SpreeAvatax::Shared.tax_svc).to receive(:gettax).never
|
320
|
+
subject
|
321
|
+
end
|
322
|
+
end
|
323
|
+
end
|
324
|
+
|
325
|
+
describe '.commit' do
|
326
|
+
subject do
|
327
|
+
SpreeAvatax::SalesInvoice.commit(order)
|
328
|
+
end
|
329
|
+
|
330
|
+
let!(:order) { sales_invoice.order }
|
331
|
+
let(:sales_invoice) { create(:avatax_sales_invoice) }
|
332
|
+
|
333
|
+
let(:expected_posttax_params) do
|
334
|
+
{
|
335
|
+
doccode: sales_invoice.doc_code,
|
336
|
+
companycode: SpreeAvatax::Config.company_code,
|
337
|
+
|
338
|
+
doctype: SpreeAvatax::SalesInvoice::DOC_TYPE,
|
339
|
+
docdate: sales_invoice.doc_date,
|
340
|
+
|
341
|
+
commit: true,
|
342
|
+
|
343
|
+
totalamount: sales_invoice.pre_tax_total,
|
344
|
+
totaltax: sales_invoice.additional_tax_total,
|
345
|
+
}
|
346
|
+
end
|
347
|
+
|
348
|
+
context 'when the order is taxable' do
|
349
|
+
let!(:posttax_stub) do
|
350
|
+
expect(SpreeAvatax::Shared.tax_svc)
|
351
|
+
.to receive(:posttax)
|
352
|
+
.with(expected_posttax_params)
|
353
|
+
.and_return(
|
354
|
+
sales_invoice_posttax_response
|
355
|
+
)
|
356
|
+
end
|
357
|
+
|
358
|
+
it 'marks the sales invoice as committed' do
|
359
|
+
expect {
|
360
|
+
subject
|
361
|
+
}.to change { sales_invoice.reload.committed_at? }.from(false).to(true)
|
362
|
+
end
|
363
|
+
end
|
364
|
+
|
365
|
+
context 'when the order is not taxable' do
|
366
|
+
before do
|
367
|
+
expect(SpreeAvatax::Shared).to receive(:taxable_order?).with(sales_invoice.order).and_return(false)
|
368
|
+
end
|
369
|
+
|
370
|
+
it 'does not call avatax' do
|
371
|
+
expect(SpreeAvatax::Shared.tax_svc).to receive(:posttax).never
|
372
|
+
subject
|
373
|
+
end
|
374
|
+
end
|
375
|
+
|
376
|
+
context 'when the sales_invoice does not exist' do
|
377
|
+
let(:sales_invoice) { nil }
|
378
|
+
let(:order) { create(:shipped_order, line_items_count: 1) }
|
379
|
+
|
380
|
+
it 'raises a SalesInvoiceNotFound error' do
|
381
|
+
expect {
|
382
|
+
subject
|
383
|
+
}.to raise_error(SpreeAvatax::SalesInvoice::CommitInvoiceNotFound)
|
384
|
+
end
|
385
|
+
end
|
386
|
+
|
387
|
+
context 'when an error occurs' do
|
388
|
+
let(:error) { StandardError.new('just testing') }
|
389
|
+
let!(:posttax_stub) { }
|
390
|
+
|
391
|
+
before do
|
392
|
+
expect(SpreeAvatax::SalesInvoice)
|
393
|
+
.to receive(:post_tax)
|
394
|
+
.and_raise(error)
|
395
|
+
end
|
396
|
+
|
397
|
+
context 'when an error_handler is not defined' do
|
398
|
+
it 'raises the original error' do
|
399
|
+
expect {
|
400
|
+
subject
|
401
|
+
}.to raise_error(error)
|
402
|
+
end
|
403
|
+
end
|
404
|
+
|
405
|
+
context 'when an error_handler is defined' do
|
406
|
+
let(:handler) { -> (o, e) { raise new_error } }
|
407
|
+
let(:new_error) { StandardError.new('just testing 2') }
|
408
|
+
|
409
|
+
before do
|
410
|
+
allow(SpreeAvatax::Config).to receive_messages(sales_invoice_commit_error_handler: handler)
|
411
|
+
end
|
412
|
+
|
413
|
+
it 'calls the handler instead of raising the original error' do
|
414
|
+
expect {
|
415
|
+
subject
|
416
|
+
}.to raise_error(new_error)
|
417
|
+
end
|
418
|
+
end
|
419
|
+
end
|
420
|
+
end
|
421
|
+
|
422
|
+
describe '.cancel' do
|
423
|
+
subject do
|
424
|
+
SpreeAvatax::SalesInvoice.cancel(order)
|
425
|
+
end
|
426
|
+
|
427
|
+
context 'when the sales invoice exists' do
|
428
|
+
let(:order) { sales_invoice.order }
|
429
|
+
let(:sales_invoice) { create(:avatax_sales_invoice, committed_at: Time.now) }
|
430
|
+
|
431
|
+
let(:expected_canceltax_params) do
|
432
|
+
{
|
433
|
+
doccode: sales_invoice.doc_code,
|
434
|
+
doctype: SpreeAvatax::SalesInvoice::DOC_TYPE,
|
435
|
+
cancelcode: SpreeAvatax::SalesInvoice::CANCEL_CODE,
|
436
|
+
companycode: SpreeAvatax::Config.company_code,
|
437
|
+
}
|
438
|
+
end
|
439
|
+
|
440
|
+
let(:canceltax_response) { sales_invoice_canceltax_response }
|
441
|
+
|
442
|
+
let!(:canceltax_stub) do
|
443
|
+
expect(SpreeAvatax::Shared.tax_svc)
|
444
|
+
.to receive(:canceltax)
|
445
|
+
.with(expected_canceltax_params)
|
446
|
+
.and_return(canceltax_response)
|
447
|
+
end
|
448
|
+
|
449
|
+
it 'should update the sales invoice' do
|
450
|
+
expect {
|
451
|
+
subject
|
452
|
+
}.to change { sales_invoice.canceled_at }.from(nil)
|
453
|
+
expect(sales_invoice.cancel_transaction_id).to eq canceltax_response[:transaction_id]
|
454
|
+
end
|
455
|
+
|
456
|
+
context 'when an error occurs' do
|
457
|
+
let(:error) { StandardError.new('just testing') }
|
458
|
+
let!(:canceltax_stub) { }
|
459
|
+
|
460
|
+
before do
|
461
|
+
expect(SpreeAvatax::SalesInvoice)
|
462
|
+
.to receive(:cancel_tax)
|
463
|
+
.and_raise(error)
|
464
|
+
end
|
465
|
+
|
466
|
+
context 'when an error_handler is not defined' do
|
467
|
+
it 'raises the original error' do
|
468
|
+
expect {
|
469
|
+
subject
|
470
|
+
}.to raise_error(error)
|
471
|
+
end
|
472
|
+
end
|
473
|
+
|
474
|
+
context 'when an error_handler is defined' do
|
475
|
+
let(:handler) { -> (o, e) { raise new_error } }
|
476
|
+
let(:new_error) { StandardError.new('just testing 2') }
|
477
|
+
|
478
|
+
before do
|
479
|
+
allow(SpreeAvatax::Config).to receive_messages(sales_invoice_cancel_error_handler: handler)
|
480
|
+
end
|
481
|
+
|
482
|
+
it 'calls the handler instead of raising the original error' do
|
483
|
+
expect {
|
484
|
+
subject
|
485
|
+
}.to raise_error(new_error)
|
486
|
+
end
|
487
|
+
end
|
488
|
+
end
|
489
|
+
end
|
490
|
+
end
|
491
|
+
end
|