lucabook 0.2.18 → 0.2.23

Sign up to get free protection for your applications and to get access to all the features.
@@ -31,7 +31,7 @@ module LucaBook
31
31
  new data, Date.new(from_year.to_i, from_month.to_i, 1), code
32
32
  end
33
33
 
34
- def list_on_code
34
+ def list_by_code
35
35
  calc_code
36
36
  convert_label
37
37
  @data = [code_header] + @data.map do |dat|
@@ -47,7 +47,7 @@ module LucaBook
47
47
  res['note'] = dat[:note]
48
48
  end
49
49
  end
50
- self
50
+ readable(@data)
51
51
  end
52
52
 
53
53
  def list_journals
@@ -65,7 +65,7 @@ module LucaBook
65
65
  res['note'] = dat[:note]
66
66
  end
67
67
  end
68
- self
68
+ readable(@data)
69
69
  end
70
70
 
71
71
  def accumulate_code
@@ -74,10 +74,6 @@ module LucaBook
74
74
  end
75
75
  end
76
76
 
77
- def to_yaml
78
- YAML.dump(LucaSupport::Code.readable(@data)).tap { |data| puts data }
79
- end
80
-
81
77
  private
82
78
 
83
79
  def set_balance
@@ -0,0 +1,120 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'pathname'
4
+ require 'date'
5
+ require 'luca_support'
6
+ require 'luca_record'
7
+ require 'luca_record/dict'
8
+ require 'luca_book'
9
+
10
+ # Journal List on specified term
11
+ #
12
+ module LucaBook
13
+ class ListByHeader < LucaBook::Journal
14
+ @dirname = 'journals'
15
+
16
+ def initialize(data, start_date, code = nil, header_name = nil)
17
+ @data = data
18
+ @code = code
19
+ @header = header_name
20
+ @start = start_date
21
+ @dict = LucaRecord::Dict.load('base.tsv')
22
+ end
23
+
24
+ def self.term(from_year, from_month, to_year = from_year, to_month = from_month, code: nil, header: nil, basedir: @dirname)
25
+ data = Journal.term(from_year, from_month, to_year, to_month, code).select do |dat|
26
+ if code.nil?
27
+ true
28
+ else
29
+ [:debit, :credit].map { |key| serialize_on_key(dat[key], :code) }.flatten.include?(code)
30
+ end
31
+ end
32
+ new data, Date.new(from_year.to_i, from_month.to_i, 1), code, header
33
+ end
34
+
35
+ def list_by_code
36
+ calc_code
37
+ convert_label
38
+ @data = @data.each_with_object([]) do |(k, v), a|
39
+ journals = v.map do |dat|
40
+ date, txid = decode_id(dat[:id])
41
+ {}.tap do |res|
42
+ res['header'] = k
43
+ res['date'] = date
44
+ res['no'] = txid
45
+ res['id'] = dat[:id]
46
+ res['diff'] = dat[:diff]
47
+ res['balance'] = dat[:balance]
48
+ res['counter_code'] = dat[:counter_code].length == 1 ? dat[:counter_code].first : dat[:counter_code]
49
+ res['note'] = dat[:note]
50
+ end
51
+ end
52
+ a << { 'code' => v.last[:code], 'header' => k, 'balance' => v.last[:balance], 'count' => v.count, 'jounals' => journals }
53
+ end
54
+ readable(@data)
55
+ end
56
+
57
+ def accumulate_code
58
+ @data.each_with_object({}) do |dat, sum|
59
+ idx = dat.dig(:headers, @header) || 'others'
60
+ sum[idx] ||= BigDecimal('0')
61
+ sum[idx] += Util.diff_by_code(dat[:debit], @code) - Util.diff_by_code(dat[:credit], @code)
62
+ end
63
+ end
64
+
65
+ private
66
+
67
+ def set_balance
68
+ return BigDecimal('0') if @code.nil? || /^[A-H]/.match(@code)
69
+
70
+ balance_dict = Dict.latest_balance
71
+ start_balance = BigDecimal(balance_dict.dig(@code.to_s, :balance) || '0')
72
+ start = Dict.issue_date(balance_dict)&.next_month
73
+ last = @start.prev_month
74
+ if last.year >= start.year && last.month >= start.month
75
+ #TODO: start_balance to be implemented by header
76
+ self.class.term(start.year, start.month, last.year, last.month, code: @code).accumulate_code
77
+ else
78
+ #start_balance
79
+ end
80
+ end
81
+
82
+ def calc_code
83
+ raise 'no account code specified' if @code.nil?
84
+
85
+ @balance = set_balance
86
+ balance = @balance
87
+ res = {}
88
+ @data.each do |dat|
89
+ idx = dat.dig(:headers, @header) || 'others'
90
+ balance[idx] ||= BigDecimal('0')
91
+ res[idx] ||= []
92
+ {}.tap do |h|
93
+ h[:id] = dat[:id]
94
+ h[:diff] = Util.diff_by_code(dat[:debit], @code) - Util.diff_by_code(dat[:credit], @code)
95
+ balance[idx] += h[:diff]
96
+ h[:balance] = balance[idx]
97
+ h[:code] = @code
98
+ counter = h[:diff] * Util.pn_debit(@code) > 0 ? :credit : :debit
99
+ h[:counter_code] = dat[counter].map { |d| d[:code] }
100
+ h[:note] = dat[:note]
101
+ res[idx] << h
102
+ end
103
+ end
104
+ @data = res
105
+ self
106
+ end
107
+
108
+ def convert_label
109
+ @data.each do |_k, v|
110
+ v.each do |dat|
111
+ raise 'no account code specified' if @code.nil?
112
+
113
+ dat[:code] = "#{dat[:code]} #{@dict.dig(dat[:code], :label)}"
114
+ dat[:counter_code] = dat[:counter_code].map { |counter| "#{counter} #{@dict.dig(counter, :label)}" }
115
+ end
116
+ end
117
+ self
118
+ end
119
+ end
120
+ end
@@ -6,7 +6,7 @@ require 'fileutils'
6
6
  module LucaBook
