moss_generator 0.1.2 → 0.4.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: 3afa29e4a1e8b9b65c08865b7422feee8ccf38ae9e438f4a53fe286a50c6578d
4
- data.tar.gz: 0aab051d4d1b1f298de2a8aba41d62b0fb9fc5fdd95c73e87ea8d68c0aad8722
3
+ metadata.gz: b18873ce424594b2a4cafe9dd26d23f6688352561e59820aa7f8229911cc4857
4
+ data.tar.gz: cc35447764a10b96f53035af22e5429809ad7ea10dc7adcb835089e0e69b5024
5
5
  SHA512:
6
- metadata.gz: 385d013dac1ac59573715db433f3b48a600ccbf6313b6b66247dc1d98caf51b10a7eaf95cd99c3113cdfba2596d6969051eae4b5b6da9fd63d81e1af449a1d52
7
- data.tar.gz: 448272b98a2f174eb435f2fab99a5068348af7531e346b38c11cd798b77994fbcbd4aa1305afeb61e74e8425d9243fca6551eae3069cfe0d8f3630b35de94f66
6
+ metadata.gz: 5ff56e1b296d590a99db183d73cd1b4ebb80efbfaaccceb4df5862bc7a01da9d06f50340fe5a941a3c463a556af1293b5dbc6a500938b6bb52b264c54d53af04
7
+ data.tar.gz: 6ec37d480db38da5abc948afd423928741e25b0c4273dbb02c8e373fe74ca697d04f86cc2e8c424061ae536c4697b6790a1910fff46ffef7fd33841380b68234
@@ -1,5 +1,9 @@
1
1
  name: Gem push
2
- on: [push]
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+
3
7
  jobs:
4
8
  github:
5
9
  name: Build + Publish to GitHub
@@ -1,6 +1,6 @@
1
1
  name: Ruby
2
2
 
3
- on: [push,pull_request]
3
+ on: [pull_request]
4
4
 
5
5
  jobs:
6
6
  build:
data/.rubocop.yml CHANGED
@@ -13,3 +13,6 @@ Layout/LineLength:
13
13
  Metrics/BlockLength:
14
14
  Exclude:
15
15
  - 'spec/**/*'
16
+
17
+ RSpec/NestedGroups:
18
+ Max: 4
data/Gemfile.lock CHANGED
@@ -1,16 +1,55 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- moss_generator (0.1.2)
4
+ moss_generator (0.4.0)
5
+ countries (~> 3.1)
6
+ money (~> 6.14)
7
+ valvat (~> 1.1)
5
8
 
6
9
  GEM
7
10
  remote: https://rubygems.org/
8
11
  specs:
12
+ addressable (2.7.0)
13
+ public_suffix (>= 2.0.2, < 5.0)
14
+ akami (1.3.1)
15
+ gyoku (>= 0.4.0)
16
+ nokogiri
9
17
  ast (2.4.1)
18
+ builder (3.2.4)
19
+ byebug (11.1.3)
20
+ coderay (1.1.3)
21
+ concurrent-ruby (1.1.8)
22
+ countries (3.1.0)
23
+ i18n_data (~> 0.11.0)
24
+ sixarm_ruby_unaccent (~> 1.1)
25
+ unicode_utils (~> 1.4)
10
26
  diff-lcs (1.4.4)
27
+ gyoku (1.3.1)
28
+ builder (>= 2.1.2)
29
+ httpi (2.4.5)
30
+ rack
31
+ socksify
32
+ i18n (1.8.10)
33
+ concurrent-ruby (~> 1.0)
34
+ i18n_data (0.11.0)
35
+ method_source (1.0.0)
36
+ money (6.14.1)
37
+ i18n (>= 0.6.4, <= 2)
38
+ nokogiri (1.11.3-x86_64-darwin)
39
+ racc (~> 1.4)
40
+ nori (2.6.0)
11
41
  parallel (1.20.1)
