1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

フリーランスの税金、毎年パニクるから自動計算ツール作った【Next.js】

1
Posted at

はじめに — 確定申告の季節が来るたびに胃が痛い

フリーランス2年目の確定申告で、自分は完全にパニックになった。

1年目は開業届を出すのが精一杯で、経費の仕分けもろくにやってなかった。いざ申告の時期になって「所得税ってどう計算するんだっけ」「住民税は?」「国保って所得で変わるの?」と調べ始めたら、計算式が4種類もあって頭がバグった。

所得税、住民税、個人事業税、国民健康保険。それぞれ計算ロジックが違うし、控除の種類も違う。しかも毎年微妙に税率や控除額が変わる。Excelで管理しようとして3回挫折した。

結局「もう自分で計算ツール作るしかない」と思い立って、Next.jsで税金シミュレーターを作った話を書く。

そもそも何を計算する必要があるのか

フリーランスが把握すべき税金・社会保険料は主に4つ。

項目 概要 計算の厄介さ
所得税 累進課税。課税所得に応じて5%〜45% 控除が多くて課税所得の算出が面倒
住民税 一律10%(都道府県4% + 市区町村6%)+ 均等割 所得税と控除額が微妙に違う
個人事業税 業種によって3〜5%。290万円の事業主控除あり 対象業種かどうかの判定が必要
国民健康保険 自治体ごとに料率が違う。所得割+均等割+平等割 自治体によって計算式がバラバラ

これを毎回手計算するのは現実的じゃない。特に「売上がこれくらいだったら手取りいくらになるのか」をサクッと知りたい場面が多い。見積もり段階で「この案件受けたら税金いくら増えるんだろう」とか。

計算ロジックの実装

所得税の累進課税テーブル

まず所得税。これが一番ややこしい。日本の所得税は超過累進税率で、課税所得の金額によって税率が段階的に上がる。

// 令和5年分以降の所得税率テーブル
interface TaxBracket {
  min: number;
  max: number;
  rate: number;
  deduction: number;
}

const INCOME_TAX_BRACKETS: TaxBracket[] = [
  { min: 0,         max: 1_949_999,   rate: 0.05, deduction: 0 },
  { min: 1_950_000, max: 3_299_999,   rate: 0.10, deduction: 97_500 },
  { min: 3_300_000, max: 6_949_999,   rate: 0.20, deduction: 427_500 },
  { min: 6_950_000, max: 8_999_999,   rate: 0.23, deduction: 636_000 },
  { min: 9_000_000, max: 17_999_999,  rate: 0.33, deduction: 1_536_000 },
  { min: 18_000_000, max: 39_999_999, rate: 0.40, deduction: 2_796_000 },
  { min: 40_000_000, max: Infinity,   rate: 0.45, deduction: 4_796_000 },
];

function calcIncomeTax(taxableIncome: number): number {
  if (taxableIncome <= 0) return 0;
  
  const bracket = INCOME_TAX_BRACKETS.find(
    b => taxableIncome >= b.min && taxableIncome <= b.max
  );
  
  if (!bracket) return 0;
  
  // 基本の所得税額
  const baseTax = Math.floor(taxableIncome * bracket.rate - bracket.deduction);
  
  // 復興特別所得税(2.1%)を加算
  const reconstructionTax = Math.floor(baseTax * 0.021);
  
  return baseTax + reconstructionTax;
}

ポイントは deduction(控除額)をテーブルに持たせているところ。超過累進課税は本来「各段階ごとに税額を計算して合算」するんだけど、控除額を使えば一発で計算できる。国税庁の速算表と同じ方式。

復興特別所得税の2.1%上乗せも忘れがち。2037年まで続く。

控除額の計算

課税所得を出すには、収入から経費と各種控除を引く必要がある。青色申告特別控除とか基礎控除とか、積み上げていく。

interface DeductionInput {
  revenue: number;           // 売上
  expenses: number;          // 経費
  blueFormDeduction: boolean; // 青色申告か
  iDeCoMonthly: number;      // iDeCo月額
  socialInsurance: number;    // 社会保険料(国保+年金)
  medicalExpenses: number;    // 医療費
  dependents: number;         // 扶養人数
}

