vat-gst-calculator 0.7.0 → 0.8.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 +4 -4
- data/.gitignore +1 -0
- data/lib/easyship/sales_tax/calculator/version.rb +1 -1
- data/lib/easyship/sales_tax/calculator.rb +97 -42
- data/vat-gst-calculator.gemspec +2 -0
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 47259f182d190ca603c7694139e25c002852bc1c60952dbc8967ae170031dea5
|
4
|
+
data.tar.gz: 76f58ac22a22144627b1144ef6b9469179b68034ed104e0f369c1d726e53c8ac
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 89e1e20dabc983e4bcd34a3ace0982ebab08a56f6242ee2037b8cdf5a9608814064603fe7e3bffb9e3c49f6240ef85ba614eac96d2ea85435191f769d48f719a
|
7
|
+
data.tar.gz: 39b36cf998538c48282da9ec6462f29770b701dba666bc90501deaac39326a2ab12c5de231875b8a2f75b02895bac7b18477f2ec413c5ae8185d6e5844d97661
|
data/.gitignore
CHANGED
@@ -7,67 +7,122 @@ module Easyship
|
|
7
7
|
class Error < StandardError; end
|
8
8
|
|
9
9
|
FALLBACK_VALUE = {sales_tax: 0, provincial_sales_tax: 0}.freeze
|
10
|
+
FALLBACK_VALUE_WITH_DETAILS =
|
11
|
+
{
|
12
|
+
sales_tax: 0,
|
13
|
+
provincial_sales_tax: 0,
|
14
|
+
sales_tax_detail: Easyship::SalesTax::Formula::NO_TAX,
|
15
|
+
provincial_sales_tax_detail: Easyship::SalesTax::Formula::NO_TAX
|
16
|
+
}.freeze
|
17
|
+
EU_COUNTRY_ALPHA2S = %w[NL LU EE LT HU BE PT SK HR CZ IT FI PL MT DE SI RO BG AT SE CY DK FR IE ES GR LV].freeze
|
10
18
|
|
11
|
-
|
12
|
-
|
13
|
-
|
19
|
+
class << self
|
20
|
+
def calculate(
|
21
|
+
origin_country_alpha2: nil,
|
22
|
+
destination_country_alpha2: nil,
|
23
|
+
origin_state: nil,
|
24
|
+
destination_state: nil,
|
25
|
+
fees: nil,
|
26
|
+
effective_timestamp: nil,
|
27
|
+
effective_country_alpha2s: [],
|
28
|
+
with_detail: false
|
29
|
+
)
|
30
|
+
return fallback_value(with_detail: with_detail) if origin_country_alpha2&.strip&.empty? || destination_country_alpha2&.strip&.empty?
|
31
|
+
return fallback_value(with_detail: with_detail) unless fees.is_a?(Fee)
|
32
|
+
return fallback_value(with_detail: with_detail) unless tax_eligible?(origin_country_alpha2, destination_country_alpha2)
|
14
33
|
|
15
|
-
if domestic?(origin_country_alpha2, destination_country_alpha2) || within_eu?(origin_country_alpha2, destination_country_alpha2)
|
16
34
|
domestic_value(
|
17
35
|
origin_country_alpha2: origin_country_alpha2,
|
18
36
|
origin_state: origin_state,
|
19
37
|
destination_state: destination_state,
|
20
38
|
fees: fees,
|
21
39
|
effective_timestamp: effective_timestamp,
|
22
|
-
effective_country_alpha2s: effective_country_alpha2s
|
40
|
+
effective_country_alpha2s: effective_country_alpha2s,
|
41
|
+
with_detail: with_detail
|
23
42
|
)
|
24
|
-
|
25
|
-
|
43
|
+
rescue
|
44
|
+
fallback_value(with_detail: with_detail)
|
26
45
|
end
|
27
|
-
rescue
|
28
|
-
FALLBACK_VALUE
|
29
|
-
end
|
30
46
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
end
|
47
|
+
def calculate_with_detail(**kwargs)
|
48
|
+
calculate(with_detail: true, **kwargs)
|
49
|
+
end
|
35
50
|
|
36
|
-
|
51
|
+
def sales_tax_website_name(country_alpha2, effective_timestamp = nil)
|
52
|
+
rates = Formula.effective_data(country_alpha2, effective_timestamp)
|
53
|
+
(rates || {}).dig(:sales_tax_website_name)
|
54
|
+
end
|
37
55
|
|
38
|
-
|
39
|
-
rates = Formula.effective_data(origin_country_alpha2, effective_timestamp, effective_country_alpha2s)
|
40
|
-
return FALLBACK_VALUE if rates.nil?
|
56
|
+
private
|
41
57
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
58
|
+
def domestic_value(
|
59
|
+
origin_country_alpha2: nil,
|
60
|
+
origin_state: nil,
|
61
|
+
destination_state: nil,
|
62
|
+
fees: nil,
|
63
|
+
effective_timestamp: nil,
|
64
|
+
effective_country_alpha2s: [],
|
65
|
+
with_detail: false
|
66
|
+
)
|
67
|
+
rates = Formula.effective_data(origin_country_alpha2, effective_timestamp, effective_country_alpha2s)
|
68
|
+
return fallback_value(with_detail: with_detail) if rates.nil?
|
69
|
+
|
70
|
+
{}.tap do |h|
|
71
|
+
h[:sales_tax] = tax_calculate(rates[:sales_tax], nil, destination_state, fees, false)
|
72
|
+
h[:provincial_sales_tax] = tax_calculate(rates[:provincial_sales_taxes], origin_state, destination_state, fees, true)
|
47
73
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
fees.to_h.inject(0) { |sum, (k, v)| sum + (tax_destination_formula[k] * v.to_f) }.round(2)
|
54
|
-
elsif formula[:_ALL]
|
55
|
-
fees.to_h.inject(0) { |sum, (k, v)| sum + (formula[:_ALL][k] * v.to_f) }.round(2)
|
56
|
-
else
|
57
|
-
0
|
74
|
+
if with_detail
|
75
|
+
h[:sales_tax_detail] = tax_detail(rates[:sales_tax], nil, destination_state, fees, false)
|
76
|
+
h[:provincial_sales_tax_detail] = tax_detail(rates[:provincial_sales_taxes], origin_state, destination_state, fees, true)
|
77
|
+
end
|
78
|
+
end
|
58
79
|
end
|
59
|
-
end
|
60
80
|
|
61
|
-
|
62
|
-
|
63
|
-
|
81
|
+
def tax_calculate(formula, origin_state, destination_state, fees, is_provincial_sales_taxes)
|
82
|
+
if (tax_destination_formula = formula[destination_state.to_s.upcase])
|
83
|
+
# ONLY CA has provincial_sales_taxes(QST/PST) and it only apply when ship within same state
|
84
|
+
# https://www.fedex.com/en-ca/news/canadian-sales-taxes.html
|
85
|
+
return 0 if origin_state != destination_state && is_provincial_sales_taxes
|
86
|
+
fees.to_h.inject(0) { |sum, (k, v)| sum + (tax_destination_formula[k] * v.to_f) }.round(2)
|
87
|
+
elsif formula[:_ALL]
|
88
|
+
fees.to_h.inject(0) { |sum, (k, v)| sum + (formula[:_ALL][k] * v.to_f) }.round(2)
|
89
|
+
else
|
90
|
+
0
|
91
|
+
end
|
92
|
+
end
|
64
93
|
|
65
|
-
|
66
|
-
|
67
|
-
|
94
|
+
def tax_detail(formula, origin_state, destination_state, fees, is_provincial_sales_taxes)
|
95
|
+
if (tax_destination_formula = formula[destination_state.to_s.upcase])
|
96
|
+
# ONLY CA has provincial_sales_taxes(QST/PST) and it only apply when ship within same state
|
97
|
+
# https://www.fedex.com/en-ca/news/canadian-sales-taxes.html
|
98
|
+
return Easyship::SalesTax::Formula::NO_TAX if origin_state != destination_state && is_provincial_sales_taxes
|
99
|
+
fees.to_h.each_with_object({}) { |(k, v), hash| hash[k] = (tax_destination_formula[k] * v.to_f).round(2) }
|
100
|
+
elsif formula[:_ALL]
|
101
|
+
fees.to_h.each_with_object({}) { |(k, v), hash| hash[k] = (formula[:_ALL][k] * v.to_f).round(2) }
|
102
|
+
else
|
103
|
+
Easyship::SalesTax::Formula::NO_TAX
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def in_eu?(country_alpha2)
|
108
|
+
EU_COUNTRY_ALPHA2S.include?(country_alpha2)
|
109
|
+
end
|
110
|
+
|
111
|
+
def domestic?(origin_country_alpha2 = nil, destination_country_alpha2 = nil)
|
112
|
+
!origin_country_alpha2&.strip&.empty? && origin_country_alpha2 == destination_country_alpha2
|
113
|
+
end
|
68
114
|
|
69
|
-
|
70
|
-
|
115
|
+
def within_eu?(origin_country_alpha2 = nil, destination_country_alpha2 = nil)
|
116
|
+
in_eu?(origin_country_alpha2) && in_eu?(destination_country_alpha2)
|
117
|
+
end
|
118
|
+
|
119
|
+
def tax_eligible?(...)
|
120
|
+
domestic?(...) || within_eu?(...)
|
121
|
+
end
|
122
|
+
|
123
|
+
def fallback_value(with_detail: false)
|
124
|
+
with_detail ? FALLBACK_VALUE_WITH_DETAILS : FALLBACK_VALUE
|
125
|
+
end
|
71
126
|
end
|
72
127
|
end
|
73
128
|
end
|
data/vat-gst-calculator.gemspec
CHANGED
@@ -23,6 +23,8 @@ Gem::Specification.new do |spec|
|
|
23
23
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
24
24
|
spec.require_paths = ["lib"]
|
25
25
|
|
26
|
+
spec.required_ruby_version = ">= 3.0.6"
|
27
|
+
|
26
28
|
spec.add_development_dependency "rspec", "~> 3.0"
|
27
29
|
spec.add_development_dependency "byebug"
|
28
30
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: vat-gst-calculator
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Aloha Chen
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: exe
|
11
11
|
cert_chain: []
|
12
|
-
date: 2023-
|
12
|
+
date: 2023-07-10 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|
@@ -72,14 +72,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
72
72
|
requirements:
|
73
73
|
- - ">="
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version:
|
75
|
+
version: 3.0.6
|
76
76
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
77
77
|
requirements:
|
78
78
|
- - ">="
|
79
79
|
- !ruby/object:Gem::Version
|
80
80
|
version: '0'
|
81
81
|
requirements: []
|
82
|
-
rubygems_version: 3.
|
82
|
+
rubygems_version: 3.2.33
|
83
83
|
signing_key:
|
84
84
|
specification_version: 4
|
85
85
|
summary: Calculate Sales Tax
|