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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4c0b1547695777a69f063993628affe4eaf28498180236ca0bd2e5902d5bd7d7
4
- data.tar.gz: 5f7fd7051a155b3f5c0187ec2ebde52df83991a35491e0d8abf780d93ff94aed
3
+ metadata.gz: 47259f182d190ca603c7694139e25c002852bc1c60952dbc8967ae170031dea5
4
+ data.tar.gz: 76f58ac22a22144627b1144ef6b9469179b68034ed104e0f369c1d726e53c8ac
5
5
  SHA512:
6
- metadata.gz: 444a34ccad4d894adca304083e25cc4baae48ae6a6abb7d1aabcd0c074a87d790120f0c6abd6ff2bfa242174c9939a00957c53a399151d68fe1acc0a551d7fbb
7
- data.tar.gz: a7b0bcf732ca7a34da47c703e6b9f85fdae33461ad2602c73058f5770284b0e50204a3938b6674fd30a46317ab5481971a2d5d282665fccc70e713f1c9c8a28c
6
+ metadata.gz: 89e1e20dabc983e4bcd34a3ace0982ebab08a56f6242ee2037b8cdf5a9608814064603fe7e3bffb9e3c49f6240ef85ba614eac96d2ea85435191f769d48f719a
7
+ data.tar.gz: 39b36cf998538c48282da9ec6462f29770b701dba666bc90501deaac39326a2ab12c5de231875b8a2f75b02895bac7b18477f2ec413c5ae8185d6e5844d97661
data/.gitignore CHANGED
@@ -4,3 +4,4 @@ Gemfile.lock
4
4
  .idea/*
5
5
  *.swp
6
6
  tags
7
+ .tool-versions
@@ -1,7 +1,7 @@
1
1
  module Easyship
2
2
  module SalesTax
3
3
  module Calculator
4
- VERSION = "0.7.0"
4
+ VERSION = "0.8.0"
5
5
  end
6
6
  end
7
7
  end
@@ -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
- def self.calculate(origin_country_alpha2: nil, destination_country_alpha2: nil, origin_state: nil, destination_state: nil, fees: nil, effective_timestamp: nil, effective_country_alpha2s: [])
12
- return FALLBACK_VALUE if origin_country_alpha2.nil? || origin_country_alpha2.empty? || destination_country_alpha2.nil? || destination_country_alpha2.empty?
13
- return FALLBACK_VALUE unless fees.is_a?(Fee)
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
- else
25
- FALLBACK_VALUE
43
+ rescue
44
+ fallback_value(with_detail: with_detail)
26
45
  end
27
- rescue
28
- FALLBACK_VALUE
29
- end
30
46
 
31
- def self.sales_tax_website_name(country_alpha2, effective_timestamp = nil)
32
- rates = Formula.effective_data(country_alpha2, effective_timestamp)
33
- (rates || {}).dig(:sales_tax_website_name)
34
- end
47
+ def calculate_with_detail(**kwargs)
48
+ calculate(with_detail: true, **kwargs)
49
+ end
35
50
 
36
- private
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
- def self.domestic_value(origin_country_alpha2: nil, origin_state: nil, destination_state: nil, fees: nil, effective_timestamp: nil, effective_country_alpha2s: [])
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
- sales_tax: tax_calculate(rates[:sales_tax], nil, destination_state, fees, false),
44
- provincial_sales_tax: tax_calculate(rates[:provincial_sales_taxes], origin_state, destination_state, fees, true)
45
- }
46
- end
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
- def self.tax_calculate(formula, origin_state, destination_state, fees, is_provincial_sales_taxes)
49
- if (tax_destination_formula = formula[destination_state.to_s.upcase])
50
- # ONLY CA has provincial_sales_taxes(QST/PST) and it only apply when ship within same state
51
- # https://www.fedex.com/en-ca/news/canadian-sales-taxes.html
52
- return 0 if origin_state != destination_state && is_provincial_sales_taxes
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
- def self.in_eu?(country_alpha2)
62
- %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).include?(country_alpha2)
63
- end
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
- def self.domestic?(origin_country_alpha2 = nil, destination_country_alpha2 = nil)
66
- !origin_country_alpha2.nil? && !origin_country_alpha2.empty? && origin_country_alpha2 == destination_country_alpha2
67
- end
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
- def self.within_eu?(origin_country_alpha2 = nil, destination_country_alpha2 = nil)
70
- in_eu?(origin_country_alpha2) && in_eu?(destination_country_alpha2)
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
@@ -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.7.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-01-31 00:00:00.000000000 Z
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: '0'
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.0.9
82
+ rubygems_version: 3.2.33
83
83
  signing_key:
84
84
  specification_version: 4
85
85
  summary: Calculate Sales Tax