取引相手(Counterparty)モデルを追加
インボイス制度対応のため、取引相手を管理する Counterparty モデルを追加した。
適格請求書発行事業者かどうかで経費の仕入税額控除が変わるので、取引相手ごとに登録番号と適格事業者かどうかを持たせておきたい。
BusinessUnit に紐づけて、取引相手ごとに名前・登録番号・適格事業者フラグ・メモを管理する。
Transaction に counterparty_id を追加し、どの取引が誰との取引かを紐づけられるようにした。
適格事業者の履歴管理
適格事業者かどうかを単純な boolean で持たせていたが、これだと「いつからその区分になったか」が分からないことに気づいた。
取引相手の適格事業者区分は、登録・失効のタイミングで年度の途中に変わることがある。過去の取引を見返したときに「その時点でどうだったか」を再現できないと、正しく仕入税額控除の判定ができない。
なので、状態そのもの(boolean)を持たせるのではなく、履歴として管理する方針に変更した。
区分は「不明」「適格」「非適格」の3つ。取引相手を登録した時点ではまだ分からないことが多いので、初期状態は「不明」にしておき、あとから確定したタイミングで履歴を追加していく。
履歴には「いつから有効か」と「実際にいつ記録したか」の2つの日付を持たせている。これは、リアルタイムで区分が変わった場合と、あとから過去に遡って訂正した場合を区別できるようにするため。
Counterparty の状態が変わるとき、履歴への記録が漏れると困るので、モデルの保存イベントに自動化した。呼び出す側は「区分を変更する」という1つの操作を呼ぶだけでよい。
任意の日付時点での区分も、履歴から遡って求められるようにしておいた。
取引相手ごとのSummary機能
確定申告の際、「この取引相手とはいくら取引したか」を勘定科目ごとに知りたくなる場面が多い(家賃の支払い先、外注先など)。
Counterparty に、取引のサマリーを集計する機能を追加した。
支出と収入を分けて、勘定科目ごとの内訳と合計を出す。年度ごとの集計と、全期間通しての集計の両方を用意した。
集計ロジックがそれなりに複雑なので、FiscalYear の Summary の時と同様、専用のサービスクラスに切り出して管理する。
なお、7/16に補助科目を必須にする設計変更をしたおかげで、勘定科目までの辿り方がシンプルになり、集計クエリも素直に書けた。
削除済み扱い(is_active=false)の Transaction は、当然ながら集計対象から除外する。
今後の展望
取引先ごとに実績が積み上がってくると、勘定科目や税率の使われ方に「いつもと違う」傾向が見えてくるはず。例えば、いつも10%課税で処理している取引先に8%の仕訳が混ざっていたり、通信費で処理していた取引先が急に消耗品費になっていたり。
今はまだ集計を出すだけだが、将来的にはこうした「ズレ」に気づけるような仕組みも検討したい。