moss_generator 0.1.5 → 0.4.1.1

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: ad1ddceb7b906a75ee7db040f6f02daa81743a0740ee9f3c060d6ec91b4fdf29
4
- data.tar.gz: 94c9ba93ab8d08a7db9829cadd1c9e2cc5770777d09015e6bbbfa085aa207cd5
3
+ metadata.gz: c5a596216f6d84e6178eed61ca60146695d1442651cd4d1193b8d430a061d01e
4
+ data.tar.gz: 511e5e30a8e24910c05abd028a977fcebb039353073476ca3afaa05a4975a4f5
5
5
  SHA512:
6
- metadata.gz: 2c550595f24be6127e4555c58320e6e48c331cd17a8e74000ea57fbf7939d53c73c31bb390b3d7f71d84f7b0768f7c823e519a93b2b90bc226f30b6945bbb8af
7
- data.tar.gz: d803e9ec37eceb859a5d726d0a5376659a979039add06b84a2d8ce47dc2cb19a55adbc2be9f7cad0f4f88a7ed00095b430a3dbe641811996f7fbe87fded1f378
6
+ metadata.gz: b9c353f6e72d5586820db41c452ecf1b3d6f9c2db7ff1713ffc4ffe5fe03a5e0a0bfb3872c5d4959bec6aad36b0e64fe75836d152eec0923c32e45bc410acc81
7
+ data.tar.gz: d3f0b382e87bcf84e3473811d1ff54da883cebe614b81d6ce46aad7ad63822bb9c6adcc5e449da0d7ef14d80bde0e1e7ea552c20f7d641c395bf91ecec78f0ec
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: 5
data/Gemfile.lock CHANGED
@@ -1,16 +1,55 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- moss_generator (0.1.5)
4
+ moss_generator (0.4.1.1)
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": 16,
133
+ "standard_rate": 19,
134
134
  "reduced_rates": {
135
135
  "foodstuffs": 7,
136
136
  "books": 7,
@@ -365,19 +365,5 @@
365
365
  "foodstuffs": 12,
366
366
  "books": 6
367
367
  }
368
- },
369
- "GB": {
370
- "country_name": "United Kingdom",
371
- "standard_rate": 20,
372
- "reduced_rates": {
373
- "property renovations": 5,
374
- "foodstuffs": 0,
375
- "books": 0,
376
- "pharmaceuticals": 0,
377
- "medical": 0,
378
- "passenger transport": 0,
379
- "newspapers": 0,
380
- "childrens clothing": 0
381
- }
382
368
  }
383
369
  }