7
7
  class Setup
8
8
  # create project skeleton under specified directory
9
- def self.create_project(country = nil, dir = LucaSupport::Config::Pjdir)
9
+ def self.create_project(country = nil, dir = LucaSupport::PJDIR)
10
10
  FileUtils.mkdir_p(dir) unless Dir.exist?(dir)
11
11
  Dir.chdir(dir) do
12
12
  %w[data/journals data/balance dict].each do |subdir|
@@ -18,6 +18,7 @@ module LucaBook
18
18
  'dict-en.tsv'
19
19
  end
20
20
  FileUtils.cp("#{__dir__}/templates/#{dict}", 'dict/base.tsv') unless File.exist?('dict/base.tsv')
21
+ FileUtils.cp("#{__dir__}/templates/config.yml", 'config.yml') unless File.exist?('config.yml')
21
22
  prepare_starttsv(dict) unless File.exist? 'data/balance/start.tsv'
22
23
  end
23
24
  end
@@ -17,28 +17,15 @@ module LucaBook
17
17
 
18
18
  attr_reader :statement
19
19
 
20
- def initialize(data, count = nil)
20
+ def initialize(data, count = nil, date: nil)
21
21
  @data = data
22
22
  @count = count
23
23
  @dict = LucaRecord::Dict.load('base.tsv')
24
+ @start_date = date
24
25
  @start_balance = set_balance
25
26
  end
26
27
 
27
- # TODO: not compatible with LucaRecord::Base.open_records
28
- def search_tag(code)
29
- count = 0
30
- Dir.children(LucaSupport::Config::Pjdir).sort.each do |dir|
31
- next if ! FileTest.directory?(LucaSupport::Config::Pjdir+dir)
32
-
33
- open_records(datadir, dir, 3) do |row, i|
34
- next if i == 2
35
- count += 1 if row.include?(code)
36
- end
37
- end
38
- puts "#{code}: #{count}"
39
- end
40
-
41
- def self.term(from_year, from_month, to_year = from_year, to_month = from_month)
28
+ def self.range(from_year, from_month, to_year = from_year, to_month = from_month)
42
29
  date = Date.new(from_year.to_i, from_month.to_i, -1)
43
30
  last_date = Date.new(to_year.to_i, to_month.to_i, -1)
44
31
  raise 'invalid term specified' if date > last_date
@@ -52,35 +39,34 @@ module LucaBook
52
39
  date = Date.new(date.next_month.year, date.next_month.month, -1)
53
40
  end
54
41
  end
