ActiveReportsJSのカスタム関数で税率変更に対応した請求書を作成する

企業で利用する請求書や見積書などの帳票では、制度改正や法改正に伴い、計算ルールの見直しが必要になることがあります。近年は飲食料品に係る消費税率の引下げが議論されるなど、税率変更への対応も注目を集めています。

こうした変更に対応するためのロジックを帳票に埋め込むと、条件分岐が増えて複雑になりがちです。また、ルール変更のたびに複数箇所を修正しなければならず、保守の負担も大きくなります。

JavaScript帳票ライブラリ「ActiveReportsJS(アクティブレポートJS)」では、JavaScriptで独自のカスタム関数を定義し、帳票から呼び出すことができます。本記事では、税率変更に対応した請求書を題材に、カスタム関数を利用して税率判定ロジックを実装する方法を紹介します。

事前準備

今回はActiveReportsJSの「V6J(v6.0.1)」を使用します。事前準備として、あらかじめ製品版、またはトライアル版をインストールしてください。トライアル版は無料で以下より入手可能です。

また、今回は以下の開発環境を使用します。事前にご準備ください。

また、作成した帳票をブラウザ上に表示するため、以下のクイックスタートを参考に、ActiveReportsJSの帳票ビューワを組み込んだWebアプリケーションをあらかじめ作成してください。

サンプル帳票の準備

今回はActiveReportsJSの請求書サンプル「Invoice-2-WithTaxDetails.rdlx-json」をベースに税率変更へ対応した請求書を作成します。

Invoice-2-WithTaxDetails は以下のGitHubリポジトリから入手できます。
※ GitHubリポジトリの[Download raw file]ボタンより取得してください。

帳票を表示すると以下のような請求書が表示されます。

サンプル帳票

既存の請求書の税率計算を確認する

まずは、サンプル帳票で税率がどのように計算されているかを確認します。

請求書の明細行と合計行には、それぞれ次の計算式が設定されています。

項目 計算式
税率 {IIF(ProductCategory = “飲料” Or ProductCategory = “食品”, 0.08, 0.1)}
税 {Floor(IIF(ProductCategory = “飲料” Or ProductCategory = “食品”, 0.08, 0.1) * Price)}
税込み金額 {Floor(IIF(ProductCategory = “飲料” Or ProductCategory = “食品”, 0.08, 0.1) * Price) + Price}
税(合計) {Sum(Floor(IIF(ProductCategory = “飲料” Or ProductCategory = “食品”, 0.08, 0.1) * Price))}
税込み金額(合計) {Sum(Floor(IIF(ProductCategory = “飲料” Or ProductCategory = “食品”, 0.08, 0.1) * Price) + Price)}
税込みご請求金額 {Sum(Floor(IIF(ProductCategory = “飲料” Or ProductCategory = “食品”, 0.08, 0.1) * Price) + Price)}

式を確認すると、商品区分が「飲料」「食品」なら8%、それ以外なら10%とする税率判定が、6か所すべてに同じ形で書かれていることが分かります。税率の判定条件を変える場合は、これらの式をすべて修正しなければなりません。

税率変更へ対応する場合

例えば、飲食料品の税率が2027年4月1日から変更されるケースを考えます。

商品区分 ~2027/3/31 2027/4/1~
飲料・食品 8% 1%
上記以外 10% 10%

この場合、商品区分に加えて明細の日付も判定条件に含める必要があります。たとえば税額の式は、次のようになります。

{Floor(
  IIF(ProductCategory = "飲料" Or ProductCategory = "食品",
    IIF(Date >= ToDateTime("2027/04/01"), 0.01, 0.08),
    0.1
  ) * Price
)}

この入れ子の判定を、先ほどの6か所すべてに書き込む必要があります。さらに税率が変わるたびに、全箇所を漏れなく修正しなければなりません。

税率の判定を1か所にまとめておけば、各計算式はそれを呼び出すだけで済み、ルールが変わっても修正は1か所で済みます。これを実現するのが、ActiveReportsJSのカスタム関数です。

カスタム関数を作成する

それでは、これまで6か所に分散していた税率の判定を、カスタム関数として1か所にまとめていきます。

