こんにちは。LayerX エンジニアの花村(@naomasabit)です。
プレスリリースでも多く出していますが、請求書処理を行うLayerX インボイスは多くの会計ソフトと連携しています。他ソフトウェアと連携するという機能は複雑性を伴いますが、この記事では私が会計ソフト連携部分の開発を実施してきてぶつかった課題、と対応してきた内容をご紹介します。
多くの会計ソフトと連携しているLayerX インボイス
具体的な連携内容は
- 会計ソフトからマスタデータの取り込み
- そして会計ソフトへの仕訳データの取り込み
です。「仕訳」とは経済活動を一定のルールで表した概念で、例えば 5/1に銀行の普通預金から現金を10,000円引き出したら「5/1 現金 10,000 普通預金 10,000」といった形式で記述します。実際には会計ソフトによって仕訳のフォーマットは多種多様であり、環境が異なるため、ユーザーの利用ソフトに合わせて多くの連携を考える必要があります。
しかし、会計ソフト対応といっても一筋縄にはいきません。これまで多くの会計ソフトに対応する中であたった
- 課題1. 会計ソフトが持つマスタがそれぞれ異なる
- 課題2. 仕訳出力フォーマットの違いによる実装パターンの増加への対応
- 課題3. チーム内における仕様理解の混乱
について、それぞれへの対応を述べていきます。
課題1: 会計ソフトが持つマスタがそれぞれ異なる
基本的に、「勘定科目」、「部門」といったマスタデータはどの会計ソフトも持っているのですが、会計ソフトによって保持するマスタが異なり、例えば「取引先」は会計ソフトごとに持っていたり持っていなかったりします。また、「補助科目」という勘定科目をより細かく分類するためにつけるグループについては、freeeでは同様の役割を「品目」や「メモタグ」等の概念で表すなど、保持マスタは千差万別です。
対応: 地道な調査による対応と、マスタの利用設定を管理する仕組みの提供による対応
これらはまず、地道な調査による会計ソフトが持つマスタ群の理解を行いました。
会計ソフトが持つマスタ群についてそれぞれ理解し、上記のような早見表にしています。(内容は伏せます)会計ソフトのドキュメントに加えて、実機の動作を確認して調査します。調査して仕様を切る人と実装者が別々だとスピードが遅くなってしまうので、実装者自身が調査してクイックに実装しています。
調査した結果を環境に反映するために、マスタの利用設定を管理する機能を用意しています。LayerX インボイス利用ユーザーの環境毎にfreee利用ユーザーではこのマスタとこのマスタを利用する、マネーフォワード利用ユーザーではこのマスタとこのマスタを利用する等、対応する会計ソフト毎に設定できる実装にしています。
課題2: 仕訳出力フォーマットの違いによる実装パターンの増加への対応
仕訳出力フォーマットも大きく異なります。会計ソフトにインポートするために、さまざまなフォーマットでの出力対応が必要です。対応する会計ソフトが増えるごとにそれぞれフォーマットが必要です。
なお、@yyoshikiがfreeeのAPIライブラリを先日公開しましたが、こちらのようにLayerX インボイスが仕訳APIも連携している会計ソフトについては別の実装になるのですが、ここでは主にCSV出力による連携を述べます。
対応1: 仕訳テンプレートを定義したjsonの追加だけで仕訳出力の対応を可能にしてスケールしやすくした
当初は会計ソフトに合わせた加工のコードを書いていたのですが、対応会計ソフトが増える毎に実装が増えていき、スケールしづらくなってきました。そこで現在は、様々な仕訳フォーマットに対応するために、仕訳出力テンプレートをjson形式で設定し、マッピング・加工して出力するようにしています。これにより、新しい会計ソフトへの対応が必要になった時も、新しくjsonを定義するだけで新しい会計ソフトの仕訳出力に対応できます。
対応2: 横展開可能な仕訳テストの標準化による品質とスピードの両立をした
定義した出力が正しいかを確認する必要があります。LayerX インボイスでは、会計ソフト横断で同一のインプットデータを用意し、それぞれの会計ソフトフォーマットに合わせたCSVが出力されるかというに期待値テストを行います。
GoではTable Driven Testを使ったテストがメジャーですが、仕訳構造のような複雑なデータはコード内に書くと可読性が下がるため、図のようにCSVで期待値を定義して、こちらを読み込むようにしています。CSVで書くことで、数十列あるような仕訳フォーマットでも期待値を作りやすくしています。
また、同一ケースを使い、仕訳を組み立てて比較する部分は共通モジュールにしているので、新しい会計ソフトが出てきても以下のような数行を書けば横展開できるようにしています。
// ほげほげ会計ソフトのテスト実装 func TestJournalsHogeHogeAccountingSoft(t *testing.T) { // 期待値のCSVを読み込んで共通の型にする共通関数 expectedJournals := importExpectedJournals(ExpectedHogeHogeAccountingSoftCSV) var eTests = setTestDataTable(expectedJournals) // テストを行う関数 testExpenseCase(t, model.HogeHogeAccountingSoft, eTests) }
課題3: チーム内における仕様理解の混乱
いくつもの会計ソフトに対応していることで、チームメンバーの仕様理解にハードルがいくつもあります。メンバー間で知識差分があると意思決定のスピードが遅くなり、精度も悪くなりますし無駄な体力を使うことになります。
対応: 各会計ソフトの知見をPlaybookとして整備し、チーム内へ知見の共有
詳細仕様について会計ソフトを理解するためのPlaybookを作成し、共有できるようにしています。
上記はPlaybookの一部抜粋で、勘定奉行シリーズについて書いています。もっとも、Playbookだけでは理解に繋がらず、実機を触ってもらわないと理解が浅く終わってしまうため、定期的に実機を触ってもらうような取り組みを始めています。
まとめ
多くのソフトウェアと繋がるソフトウェアは考慮事項が多く複雑になりがちです。1つ1つ課題を解きほぐして、打ち手を立てていくことでこれまで対応してきました。ユーザーに合わせた環境提供の柔軟性、仕訳出力の共通化と品質向上施策など実装に加え、チームメンバー間でドメイン知識の差分をなくすための仕組みやドキュメントなども整理しています。実装、チームへのナレッジ共有とバランス感が求められる仕事をしています。
このようなSaaSの課題を解いていきたい方、また会計についても学んでいきたい知的好奇心の強い方、ぜひ下記のリンクからご応募ください。お待ちしております。
最後までお読みいただきありがとうございます。
追記: 図中のGopherアイコンはTakuya Ueda(@tenntenn)さん作のものを利用させていただきました。当初作者表記が漏れていたのをご指摘いただき、修正追記いたしました。