@@ -0,0 +1,383 @@
1
+ {
2
+ "AT": {
3
+ "country_name": "Austria",
4
+ "standard_rate": 20,
5
+ "reduced_rates": {
6
+ "foodstuffs": 10,
7
+ "books": 5,
8
+ "pharmaceuticals": 10,
9
+ "passenger transport": 10,
10
+ "newspapers": 5,
11
+ "admission to cultural events": 5,
12
+ "hotels": 5,
13
+ "admission to entertainment events": 5
14
+ }
15
+ },
16
+ "BE": {
17
+ "country_name": "Belgium",
18
+ "standard_rate": 21,
19
+ "reduced_rates": {
20
+ "restaurants": 12,
21
+ "foodstuffs": 6,
22
+ "water": 6,
23
+ "pharmaceuticals": 6,
24
+ "medical": 6,
25
+ "books": 6,
26
+ "newspapers": 6,
27
+ "hotels": 6,
28
+ "admission to cultural events": 6,
29
+ "admission to entertainment events": 6
30
+ }
31
+ },
32
+ "BG": {
33
+ "country_name": "Bulgaria",
34
+ "standard_rate": 20,
35
+ "reduced_rates": {
36
+ "hotels": 9
37
+ }
38
+ },
39
+ "HR": {
40
+ "country_name": "Croatia",
41
+ "standard_rate": 25,
42
+ "reduced_rates": {
43
+ "hotels": 13,
44
+ "newspapers": 13
45
+ }
46
+ },
47
+ "CY": {
48
+ "country_name": "Cyprus",
49
+ "standard_rate": 19,
50
+ "reduced_rates": {
51
+ "hotels": 9,
52
+ "restaurants": 9,
53
+ "foodstuffs": 5,
54
+ "books": 5,
55
+ "pharmaceuticals": 5,
56
+ "medical": 5,
57
+ "passenger transport": 5,
58
+ "newspapers": 5,
59
+ "admission to cultural events": 5,
60
+ "admission to entertainment events": 5,
61
+ "admission to sporting events": 5
62
+ }
63
+ },
64
+ "CZ": {
65
+ "country_name": "Czech Republic",
66
+ "standard_rate": 21,
67
+ "reduced_rates": {
68
+ "foodstuffs": 15,
69
+ "medical": 10,
70
+ "pharmaceuticals": 10,
71
+ "passenger transport": 15,
72
+ "newspapers": 15,
73
+ "admission to cultural events": 15,
74
+ "admission to sporting events": 15,
75
+ "admission to entertainment events": 15,
76
+ "hotels": 15,
77
+ "books": 10,
78
+ "baby foodstuffs": 10
79
+ }
80
+ },
81
+ "DK": {
82
+ "country_name": "Denmark",
83
+ "standard_rate": 25,
84
+ "reduced_rates": null
85
+ },
86
+ "EE": {
87
+ "country_name": "Estonia",
88
+ "standard_rate": 20,
89
+ "reduced_rates": {
90
+ "books": 9,
91
+ "pharmaceuticals": 9,
92
+ "medical": 9,
93
+ "hotels": 9
94
+ }
95
+ },
96
+ "FI": {
97
+ "country_name": "Finland",
98
+ "standard_rate": 24,
99
+ "reduced_rates": {
100
+ "foodstuffs": 14,
101
+ "restaurants": 14,
102
+ "books": 10,
103
+ "pharmaceuticals": 10,
104
+ "passenger transport": 10,
105
+ "newspapers": 10,
106
+ "admission to cultural events": 10,
107
+ "admission to sporting events": 10,
108
+ "admission to entertainment events": 10,
109
+ "hotels": 10
110
+ }
111
+ },
112
+ "FR": {
113
+ "country_name": "France",
114
+ "standard_rate": 20,
115
+ "reduced_rates": {
116
+ "pharmaceuticals": 2.1,
117
+ "passenger transport": 10,
118
+ "admission to cultural events": 10,
119
+ "admission to sporting events": 10,
120
+ "admission to entertainment events": 10,
121
+ "hotels": 10,
122
+ "accommodation": 10,
123
+ "restaurants": 10,
124
+ "medical": 5.5,
125
+ "foodstuffs": 5.5,
126
+ "e-books": 5.5,
127
+ "books": 5.5,
128
+ "newspapers": 2.1
129
+ }
130
+ },
131
+ "DE": {
132
+ "country_name": "Germany",
133
+ "standard_rate": 16,
134
+ "reduced_rates": {
135
+ "foodstuffs": 7,
136
+ "books": 7,
137
+ "medical": 7,
138
+ "passenger transport": 7,
139
+ "newspapers": 7,
140
+ "admission to cultural events": 7,
141
+ "admission to entertainment events": 7,
142
+ "hotels": 7
143
+ }
144
+ },
145
+ "GR": {
146
+ "country_name": "Greece",
147
+ "standard_rate": 24,
148
+ "reduced_rates": {
149
+ "foodstuffs": 13,
150
+ "pharmaceuticals": 13,
151
+ "medical": 13,
152
+ "admission to cultural events": 13,
153
+ "admission to sporting events": 13,
154
+ "admission to entertainment events": 13,
155
+ "books": 6.5,
156
+ "newspapers": 6.5,
157
+ "hotels": 6.5
158
+ }
159
+ },
160
+ "HU": {
161
+ "country_name": "Hungary",
162
+ "standard_rate": 27,
163
+ "reduced_rates": {
164
+ "foodstuffs": 18,
165
+ "hotels": 18,
166
+ "books": 5,
167
+ "pharmaceuticals": 5,
168
+ "medical": 5
169
+ }
170
+ },
171
+ "IE": {
172
+ "country_name": "Ireland",
173
+ "standard_rate": 21,
174
+ "reduced_rates": {
175
+ "medical": 13.5,
176
+ "newspapers": 9,
177
+ "admission to cultural events": 13.5,
178
+ "admission to sporting events": 0,
179
+ "admission to entertainment events": 13.5,
180
+ "hotels": 13.5,
181
+ "restaurants": 13.5,
182
+ "foodstuffs": 4.8,
183
+ "books": 0,
184
+ "childrens clothing": 0
185
+ }
186
+ },
187
+ "IT": {
188
+ "country_name": "Italy",
189
+ "standard_rate": 22,
190
+ "reduced_rates": {
191
+ "pharmaceuticals": 10,
192
+ "passenger transport": 10,
193
+ "admission to cultural events": 10,
194
+ "admission to entertainment events": 10,
195
+ "hotels": 10,
196
+ "restaurants": 10,
197
+ "foodstuffs": 4,
198
+ "medical": 4,
199
+ "books": 4,
200
+ "e-books": 4
201
+ }
202
+ },
203
+ "LV": {
204
+ "country_name": "Latvia",
205
+ "standard_rate": 21,
206
+ "reduced_rates": {
207
+ "books": 12,
208
+ "pharmaceuticals": 12,
209
+ "medical": 12,
210
+ "newspapers": 12,
211
+ "hotels": 12
212
+ }
213
+ },
214
+ "LT": {
215
+ "country_name": "Lithuania",
216
+ "standard_rate": 21,
217
+ "reduced_rates": {
218
+ "books": 9,
219
+ "pharmaceuticals": 5,
220
+ "medical": 5
221
+ }
222
+ },
223
+ "LU": {
224
+ "country_name": "Luxembourg",
225
+ "standard_rate": 17,
226
+ "reduced_rates": {
227
+ "wine": 14,
228
+ "domestic fuel": 14,
229
+ "advertising": 14,
230
+ "bikes": 8,
231
+ "domestic services": 8,
232
+ "books": 3,
233
+ "foodstuffs": 3,
234
+ "pharmaceuticals": 3,
235
+ "medical": 3,
236
+ "passenger transport": 3,
237
+ "newspapers": 3,
238
+ "admission to cultural events": 3,
239
+ "admission to sporting events": 3,
240
+ "admission to entertainment events": 3,
241
+ "hotels": 3,
242
+ "restaurants": 3,
243
+ "e-books": 3
244
+ }
245
+ },
246
+ "MT": {
247
+ "country_name": "Malta",
248
+ "standard_rate": 18,
249
+ "reduced_rates": {
250
+ "hotels": 7,
251
+ "books": 5,
252
+ "medical": 5,
253
+ "newspapers": 5,
254
+ "admission to cultural events": 5,
255
+ "e-books": 5,
256
+ "foodstuffs": 0,
257
+ "pharmaceuticals": 0
258
+ }
259
+ },
260
+ "NL": {
261
+ "country_name": "Netherlands",
262
+ "standard_rate": 21,
263
+ "reduced_rates": {
264
+ "foodstuffs": 9,
265
+ "books": 9,
266
+ "pharmaceuticals": 9,
267
+ "medical": 9,
268
+ "passenger transport": 9,
269
+ "admission to cultural events": 9,
270
+ "admission to entertainment events": 9,
271
+ "hotels": 9,
272
+ "accommodation": 9
273
+ }
274
+ },
275
+ "PL": {
276
+ "country_name": "Poland",
277
+ "standard_rate": 23,
278
+ "reduced_rates": {
279
+ "pharmaceuticals": 8,
280
+ "medical": 8,
281
+ "passenger transport": 8,
282
+ "newspapers": 8,
283
+ "hotels": 8,
284
+ "restaurants": 8,
285
+ "admission to cultural events": 8,
286
+ "admission to sporting events": 8,
287
+ "admission to entertainment events": 8,
288
+ "foodstuffs": 5
289
+ }
290
+ },
291
+ "PT": {
292
+ "country_name": "Portugal",
293
+ "standard_rate": 23,
294
+ "reduced_rates": {
295
+ "foodstuffs": 6,
296
+ "agricultural supplies": 13,
297
+ "books": 6,
298
+ "pharmaceuticals": 6,
299
+ "medical": 6,
300
+ "newspapers": 6,
301
+ "hotels": 6,
302
+ "passenger transport": 6
303
+ }
304
+ },
305
+ "RO": {
306
+ "country_name": "Romania",
307
+ "standard_rate": 19,
308
+ "reduced_rates": {
309
+ "books": 9,
310
+ "pharmaceuticals": 9,
311
+ "medical": 9,
312
+ "newspapers": 9,
313
+ "admission to cultural events": 9,
314
+ "admission to entertainment events": 9,
315
+ "hotels": 9,
316
+ "foodstuffs": 9,
317
+ "social housing": 5
318
+ }
319
+ },
320
+ "SK": {
321
+ "country_name": "Slovakia",
322
+ "standard_rate": 20,
323
+ "reduced_rates": {
324
+ "books": 10,
325
+ "foodstuffs": 10,
326
+ "medical": 10,
327
+ "pharmaceuticals": 10,
328
+ "admission to cultural events": 10,
329
+ "admission to entertainment events": 10
330
+ }
331
+ },
332
+ "SI": {
333
+ "country_name": "Slovenia",
334
+ "standard_rate": 22,
335
+ "reduced_rates": {
336
+ "foodstuffs": 9.5,
337
+ "books": 9.5,
338
+ "pharmaceuticals": 9.5,
339
+ "medical": 9.5,
340
+ "newspapers": 9.5,
341
+ "admission to sporting events": 9.5,
342
+ "admission to cultural events": 9.5,
343
+ "admission to entertainment events": 9.5,
344
+ "hotels": 9.5
345
+ }
346
+ },
347
+ "ES": {
348
+ "country_name": "Spain",
349
+ "standard_rate": 21,
350
+ "reduced_rates": {
351
+ "medical": 10,
352
+ "pharmaceuticals": 10,
353
+ "passenger transport": 10,
354
+ "admission to cultural events": 10,
355
+ "admission to sporting events": 10,
356
+ "admission to entertainment events": 10,
357
+ "foodstuffs": 4,
358
+ "newspapers": 4
359
+ }
360
+ },
361
+ "SE": {
362
+ "country_name": "Sweden",
363
+ "standard_rate": 25,
364
+ "reduced_rates": {
365
+ "foodstuffs": 12,
366
+ "books": 6
367
+ }
368
+ },
369
+ "GB": {
370
+ "country_name": "United Kingdom",
371
+ "standard_rate": 20,
372
+ "reduced_rates": {
373
+ "property renovations": 5,
374
+ "foodstuffs": 0,
375
+ "books": 0,
376
+ "pharmaceuticals": 0,
377
+ "medical": 0,
378
+ "passenger transport": 0,
379
+ "newspapers": 0,
380
+ "childrens clothing": 0
381
+ }
382
+ }
383
+ }
@@ -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,28 +46,30 @@ module MossGenerator
45
46
 