まずは、商品区分と明細の日付から税率を返す関数をJavaScriptで作成します。税率が切り替わる日付は関数の中に書かず、引数で受け取るようにします。

function getTaxRate(category, deliveryDate, changeDate) {
  const isFood = category === "飲料" || category === "食品";
  if (!isFood) {
    return 0.1;
  }
  return new Date(deliveryDate) >= new Date(changeDate) ? 0.01 : 0.08;
}

商品区分が「飲料」「食品」以外なら10%を返します。飲料・食品の場合は、明細の日付が切り替え日以降なら1%、それより前なら8%を返します。

なお、カスタム関数は同期処理で作成し、入力だけで結果が決まるようにする必要があります。今回の関数も、引数として受け取った値だけで税率を判定しています。

デザイナアプリにカスタム関数を登録する

作成した関数を帳票から呼び出すには、関数を登録する必要があります。まずは帳票を編集できるように、ActiveReportsJSデザイナアプリに登録します。

デザイナアプリでは、お使いのOSに応じて次のフォルダに customCode.json を作成します。

  • Windows:%AppData%\ActiveReportsJS Designer\
  • macOS:~/Library/Application Support/ActiveReportsJS Designer/

※ macOSでは、Finderの[移動]→[フォルダへ移動](Command + Shift + G)にパスを入力すると開けます。

customCode.json には、関数本体を文字列として functions 配列に記述します。

{
  "functions": [
    {
      "name": "GetTaxRate",
      "body": "function(category, deliveryDate, changeDate) { const isFood = category === '飲料' || category === '食品'; if (!isFood) { return 0.1; } return new Date(deliveryDate) >= new Date(changeDate) ? 0.01 : 0.08; }",
      "info": {
        "description": "商品区分と納品日から税率を返します。",
        "example": "Code.GetTaxRate(ProductCategory, deliveryDate, @TaxChangeDate)",
        "syntax": "Code.GetTaxRate(<商品区分>, <納品日>, <税率の切り替え日>)"
      }
    }
  ]
}

info に設定した説明や構文は、式エディタの[関数]→[カスタム関数]に表示されます。

式エディタのカスタム関数

なお、ここでの登録はデザイナアプリ上でのみ有効です。アプリケーションのビューワで帳票を表示するには、アプリケーション側にも関数を登録する必要があります。こちらは帳票の編集が終わってから設定します。

税率の切り替え日をレポートパラメータで用意する

関数に渡す切り替え日は、帳票のレポートパラメータとして用意します。デザイナアプリでレポートパラメータを追加し、次のように設定します。

プロパティ 設定値
名前 TaxChangeDate
データ型 Date
既定値 2027/04/01
非表示 オン
レポートパラメータの追加

帳票の計算式を書き換える

登録したカスタム関数を使って、6か所の計算式を書き換えます。カスタム関数は Code.関数名() の形で呼び出します。

項目 計算式
税率 {Code.GetTaxRate(ProductCategory, Date, @TaxChangeDate)}
税 {Floor(Code.GetTaxRate(ProductCategory, Date, @TaxChangeDate) * Price)}
税込み金額 {Floor(Code.GetTaxRate(ProductCategory, Date, @TaxChangeDate) * Price) + Price}
税(合計) {Sum(Floor(Code.GetTaxRate(ProductCategory, Date, @TaxChangeDate) * Price))}
税込み金額(合計) {Sum(Floor(Code.GetTaxRate(ProductCategory, Date, @TaxChangeDate) * Price) + Price)}
税込みご請求金額 {Sum(Floor(Code.GetTaxRate(ProductCategory, Date, @TaxChangeDate) * Price) + Price)}

入れ子になっていた判定がなくなり、どの式も税率を取得する部分は Code.GetTaxRate() を呼び出すだけになりました。

デザイナアプリのプレビューで、税率が正しく表示されることを確認しておきます。

デザイナプレビュー

編集が終わったら、元のサンプルと区別できるように「Invoice-2-TaxRateChange.rdlx-json」という名前で保存します。

アプリケーションにカスタム関数を登録する

帳票の編集ができたら、アプリケーションで表示できるようにします。

デザイナアプリに登録したカスタム関数は、アプリケーションには引き継がれません。そのため、ビューワで帳票を表示するには、アプリケーション側でも registerFunctions メソッドで同じ関数を登録します。

