moss_generator 0.3.0 → 0.5.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: b2b6449aa374fa85522e28aa9675f7bfd45b0b4a5ce390c6d0e912d079175ea1
4
- data.tar.gz: 5c8dceae90fc3910fd31e575a131f35a8cda3641a5804757201f900ab6f65ea6
3
+ metadata.gz: 9b732ef88aea620ba2fedc78beddbb1e6fc507aea9e67b335030ad062e5ea06d
4
+ data.tar.gz: 64bb783feb71f6dfea1c72dcc5aa2736ee41c7d135aa03399619b3aee1069f4e
5
5
  SHA512:
6
- metadata.gz: ad5637afa82ebf7b60ed543eb685ae8790d332b2062c360ff7ead5a2b714ffb6ec44719dea021f2496cb19dfe1eb75123bfb6a755ec9c4d6f682570fbca4a8dc
7
- data.tar.gz: 6db1366ba400e33e5f4e25458d4008fb4a01377950ad07775e454a3f251591fbefe7e1fe91bee589d809595cf9bd74b80e31d13b369f511bc7ebbf0ae98ddcdd
6
+ metadata.gz: e2ed158d4aa2a4d7cbf1f8fe154be50491dd42607842efa5f708050536906fcd030f1f5e124c3002dd3d145738e98b3aaa9897a6b6236d400537f16f650981e9
7
+ data.tar.gz: 75f6e9fb31900b14f2206faaeb72f229f3aa64b89ba050da8dfd1e11e2ae4ba86e7c688cdd4d23d057a851a2da24b69f4699955e693d729ba064f3b9a37793b2
data/.rubocop.yml CHANGED
@@ -10,9 +10,12 @@ AllCops:
10
10
  Layout/LineLength:
11
11
  Max: 80
12
12
 
13
+ Metrics/ParameterLists:
14
+ Max: 6
15
+
13
16
  Metrics/BlockLength:
14
17
  Exclude:
15
18
  - 'spec/**/*'
16
19
 
17
20
  RSpec/NestedGroups:
18
- Max: 4
21
+ Max: 5
data/Gemfile.lock CHANGED
@@ -1,37 +1,51 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- moss_generator (0.3.0)
4
+ moss_generator (0.5.0)
5
+ countries (~> 4.0)
5
6
  money (~> 6.14)
6
7
  valvat (~> 1.1)
7
8
 
8
9
  GEM
9
10
  remote: https://rubygems.org/
10
11
  specs:
11
- addressable (2.7.0)
12
+ addressable (2.8.0)
12
13
  public_suffix (>= 2.0.2, < 5.0)
13
14
  akami (1.3.1)
14
15
  gyoku (>= 0.4.0)
15
16
  nokogiri
16
17
  ast (2.4.1)
17
18
  builder (3.2.4)
18
- concurrent-ruby (1.1.7)
19
+ byebug (11.1.3)
20
+ coderay (1.1.3)
21
+ concurrent-ruby (1.1.9)
22
+ countries (4.0.1)
23
+ i18n_data (~> 0.13.0)
24
+ sixarm_ruby_unaccent (~> 1.1)
19
25
  diff-lcs (1.4.4)
20
26
  gyoku (1.3.1)
21
27
  builder (>= 2.1.2)
22
28
  httpi (2.4.5)
23
29
  rack
24
30
  socksify
25
- i18n (1.8.7)
31
+ i18n (1.8.10)
26
32
  concurrent-ruby (~> 1.0)
27
- money (6.14.0)
33
+ i18n_data (0.13.0)
34
+ method_source (1.0.0)
35
+ money (6.16.0)
28
36
  i18n (>= 0.6.4, <= 2)
29
- nokogiri (1.11.1-x86_64-darwin)
37
+ nokogiri (1.12.4-x86_64-darwin)
30
38
  racc (~> 1.4)
31
39
  nori (2.6.0)
32
40
  parallel (1.20.1)
33
41
  parser (3.0.0.0)
34
42
  ast (~> 2.4.1)
43
+ pry (0.13.1)
44
+ coderay (~> 1.1)
45
+ method_source (~> 1.0)
46
+ pry-byebug (3.9.0)
47
+ byebug (~> 11.0)
48
+ pry (~> 0.13.0)
35
49
  public_suffix (4.0.6)
36
50
  racc (1.5.2)