12
42
  parser (3.0.0.0)
13
43
  ast (~> 2.4.1)
44
+ pry (0.13.1)
45
+ coderay (~> 1.1)
46
+ method_source (~> 1.0)
47
+ pry-byebug (3.9.0)
48
+ byebug (~> 11.0)
49
+ pry (~> 0.13.0)
50
+ public_suffix (4.0.6)
51
+ racc (1.5.2)
52
+ rack (2.2.3)
14
53
  rainbow (3.0.0)
15
54
  rake (13.0.3)
16
55
  regexp_parser (2.0.3)
@@ -48,13 +87,31 @@ GEM
48
87
  rubocop (~> 1.0)
49
88
  rubocop-ast (>= 1.1.0)
50
89
  ruby-progressbar (1.10.1)
90
+ savon (2.12.1)
91
+ akami (~> 1.2)
92
+ builder (>= 2.1.2)
93
+ gyoku (~> 1.2)
94
+ httpi (~> 2.3)
95
+ nokogiri (>= 1.8.1)
96
+ nori (~> 2.4)
97
+ wasabi (~> 3.4)
98
+ sixarm_ruby_unaccent (1.2.0)
99
+ socksify (1.7.1)
51
100
  unicode-display_width (1.7.0)
101
+ unicode_utils (1.4.0)
102
+ valvat (1.1.0)
103
+ savon (>= 2.3.0)
104
+ wasabi (3.6.1)
105
+ addressable
106
+ httpi (~> 2.0)
107
+ nokogiri (>= 1.4.2)
52
108
 
53
109
  PLATFORMS
54
110
  x86_64-darwin-19
55
111
 
56
112
  DEPENDENCIES
57
113
  moss_generator!
114
+ pry-byebug
58
115
  rake (~> 13.0)
59
116
  rspec (~> 3.0)
60
117
  rubocop (~> 1.7)
@@ -130,7 +130,7 @@
130
130
  },