<!DOCTYPE html>

<html lang="ja">
  <head>
    <meta charset="utf-8" />
    <title>ActiveReportsJS Viewer</title>

    <link rel="stylesheet" href="./css/ar-js-ui.css" />
    <link rel="stylesheet" href="./css/ar-js-viewer.css" />
    <script type="text/javascript" src="./scripts/ar-js-core.js"></script>
    <script type="text/javascript" src="./scripts/ar-js-viewer.js"></script>
    <script type="text/javascript" src="./scripts/ar-js-pdf.js"></script>
    <script type="text/javascript" src="./scripts/ar-js-xlsxAdv.js"></script>
    <script type="text/javascript" src="./scripts/ar-js-html.js"></script>
    <script type="text/javascript" src="./scripts/ar-js-tabular-data.js"></script>
    <script type="text/javascript" src="./scripts/locales/ar-js-locales.js"></script>    
    <style>
      #viewer-host {
        margin: 0 auto;
        width: 100%;
        height: 100vh;
      }
    </style>
  </head>

  <body>
    <div id="viewer-host"></div>
    <script>
      // 商品区分と納品日から税率を返すカスタム関数
      function getTaxRate(category, deliveryDate, changeDate) {
        const isFood = category === "飲料" || category === "食品";
        if (!isFood) {
          return 0.1;
        }
        return new Date(deliveryDate) >= new Date(changeDate) ? 0.01 : 0.08;
      }

      // カスタム関数を登録
      MESCIUS.ActiveReportsJS.Core.CustomCode.registerFunctions([
        {
          name: "GetTaxRate",
          body: getTaxRate
        }
      ]);

      var viewer = new MESCIUS.ActiveReportsJS.ReportViewer.Viewer("#viewer-host", { language: "ja" });
      viewer.open("./reports/Invoice-2-TaxRateChange.rdlx-json");
    </script>
  </body>
</html>

追加したのは、<body> 内の <script> にある次の2点です。

  • getTaxRate 関数の定義
  • registerFunctions メソッドによる関数の登録

カスタム関数の登録は、viewer.open で帳票を読み込む前に行います。また、帳票ファイルは保存した「Invoice-2-TaxRateChange.rdlx-json」を reports フォルダに配置し、読み込むファイル名も合わせて変更してください。

info は式エディタに説明を表示するための設定なので、ビューワで表示するだけなら省略できます。

デザイナアプリ用の customCode.json とアプリケーション用のコードには、同じ処理を2か所に記述することになります。一方だけを修正すると、デザイナアプリのプレビューとアプリケーションの表示で結果が変わってしまうため、修正する際は両方を更新してください。

動作を確認する

アプリケーションで帳票を表示し、明細の日付に応じて税率が切り替わることを確認します。

2027/03/31以前の明細では、飲料・食品に8%が適用されています。一方、2027/04/01以降の明細では1%が適用され、税額と税込金額も税率に合わせて計算されています。酒類や日用品は、日付にかかわらず10%のままです。

さいごに

今回は、ActiveReportsJSのカスタム関数を使って、税率変更に対応した請求書を作成する方法をご紹介しました。

複数の計算式に分散していた税率の判定をカスタム関数にまとめることで、帳票の式がシンプルになり、ルール変更時の修正箇所も最小限に抑えられます。また、切り替え日をレポートパラメータとして持たせておけば、日付の変更にも柔軟に対応できます。

今回は税率の判定を題材にしましたが、カスタム関数は、複数の帳票で共通する計算処理や、条件が複雑になりやすい判定などにも活用できます。帳票の式が長くなってきたときは、ぜひお試しください。

今回ご紹介した内容のソースコード、レポートファイルは以下のGitHubリポジトリに公開済みです。ぜひ合わせてご覧ください。

ActiveReportsJSにはこの他にも日本の帳票開発のディープな要件に対応するための機能が多数搭載されていますので、ぜひWebサイトで詳しい情報をご覧ください。

Webサイトでは製品の機能を手軽に体験できるデモアプリケーションやトライアル版も公開しておりますので、こちらもご確認ください。

また、ご導入前の製品に関するご相談、ご導入後の各種サービスに関するご質問など、お気軽にお問合せください。

\  この記事をシェアする  /