46
47
  def group_charges_rows
47
48
  charges_rows = charges.map do |charge|
48
- charge_row = MossGenerator::StripeChargeRow.new(charge)
49
+ charge_row = MossGenerator::StripeChargeRow.new(charge, rates)
49
50
  next if charge_row.skippable?
50
51
 
51
52
  charge_row
52
53
  end.compact
53
- charges_rows.group_by(&:country_code)
54
+ charges_rows.group_by do |row|
55
+ [row.country_code, row.vat_rate]
56
+ end
54
57
  end
55
58
 
56
59
  def build_charges_rows
57
- group_charges_rows.map do |country, charges|
60
+ group_charges_rows.map do |(country, vat), charges|
58
61
  next if country == 'SE' && turnover_country == 'SE'
59
- next if charges.first.vat_rate.nil?
62
+ next if vat.nil?
60
63
 
61
- country_row(country, charges)
64
+ country_row(country, charges, vat)
62
65
  end.compact
63
66
  end
64
67
 
65
- def country_row(country, charges)
68
+ def country_row(country, charges, vat)
66
69
  [turnover_country,
67
70
  country,
68
- format_to_two_decimals(charges.first.vat_rate),
69
- format_to_two_decimals(charges.sum(&:amount)),
71
+ format_to_two_decimals(vat),
72
+ format_to_two_decimals(charges.sum(&:amount_without_vat)),
70
73
  format_to_two_decimals(charges.sum(&:vat_amount))]