131
131
  "DE": {
132
132
  "country_name": "Germany",
133
- "standard_rate": 19,
133
+ "standard_rate": 16,
134
134
  "reduced_rates": {
135
135
  "foodstuffs": 7,
136
136
  "books": 7,
@@ -6,4 +6,6 @@ require_relative 'moss_generator/stripe'
6
6
 
7
7
  # Generate CSV-formatted string for MOSS report
8
8
  module MossGenerator
9
+ Money.default_currency = Money::Currency.new('EUR')
10
+ Money.rounding_mode = BigDecimal::ROUND_HALF_UP
9
11
  end
@@ -8,17 +8,18 @@ module MossGenerator
8
8
  class Stripe
9
9
  class NoTurnoverCountryError < StandardError; end
10
10
 
11
- attr_reader :charges, :vat_number, :period, :year
11
+ attr_reader :charges, :vat_number, :period, :year, :rates
12
12
 
13
- def initialize(charges, vat_number, period, year)
13
+ def initialize(charges, vat_number, period, year, rates)
14
14
  @charges = charges
15
15
  @vat_number = vat_number
16
16
  @period = period
17
17
  @year = year
18
+ @rates = rates
18
19
  end
19
20
 
20
- def self.call(charges, vat_number, period, year)
21
- new(charges, vat_number, period, year).call
21
+ def self.call(charges, vat_number, period, year, rates)
22
+ new(charges, vat_number, period, year, rates).call
22
23
  end
23
24
 
24
25
  def call
@@ -45,8 +46,11 @@ module MossGenerator
45
46
 
46
47
  def group_charges_rows
47
48
  charges_rows = charges.map do |charge|
48
- MossGenerator::StripeChargeRow.new(charge)
49
- end
49
+ charge_row = MossGenerator::StripeChargeRow.new(charge, rates)
50
+ next if charge_row.skippable?
51
+
52
+ charge_row
53
+ end.compact
50
54
  charges_rows.group_by(&:country_code)
51
55
  end
52
56
 
@@ -63,7 +67,7 @@ module MossGenerator
63
67
  [turnover_country,
64
68
  country,
65
69
  format_to_two_decimals(charges.first.vat_rate),
66
- format_to_two_decimals(charges.sum(&:amount)),
70
+ format_to_two_decimals(charges.sum(&:amount_without_vat)),
67
71
  format_to_two_decimals(charges.sum(&:vat_amount))]
68
72
  end
69
73
 
@@ -1,6 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'moss_generator/vat_rate'
4
+ require 'money'
5
+ require 'valvat/local'
6
+ require 'countries'
4
7
 
5
8
  module MossGenerator
6
9
  # Parse charge data from single Stripe charge
@@ -9,10 +12,13 @@ module MossGenerator
9
12
 
10
13
  class NoVatRateForCountryError < StandardError; end
11
14
 
12
- attr_reader :charge
15
+ class NoExchangeRateForCurrencyOrDateError < StandardError; end
13
16
 
14
- def initialize(charge)
17
+ attr_reader :charge, :rates
18
+
19
+ def initialize(charge, rates)
15
20
  @charge = charge
21
+ @rates = rates
16
22
  end
17
23
 
18
24
  def country_code
@@ -21,8 +27,12 @@ module MossGenerator
21
27
  raise NoConsumptionCountryError, "charge: #{charge}"
22
28
  end
23
29
 
24
- def amount
25
- charge.dig('balance_transaction', 'amount')
30
+ def amount_without_vat
31
+ Money.new(amount_with_vat * percent_without_vat).dollars.to_f
32
+ end
33
+
34
+ def amount_without_vat_cents
35
+ Money.new(amount_with_vat * percent_without_vat).cents
26
36
  end
27
37
 
28
38
  def vat_rate
@@ -30,18 +40,77 @@ module MossGenerator
30
40
  end
31
41
 
32
42
  def vat_amount
33
- amount * vat_rate_calculatable_percent
43
+ Money.new(amount_without_vat_cents * vat_rate_calculatable_percent)
44
+ .dollars
45
+ .to_f
46
+ end
47
+
48
+ def skippable?
49
+ not_completed? ||
50
+ company? ||
51
+ fetch_country_code.nil? ||
52
+ sold_outside_of_eu? ||
53
+ swedish_charge? ||
54
+ refunded?
34
55
  end
35
56
 
36
57
  private
37
58
 
59
+ def company?
60
+ return false if charge.dig('metadata', 'vat_number').nil?
61
+
62
+ Valvat::Syntax.validate(charge.dig('metadata', 'vat_number'))
63
+ end
64
+
65
+ def sold_outside_of_eu?
66
+ ISO3166::Country.new(fetch_country_code).in_eu? ? false : true
67
+ end
68
+
69
+ def swedish_charge?
70
+ fetch_country_code.casecmp?('SE')
71
+ end
72
+
73
+ def not_completed?
74
+ charge['status'] != 'succeeded'
75
+ end
76
+
77
+ def refunded?
78
+ charge['refunded']
79
+ end
80
+
81
+ def percent_without_vat
82
+ 1 / (vat_rate_calculatable_percent + 1)
83
+ end
84
+
38
85
  def vat_rate_calculatable_percent
39
86
  (vat_rate.to_f / 100)
40
87
  end
41
88
 
42
89
  def fetch_country_code
43
- charge.dig('payment_method_details', 'card', 'country') ||
44
- charge.dig('billing_details', 'address', 'country')
90
+ charge.dig('payment_method_details', 'card', 'country')
91
+ end
92
+
93
+ def amount_with_vat
94
+ return if skippable?
95
+ return charge['amount'] if charge['currency'].casecmp?('eur')
96
+
97
+ exchanged_amount = calculate_amount_from_rate
98
+ return exchanged_amount unless exchanged_amount.nil?
99
+
100
+ raise NoExchangeRateForCurrencyOrDateError, "charge: #{charge}"
101
+ end
102
+
103
+ def calculate_amount_from_rate
104
+ # Have to reverse the rate. The base rate is in EUR, so if we have a rate
105
+ # to SEK, the rate will represent the rate from EUR to SEK, but we need
106
+ # the other way around.
107
+ date = Time.at(charge['created']).to_date.to_s
108
+ currency = charge['currency'].upcase
109
+ rate = rates.dig(date, currency)
110
+ return if rate.nil?
111
+
112
+ reversed_rate = 1 / rate
113
+ charge['amount'] * reversed_rate
45
114
  end
46
115
  end
47
116
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module MossGenerator
4
- VERSION = '0.1.2'
4
+ VERSION = '0.4.0'
5
5
  end
@@ -8,7 +8,7 @@ Gem::Specification.new do |spec|
8
8
  spec.authors = ['frdrkolsson']
9
9
  spec.email = ['fredrik.olsson@standout.se']
10
10
 
11
- spec.summary = 'Skatteverket Mini One Stop Shop(MOSS) generator.'
11
+ spec.summary = 'Skatteverket Mini One Stop Shop (MOSS) generator.'
12
12
  spec.description = spec.summary
13
13
  spec.homepage = 'https://github.com/standout/moss_generator'
14
14
  spec.license = 'MIT'
@@ -30,8 +30,12 @@ Gem::Specification.new do |spec|
30
30
  spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
31
31
  spec.require_paths = ['lib']
32
32
 
33
- # Uncomment to register a new dependency of your gem
34
- # spec.add_dependency "example-gem", "~> 1.0"
33
+ # spec.add_dependency to register a new dependency of your gem
34
+ spec.add_dependency 'countries', '~> 3.1'
35
+ spec.add_dependency 'money', '~> 6.14'
36
+ spec.add_dependency 'valvat', '~> 1.1'
37
+
38
+ spec.add_development_dependency 'pry-byebug'
35
39
 
36
40
  # For more information and examples about making a new gem, checkout our
37
41
  # guide at: https://bundler.io/guides/creating_gem.html
metadata CHANGED
@@ -1,16 +1,72 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: moss_generator
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - frdrkolsson
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-01-12 00:00:00.000000000 Z
12
- dependencies: []
13
- description: Skatteverket Mini One Stop Shop(MOSS) generator.
11
+ date: 2021-04-13 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: countries
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '3.1'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '3.1'
27
+ - !ruby/object:Gem::Dependency
28
+ name: money
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '6.14'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '6.14'
41
+ - !ruby/object:Gem::Dependency
42
+ name: valvat
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.1'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.1'
55
+ - !ruby/object:Gem::Dependency
56
+ name: pry-byebug
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description: Skatteverket Mini One Stop Shop (MOSS) generator.
14
70
  email:
15
71
  - fredrik.olsson@standout.se
16
72
  executables: []
@@ -43,7 +99,7 @@ metadata:
43
99
  homepage_uri: https://github.com/standout/moss_generator
44
100
  source_code_uri: https://github.com/standout/moss_generator
45
101
  changelog_uri: https://github.com/standout/moss_generator
46
- post_install_message:
102
+ post_install_message:
47
103
  rdoc_options: []
48
104
  require_paths:
49
105
  - lib
@@ -58,8 +114,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
58
114
  - !ruby/object:Gem::Version
59
115
  version: '0'
60
116
  requirements: []
61
- rubygems_version: 3.1.2
62
- signing_key:
117
+ rubygems_version: 3.2.3
118
+ signing_key:
63
119
  specification_version: 4
64
- summary: Skatteverket Mini One Stop Shop(MOSS) generator.
120
+ summary: Skatteverket Mini One Stop Shop (MOSS) generator.
65
121
  test_files: []