function calcTaxableIncome(input: DeductionInput): number {
  const { revenue, expenses, blueFormDeduction, iDeCoMonthly, 
          socialInsurance, medicalExpenses, dependents } = input;
  
  // 事業所得
  const businessIncome = revenue - expenses;
  
  // 青色申告特別控除(e-Tax + 電子帳簿保存で65万)
  const blueDeduction = blueFormDeduction ? 650_000 : 0;
  
  // 基礎控除(合計所得2,400万以下で48万)
  const basicDeduction = businessIncome <= 24_000_000 ? 480_000 : 0;
  
  // 社会保険料控除(全額控除)
  const socialDeduction = socialInsurance;
  
  // 小規模企業共済等掛金控除(iDeCo)
  const iDeCoDeduction = iDeCoMonthly * 12;
  
  // 医療費控除(10万円超の部分、上限200万)
  const medicalDeduction = Math.min(
    Math.max(medicalExpenses - 100_000, 0),
    2_000_000
  );
  
  // 扶養控除(一般38万、特定63万は簡略化して38万で計算)
  const dependentDeduction = dependents * 380_000;
  
  const totalDeductions = blueDeduction + basicDeduction + socialDeduction 
    + iDeCoDeduction + medicalDeduction + dependentDeduction;
  
  // 課税所得(1,000円未満切り捨て)
  return Math.max(
    Math.floor((businessIncome - totalDeductions) / 1000) * 1000,
    0
  );
}

実務上は配偶者控除や生命保険料控除とか他にもあるんだけど、フリーランスが「ざっくり手取りを知りたい」レベルなら上の項目でだいたいカバーできる。

住民税・事業税・国保の計算

住民税は所得税と似てるけど、控除額が微妙に違う(基礎控除が43万円など)。個人事業税は290万円の事業主控除がある。国保は自治体によって全然違うので、東京23区のデフォルト値を入れつつ、料率をカスタマイズできるようにした。

function calcResidentTax(taxableIncome: number): number {
  // 住民税の課税所得は控除額が所得税と異なるが、
  // ここでは簡略化して所得税の課税所得を流用
  const incomePortion = Math.floor(taxableIncome * 0.10);
  const equalPortion = 5_000; // 均等割(標準税率)
  return incomePortion + equalPortion;
}

function calcBusinessTax(businessIncome: number, taxRate: number = 0.05): number {
  // 事業主控除290万円
  const taxable = Math.max(businessIncome - 2_900_000, 0);
  return Math.floor(taxable * taxRate);
}

function calcNationalHealthInsurance(
  businessIncome: number,
  rates: { medical: number; support: number; care: number } = {
    medical: 0.0786,  // 医療分(東京23区の例)
    support: 0.0270,  // 後期高齢者支援金分
    care: 0.0222,     // 介護分(40-64歳のみ)
  },
  includeCarePortion: boolean = false
): number {
  const base = Math.max(businessIncome - 430_000, 0); // 基礎控除43万
  
  let total = Math.floor(base * rates.medical) + Math.floor(base * rates.support);
  if (includeCarePortion) {
    total += Math.floor(base * rates.care);
  }
  
  // 均等割(世帯人数1人の場合の概算)
  total += 52_000 + 17_400;
  if (includeCarePortion) total += 17_000;
  
  return total;
}

UIの設計思想

計算ロジックができたら、あとはUIの話。自分が欲しかったのは「数字を入れたらリアルタイムで結果が変わる」体験。ページ遷移とか送信ボタンとか要らない。

売上のスライダーを動かすと、所得税・住民税・事業税・国保がリアルタイムに計算されて、最終的な手取り額が表示される。経費率も調整できるようにした。

フリーランス仲間に使ってもらったら「見積もり出す前にこれで手取り計算してから単価決めてる」という使い方をしてる人がいて、それは想定外だった。確かに「月50万の案件」と言われて、実際の手取りがいくらになるかパッと計算できると便利。

作ってみて気づいたこと

税金の計算ロジック自体はそこまで複雑じゃない。面倒なのは「どの控除が自分に適用されるか」の判断と、「自治体ごとに違う国保の料率」の対応。

国保については、主要都市の料率をプリセットとして持たせて、それ以外はユーザーが手入力できるようにした。全自治体分のデータを持つのは現実的じゃないので。

あと、税制改正への対応が地味にコストかかる。毎年12月に翌年の税制大綱が出るので、年末年始にテーブルを更新する必要がある。これは仕方ない。

ツールは tax.mildsolt.jp で公開している。売上と経費を入れるだけで4種類の税金が自動計算される。自分と同じように確定申告で苦しんでるフリーランスの役に立てば嬉しい。

まとめ

  • フリーランスの税金計算は4種類(所得税・住民税・事業税・国保)
  • 超過累進課税は控除額テーブルで一発計算できる
  • 国保は自治体ごとに料率が違うのが最大の罠
  • リアルタイム計算UIにすると実用性が跳ね上がる

「自分の税金は自分で把握したい」というフリーランスの方は、tax.mildsolt.jp を試してみてほしい。見積もり前の手取りシミュレーションにも使える。

ソースコードはGitHubで公開してるので、税制改正に合わせてPR送ってくれる人がいたら助かる。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?