Raycastの拡張機能を作ってみよう（個人事業主の源泉徴収額を計算する）

Raycastを使っているプログラマであれば、拡張機能を作ってみたいと思う人は多いはず。
公開されている拡張機能の多くは高機能で、自分が作るのは難しそう…と感じているかもしれません。

でも、公開しなくても自分が便利な機能を作って、自分だけが使ってもいいんです。
今回は私が作っている拡張機能の例を紹介します。

この記事は[Raycast Advent Calendar 2024](https://qiita.com/advent-calendar/2024/raycast)に参加しています。
昨日は [@mikkegt](https://qiita.com/mikkegt) さんの『[RaycastでGoパッケージをサクッと検索！「Go Package Search」](https://greentown.tokyo/?p=6783)』でした。

# 今回作る拡張機能

ITエンジニアとして仕事をしていると、記事の執筆を依頼されたり、セミナーで登壇することを求められたりすることがあります。
個人事業主が原稿料や講演料を受け取るときには、請求書を発行するときに源泉徴収しなければなりません。
参考）https://www.nta.go.jp/taxes/shiraberu/taxanswer/gensen/2795.htm

そして、この源泉徴収の金額は、上記の国税庁のサイトに記載されている通り、次のように計算します。

| 支払金額（＝A） | 税額 |
| -- | -- |
| 100万円以下 | A×10.21％ |
| 100万円超 | （A-100万円）×20.42％＋102,100円 |

なお、求めた税額に1円未満の端数があるときは、これを切り捨てます。
それほど複雑な計算ではありませんが、これに加えて消費税を計算して請求書を発行します。

たとえば、10万円の請求書を発行する場合、次のように計算します。

| 項目 | 金額 |
| -- | --: |
| 原稿料 | 100,000円 |
| 消費税 | 10,000円 |
| 源泉徴収税額 | 10,210円 |
| 請求金額 | 99,790円 |

Excelなどで計算式を用意しておいても構いませんが、税抜きの金額からすぐに計算できると便利です。

# Raycastの標準機能で計算する

このようなちょっとした計算にRaycastは便利です。
標準で計算機能が用意されていますので、Raycastを起動して計算式を入力するだけです。

たとえば、10万円の請求に対する源泉徴収税額を計算するのであれば、
「100000*10.21/100」
と入力するだけです。

![計算機能](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309006/1840c511-b26f-fa55-a5f4-06f6ef3f1b47.png)

100万円を超えたときも、上記の計算式を入力すれば計算できます。
また、消費税も同じように計算できます。

でも、それぞれを個別に計算するのは面倒です。
税率も覚えておかないといけません。

そこで、もっと簡単に計算できるようにすることを考えます。

# Raycastの拡張機能を作る

こんなときに便利なのがRaycastの拡張機能です。
JavaScript（TypeScript）を使ってReactのプログラムを記述すると、独自の機能を作成できます。

ここでは、次の図のような拡張機能を作ります。
Raycastから税抜の金額を入力すると、消費税と源泉徴収税額、合計金額を計算してくれる機能です。

- 入力画面

![入力画面](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309006/46f6966f-97c9-a00d-8be6-afc055400cda.png)

- 計算結果画面

![計算結果](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309006/76b1b336-4bd9-6d21-3d4c-ac274b811b8a.png)

実際に作ってみましょう。

## 手順1）「Create Extension」を実行する

まずはRaycastから拡張機能のベースとなるものを作成します。
これは、Raycastで「Create Extension」というコマンドを実行するだけです。

![create extension](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309006/5d6830b6-c9b9-37a4-a237-e00588e7f904.png)

## 手順2）実行を試す

作成されたら、そのディレクトリを開いて、次のコマンドを実行します（事前に`npm`（Node.js）はインストールしておいてください）。

```sh
$ npm install
```

これで、必要なモジュールが導入されます。そして、次のコマンドを実行して、Raycastでの動作を確認します。

```sh
$ npm run dev
```

## 手順3）package.jsonを編集する

問題なく実行されることを確認できれば、「`package.json`」にてコマンドの情報を設定します。
たとえば、次のように記述すると、「`CalcTax`」というコマンドで源泉徴収を計算する画面を起動できるようになります。
この「`arguments`」がコマンドの引数で、ここに税抜の金額を入力できるようにしています。

```package.json
{
  ...
  "commands": [
    {
      "name": "index",
      "title": "CalcTax",
      "subtitle": "源泉徴収計算",
      "description": "消費税や源泉徴収を計算します。",
      "mode": "view",
      "arguments": [
        {
          "name": "param",
          "placeholder": "10000",
          "type": "text",
          "required": true
        }
      ]
    }
  ],
  ...
}
```

## 手順4）プログラムを変更する

上記の「`package.json`」の「`commands`」に指定した「`name`」に対応するTypeScriptのファイルが「`src`」ディレクトリにあります。
ここでは「`index`」という値を指定したので、「`index.tsx`」というファイルがあります。

![ts](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309006/1a6be8e8-2be2-2081-eb3a-81ec02fab17a.png)

このファイルをVS Codeなどのテキストエディタで編集します。

たとえば、次のようなプログラムを記述します。

```tsx
import { Action, ActionPanel, Detail, LaunchProps } from "@raycast/api";

export default function Command(props: LaunchProps<{ arguments: Arguments.MyCommand }>) {
  const { param } = props.arguments;
  let price = Math.floor(param);
  let tax = Math.floor(price * 0.1);
  let gensen = 0;
  if (price <= 1000000) {
    gensen = Math.floor(price * 10.21 / 100);
  } else {
    gensen = Math.floor((price - 1000000) * 20.42 / 100) + 102100;
  }
  let total = price + tax - gensen;
  let markdown = "# 計算結果\n\n" +
    "| 項目 | 金額 |\n" +
    "|:--|--:|\n" +
    "| 税抜 | &yen;" + price.toLocaleString() + " |\n" +
    "| 消費税 | &yen;" + tax.toLocaleString() + " |\n" +
    "| 源泉徴収税額 | &yen;" + gensen.toLocaleString() + " |\n" +
    "| 請求金額 | &yen;" + total.toLocaleString() + " |\n";
  return (
    <Detail
      markdown={markdown}
    />);
}
```

引数として指定した金額が「`props.arguments`」に入るので、これを「`param`」という変数で受け取っています。
そして、消費税や源泉徴収税額、合計額を計算し、Markdown形式でテーブルを作成しています。

最後に、これを表示しているだけです。

## 手順5）実行して結果を確認する

手順2と同様に、次のコマンドを実行して再度起動します。

```sh
$ npm run dev
```

実際に起動して税抜の金額を入力し、正しい結果が表示されることを確認します。

このようなプログラムを作っておくと、すぐに源泉徴収税額や請求金額を計算できます。

# まとめ

Raycastは拡張機能も手軽に作成できて便利です。
公開することを考えず、手元の環境で動かすだけであれば、上記のようにファイルを2つほど編集するだけで作成できます。

ReactやTypeScriptの勉強も含めて、便利な機能を作ってみてください。