71
74
  end
72
75
 
@@ -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,42 +27,66 @@ module MossGenerator
21
27
  raise NoConsumptionCountryError, "charge: #{charge}"
22
28
  end
23
29
 
24
- def amount
25
- amount_without_vat
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
29
- @vat_rate = MossGenerator::VatRate.for(country_code)
39
+ @vat_rate = special_vat_rate_for_2021_quarter_one
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
34
46
  end
35
47
 
36
48
  def skippable?
37
- company? || not_completed? || refunded?
49
+ not_completed? ||
50
+ company? ||
51
+ fetch_country_code.nil? ||
52
+ sold_outside_of_eu? ||
53
+ swedish_charge? ||
54
+ refunded?
38
55
  end
39
56
 
40
57
  private
41
58
 
59
+ def special_vat_rate_for_2021_quarter_one
60
+ if fetch_country_code.casecmp?('IE')
61
+ changeover_day = Date.parse('2021-03-01').to_time
62
+ return 23 if Time.at(charge['created']) >= changeover_day
63
+
64
+ 21
65
+ else
66
+ MossGenerator::VatRate.for(country_code)
67
+ end
68
+ end
69
+
42
70
  def company?
43
- charge.dig('metadata', 'vat_number').nil? ? false : true
71
+ return false if charge.dig('metadata', 'vat_number').nil?
72
+
73
+ Valvat::Syntax.validate(charge.dig('metadata', 'vat_number'))
44
74
  end
