workarea-avatax 4.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.editorconfig +20 -0
- data/.github/ISSUE_TEMPLATE/bug_report.md +37 -0
- data/.github/ISSUE_TEMPLATE/documentation-request.md +17 -0
- data/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
- data/.github/workflows/ci.yml +66 -0
- data/.gitignore +18 -0
- data/.rubocop.yml +8 -0
- data/CHANGELOG.md +123 -0
- data/CODE_OF_CONDUCT.md +3 -0
- data/CONTRIBUTING.md +3 -0
- data/Gemfile +10 -0
- data/LICENSE.md +3 -0
- data/README.md +57 -0
- data/Rakefile +50 -0
- data/app/models/workarea/avatax/usage_type.rb +17 -0
- data/app/models/workarea/pricing/calculators/avalara_tax_calculator.rb +105 -0
- data/app/models/workarea/user.decorator +7 -0
- data/app/seeds/workarea/avatax_seeds.rb +44 -0
- data/app/view_models/workarea/admin/user_view_model.decorator +21 -0
- data/app/view_models/workarea/storefront/cart_view_model.decorator +7 -0
- data/app/views/workarea/admin/users/_avatax_properties_fields.html.haml +5 -0
- data/app/workers/workarea/avatax/tax_invoice_worker.rb +29 -0
- data/bin/rails +17 -0
- data/config/initializers/appends.rb +4 -0
- data/config/initializers/avatax.rb +14 -0
- data/config/initializers/seeds.rb +1 -0
- data/config/locales/en.yml +6 -0
- data/lib/avatax/api.decorator +52 -0
- data/lib/workarea/avatax/bogus_gateway/bogus_create_transaction.rb +187 -0
- data/lib/workarea/avatax/bogus_gateway.rb +34 -0
- data/lib/workarea/avatax/engine.rb +36 -0
- data/lib/workarea/avatax/tax_request/addresses.rb +35 -0
- data/lib/workarea/avatax/tax_request/line_item.rb +47 -0
- data/lib/workarea/avatax/tax_request/order_line_item.rb +64 -0
- data/lib/workarea/avatax/tax_request/order_lines.rb +70 -0
- data/lib/workarea/avatax/tax_request/response.rb +49 -0
- data/lib/workarea/avatax/tax_request/shipping_line_item.rb +34 -0
- data/lib/workarea/avatax/tax_request.rb +77 -0
- data/lib/workarea/avatax/version.rb +5 -0
- data/lib/workarea/avatax.rb +71 -0
- data/test/dummy/Rakefile +6 -0
- data/test/dummy/bin/bundle +3 -0
- data/test/dummy/bin/rails +4 -0
- data/test/dummy/bin/rake +4 -0
- data/test/dummy/bin/setup +34 -0
- data/test/dummy/bin/update +29 -0
- data/test/dummy/config/application.rb +23 -0
- data/test/dummy/config/boot.rb +5 -0
- data/test/dummy/config/cable.yml +9 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +54 -0
- data/test/dummy/config/environments/production.rb +86 -0
- data/test/dummy/config/environments/test.rb +44 -0
- data/test/dummy/config/initializers/application_controller_renderer.rb +6 -0
- data/test/dummy/config/initializers/assets.rb +11 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/cookies_serializer.rb +5 -0
- data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/test/dummy/config/initializers/inflections.rb +16 -0
- data/test/dummy/config/initializers/mime_types.rb +4 -0
- data/test/dummy/config/initializers/new_framework_defaults.rb +23 -0
- data/test/dummy/config/initializers/workarea.rb +5 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy/config/locales/en.yml +23 -0
- data/test/dummy/config/puma.rb +47 -0
- data/test/dummy/config/routes.rb +5 -0
- data/test/dummy/config/secrets.yml +22 -0
- data/test/dummy/config/spring.rb +6 -0
- data/test/dummy/config.ru +5 -0
- data/test/dummy/db/seeds.rb +2 -0
- data/test/dummy/lib/assets/.keep +0 -0
- data/test/dummy/log/.keep +0 -0
- data/test/dummy/public/404.html +67 -0
- data/test/dummy/public/422.html +67 -0
- data/test/dummy/public/500.html +66 -0
- data/test/dummy/public/apple-touch-icon-precomposed.png +0 -0
- data/test/dummy/public/apple-touch-icon.png +0 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/factories/workarea/avatax_factories.rb +142 -0
- data/test/lib/workarea/avatax/tax_request/order_line_items_test.rb +114 -0
- data/test/lib/workarea/avatax/tax_request/response_test.rb +42 -0
- data/test/lib/workarea/avatax/tax_request_test.rb +51 -0
- data/test/lib/workarea/avatax_test.rb +28 -0
- data/test/models/workarea/avatax/usage_type_test.rb +13 -0
- data/test/models/workarea/pricing/calculators/avalara_tax_calculator_test.rb +113 -0
- data/test/support/avatax_test_settings.rb +9 -0
- data/test/system/workarea/storefront/avatax_system_test.rb +22 -0
- data/test/test_helper.rb +20 -0
- data/test/vcr_cassettes/succesful_avatax_create_transaction.yml +60 -0
- data/test/vcr_cassettes/succesful_avatax_create_transaction_multiple_shippings.yml +76 -0
- data/workarea-avatax.gemspec +20 -0
- metadata +176 -0
@@ -0,0 +1,47 @@
|
|
1
|
+
# Puma can serve each request in a thread from an internal thread pool.
|
2
|
+
# The `threads` method setting takes two numbers a minimum and maximum.
|
3
|
+
# Any libraries that use thread pools should be configured to match
|
4
|
+
# the maximum value specified for Puma. Default is set to 5 threads for minimum
|
5
|
+
# and maximum, this matches the default thread size of Active Record.
|
6
|
+
#
|
7
|
+
threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 }.to_i
|
8
|
+
threads threads_count, threads_count
|
9
|
+
|
10
|
+
# Specifies the `port` that Puma will listen on to receive requests, default is 3000.
|
11
|
+
#
|
12
|
+
port ENV.fetch("PORT") { 3000 }
|
13
|
+
|
14
|
+
# Specifies the `environment` that Puma will run in.
|
15
|
+
#
|
16
|
+
environment ENV.fetch("RAILS_ENV") { "development" }
|
17
|
+
|
18
|
+
# Specifies the number of `workers` to boot in clustered mode.
|
19
|
+
# Workers are forked webserver processes. If using threads and workers together
|
20
|
+
# the concurrency of the application would be max `threads` * `workers`.
|
21
|
+
# Workers do not work on JRuby or Windows (both of which do not support
|
22
|
+
# processes).
|
23
|
+
#
|
24
|
+
# workers ENV.fetch("WEB_CONCURRENCY") { 2 }
|
25
|
+
|
26
|
+
# Use the `preload_app!` method when specifying a `workers` number.
|
27
|
+
# This directive tells Puma to first boot the application and load code
|
28
|
+
# before forking the application. This takes advantage of Copy On Write
|
29
|
+
# process behavior so workers use less memory. If you use this option
|
30
|
+
# you need to make sure to reconnect any threads in the `on_worker_boot`
|
31
|
+
# block.
|
32
|
+
#
|
33
|
+
# preload_app!
|
34
|
+
|
35
|
+
# The code in the `on_worker_boot` will be called if you are using
|
36
|
+
# clustered mode by specifying a number of `workers`. After each worker
|
37
|
+
# process is booted this block will be run, if you are using `preload_app!`
|
38
|
+
# option you will want to use this block to reconnect to any threads
|
39
|
+
# or connections that may have been created at application boot, Ruby
|
40
|
+
# cannot share connections between processes.
|
41
|
+
#
|
42
|
+
# on_worker_boot do
|
43
|
+
# ActiveRecord::Base.establish_connection if defined?(ActiveRecord)
|
44
|
+
# end
|
45
|
+
|
46
|
+
# Allow puma to be restarted by `rails restart` command.
|
47
|
+
plugin :tmp_restart
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# Be sure to restart your server when you modify this file.
|
2
|
+
|
3
|
+
# Your secret key is used for verifying the integrity of signed cookies.
|
4
|
+
# If you change this key, all old signed cookies will become invalid!
|
5
|
+
|
6
|
+
# Make sure the secret is at least 30 characters and all random,
|
7
|
+
# no regular words or you'll be exposed to dictionary attacks.
|
8
|
+
# You can use `rails secret` to generate a secure secret key.
|
9
|
+
|
10
|
+
# Make sure the secrets in this file are kept private
|
11
|
+
# if you're sharing your code publicly.
|
12
|
+
|
13
|
+
development:
|
14
|
+
secret_key_base: e95d581460a83a669c20fbfd42ecbcd0195f257a2c1faa77a1be3d3d184c6d92231259bffe312d7730990a87997c1d38f442d6bcf6151ff9e07793f43b26d1be
|
15
|
+
|
16
|
+
test:
|
17
|
+
secret_key_base: a8af256aec30ccf03fe1d713da17fbd4c6b1ed475cd83933f95ed7b9d9781184a27ae1d9e5f8fc74280bfc420992bfa694123ef6a652e60707bcbdacbf8f7263
|
18
|
+
|
19
|
+
# Do not keep production secrets in the repository,
|
20
|
+
# instead read values from the environment.
|
21
|
+
production:
|
22
|
+
secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
|
File without changes
|
File without changes
|
@@ -0,0 +1,67 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>The page you were looking for doesn't exist (404)</title>
|
5
|
+
<meta name="viewport" content="width=device-width,initial-scale=1">
|
6
|
+
<style>
|
7
|
+
.rails-default-error-page {
|
8
|
+
background-color: #EFEFEF;
|
9
|
+
color: #2E2F30;
|
10
|
+
text-align: center;
|
11
|
+
font-family: arial, sans-serif;
|
12
|
+
margin: 0;
|
13
|
+
}
|
14
|
+
|
15
|
+
.rails-default-error-page div.dialog {
|
16
|
+
width: 95%;
|
17
|
+
max-width: 33em;
|
18
|
+
margin: 4em auto 0;
|
19
|
+
}
|
20
|
+
|
21
|
+
.rails-default-error-page div.dialog > div {
|
22
|
+
border: 1px solid #CCC;
|
23
|
+
border-right-color: #999;
|
24
|
+
border-left-color: #999;
|
25
|
+
border-bottom-color: #BBB;
|
26
|
+
border-top: #B00100 solid 4px;
|
27
|
+
border-top-left-radius: 9px;
|
28
|
+
border-top-right-radius: 9px;
|
29
|
+
background-color: white;
|
30
|
+
padding: 7px 12% 0;
|
31
|
+
box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
|
32
|
+
}
|
33
|
+
|
34
|
+
.rails-default-error-page h1 {
|
35
|
+
font-size: 100%;
|
36
|
+
color: #730E15;
|
37
|
+
line-height: 1.5em;
|
38
|
+
}
|
39
|
+
|
40
|
+
.rails-default-error-page div.dialog > p {
|
41
|
+
margin: 0 0 1em;
|
42
|
+
padding: 1em;
|
43
|
+
background-color: #F7F7F7;
|
44
|
+
border: 1px solid #CCC;
|
45
|
+
border-right-color: #999;
|
46
|
+
border-left-color: #999;
|
47
|
+
border-bottom-color: #999;
|
48
|
+
border-bottom-left-radius: 4px;
|
49
|
+
border-bottom-right-radius: 4px;
|
50
|
+
border-top-color: #DADADA;
|
51
|
+
color: #666;
|
52
|
+
box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
|
53
|
+
}
|
54
|
+
</style>
|
55
|
+
</head>
|
56
|
+
|
57
|
+
<body class="rails-default-error-page">
|
58
|
+
<!-- This file lives in public/404.html -->
|
59
|
+
<div class="dialog">
|
60
|
+
<div>
|
61
|
+
<h1>The page you were looking for doesn't exist.</h1>
|
62
|
+
<p>You may have mistyped the address or the page may have moved.</p>
|
63
|
+
</div>
|
64
|
+
<p>If you are the application owner check the logs for more information.</p>
|
65
|
+
</div>
|
66
|
+
</body>
|
67
|
+
</html>
|
@@ -0,0 +1,67 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>The change you wanted was rejected (422)</title>
|
5
|
+
<meta name="viewport" content="width=device-width,initial-scale=1">
|
6
|
+
<style>
|
7
|
+
.rails-default-error-page {
|
8
|
+
background-color: #EFEFEF;
|
9
|
+
color: #2E2F30;
|
10
|
+
text-align: center;
|
11
|
+
font-family: arial, sans-serif;
|
12
|
+
margin: 0;
|
13
|
+
}
|
14
|
+
|
15
|
+
.rails-default-error-page div.dialog {
|
16
|
+
width: 95%;
|
17
|
+
max-width: 33em;
|
18
|
+
margin: 4em auto 0;
|
19
|
+
}
|
20
|
+
|
21
|
+
.rails-default-error-page div.dialog > div {
|
22
|
+
border: 1px solid #CCC;
|
23
|
+
border-right-color: #999;
|
24
|
+
border-left-color: #999;
|
25
|
+
border-bottom-color: #BBB;
|
26
|
+
border-top: #B00100 solid 4px;
|
27
|
+
border-top-left-radius: 9px;
|
28
|
+
border-top-right-radius: 9px;
|
29
|
+
background-color: white;
|
30
|
+
padding: 7px 12% 0;
|
31
|
+
box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
|
32
|
+
}
|
33
|
+
|
34
|
+
.rails-default-error-page h1 {
|
35
|
+
font-size: 100%;
|
36
|
+
color: #730E15;
|
37
|
+
line-height: 1.5em;
|
38
|
+
}
|
39
|
+
|
40
|
+
.rails-default-error-page div.dialog > p {
|
41
|
+
margin: 0 0 1em;
|
42
|
+
padding: 1em;
|
43
|
+
background-color: #F7F7F7;
|
44
|
+
border: 1px solid #CCC;
|
45
|
+
border-right-color: #999;
|
46
|
+
border-left-color: #999;
|
47
|
+
border-bottom-color: #999;
|
48
|
+
border-bottom-left-radius: 4px;
|
49
|
+
border-bottom-right-radius: 4px;
|
50
|
+
border-top-color: #DADADA;
|
51
|
+
color: #666;
|
52
|
+
box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
|
53
|
+
}
|
54
|
+
</style>
|
55
|
+
</head>
|
56
|
+
|
57
|
+
<body class="rails-default-error-page">
|
58
|
+
<!-- This file lives in public/422.html -->
|
59
|
+
<div class="dialog">
|
60
|
+
<div>
|
61
|
+
<h1>The change you wanted was rejected.</h1>
|
62
|
+
<p>Maybe you tried to change something you didn't have access to.</p>
|
63
|
+
</div>
|
64
|
+
<p>If you are the application owner check the logs for more information.</p>
|
65
|
+
</div>
|
66
|
+
</body>
|
67
|
+
</html>
|
@@ -0,0 +1,66 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>We're sorry, but something went wrong (500)</title>
|
5
|
+
<meta name="viewport" content="width=device-width,initial-scale=1">
|
6
|
+
<style>
|
7
|
+
.rails-default-error-page {
|
8
|
+
background-color: #EFEFEF;
|
9
|
+
color: #2E2F30;
|
10
|
+
text-align: center;
|
11
|
+
font-family: arial, sans-serif;
|
12
|
+
margin: 0;
|
13
|
+
}
|
14
|
+
|
15
|
+
.rails-default-error-page div.dialog {
|
16
|
+
width: 95%;
|
17
|
+
max-width: 33em;
|
18
|
+
margin: 4em auto 0;
|
19
|
+
}
|
20
|
+
|
21
|
+
.rails-default-error-page div.dialog > div {
|
22
|
+
border: 1px solid #CCC;
|
23
|
+
border-right-color: #999;
|
24
|
+
border-left-color: #999;
|
25
|
+
border-bottom-color: #BBB;
|
26
|
+
border-top: #B00100 solid 4px;
|
27
|
+
border-top-left-radius: 9px;
|
28
|
+
border-top-right-radius: 9px;
|
29
|
+
background-color: white;
|
30
|
+
padding: 7px 12% 0;
|
31
|
+
box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
|
32
|
+
}
|
33
|
+
|
34
|
+
.rails-default-error-page h1 {
|
35
|
+
font-size: 100%;
|
36
|
+
color: #730E15;
|
37
|
+
line-height: 1.5em;
|
38
|
+
}
|
39
|
+
|
40
|
+
.rails-default-error-page div.dialog > p {
|
41
|
+
margin: 0 0 1em;
|
42
|
+
padding: 1em;
|
43
|
+
background-color: #F7F7F7;
|
44
|
+
border: 1px solid #CCC;
|
45
|
+
border-right-color: #999;
|
46
|
+
border-left-color: #999;
|
47
|
+
border-bottom-color: #999;
|
48
|
+
border-bottom-left-radius: 4px;
|
49
|
+
border-bottom-right-radius: 4px;
|
50
|
+
border-top-color: #DADADA;
|
51
|
+
color: #666;
|
52
|
+
box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
|
53
|
+
}
|
54
|
+
</style>
|
55
|
+
</head>
|
56
|
+
|
57
|
+
<body class="rails-default-error-page">
|
58
|
+
<!-- This file lives in public/500.html -->
|
59
|
+
<div class="dialog">
|
60
|
+
<div>
|
61
|
+
<h1>We're sorry, but something went wrong.</h1>
|
62
|
+
</div>
|
63
|
+
<p>If you are the application owner check the logs for more information.</p>
|
64
|
+
</div>
|
65
|
+
</body>
|
66
|
+
</html>
|
File without changes
|
File without changes
|
File without changes
|
@@ -0,0 +1,142 @@
|
|
1
|
+
module Workarea
|
2
|
+
module Factories
|
3
|
+
module AvataxFactories
|
4
|
+
Factories.add self
|
5
|
+
|
6
|
+
def create_checkout_order(overrides = {})
|
7
|
+
attributes = overrides
|
8
|
+
|
9
|
+
shipping_service = create_shipping_service(tax_code: "P0000000")
|
10
|
+
sku = "SKU1"
|
11
|
+
product = create_product(variants: [{ sku: sku, regular: 5.to_m, tax_code: "P0000000" }])
|
12
|
+
|
13
|
+
Workarea::Order.new(attributes).tap do |order|
|
14
|
+
shipping = Workarea::Shipping.create!(order_id: order.id)
|
15
|
+
|
16
|
+
shipping.set_shipping_service(
|
17
|
+
id: shipping_service.id,
|
18
|
+
name: shipping_service.name,
|
19
|
+
base_price: shipping_service.rates.first.price,
|
20
|
+
tax_code: shipping_service.tax_code
|
21
|
+
)
|
22
|
+
|
23
|
+
order.items.build(
|
24
|
+
product_id: product.id,
|
25
|
+
sku: sku,
|
26
|
+
quantity: 2,
|
27
|
+
product_attributes: product.as_document
|
28
|
+
)
|
29
|
+
|
30
|
+
shipping.set_address(
|
31
|
+
first_name: "Eric",
|
32
|
+
last_name: "Pigeon",
|
33
|
+
street: "22 S 3rd St",
|
34
|
+
city: "Philadelphia",
|
35
|
+
region: "PA",
|
36
|
+
postal_code: 19106,
|
37
|
+
country: "US"
|
38
|
+
)
|
39
|
+
|
40
|
+
Workarea::Pricing.perform(order)
|
41
|
+
|
42
|
+
order.save!
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def create_split_shipping_checkout_order(overrides = {})
|
47
|
+
attributes = { email: "epigeon@workarea.com" }.merge overrides
|
48
|
+
product_1 = create_product(
|
49
|
+
id: "PROD1",
|
50
|
+
name: "Split Shipping Product One",
|
51
|
+
variants: [{ sku: "SKU1", regular: 5.to_m, tax_code: "001" }]
|
52
|
+
)
|
53
|
+
product_2 = create_product(
|
54
|
+
id: "PROD2",
|
55
|
+
name: "Split Shipping Product Two",
|
56
|
+
variants: [{ sku: "SKU2", regular: 7.to_m, tax_code: "001" }]
|
57
|
+
)
|
58
|
+
product_3 = create_product(
|
59
|
+
id: "PROD3",
|
60
|
+
name: "Split Shipping Product Three",
|
61
|
+
variants: [{ sku: "SKU3", regular: 9.to_m, tax_code: "001" }]
|
62
|
+
)
|
63
|
+
ground = create_shipping_service(name: "Ground", tax_code: "001", rates: [{ price: 5.to_m }])
|
64
|
+
express = create_shipping_service(name: "Express", tax_code: "001", rates: [{ price: 10.to_m }])
|
65
|
+
|
66
|
+
Workarea::Order.new(attributes).tap do |order|
|
67
|
+
order.items.build(
|
68
|
+
product_id: "PROD1",
|
69
|
+
sku: "SKU1",
|
70
|
+
quantity: 2,
|
71
|
+
product_attributes: product_1.as_document
|
72
|
+
)
|
73
|
+
|
74
|
+
order.items.build(
|
75
|
+
product_id: "PROD2",
|
76
|
+
sku: "SKU2",
|
77
|
+
quantity: 2,
|
78
|
+
product_attributes: product_2.as_document
|
79
|
+
)
|
80
|
+
|
81
|
+
order.items.build(
|
82
|
+
product_id: "PROD3",
|
83
|
+
sku: "SKU3",
|
84
|
+
quantity: 4,
|
85
|
+
product_attributes: product_3.as_document
|
86
|
+
)
|
87
|
+
|
88
|
+
shipping_1 = Workarea::Shipping.create!(
|
89
|
+
order_id: order.id,
|
90
|
+
quantities: {
|
91
|
+
order.items.first.id.to_s => 2,
|
92
|
+
order.items.second.id.to_s => 1
|
93
|
+
},
|
94
|
+
address: {
|
95
|
+
first_name: "Eric",
|
96
|
+
last_name: "Pigeon",
|
97
|
+
street: "22 S 3rd St",
|
98
|
+
city: "Philadelphia",
|
99
|
+
region: "PA",
|
100
|
+
postal_code: 19106,
|
101
|
+
country: "US"
|
102
|
+
}
|
103
|
+
)
|
104
|
+
|
105
|
+
shipping_1.set_shipping_service(
|
106
|
+
id: ground.id,
|
107
|
+
name: ground.name,
|
108
|
+
base_price: ground.rates.first.price,
|
109
|
+
tax_code: ground.tax_code
|
110
|
+
)
|
111
|
+
|
112
|
+
shipping_2 = Workarea::Shipping.create!(
|
113
|
+
order_id: order.id,
|
114
|
+
quantities: {
|
115
|
+
order.items.second.id.to_s => 1,
|
116
|
+
order.items.third.id.to_s => 4
|
117
|
+
},
|
118
|
+
address: {
|
119
|
+
first_name: "Eric",
|
120
|
+
last_name: "Pigeon",
|
121
|
+
street: "12 N 3rd St",
|
122
|
+
city: "Philadelphia",
|
123
|
+
region: "PA",
|
124
|
+
postal_code: 19106,
|
125
|
+
country: "US"
|
126
|
+
}
|
127
|
+
)
|
128
|
+
|
129
|
+
shipping_2.set_shipping_service(
|
130
|
+
id: express.id,
|
131
|
+
name: express.name,
|
132
|
+
base_price: express.rates.first.price,
|
133
|
+
tax_code: express.tax_code
|
134
|
+
)
|
135
|
+
|
136
|
+
Workarea::Pricing.perform(order)
|
137
|
+
order.save!
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
@@ -0,0 +1,114 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
module Workarea
|
4
|
+
module Avatax
|
5
|
+
class TaxRequest::OrderLinesTest < TestCase
|
6
|
+
def test_lines_with_single_shipping
|
7
|
+
order = create_checkout_order(email: "epigeon@weblinc.com")
|
8
|
+
shippings = Shipping.where(order_id: order.id)
|
9
|
+
order_line_items = TaxRequest::OrderLines.new(order, shippings)
|
10
|
+
|
11
|
+
assert_equal 2, order_line_items.lines.size
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_lines_with_split_shippings
|
15
|
+
order = create_split_shipping_checkout_order
|
16
|
+
shippings = Shipping.where(order_id: order.id)
|
17
|
+
order_line_items = TaxRequest::OrderLines.new(order, shippings)
|
18
|
+
|
19
|
+
assert_equal 6, order_line_items.lines.size
|
20
|
+
expected_lines = [
|
21
|
+
{
|
22
|
+
quantity: 2,
|
23
|
+
amount: "10.00",
|
24
|
+
itemCode: "SKU1",
|
25
|
+
taxCode: "001",
|
26
|
+
description: "Split Shipping Product One",
|
27
|
+
number: 1,
|
28
|
+
addresses: {
|
29
|
+
shipTo: {
|
30
|
+
line1: "22 S 3rd St",
|
31
|
+
line2: nil,
|
32
|
+
city: "Philadelphia",
|
33
|
+
region: "PA",
|
34
|
+
country: "US",
|
35
|
+
postalCode: "19106"
|
36
|
+
}
|
37
|
+
}
|
38
|
+
},
|
39
|
+
{
|
40
|
+
quantity: 1,
|
41
|
+
amount: "7.00",
|
42
|
+
itemCode: "SKU2",
|
43
|
+
taxCode: "001",
|
44
|
+
description: "Split Shipping Product Two",
|
45
|
+
number: 2,
|
46
|
+
addresses: {
|
47
|
+
shipTo: {
|
48
|
+
line1: "22 S 3rd St",
|
49
|
+
line2: nil,
|
50
|
+
city: "Philadelphia",
|
51
|
+
region: "PA",
|
52
|
+
country: "US",
|
53
|
+
postalCode: "19106"
|
54
|
+
}
|
55
|
+
}
|
56
|
+
},
|
57
|
+
{
|
58
|
+
quantity: 1,
|
59
|
+
amount: "7.00",
|
60
|
+
itemCode: "SKU2",
|
61
|
+
taxCode: "001",
|
62
|
+
description: "Split Shipping Product Two",
|
63
|
+
number: 3,
|
64
|
+
addresses: {
|
65
|
+
shipTo: {
|
66
|
+
line1: "12 N 3rd St",
|
67
|
+
line2: nil,
|
68
|
+
city: "Philadelphia",
|
69
|
+
region: "PA",
|
70
|
+
country: "US",
|
71
|
+
postalCode: "19106"
|
72
|
+
}
|
73
|
+
}
|
74
|
+
},
|
75
|
+
{
|
76
|
+
quantity: 4,
|
77
|
+
amount: "36.00",
|
78
|
+
itemCode: "SKU3",
|
79
|
+
taxCode: "001",
|
80
|
+
description: "Split Shipping Product Three",
|
81
|
+
number: 4,
|
82
|
+
addresses: {
|
83
|
+
shipTo: {
|
84
|
+
line1: "12 N 3rd St",
|
85
|
+
line2: nil,
|
86
|
+
city: "Philadelphia",
|
87
|
+
region: "PA",
|
88
|
+
country: "US",
|
89
|
+
postalCode: "19106"
|
90
|
+
}
|
91
|
+
}
|
92
|
+
},
|
93
|
+
{
|
94
|
+
quantity: 1,
|
95
|
+
amount: "5.00",
|
96
|
+
itemCode: "SHIPPING",
|
97
|
+
taxCode: "001",
|
98
|
+
description: "Ground",
|
99
|
+
number: 5
|
100
|
+
},
|
101
|
+
{
|
102
|
+
quantity: 1,
|
103
|
+
amount: "10.00",
|
104
|
+
itemCode: "SHIPPING",
|
105
|
+
taxCode: "001",
|
106
|
+
description: "Express",
|
107
|
+
number: 6
|
108
|
+
}
|
109
|
+
]
|
110
|
+
assert_equal expected_lines, order_line_items.lines.map(&:hash)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
module Workarea
|
4
|
+
module Avatax
|
5
|
+
class TaxRequest::ResponseTest < Workarea::TestCase
|
6
|
+
setup :create_tax_rate
|
7
|
+
|
8
|
+
def test_tax_line_for_adjustment
|
9
|
+
response = TaxRequest.new(order: order, shippings: shippings).response
|
10
|
+
|
11
|
+
adjustment = order.price_adjustments.detect { |a| a.data["tax_code"].present? }
|
12
|
+
adjustment_tax_line = response.tax_line_for_adjustment(adjustment)
|
13
|
+
assert_equal "0.80", adjustment_tax_line.tax
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_tax_line_for_shipping
|
17
|
+
response = TaxRequest.new(order: order, shippings: shippings).response
|
18
|
+
|
19
|
+
shipping = shippings.first
|
20
|
+
shipping_tax_line = response.tax_line_for_shipping(shipping)
|
21
|
+
assert_equal "0.08", shipping_tax_line.tax
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def order
|
27
|
+
@order ||= create_checkout_order(email: "epigeon@weblinc.com")
|
28
|
+
end
|
29
|
+
|
30
|
+
def shippings
|
31
|
+
@shippings ||= Shipping.where(order_id: order.id)
|
32
|
+
end
|
33
|
+
|
34
|
+
def create_tax_rate
|
35
|
+
create_tax_category(
|
36
|
+
code: "P0000000",
|
37
|
+
rates: [{ percentage: 0.08, country: "US", region: "PA" }]
|
38
|
+
)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
module Workarea
|
4
|
+
module Avatax
|
5
|
+
class TaxRequestTest < Workarea::TestCase
|
6
|
+
setup :configure_sandbox
|
7
|
+
teardown :reset_avatax_config
|
8
|
+
|
9
|
+
def test_successful_response
|
10
|
+
order = create_checkout_order(email: "epigeon@weblinc.com")
|
11
|
+
shippings = Shipping.where(order_id: order.id)
|
12
|
+
request = TaxRequest.new(order: order, shippings: shippings)
|
13
|
+
|
14
|
+
response = VCR.use_cassette :succesful_avatax_create_transaction do
|
15
|
+
request.response
|
16
|
+
end
|
17
|
+
|
18
|
+
assert response.success?
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_body_lines_split_shippings
|
22
|
+
order = create_split_shipping_checkout_order
|
23
|
+
shippings = Shipping.where(order_id: order.id)
|
24
|
+
request = TaxRequest.new(order: order, shippings: shippings)
|
25
|
+
|
26
|
+
response = VCR.use_cassette :succesful_avatax_create_transaction_multiple_shippings do
|
27
|
+
request.response
|
28
|
+
end
|
29
|
+
|
30
|
+
assert response.success?
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def configure_sandbox
|
36
|
+
AvaTax.configure do |config|
|
37
|
+
config.endpoint = "https://sandbox-rest.avatax.com/"
|
38
|
+
config.username = "jyucis-lp-avatax@weblinc.com"
|
39
|
+
config.password = "Jm{m3NX.Q"
|
40
|
+
end
|
41
|
+
|
42
|
+
Avatax.gateway = ::AvaTax.client
|
43
|
+
end
|
44
|
+
|
45
|
+
def reset_avatax_config
|
46
|
+
AvaTax.reset
|
47
|
+
Avatax.gateway = Avatax::BogusGateway.new
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
module Workarea
|
4
|
+
class AvataxTest < Workarea::TestCase
|
5
|
+
def test_auto_configure_gateway_creates_bogus_gateway_without_secrets
|
6
|
+
assert_instance_of(Avatax::BogusGateway, Avatax.gateway)
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_auto_configure_gateway_creates_real_gateway_with_secrets
|
10
|
+
Rails.application.secrets.merge!(
|
11
|
+
avatax: {
|
12
|
+
username: "epigeon@weblinc.com",
|
13
|
+
password: "648B0A9851",
|
14
|
+
endpoint: "https://sandbox-rest.avatax.com/"
|
15
|
+
}
|
16
|
+
)
|
17
|
+
|
18
|
+
Avatax.auto_configure_gateway
|
19
|
+
assert_instance_of(AvaTax::Client, Avatax.gateway)
|
20
|
+
|
21
|
+
assert_includes(Avatax.gateway.connection_options[:request].keys, :timeout)
|
22
|
+
|
23
|
+
ensure
|
24
|
+
Rails.application.secrets.delete(:avatax)
|
25
|
+
Avatax.gateway = Avatax::BogusGateway.new
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|