• #Chrome拡張機能
  • #クラウド会計
  • #自動仕訳
  • #証憑アップロード
  • #スプレッドシート
  • #API解析
開発tax-assistantメモ

Chrome拡張 未登録明細タブ・自動仕訳コマンド・証憑アップロード

前日までに自動仕訳ルールタブを独立させたChrome拡張に、未登録明細タブを載せた。APIを1本叩くだけで6サービス211件の明細が返ってきて、手が止まった。「これ全部スプレッドシートに出して、仕訳済みの状態で書き戻せたら月次処理が一気に縮まる」。そこから一日かけて、エクスポート・インポート・自動仕訳コマンド・証憑アップロードまで一気に組み上げた。


未登録明細タブの実装(Step 1: タブUI + エクスポート/インポート)

journalizing_suggestions APIで一括取得

未登録明細の取得には journalizing_suggestions APIを使った。連携サービスを個別に指定しなくても、全サービスの未登録明細がまとめて返ってくる。テスト環境で叩くと211件・6サービス分のデータが落ちてきた。

各明細にはサービス名、日付、金額、推定勘定科目、direction(出金/入金)が含まれている。directionと口座連動科目の情報があれば、借方/貸方のどちら側にデフォルト値を入れるか判定できる。

サービス別シート分割のスプレッドシート出力

エクスポート先のスプレッドシートは以下のシート構成にした。

シート名内容
全明細全サービスの明細を1シートにまとめたもの
サービスA, B, ...サービスごとに分割した個別シート

サービスが6つあれば計7シートになる。月次レビュー時は全明細シートで俯瞰し、個別確認はサービスシートで見る想定。

複式簿記形式のインポートシート設計

インポートシートの設計に一番時間を使った。ポイントは「ユーザーが空欄の側だけ埋めれば仕訳が完成する」こと。

仕組み:

  • direction(出金/入金)と口座連動科目から、借方・貸方のどちらがデフォルト確定するかを事前判定
  • 確定した側にはデフォルト値を入れ、セル背景をグレーにする
  • ユーザーは白いセル(空欄の側)だけ入力すればよい

たとえば出金明細なら貸方に口座科目がデフォルト入力され、借方(費用科目)が空欄になる。入金明細はその逆。視覚的にどこを埋めるか迷わない。

設計判断: saveAsRule=false 固定

仕訳登録時に「この仕訳をルールとして保存するか」のフラグがある。これを常にfalseに固定した。自動仕訳ルールはクラウド会計側のUI上で管理する方針で、Chrome拡張から暗黙的にルールを増やさない。

journalId書き戻し・ステータス列の削除

当初はインポートシートにjournalIdとステータス列を持たせていた。しかし再エクスポートすると最新データで上書きされるため、これらの列は無意味だと気づいて削除した。余計な列があるとシートが横に広がって視認性が落ちる。


証憑アップロード機能

coffret upload_attach APIの発見

証憑ボックス(coffret)のAPIを調べていて、upload_attach エンドポイントを見つけた。証憑ファイルをこのAPIに投げると、クラウド会計の仕訳に紐づく証憑として登録される。

Google Drive→Chrome拡張→クラウド会計のフロー

証憑のソースはGoogle Drive。スキャンしたレシートや請求書がDriveに入っているので、以下のフローで組んだ。

  1. インポートシートのN列に「証憑URL」列を追加
  2. ユーザーがGoogle DriveのURLを貼る
  3. Chrome拡張のbackground.jsがDrive APIでファイルを取得
  4. 取得したファイルをcoffretのupload_attach APIに送信

manifest.jsonに drive.googleapis.com のhost_permissionsを追加して、拡張からDrive APIを直接叩けるようにした。


bulk_register APIの調査と断念

未登録明細を1件ずつ登録するのは遅い。クラウド会計の画面上には「一括登録」ボタンがあるので、裏で叩いているAPIを使えないか調べた。

React内部状態への依存

DevToolsのNetworkタブで一括登録リクエストを捕捉すると、リクエストボディの中にReactコンポーネントが内部生成する uid が含まれていた。このuidはDOMレンダリング時にReactが振り出す一時的な識別子で、外部から予測できない。