37
51
  rack (2.2.3)
@@ -80,9 +94,10 @@ GEM
80
94
  nokogiri (>= 1.8.1)
81
95
  nori (~> 2.4)
82
96
  wasabi (~> 3.4)
97
+ sixarm_ruby_unaccent (1.2.0)
83
98
  socksify (1.7.1)
84
99
  unicode-display_width (1.7.0)
85
- valvat (1.1.0)
100
+ valvat (1.1.1)
86
101
  savon (>= 2.3.0)
87
102
  wasabi (3.6.1)
88
103
  addressable
@@ -94,6 +109,7 @@ PLATFORMS
94
109
 
95
110
  DEPENDENCIES
96
111
  moss_generator!
112
+ pry-byebug
97
113
  rake (~> 13.0)
98
114
  rspec (~> 3.0)
99
115
  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
+ }
@@ -8,17 +8,19 @@ 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, :sale_type
12
12
 
13
- def initialize(charges, vat_number, period, year)
13
+ def initialize(charges, vat_number, period, year, rates, sale_type)
14
14
  @charges = charges
15
15
  @vat_number = vat_number
16
16
  @period = period
17
17
  @year = year
18
+ @rates = rates
19
+ @sale_type = sale_type
18
20
  end
19
21
 
20
- def self.call(charges, vat_number, period, year)
21
- new(charges, vat_number, period, year).call
22
+ def self.call(charges, vat_number, period, year, rates, sale_type)
23
+ new(charges, vat_number, period, year, rates, sale_type).call
22
24
  end
23
25
 
24
26
  def call
@@ -32,7 +34,7 @@ module MossGenerator
32
34
  private
33
35
 
34
36
  def first_row
35
- ['MOSS_001']
37
+ ['OSS_001']
36
38
  end
37
39
 
38
40
  def second_row
@@ -45,29 +47,32 @@ module MossGenerator
45
47
 
46
48
  def group_charges_rows
47
49
  charges_rows = charges.map do |charge|
48
- charge_row = MossGenerator::StripeChargeRow.new(charge)
50
+ charge_row = MossGenerator::StripeChargeRow.new(charge, rates)
49
51
  next if charge_row.skippable?
50
52
 
51
53
  charge_row
52
54
  end.compact
53
- charges_rows.group_by(&:country_code)
55
+ charges_rows.group_by do |row|
56
+ [row.country_code, row.vat_rate]
57
+ end
54
58
  end
55
59
 
56
60
  def build_charges_rows
57
- group_charges_rows.map do |country, charges|
61
+ group_charges_rows.map do |(country, vat), charges|
58
62
  next if country == 'SE' && turnover_country == 'SE'
59
- next if charges.first.vat_rate.nil?
63
+ next if vat.nil?
60
64
 
61
- country_row(country, charges)
65
+ country_row(country, charges, vat)
62
66
  end.compact
63
67
  end
64
68
 
65
- def country_row(country, charges)
69
+ def country_row(country, charges, vat)
66
70
  [turnover_country,
67
71
  country,
68
- format_to_two_decimals(charges.first.vat_rate),
72
+ format_to_two_decimals(vat),
69
73
  format_to_two_decimals(charges.sum(&:amount_without_vat)),
70
- format_to_two_decimals(charges.sum(&:vat_amount))]
74
+ format_to_two_decimals(charges.sum(&:vat_amount)),
75
+ sale_type]
71
76
  end
72
77
 
73
78
  def csv_options
@@ -3,6 +3,7 @@
3
3
  require 'moss_generator/vat_rate'
4
4
  require 'money'
5
5
  require 'valvat/local'
6
+ require 'countries'
6
7
 
7
8
  module MossGenerator
8
9
  # Parse charge data from single Stripe charge
@@ -11,12 +12,13 @@ module MossGenerator
11
12
 
12
13
  class NoVatRateForCountryError < StandardError; end
13
14
 
14
- class NotInEuroError < StandardError; end
15
+ class NoExchangeRateForCurrencyOrDateError < StandardError; end
15
16
 
16
- attr_reader :charge
17
+ attr_reader :charge, :rates
17
18
 
18
- def initialize(charge)
19
+ def initialize(charge, rates)
19
20
  @charge = charge
21
+ @rates = rates
20
22
  end
21
23
 
22
24
  def country_code
@@ -34,7 +36,7 @@ module MossGenerator
34
36
  end
