Webエンジニア向けプログラミング解説動画をYouTubeで配信中!
▶ チャンネル登録はこちら

【ITニュース解説】Building FoxyInvoice — Chapter 5: The domain — invoices, tax, and money math

2026年09月21日に「Dev.to」が公開したITニュース「Building FoxyInvoice — Chapter 5: The domain — invoices, tax, and money math」について初心者にもわかりやすく解説しています。

作成日: 更新日:

ITニュース概要

FoxyInvoiceのドメインロジックは、請求書の状態管理、複雑な税金計算、見積もりから請求書への変換、支払い処理を扱う。会計士向けの多様なエクスポート機能も備え、金額計算はサーバーで厳密に行い、システムの信頼性を高める。

ITニュース解説

ソフトウェア開発において、「ドメイン」とは、そのシステムが解決するビジネス上の問題を指す。例えば、請求書がどのようなものか、税金がいつ適用されるか、見積もりがどう請求書になるかといった、紙ベースの業務でも変わらない核となるルールや概念のことだ。このドメインのロジックを正確に設計することは、ウェブ、共有リンク、データ出力ファイルなど、どんな形式でシステムとやり取りしても、常に一貫した真実を提供するために非常に重要となる。FoxyInvoiceの開発では、このドメインロジックに最も多くの本格的なエンジニアリングの努力が注がれている。

請求書のライフサイクルは「ステートマシン」として表現される。これは、請求書が「下書き」から始まり、「送信済み」となり、その後「支払い済み」「一部支払い」「期限超過」のいずれか、または「無効」という状態に遷移する流れだ。見積もりは、顧客に承認されると正式な請求書に変換される。システムは状態数を少なく保つよう設計されており、これによりユーザーインターフェースやサポートの複雑さを軽減している。「期限超過」は、データベースに直接保存される状態ではなく、日次処理によって期限を過ぎた「送信済み」の請求書から自動的に判断される。この処理は、期限前や期限超過後にリマインダーを自動送信するトリガーにもなる。返金や調整のためには「クレジットノート」という種類の請求書も存在する。

このステートマシンには二つの重要な「不変条件」がある。一つは、請求書の合計金額は常にサーバー側で計算され管理される点だ。ブラウザで表示される金額はプレビューであり、クライアントから送られる合計金額は信頼されない。請求書の内容が変更されるたびに、明細項目から税金計算エンジンを経て、合計金額がすべて再計算される。これにより、クライアントが誤った合計金額を送ってもシステムに影響はない。二つ目は、「編集期間」だ。請求書は特定の状態遷移後、一定期間(デフォルト24時間)経過すると編集がロックされる。これは、会計システムが過去の記録の変更を好まないため、履歴の整合性を保つための仕組みである。

税金計算は、特に米国の消費税のような複雑なシステムでは、単純な税率カラムでは対応できないため、「税金エンジン」が必要となる。消費税を徴収するかどうかは、事業者が「ネクサス」(納税義務が生じる拠点)を持っているか、顧客がどの「管轄区域」にいるか、そして販売物が「サービス」か「商品」か、課税対象か非課税か、といった複数の要因で決まる。税金エンジンは、これらのルールを明細項目ごとに評価する。まず顧客が免税か、次に事業者が顧客の管轄区域にネクサスがあるかを確認し、なければ税金は徴収されない。その管轄区域の税率が既知か、製品タイプに固有の課税ルールがあるかを確認し適用する。適用される税率は明細の合計に乗算され、最終的な税額はセント単位で丸められる。この計算は常に正確な金額計算(decimal)で行われる。管轄区域は、納税報告のために州、郡、市といった詳細な内訳を持つ。この税金計算機は、外部との入出力がない「純粋関数」として設計されており、システム内で最もテストが徹底されている部分の一つだ。

見積もりは、タイプが「Quote」であること以外は請求書と同じ計算ロジックとデータ構造を持つ。顧客が見積もりを承認すると、その内容は正式な請求書に変換される。具体的には、見積もりのヘッダー情報と明細が新しい「下書き」状態の請求書に複製される。この際、新しい請求書番号がシステムのシーケンスから排他的に割り当てられる。変換後、元の見積もりは二重変換を防ぐために無効化される。顧客向けには「承認」または「拒否」ボタン付きの共有リンクが提供され、承認されるとサーバー側でこの変換処理が実行され、同時にオーナーへ通知される。

支払いの受け付けには二つの方法がある。一つは「オンライン支払い」だ。各請求書にはStripeの支払いリンクが紐付けられており、顧客が支払いを完了すると、Stripeからのウェブフックによって支払い情報が自動記録され、請求書の状態が更新される。この際、顧客のクレジットカード情報がFoxyInvoiceのサーバーに触れることはない。もう一つは「オフライン支払い」だ。これは手動で支払いを記録する方法か、または専用のメールアドレスに支払い通知を送る方法がある。後者の場合、受信したメールはシステムが解析し、最終的に人間が内容を確認して承認することで、会計帳簿に記録される。この「機械が提案し、人間が最終確認を行う」という原則は、金銭に関わる処理において信頼性を高めるために非常に重要だ。

定期的に発生する請求書については、「定期請求書」機能が提供される。これは、テンプレートとスケジュールに基づいて、ワーカーが定期的に「下書き」状態の請求書を自動生成する。生成された請求書は、通常の請求書と同様に税金エンジンを通って計算され、自動送信も可能だ。既存の請求書作成パスを再利用するため、合計金額のサーバー管理や編集期間といった不変条件が、この定期請求書にも自動的に適用される。

経理担当者への「エクスポート」機能は、請求書製品が実用的なツールであるために不可欠だ。FoxyInvoiceは現在、CSV、QuickBooks IIF(会計の借方と貸方がゼロになる必要あり)、インド向けのTally XML形式(各伝票がバランスする必要あり)の三つの形式に対応している。各ワークスペースにはエクスポートプロファイルが設定されており、国、納税者登録番号、地域に合わせたラベル、会計年度の開始日などが含まれる。これにより、例えばインド向けのPDF請求書では、「GSTIN: 27ABCDE…」と自動表示され、手動設定は不要となる。エクスポート機能の開発を通じて、会計士が抱える問題は、数学的な計算よりもデータフォーマットの問題であることが多いと理解されている。

金額の扱いは、システム全体で非常に精密に行われる。すべての金額は、通貨情報とともに「decimal」型として扱われる。異なる通貨間での直接的な算術演算はエラーとなる。請求書の合計金額は、個々の明細のdecimal値を集計したものだ。丸め処理は、小計、税金、合計といった各段階で一度だけ、セント単位で、固定された順序で行われる。この丸め処理の順序は、会計士との間で取り決められた「API契約」の一部であり、正確な会計処理を保証するために非常に重要だ。

関連コンテンツ

関連IT用語

関連ITニュース