APIリクエストを再現しようとuidを固定値にして投げてみたが、400エラーが返る。Reactの内部stateと紐づいたuidを正しく生成するには、Reactコンポーネントのライフサイクルに乗る必要がある。

結論: 1件ずつ + 0.5秒ウェイト

一括APIの外部呼び出しは断念し、個別登録APIを1件ずつ叩く方式を採用した。0.5秒のウェイトを挟んでレートリミットを避ける。211件で約2分弱。月次1回の処理なので許容範囲。


/mf-auto-journal スラッシュコマンド

手動で全行の勘定科目を入力するのは現実的ではない。既存の自動仕訳ルールで大半をカバーできるので、Pythonスクリプトでマッチングするスラッシュコマンドを作った。

処理フロー

  1. スプレッドシートから未登録明細と自動仕訳ルール(ルール_残すシート)をダウンロード
  2. Pythonスクリプトで明細とルールをマッチング
  3. マッチした行の空欄セルに勘定科目・補助科目・税区分を埋める
  4. バランス検証(借方合計 = 貸方合計)
  5. スプレッドシートに一括書き込み

複合仕訳への対応

政策公庫の借入金返済のように、1つの明細に対して2行の仕訳が必要なケースがある(借入金の元本返済 + 利子割引料)。ルール定義に複数行を持たせ、マッチ時にスプレッドシートに行を挿入する仕組みを入れた。

行ずれバグとの格闘

複合仕訳で行を挿入すると、後続行の位置がずれる。adjust_row 関数で累積オフセットを管理していたが、比較対象が「挿入位置」ではなく「元の行番号」になっていて、2件目以降の複合仕訳で行がずれた。

デバッグ中にログを仕込んで各ステップのオフセット値を出力し、比較のタイミングが間違っていることを突き止めた。修正後、複合仕訳が3件連続しても行がずれないことを確認。

入金明細のスキップ判定

最初は出金明細だけを想定していたが、入金明細(売上入金、利息受取など)も同じルールでマッチングする必要があった。出金明細では借方が空欄・貸方がデフォルト、入金明細ではその逆。スキップ判定のロジックにdirectionを加えて、入金時は貸方側を埋める処理に分岐させた。

最終設計: ダウンロード→全行組み立て→検証→一括書き込み

当初はマッチした行を1行ずつスプレッドシートに書き込んでいたが、途中でエラーが起きると中途半端な状態になる。最終的に「全行をメモリ上で組み立て→借方/貸方のバランス検証→問題なければ一括書き込み」の設計に落ち着いた。


/mf-review-rules スラッシュコマンド

自動仕訳ルールの品質をレビューするコマンドも作った。チェック項目:

  • 半角/全角の重複(例: ABCABC が別ルールとして存在)
  • 税区分が未設定のルール
  • 入出金方向と勘定科目の不整合(出金なのに収益科目が設定されている等)

検出した問題に対して自動修正はせず、全項目「ユーザーに聞く」方針で統一した。ルールの意図はユーザーにしかわからないので、勝手に直すと却って混乱する。


勘定科目設定(データ連携)のエクスポート/インポート

モーダルのHTML構造調査

勘定科目設定の編集画面は /accounts/{accountId} のモーダルで開く。DevToolsで構造を調べたところ、更新APIは PUT /sub_account_itemables/{id} だった。

手動管理口座の罠

手動管理口座(連携サービスではなくユーザーが手入力で管理する口座)の更新は別のエンドポイント PUT /account_itemables/{id} を使う。同じ勘定科目設定画面に見えて、裏のAPIが異なる。最初これに気づかず、手動管理口座の更新が404で落ちて首をかしげた。


振り返り

朝の時点では「未登録明細をスプレッドシートに出すだけ」のつもりだった。APIを叩いてデータの構造を見ているうちに「ここまで自動化できるなら仕訳投入まで繋げよう」と手が伸び、気づいたら証憑アップロードまで組んでいた。bulk_register APIを断念する判断に30分ほど使ったが、Reactの内部状態に依存したuidを見た瞬間に「これは無理だ」と腹を括れた。行ずれバグはログを仕込んでオフセット値の推移を追ったことで原因が見え、修正自体は数行で済んだ。