55
- new reports, counts
42
+ new(reports, counts, date: Date.new(from_year.to_i, from_month.to_i, -1))
56
43
  end
57
44
 
58
- def by_code(code, year=nil, month=nil)
59
- raise 'not supported year range yet' if ! year.nil? && month.nil?
60
-
61
- balance = @book.load_start.dig(code) || 0
62
- full_term = self.class.scan_terms
63
- if ! month.nil?
64
- pre_term = full_term.select { |y, m| y <= year.to_i && m < month.to_i }
65
- balance += pre_term.map { |y, m| self.class.net(y, m)}.inject(0){|sum, h| sum + h[code] }
66
- [{ code: code, balance: balance, note: "#{code} #{@dict.dig(code, :label)}" }] + records_with_balance(year, month, code, balance)
67
- else
68
- start = { code: code, balance: balance, note: "#{code} #{@dict.dig(code, :label)}" }
69
- full_term.map { |y, m| y }.uniq.map { |y|
70
- records_with_balance(y, nil, code, balance)
71
- }.flatten.prepend(start)
72
- end
73
- end
45
+ def self.by_code(code, from_year, from_month, to_year = from_year, to_month = from_month)
46
+ date = Date.new(from_year.to_i, from_month.to_i, -1)
47
+ last_date = Date.new(to_year.to_i, to_month.to_i, -1)
48
+ raise 'invalid term specified' if date > last_date
74
49
 
75
- def records_with_balance(year, month, code, balance)
76
- @book.search(year, month, nil, code).each do |h|
77
- balance += Util.calc_diff(Util.amount_by_code(h[:debit], code), code) - Util.calc_diff(Util.amount_by_code(h[:credit], code), code)
78
- h[:balance] = balance
50
+ reports = [].tap do |r|
51
+ while date <= last_date do
52
+ diff = {}.tap do |h|
53
+ g = gross(date.year, date.month, code: code)
54
+ sum = g.dig(:debit).nil? ? BigDecimal('0') : Util.calc_diff(g[:debit], code)
55
+ sum -= g.dig(:credit).nil? ? BigDecimal('0') : Util.calc_diff(g[:credit], code)
56
+ h['code'] = code
57
+ h['label'] = LucaRecord::Dict.load('base.tsv').dig(code, :label)
58
+ h['net'] = sum
59
+ h['debit_amount'] = g[:debit]
60
+ h['debit_count'] = g[:debit_count]
61
+ h['credit_amount'] = g[:credit]
62
+ h['credit_count'] = g[:credit_count]
63
+ h['_d'] = date.to_s
64
+ end
65
+ r << diff
66
+ date = Date.new(date.next_month.year, date.next_month.month, -1)
67
+ end
79
68
  end
80
- end
81
-
82
- def to_yaml
83
- YAML.dump(code2label).tap { |data| puts data }
69
+ LucaSupport::Code.readable(reports)
84
70
  end
85
71
 
86
72
  def code2label
@@ -113,30 +99,29 @@ module LucaBook
113
99
  end
114
100
  keys.map! { |k| k[0, level] }.uniq.select! { |k| k.length <= level } if level
115
101
  @count.prepend({}.tap { |header| keys.each { |k| header[k] = @dict.dig(k, :label) }})
116
- puts YAML.dump(@count)
117
102
  @count
118
103
  end
119
104
 
120
105
  def bs(level = 3, legal: false)
106
+ @start_balance.keys.each { |k| @data.first[k] ||= 0 }
121
107
  @data.map! { |data| data.select { |k, _v| k.length <= level } }
122
108
  @data.map! { |data| code_sum(data).merge(data) } if legal
123
109
  base = accumulate_balance(@data)
124
- length = [base[:debit].length, base[:credit].length].max
110
+ rows = [base[:debit].length, base[:credit].length].max
125
111
  @statement = [].tap do |a|
126
- length.times do |i|
112
+ rows.times do |i|
127
113
  {}.tap do |res|
128
114
  res['debit_label'] = base[:debit][i] ? @dict.dig(base[:debit][i].keys[0], :label) : ''
129
- res['debit_balance'] = base[:debit][i] ? @start_balance.dig(base[:debit][i].keys[0]) + base[:debit][i].values[0] : ''
115
+ res['debit_balance'] = base[:debit][i] ? (@start_balance.dig(base[:debit][i].keys[0]) || 0) + base[:debit][i].values[0] : ''
130
116
  res['debit_diff'] = base[:debit][i] ? base[:debit][i].values[0] : ''