45
75
 
46
- def not_completed?
47
- charge['status'] != 'succeeded'
76
+ def sold_outside_of_eu?
77
+ ISO3166::Country.new(fetch_country_code).in_eu? ? false : true
48
78
  end
49
79
 
50
- def refunded?
51
- charge['refunded']
80
+ def swedish_charge?
81
+ fetch_country_code.casecmp?('SE')
52
82
  end
53
83
 
54
- def amount_without_vat
55
- amount_with_vat * percent_without_vat
84
+ def not_completed?
85
+ charge['status'] != 'succeeded'
56
86
  end
57
87
 
58
- def amount_with_vat
59
- charge.dig('balance_transaction', 'amount')
88
+ def refunded?
89
+ charge['refunded']
60
90
  end
61
91
 
62
92
  def percent_without_vat
@@ -70,5 +100,28 @@ module MossGenerator
70
100
  def fetch_country_code
71
101
  charge.dig('payment_method_details', 'card', 'country')
72
102
  end
103
+
104
+ def amount_with_vat
105
+ return if skippable?
106
+ return charge['amount'] if charge['currency'].casecmp?('eur')
107
+
108
+ exchanged_amount = calculate_amount_from_rate
109
+ return exchanged_amount unless exchanged_amount.nil?
110
+
111
+ raise NoExchangeRateForCurrencyOrDateError, "charge: #{charge}"
112
+ end
113
+
114
+ def calculate_amount_from_rate
115
+ # Have to reverse the rate. The base rate is in EUR, so if we have a rate
116
+ # to SEK, the rate will represent the rate from EUR to SEK, but we need
117
+ # the other way around.
118
+ date = Time.at(charge['created']).to_date.to_s
119
+ currency = charge['currency'].upcase
120
+ rate = rates.dig(date, currency)
121
+ return if rate.nil?
122
+
123
+ reversed_rate = 1 / rate
124
+ charge['amount'] * reversed_rate
125
+ end
73
126
  end
74
127
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module MossGenerator
4
- VERSION = '0.1.5'
4
+ VERSION = '0.4.1.1'
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.5
4
+ version: 0.4.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - frdrkolsson
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-01-15 00:00:00.000000000 Z
12
- dependencies: []
13
- description: Skatteverket Mini One Stop Shop(MOSS) generator.
11
+ date: 2021-04-14 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: []
@@ -30,6 +86,7 @@ files:
30
86
  - bin/console
31
87
  - bin/setup
32
88
  - config/vat_rates.json
89
+ - config/vat_rates_2020_4.json
33
90
  - lib/moss_generator.rb
34
91
  - lib/moss_generator/stripe.rb
35
92
  - lib/moss_generator/stripe_charge_row.rb
@@ -61,5 +118,5 @@ requirements: []
61
118
  rubygems_version: 3.2.3
62
119
  signing_key:
63
120
  specification_version: 4
64
- summary: Skatteverket Mini One Stop Shop(MOSS) generator.
121
+ summary: Skatteverket Mini One Stop Shop (MOSS) generator.
65
122
  test_files: []