35
37
 
36
38
  def vat_rate
37
- @vat_rate = MossGenerator::VatRate.for(country_code)
39
+ @vat_rate = special_vat_rate_for_2021_quarter_one
38
40
  end
39
41
 
40
42
  def vat_amount
@@ -44,17 +46,41 @@ module MossGenerator
44
46
  end
45
47
 
46
48
  def skippable?
47
- company? || not_completed? || refunded?
49
+ not_completed? ||
50
+ company? ||
51
+ fetch_country_code.nil? ||
52
+ sold_outside_of_eu? ||
53
+ swedish_charge? ||
54
+ refunded?
48
55
  end
49
56
 
50
57
  private
51
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
+
52
70
  def company?
53
71
  return false if charge.dig('metadata', 'vat_number').nil?
54
72
 
55
73
  Valvat::Syntax.validate(charge.dig('metadata', 'vat_number'))
56
74
  end
57
75
 
76
+ def sold_outside_of_eu?
77
+ ISO3166::Country.new(fetch_country_code).in_eu? ? false : true
78
+ end
79
+
80
+ def swedish_charge?
81
+ fetch_country_code.casecmp?('SE')
82
+ end
83
+
58
84
  def not_completed?
59
85
  charge['status'] != 'succeeded'
60
86
  end
@@ -63,13 +89,6 @@ module MossGenerator
63
89
  charge['refunded']
64
90
  end
65
91
 
66
- def amount_with_vat
67
- return charge['amount'] if charge['currency'].casecmp?('eur')
68
- return if skippable?
69
-
70
- raise NotInEuroError, "charge: #{charge}"
71
- end
72
-
73
92
  def percent_without_vat
74
93
  1 / (vat_rate_calculatable_percent + 1)
75
94
  end
@@ -81,5 +100,28 @@ module MossGenerator
81
100
  def fetch_country_code
82
101
  charge.dig('payment_method_details', 'card', 'country')
83
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
84
126
  end
85
127
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module MossGenerator
4
- VERSION = '0.3.0'
4
+ VERSION = '0.5.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 One Stop Shop (OSS) generator.'
12
12
  spec.description = spec.summary
13
13
  spec.homepage = 'https://github.com/standout/moss_generator'
14
14
  spec.license = 'MIT'
@@ -31,9 +31,12 @@ Gem::Specification.new do |spec|
31
31
  spec.require_paths = ['lib']
32
32
 
33
33
  # spec.add_dependency to register a new dependency of your gem
34
+ spec.add_dependency 'countries', '~> 4.0'
34
35
  spec.add_dependency 'money', '~> 6.14'
35
36
  spec.add_dependency 'valvat', '~> 1.1'
36
37
 
38
+ spec.add_development_dependency 'pry-byebug'
39
+
37
40
  # For more information and examples about making a new gem, checkout our
38
41
  # guide at: https://bundler.io/guides/creating_gem.html
39
42
  end
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: moss_generator
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.5.0
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-20 00:00:00.000000000 Z
11
+ date: 2021-09-10 00:00:00.000000000 Z
12
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: '4.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '4.0'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: money
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -38,7 +52,21 @@ dependencies:
38
52
  - - "~>"
39
53
  - !ruby/object:Gem::Version
40
54
  version: '1.1'
41
- description: Skatteverket Mini One Stop Shop (MOSS) generator.
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 One Stop Shop (OSS) generator.
42
70
  email:
43
71
  - fredrik.olsson@standout.se
44
72
  executables: []
@@ -58,6 +86,7 @@ files:
58
86
  - bin/console
59
87
  - bin/setup
60
88
  - config/vat_rates.json
89
+ - config/vat_rates_2020_4.json
61
90
  - lib/moss_generator.rb
62
91
  - lib/moss_generator/stripe.rb
63
92
  - lib/moss_generator/stripe_charge_row.rb
@@ -86,8 +115,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
86
115
  - !ruby/object:Gem::Version
87
116
  version: '0'
88
117
  requirements: []
89
- rubygems_version: 3.2.3
118
+ rubygems_version: 3.2.22
90
119
  signing_key:
91
120
  specification_version: 4
92
- summary: Skatteverket Mini One Stop Shop (MOSS) generator.
121
+ summary: Skatteverket One Stop Shop (OSS) generator.
93
122
  test_files: []