131
117
  res['credit_label'] = base[:credit][i] ? @dict.dig(base[:credit][i].keys[0], :label) : ''
132
- res['credit_balance'] = base[:credit][i] ? @start_balance.dig(base[:credit][i].keys[0]) + base[:credit][i].values[0] : ''
118
+ res['credit_balance'] = base[:credit][i] ? (@start_balance.dig(base[:credit][i].keys[0]) || 0) + base[:credit][i].values[0] : ''
133
119
  res['credit_diff'] = base[:credit][i] ? base[:credit][i].values[0] : ''
134
120
  a << res
135
121
  end
136
122
  end
137
123
  end
138
- puts YAML.dump(@statement)
139
- self
124
+ readable(@statement)
140
125
  end
141
126
 
142
127
  def accumulate_balance(monthly_diffs)
@@ -144,9 +129,9 @@ module LucaBook
144
129
  month.each do |k, v|
145
130
  h[k] = h[k].nil? ? v : h[k] + v
146
131
  end
147
- end.sort.to_h
132
+ end
148
133
  { debit: [], credit: [] }.tap do |res|
149
- data.each do |k, v|
134
+ data.sort.to_h.each do |k, v|
150
135
  case k
151
136
  when /^[0-4].*/
152
137
  res[:debit] << { k => v }
@@ -157,11 +142,45 @@ module LucaBook
157
142
  end
158
143
  end
159
144
 
160
- def pl
161
- @statement = @data.map { |data| data.select { |k, _v| /^[A-H_].+/.match(k) } }
162
- @statement << @statement.each_with_object({}) { |item, h| item.each { |k, v| h[k].nil? ? h[k] = v : h[k] += v } }
163
- .tap { |h| h['_d'] = 'Total' }
164
- self
145
+ def pl(level = 2)
146
+ term_keys = @data.inject([]) { |a, data| a + data.keys }
147
+ .compact.select { |k| /^[A-H_].+/.match(k) }
148
+ fy = @start_balance.select { |k, _v| /^[A-H].+/.match(k) }
149
+ keys = (term_keys + fy.keys).uniq.sort
150
+ keys.select! { |k| k.length <= level }
151
+ @statement = @data.map do |data|
152
+ {}.tap do |h|
153
+ keys.each { |k| h[k] = data[k] || BigDecimal('0') }
154
+ end
155
+ end
156
+ term = @statement.each_with_object({}) do |item, h|
157
+ item.each do |k, v|
158
+ h[k] = h[k].nil? ? v : h[k] + v if /^[^_]/.match(k)
159
+ end
160
+ end
161
+ fy = {}.tap do |h|
162
+ keys.each do |k|
163
+ h[k] = BigDecimal(fy[k] || '0') + BigDecimal(term[k] || '0')
164
+ end
165
+ end
166
+ @statement << term.tap { |h| h['_d'] = 'Period Total' }
167
+ @statement << fy.tap { |h| h['_d'] = 'FY Total' }
168
+ readable(code2label)
169
+ end
170
+
171
+ def self.accumulate_term(start_year, start_month, end_year, end_month)
172
+ date = Date.new(start_year, start_month, 1)
173
+ last_date = Date.new(end_year, end_month, -1)
174
+ return nil if date > last_date
175
+
176
+ {}.tap do |res|
177
+ diff, _count = net(date.year, date.month, last_date.year, last_date.month)
178
+ diff.each do |k, v|
179
+ next if /^[_]/.match(k)
180
+
181
+ res[k] = res[k].nil? ? v : res[k] + v
182
+ end
183
+ end
165
184
  end
166
185
 
167
186
  def self.accumulate_month(year, month)
@@ -187,18 +206,27 @@ module LucaBook
187
206
  res['H0'] = sum_matched(report, /^[H][0-9][0-9A-Z]{1,}/)
188
207
  res['HA'] = res['GA'] - res['H0']
189
208
 
