Okinawa.rb Advent Calendar 2017 1日目です。
https://qiita.com/advent-calendar/2017/okinawarb
沖縄県の各市町村の国民健康保険料の金額をRubyで計算します。
国民健康保険税
日本は国民皆保険制度なので国民全員がいずれかの公的医療保険制度に加入しています。1
市町村国保とは、他の医療保険に加入していない住民を被保険者とする国民皆保険制度の基礎です。2
国民健康保険料は国民健康保険税という税金として納める事が多いです。詳しくはWikipediaの国民健康保険税の記事3や、freeeさんの国民健康保険料の計算方法をわかりやすく解説|知っておきたい税の基本4を読んで下さい。
沖縄県の国民健康保険料
市町村が運営しているので自治体によって金額が違います。赤字なので保険料が高いです
国保、沖縄県内10市町村で保険料上昇予測 県は徴収料統一検討
http://www.okinawatimes.co.jp/articles/-/133399
沖縄戦の影響で全国と比べ前期高齢者(65~74歳)の割合が低く、前期高齢者の割合を基に算出される交付金が低いことが、国保財政の悪化につながっている。
https://ryukyushimpo.jp/news/entry-435651.html
計算方法
那覇市を例にします。以下の3つの区分の合算です。
保険税の年税額は、医療分と支援分と介護分(40歳~64歳の方)の合算額です。医療分と支援分と介護分はそれぞれ別々に計算されます。
http://www.city.naha.okinawa.jp/kakuka/kokuhotyoujyu/hokenzeinoufu.html
65歳からは介護分は掛かりませんが、介護保険料が別途掛かります(また、75歳からは国保ではなく後期高齢者医療制度に加入することになります)。
那覇市の場合はそれぞれの分について以下の3つを計算していきます。
- 所得割: 所得×税率
- 均等割: 加入者数×◯円
- 平等割: 世帯あたり◯円
自治体によっては所得割、均等割、平等割の他に資産割があったりします。その場合固定資産税×税率を計算します。
実装
計算機の初期化
国保は世帯ごとに請求されるので計算機の引数で国保に加入する世帯の構成員を取ります。詳しくは擬制世帯でググってください。
class JapaneseNationalHealthInsuranceCalculator
def initialize(household)
@household = household
end
end
初期化する際に引数で渡す世帯の構成員を定義してみましょう。
国保税を計算するためには以下の情報が取れる必要があります。
- 介護分の計算: 年齢
- 所得割の計算: 所得
- 資産割の計算: 固定資産税額
それに加え、介護分が必要な年齢か調べるメソッドも追加しましょう
class HouseholdMember < Struct.new(:age, :income, :fixed_assets_tax)
def long_term_care_insurance_premium?
(40...65).cover?(age)
end
end
これで以下のように世帯を渡して国民健康保険料の計算機を初期化できるようになりました。
household = [
HouseholdMember.new(27, 2472120, 0),
HouseholdMember.new(29, 0, 0),
HouseholdMember.new(0, 0, 0)
]
calculator = JapaneseNationalHealthInsuranceCalculator.new(household)
国民健康保険料の計算
国民健康保険料の計算について、以下3つの金額の合計なので定義は簡単です。
- 医療分
- 支援分
- 介護分
class JapaneseNationalHealthInsuranceCalculator
def calculate
medical_insurance_premium + medical_care_assistance + long_term_care_insurance_premium
end
end
問題は自治体によって、所得割・資産割の税率や均等割・平等割の金額が変わること、資産割がある/ないが変わることです。
- 所得割: 所得×税率
- 均等割: 加入者数×◯円
- 平等割: 世帯あたり◯円
- 資産割: 固定資産税×税率
部分ごとの計算機をつくる
以下の4種類の計算機を作りましょう。
- 所得割
- 均等割
- 平等割
- 資産割
それぞれの計算機に以下の3つを計算するAPIを実装します。
- 医療分
- 支援分
- 介護分
例えば所得割の場合、以下のように所得割の税率を引数で受け取るようにすると、自治体ごとに個別の計算機を作る必要がなくなるので便利でしょう。
class IncomeLevyCalculator < Struct.new(:household_member, :medical_insurance_premium_ratio, :medical_care_assistance_ratio, :long_term_care_insurance_premium_ratio)
def medical_insurance_premium
income * medical_insurance_premium_ratio
end
def medical_care_assistance
income * medical_care_assistance_ratio
end
def long_term_care_insurance_premium
if household_member.long_term_care_insurance_premium?
income * long_term_care_insurance_ratio
else
0
end
end
private
def income
[household_member.income - basic_deduction, 0].max
end
def basic_deduction
330_000
end
end
同じような感じで他の計算機も作ります。
# 均等割
class PerCapitaBasisLevyCalculator < Struct.new(:medical_insurance_premium, :medical_care_assistance, :long_term_care_insurance_premium)
end
# 平等割
class FlatLevyCalculator < Struct.new(:medical_insurance_premium, :medical_care_assistance, :long_term_care_insurance_premium)
end
# 資産割
class PropertyLevyCalculator
def initialize(fixed_assets_tax, medical_insurance_premium_ratio, medical_care_assistance_ratio, long_term_care_insurance_premium_ratio)
@fixed_assets_tax = fixed_assets_tax
@medical_insurance_premium_ratio = medical_insurance_premium_ratio
@medical_care_assistance_ratio = medical_care_assistance_ratio
@long_term_care_insurance_premium_ratio = long_term_care_insurance_premium_ratio
end
def medical_insurance_premium
@medical_insurance_premium_ratio * @fixed_assets_tax
end
def medical_care_assistance
@medical_care_assistance_ratio * @fixed_assets_tax
end
def long_term_care_insurance_premium
@long_term_care_insurance_ratio * @fixed_assets_tax
end
end
計算機を組み合わせる
それぞれの市町村に必要な計算機を作ります。
例えば那覇市の場合
所得割
医療分 | 支援分 | 介護分 |
---|---|---|
9.70% | 1.59% | 1.56% |
均等割
医療分 | 支援分 | 介護分 |
---|---|---|
18,200 | 3,300 | 7,700 |
平等割
医療分 | 支援分 | 介護分 |
---|---|---|
25,400 | 5,300 | 4,600 |
なので以下のような組み合わせです。
calculators = [
household.map { |household_member| IncomeLevyCalculator.new(household_member, 970/10000r, 159/10000r, 156/10000r) },
PerCapitaBasisLevyCalculator.new(household, 18_200, 3_300, 7_700),
FlatLevyCalculator.new(household, 25_400, 5_300, 4_600)
].flatten
国保計算機にこれらの子計算機を入れられるようにします。
class JapaneseNationalHealthInsuranceCalculator
attr_accessor :calculators
end
calculator.calculators = calculators
子計算機を使って計算するようメソッドを定義します。
class JapaneseNationalHealthInsuranceCalculator
def medical_insurance_premium
calculators.sum(&:medical_insurance_premium)
end
def medical_care_assistance
calculators.sum(&:medical_care_assistance)
end
def long_term_care_insurance_premium
calculators.sum(&:long_term_care_insurance_premium)
end
end
結果
puts calculator.calculate.to_i
# 337045
無事国民健康保険料が計算できました!
沖縄県の各市町村で計算してみる
資産のことを気にしなければさっきの要領で子計算機を作る処理を使いまわせます。
ググったりして以下のようなTSVのデータを用意します。自治体によってはウェブに保険料が載っていないのでとりあえず市だけ調べました。
tsv = <<TSV
那覇市 9.70% 1.59% 1.56% 18200 3300 7700 25400 5300 4600 http://www.city.naha.okinawa.jp/kakuka/kokuhotyoujyu/hokenzeinoufu.html
浦添市 8.20% 2.40% 2.40% 19000 7500 9500 17000 6000 6000 http://www.city.urasoe.lg.jp/docs/2014110102709/
南城市 6.70% 2.60% 1.90% 16700 7000 5900 18200 7000 4300 http://www.city.nanjo.okinawa.jp/life/insurance/kokuho.html
沖縄市 9.12% 2.27% 1.86% 19712 5312 5686 20919 5637 3927 https://www.city.okinawa.okinawa.jp/kurashi/365/2286
豊見城市 8.44% 2.61% 2.10% 17200 6200 6600 23200 5400 3700 http://www.city.tomigusuku.okinawa.jp/userfiles/files/health/2016bookall.pdf
宜野湾市 6.63% 2.75% 1.62% 14300 5200 3900 19500 7100 5100 http://www.city.ginowan.okinawa.jp/life/health/02/37447.html
糸満市 9.00% 1.50% 2.20% 16000 3700 6900 20000 5000 4700 30.00% 6.50% 5.10% http://www.city.itoman.lg.jp/docs/2013020102935/
うるま市 7.70% 2.50% 2.10% 14000 6500 7200 22000 6000 6000 http://www.city.uruma.lg.jp/kurashi/122/3149/492
宮古島市 8.35% 2.10% 2% 17500 4300 5000 15500 4000 3000 30% 7% 5.8 http://www.city.miyakojima.lg.jp/kurashi/kokumin/kenkouhoken/2017-0616-1306-81.html
石垣市 8.35% 2.20% 2.20% 18300 4300 6500 16600 5500 4000 19% 5% 4.20% http://www.city.ishigaki.okinawa.jp/home/shiminhokenbu/kenkouhoken/index.htm#p2
名護市 6.30% 2.70% 1.20% 14500 5900 4300 12500 5100 3600 20.00% 9.00% 4.00% http://www.city.nago.okinawa.jp/4/3835.html
TSV
おもむろにこねくり回す
puts "自治体 | 国保料"
puts "--- | ---"
tsv.lines.map { |l| l.chomp.split("\t") }.each do |row|
local_gov = row[0]
income_lavy_ratios = row[1..3].map {|percentage| percentage.delete('.%').to_i / 10000r }
per_capita_basis = row[4..6].map(&:to_i)
flat = row[7..9].map(&:to_i)
calculator.calculators = [
household.map { |household_member| IncomeLevyCalculator.new(household_member, *income_lavy_ratios) },
PerCapitaBasisLevyCalculator.new(household, *per_capita_basis),
FlatLevyCalculator.new(household, *flat)
].flatten
tax = calculator.calculate.to_i
puts "[#{local_gov}](#{row[13]}) | #{tax}"
end
はい
自治体 | 国保料 |
---|---|
那覇市 | 337045 |
浦添市 | 329564 |
南城市 | 295517 |
沖縄市 | 345615 |
豊見城市 | 335504 |
宜野湾市 | 286030 |
糸満市 | 309022 |
うるま市 | 307996 |
宮古島市 | 308751 |
石垣市 | 315893 |
名護市 | 271590 |
まとめ
- Rubyを使うと国保税が計算できてべんり
- 沖縄の国保税意外と高い
明日の記事はあっとんさんです。
コード
class JapaneseNationalHealthInsuranceCalculator
attr_accessor :calculators
def initialize(household)
@household = household
end
def calculate
medical_insurance_premium + medical_care_assistance + long_term_care_insurance_premium
end
def medical_insurance_premium
calculators.sum(&:medical_insurance_premium)
end
def medical_care_assistance
calculators.sum(&:medical_care_assistance)
end
def long_term_care_insurance_premium
calculators.sum(&:long_term_care_insurance_premium)
end
end
class HouseholdMember < Struct.new(:age, :income, :fixed_assets_tax)
def long_term_care_insurance_premium?
(40...65).cover?(age)
end
end
class IncomeLevyCalculator < Struct.new(:household_member, :medical_insurance_premium_ratio, :medical_care_assistance_ratio, :long_term_care_insurance_premium_ratio)
def medical_insurance_premium
income * medical_insurance_premium_ratio
end
def medical_care_assistance
income * medical_care_assistance_ratio
end
def long_term_care_insurance_premium
if household_member.long_term_care_insurance_premium?
income * long_term_care_insurance_ratio
else
0
end
end
private
def income
[household_member.income - basic_deduction, 0].max
end
def basic_deduction
330_000
end
end
# 均等割
class PerCapitaBasisLevyCalculator < Struct.new(:household_members, :medical_insurance_premium, :medical_care_assistance, :long_term_care_insurance_premium)
def medical_insurance_premium
super * household_member_num
end
def medical_care_assistance
super * household_member_num
end
def long_term_care_insurance_premium
super * long_term_care_insurance_premium_member_num
end
private
def household_member_num
household_members.size
end
def long_term_care_insurance_premium_member_num
household_members.select(&:long_term_care_insurance_premium?).size
end
end
# 平等割
class FlatLevyCalculator < Struct.new(:household_members, :medical_insurance_premium, :medical_care_assistance, :long_term_care_insurance_premium)
def long_term_care_insurance_premium
if household_members.any?(&:long_term_care_insurance_premium?)
super
else
0
end
end
end
# 資産割
class PropertyLevyCalculator < Struct.new(:household_members, :fixed_assets_tax, :medical_insurance_premium_ratio, :medical_care_assistance_ratio, :long_term_care_insurance_premium_ratio)
def medical_insurance_premium
@medical_insurance_premium_ratio * @fixed_assets_tax
end
def medical_care_assistance
@medical_care_assistance_ratio * @fixed_assets_tax
end
def long_term_care_insurance_premium
if household_members.any?(&:long_term_care_insurance_premium?)
@long_term_care_insurance_ratio * @fixed_assets_tax
else
0
end
end
end
household = [
HouseholdMember.new(27, 2472120, 0),
HouseholdMember.new(29, 0, 0),
HouseholdMember.new(0, 0, 0)
]
calculator = JapaneseNationalHealthInsuranceCalculator.new(household)
tsv = <<TSV
那覇市 9.70% 1.59% 1.56% 18200 3300 7700 25400 5300 4600 http://www.city.naha.okinawa.jp/kakuka/kokuhotyoujyu/hokenzeinoufu.html
浦添市 8.20% 2.40% 2.40% 19000 7500 9500 17000 6000 6000 http://www.city.urasoe.lg.jp/docs/2014110102709/
南城市 6.70% 2.60% 1.90% 16700 7000 5900 18200 7000 4300 http://www.city.nanjo.okinawa.jp/life/insurance/kokuho.html
沖縄市 9.12% 2.27% 1.86% 19712 5312 5686 20919 5637 3927 https://www.city.okinawa.okinawa.jp/kurashi/365/2286
豊見城市 8.44% 2.61% 2.10% 17200 6200 6600 23200 5400 3700 http://www.city.tomigusuku.okinawa.jp/userfiles/files/health/2016bookall.pdf
宜野湾市 6.63% 2.75% 1.62% 14300 5200 3900 19500 7100 5100 http://www.city.ginowan.okinawa.jp/life/health/02/37447.html
糸満市 9.00% 1.50% 2.20% 16000 3700 6900 20000 5000 4700 30.00% 6.50% 5.10% http://www.city.itoman.lg.jp/docs/2013020102935/
うるま市 7.70% 2.50% 2.10% 14000 6500 7200 22000 6000 6000 http://www.city.uruma.lg.jp/kurashi/122/3149/492
宮古島市 8.35% 2.10% 2% 17500 4300 5000 15500 4000 3000 30% 7% 5.8 http://www.city.miyakojima.lg.jp/kurashi/kokumin/kenkouhoken/2017-0616-1306-81.html
石垣市 8.35% 2.20% 2.20% 18300 4300 6500 16600 5500 4000 19% 5% 4.20% http://www.city.ishigaki.okinawa.jp/home/shiminhokenbu/kenkouhoken/index.htm#p2
名護市 6.30% 2.70% 1.20% 14500 5900 4300 12500 5100 3600 20.00% 9.00% 4.00% http://www.city.nago.okinawa.jp/4/3835.html
TSV
puts "自治体 | 国保料"
puts "--- | ---"
tsv.lines.map { |l| l.chomp.split("\t") }.each do |row|
local_gov = row[0]
income_lavy_ratios = row[1..3].map {|percentage| percentage.delete('.%').to_i / 10000r }
per_capita_basis = row[4..6].map(&:to_i)
flat = row[7..9].map(&:to_i)
calculator.calculators = [
household.map { |household_member| IncomeLevyCalculator.new(household_member, *income_lavy_ratios) },
PerCapitaBasisLevyCalculator.new(household, *per_capita_basis),
FlatLevyCalculator.new(household, *flat)
].flatten
tax = calculator.calculate.to_i
puts "[#{local_gov}](#{row[13]}) | #{tax}"
end
脚注
-
http://www.mhlw.go.jp/houdou_kouhou/kouhou_shuppan/pdf/2015-jimu_13.pdf ↩
-
http://www.mhlw.go.jp/stf/seisakunitsuite/bunya/kenkou_iryou/iryouhoken/iryouhoken01/index.html ↩
-
https://ja.wikipedia.org/wiki/%E5%9B%BD%E6%B0%91%E5%81%A5%E5%BA%B7%E4%BF%9D%E9%99%BA%E7%A8%8E ↩
-
固定資産がある人はcalculators設定まわり直して下さい ↩
-
実際は10期に支払いが分かれていたり年度中に年齢が変わる場合やx円未満切り捨てなどでもっと計算が難しい ↩