190
- res['9142'] = (report['9142'] || 0) + res['HA']
191
- res['10'] = sum_matched(report, /^[123][0-9A-Z]{2,}/)
192
- res['40'] = sum_matched(report, /^[4][0-9A-Z]{2,}/)
209
+ report['9142'] = (report['9142'] || BigDecimal('0')) + res['HA']
210
+ res['9142'] = report['9142']
211
+ res['10'] = sum_matched(report, /^[12][0-9A-Z]{2,}/)
212
+ jp_4v = sum_matched(report, /^[4][V]{2,}/) # deferred assets for JP GAAP
213
+ res['30'] = sum_matched(report, /^[34][0-9A-Z]{2,}/) - jp_4v
214
+ res['4V'] = jp_4v if CONFIG['country'] == 'jp'
193
215
  res['50'] = sum_matched(report, /^[56][0-9A-Z]{2,}/)
194
216
  res['70'] = sum_matched(report, /^[78][0-9A-Z]{2,}/)
217
+ res['91'] = sum_matched(report, /^91[0-9A-Z]{1,}/)
195
218
  res['8ZZ'] = res['50'] + res['70']
196
219
  res['9ZZ'] = sum_matched(report, /^[9][0-9A-Z]{2,}/)
197
220
 
198
- res['1'] = res['10'] + res['40']
199
- res['5'] = res['8ZZ'] + res['9ZZ'] + res['HA']
221
+ res['1'] = res['10'] + res['30']
222
+ res['5'] = res['8ZZ'] + res['9ZZ']
200
223
  res['_d'] = report['_d']
201
224
 
225
+ report.each do |k, v|
226
+ res[k] ||= sum_matched(report, /^#{k}[0-9A-Z]{1,}/) if k.length == 2
227
+ res[k] = v if k.length == 3
228
+ end
229
+
202
230
  report.each do |k, v|
203
231
  if k.length >= 4
204
232
  if res[k[0, 3]]
@@ -219,10 +247,25 @@ module LucaBook
219
247
  end
220
248
 
221
249
  def set_balance
250
+ pre_last = @start_date.prev_month
251
+ start_year = if @start_date.month > CONFIG['fy_start'].to_i
252
+ pre_last.year
253
+ else
254
+ pre_last.year - 1
255
+ end
256
+ pre = self.class.accumulate_term(start_year, CONFIG['fy_start'], pre_last.year, pre_last.month)
257
+
222
258
  base = Dict.latest_balance.each_with_object({}) do |(k, v), h|
223
- h[k] = v[:balance].to_i if v[:balance]
259
+ h[k] = BigDecimal(v[:balance].to_s) if v[:balance]
260
+ h[k] ||= BigDecimal('0') if k.length == 2
224
261
  end
225
- code_sum(base).merge(self.class.total_subaccount(base))
262
+ if pre
263
+ idx = (pre.keys + base.keys).uniq
264
+ base = {}.tap do |h|
265
+ idx.each { |k| h[k] = (base[k] || BigDecimal('0')) + (pre[k] || BigDecimal('0')) }
266
+ end
267
+ end
268
+ self.class.total_subaccount(base)
226
269
  end
227
270
 
228
271
  def self.sum_matched(report, reg)
@@ -230,39 +273,49 @@ module LucaBook
230
273
  end
231
274
 
232
275
  # for assert purpose
233
- def self.gross(year, month = nil, code = nil, date_range = nil, rows = 4)
276
+ #
277
+ def self.gross(start_year, start_month, end_year = nil, end_month = nil, code: nil, date_range: nil, rows: 4)
234
278
  if ! date_range.nil?
235
279
  raise if date_range.class != Range
236
280
  # TODO: date based range search
237
281
  end
238
282
 
283
+ end_year ||= start_year
284
+ end_month ||= start_month
239
285
  sum = { debit: {}, credit: {}, debit_count: {}, credit_count: {} }
240
286
  idx_memo = []
241
- asof(year, month) do |f, _path|
287
+ term(start_year, start_month, end_year, end_month, code) do |f, _path|
242
288
  CSV.new(f, headers: false, col_sep: "\t", encoding: 'UTF-8')
243
289
  .each_with_index do |row, i|
244
290
  break if i >= rows
291
+
245
292
  case i
246
293
  when 0
247
294
  idx_memo = row.map(&:to_s)
295
+ next if code && !idx_memo.include?(code)
296
+
248
297
  idx_memo.each do |r|
249
- sum[:debit][r] ||= 0
298
+ sum[:debit][r] ||= BigDecimal('0')
250
299
  sum[:debit_count][r] ||= 0
251
300
  end
252
301
  when 1
302
+ next if code && !idx_memo.include?(code)
303
+
253
304
  row.each_with_index do |r, j|
254
- sum[:debit][idx_memo[j]] += r.to_i # TODO: bigdecimal support
305
+ sum[:debit][idx_memo[j]] += BigDecimal(r.to_s)
255
306
  sum[:debit_count][idx_memo[j]] += 1
256
307
  end
257
308
  when 2
258
309
  idx_memo = row.map(&:to_s)
310
+ break if code && !idx_memo.include?(code)
311
+
259
312
  idx_memo.each do |r|
260
- sum[:credit][r] ||= 0
313
+ sum[:credit][r] ||= BigDecimal('0')
261
314
  sum[:credit_count][r] ||= 0
262
315
  end
263
316
  when 3
264
317
  row.each_with_index do |r, j|
265
- sum[:credit][idx_memo[j]] += r.to_i # TODO: bigdecimal support
318
+ sum[:credit][idx_memo[j]] += BigDecimal(r.to_s)
266
319
  sum[:credit_count][idx_memo[j]] += 1
267
320
  end
268
321
  else
@@ -270,49 +323,39 @@ module LucaBook
270
323
  end
271
324
  end
272
325
  end
326
+ if code
327
+ sum[:debit] = sum[:debit][code] || BigDecimal('0')
328
+ sum[:credit] = sum[:credit][code] || BigDecimal('0')
329
+ sum[:debit_count] = sum[:debit_count][code] || 0
330
+ sum[:credit_count] = sum[:credit_count][code] || 0
331
+ end
273
332
  sum
274
333
  end
275
334
 
276
335
  # netting vouchers in specified term
277
- def self.net(year, month = nil, code = nil, date_range = nil)
278
- g = gross(year, month, code, date_range)
336
+ #
337
+ def self.net(start_year, start_month, end_year = nil, end_month = nil, code: nil, date_range: nil)
338
+ g = gross(start_year, start_month, end_year, end_month, code: code, date_range: date_range)
279
339
  idx = (g[:debit].keys + g[:credit].keys).uniq.sort
280
340
  count = {}
281
341
  diff = {}.tap do |sum|
282
342
  idx.each do |code|
283
- sum[code] = g.dig(:debit, code).nil? ? 0 : Util.calc_diff(g[:debit][code], code)
284
- sum[code] -= g.dig(:credit, code).nil? ? 0 : Util.calc_diff(g[:credit][code], code)
343
+ sum[code] = g.dig(:debit, code).nil? ? BigDecimal('0') : Util.calc_diff(g[:debit][code], code)
344
+ sum[code] -= g.dig(:credit, code).nil? ? BigDecimal('0') : Util.calc_diff(g[:credit][code], code)
285
345
  count[code] = (g.dig(:debit_count, code) || 0) + (g.dig(:credit_count, code) || 0)
286
346
  end
287
347
  end
288
348
  [diff, count]
289
349
  end
290
350
 
291
- # TODO: replace load_tsv -> generic load_tsv_dict
292
- def load_start
293
- file = Pathname(LucaSupport::Config::Pjdir) / 'data' / 'balance' / 'start.tsv'
294
- {}.tap do |dic|
295
- load_tsv(file) do |row|
296
- dic[row[0]] = row[2].to_i if ! row[2].nil?
297
- end
298
- end
299
- end
300
-
301
- def load_tsv(path)
302
- return enum_for(:load_tsv, path) unless block_given?
303
-
304
- data = CSV.read(path, headers: true, col_sep: "\t", encoding: 'UTF-8')
305
- data.each { |row| yield row }
306
- end
307
-
308
351
  private
309
352
 
310
353
  def legal_items
311
- return [] unless LucaSupport::Config::COUNTRY
354
+ return [] unless CONFIG['country']
312
355
 
313
- case LucaSupport::Config::COUNTRY
356
+ case CONFIG['country']
314
357
  when 'jp'
315
- ['91', '911', '912', '913', '9131', '9132', '914', '9141', '9142', '915', '916', '92', '93']
358
+ ['31', '32', '33', '91', '911', '912', '913', '9131', '9132', '914', '9141', '9142', '915', '916', '92', '93']
316
359
  end
317
360
  end
318
361
  end