目的別によるAIの紹介とその活用方法について

はじめに

昨今、生成AIの発展により、エンジニアの業務効率は大きく向上しています。
しかし、実際の業務システムの開発にどう活用すればいいのか悩む方も多いのではないでしょうか。 AIには得意不得意があり、用途に合わせて使い分けることが重要です。
今回は、AIを4つの目的別に整理し、intra-mart開発における活用方法を紹介します。

目的別によるAIの紹介

本記事では、以下の4つに分類したAIをご紹介します。

● 文章生成・要約系AI
● コード生成・補助系AI
● 分類・判定系AI
● 分析・予測系AI

● 文章生成・要約系AI

文章生成・要約系AIは、人が読む文章を扱うことを得意とします。

主な用途:
・問い合わせ回答文の下書き作成
・申請内容や長文テキストの要約
・操作マニュアルや設計ドキュメントの生成

代表的な関連AIサービス:
・Gemini:文章生成・要約・言い換えなど汎用的に利用可能
・Claude:長文入力や要約が得意

● コード生成・補助系AI

コード生成・補助系AIは、プログラムの作成や理解を支援することを得意とします。

主な用途:
スクリプト開発
・コードレビュー(ロジックの脆弱性指摘やリファクタリング案の提示)

代表的な関連AIサービス:
GitHub Copilot:エディタ上でのリアルタイムにコード補完・生成
・ChatGPT:コード例の提示やロジック解説
・Codeium:無償枠があり、補完性能も高い

● 分類・判定系AI

分類・判定系AIは、入力されたデータがどのカテゴリに属するか判断することを得意とします。

主な用途:
・問い合わせ内容のカテゴリ分け
・処理ルートや優先度の判定

代表的な関連AIサービス:
・Azure OpenAI Service:業務システム連携向けに利用しやすい

● 分析・予測系AI

分析・予測系AIは、数値や履歴データから傾向を捉え、未来の予測や異常検知を得意とします。

主な用途:
・ログデータの分析
・利用傾向の把握
・異常検知

代表的な関連AIサービス:
・BigQuery ML:大量の蓄積データを活用し、本格的な予測モデルを構築。

intra-martとAIの役割分担

「IMのAPIを利用したコード実行の考え方」
ここまで紹介したAIは、あくまで「考える」「判断する」役割を担います。
実際の業務処理(登録・更新・起動など)を行うのは intra-mart です。
その橋渡しとなるのが intra-martのAPI です。

基本的な役割分担
・AI:曖昧な入力を解析し、「何をすべきか」という判断結果を返す。
・IM:APIで業務処理を実行する。

このように役割を明確に分けることで、安全にAIを業務へ組み込むことができます。

intra-martでの活用

作成したい機能のスクリプトをAIを活用して作成してみます。
今回は、IM-LogicDesigner JavaScript定義内を使用します。

実装するスクリプト
・ログインユーザの情報を取得
・ユーザコード、ユーザ名、メールアドレスを返却

1.作成する機能のプロンプトを生成
いきなりコードを書かせるのではなく、まずはAIに「IMの仕様に沿ったコードを出力させるためのプロンプト」を作成してもらいます。
※今回、文章生成AIで紹介した「Gemini」を使用します。
機能要件とAPI等の参照元を明示した入力により以下のようなプロンプトが生成されました。

# 依頼
intra-mart Accel PlatformのLogicDesigner(JS定義)で使用する、ログインユーザ情報を取得するスクリプトを作成してください。

# 開発環境・前提
- 言語: Server-side JavaScript (SSJS)
- APIバージョン: intra-mart Accel Platform 最新版
- 実装形式: function run(input) { ... } の形式

# 必須要件(実装の指定)
以下の手順とAPIを正確に使用してください。

1. **Contexts.getUserContext()** を使用して、ログイン中のユーザのコンテキスト情報を一括で取得する。
2. 取得した `userContext` およびその中の `userProfile` が存在するかチェックする(存在しない場合はnullを返すエラーハンドリングを入れる)。
3. `userContext.userProfile` から以下の項目を抽出し、戻り値のオブジェクトとして返却する。
   - userCd (userCodeとして返却)
   - userName (userNameとして返却)
   - emailAddress1 (emailAddressとして返却)

# 制約事項
- JSDoc形式のコメント(@param, @return)を関数の上部に付与すること。
- 余計な外部ライブラリ(Identifierなど)は使わず、Contexts APIのみで完結させること。

# 出力形式
- スクリプトコードのみ

2.生成したプロンプトからスクリプトを生成
生成したプロンプトからスクリプトを作成してもらいます。
※今回、コード生成AIで紹介した「ChatGPT」を使用します。

/**
 * run.
 *
 * @param input {Object} - task input data.
 * @return {Object} task result.
 */
function run(input) {
    // ログイン中ユーザ情報を取得
    var userContext = Contexts.getUserContext();
    // userProfile が存在しない場合
    if (!userContext || !userContext.userProfile) {
        return {
            userCode: null,
            userName: null,
            emailAddress: null
        };
    }
    var profile = userContext.userProfile;
    // 戻り値
    return {
        userCode: profile.userCd,
        userName: profile.userName,
        emailAddress: profile.emailAddress1
    };
}

生成されたプロンプトで上記のようなスクリプトを作成することができました。

3.生成したスクリプトを実行
「ChatGPT」により生成されたスクリプトをIM-LogicDesignerで実行させます。

IM-LogicDesigner_スクリプト実行

実行が正常に終了し、ユーザコード、ユーザ名、メールアドレスが出力されていることを確認できました。

※導入時の注意点
・機密情報の入力禁止
パブリックなAIを利用する場合、入力したプロンプトが学習データとして利用される可能性があります。 顧客情報、個人情報、社外秘のロジックなどは絶対に入力せず、今回のように「標準APIの使い方」などの汎用的な指示に留めてください。
・もっともらしい嘘への対策
AIは存在しないAPIや、古い仕様のコードを出力することがあります。 生成されたコードは必ず公式ドキュメント等と照らし合わせ、動作検証環境でテストを行ってください。
著作権とライセンスの確認
生成されたコードにライセンス上の問題がないか、また自社の開発ガイドラインに沿っているかを確認してからプロジェクトへ適用してください。

おわりに

本記事では、目的別にAIを整理し、intra-martのAPIと組み合わせた活用イメージを紹介しました。 AI単体では業務は完結しませんが、連携することでより効率的に業務を遂行することができます。 まずは小さなユースケースから試し、徐々に適用範囲を広げていくことをおすすめします。

BloomMaker開発-テーブルのCSS変更方法

はじめに

こんにちは。開発部のK.Tです。

IM-BloomMakerでリッチテーブルや繰り返しテーブルを使った一覧画面を作っていると、

・行ごとに背景色を変えたい

・同じCSSを複数のエレメントで使い回したい

といった 見た目の微調整をしたくなる場面が多いと思います。

本記事では、IM-BloomMakerでテーブルの見た目を調整する際に押さえておきたい

  1. CSSエディタでテーブルのCSSを変える方法

  2. CSSクラスをグルーピングして複数指定する方法

についてまとめておきます。

環境構築

前提・環境

・開発ツール:IM-BloomMaker

・コンテンツ種別:imui / Bulma どちらでも可(例では Bulma 寄り)

・テーブル:

 ・フォーム部品の「リッチテーブル」

1. テーブルのCSSを変える方法

以下の手順でテーブルの見た目を変えることができます。

  1. CSSエディタで全体のスタイルを定義する

  2. エレメントにCSSクラスを付けて、クラス単位でスタイルを当てる


1-1. CSSエディタでテーブル用スタイルを定義する

BloomMakerには画面単位のCSSを記述できる「CSSエディタ」があり、ここで書いたスタイルをコンテナ内にだけ適用することができます。

テーブル用のスタイル例はこんな感じです。

/* テーブル全体のベーススタイル */
.demo-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.9rem;
}

/* ヘッダ */
.demo-table thead th {
  background-color: #f5f5f5;
  border-bottom: 2px solid #ccc;
}

/* ボーダーと余白 */
.demo-table th,
.demo-table td {
  border-bottom: 1px solid #e0e0e0;
  padding: 0.4rem 0.6rem;
}

/* 偶数行を縞々に */
.demo-table tr:nth-child(even) {
  background-color: #fafafa;
}

CSSエディタにこのCSSを書いておくと、クラス demo-table を持つ table要素に対して一括でスタイルが適用されます。

ただし、そのままタグ名(例:table { ... })で指定すると、コンテナ外のテーブルにも効いてしまうので、コンテナのクラスをセレクタに含める書き方にしておくと安心です。

/* コンテナ内のテーブルだけに適用する例 */
.im-hichee-container .demo-table {
  /* ここにスタイルを書く */
}

1-2. リッチテーブルにCSSクラスを割り当てる

CSSを書いただけではBloomMaker側のテーブルにクラスが付いていないので、デザイナでリッチテーブルにクラス名を設定します。

  1. リッチテーブルエレメントをクリック

  2. 右ペインで「プロパティ」タブを開く

  3. CSSクラス」カテゴリの「クラス名」を demo-table に設定

これで、リッチテーブルのHTMLに class="demo-table" が付き、先ほどCSSエディタに書いたスタイルが効くようになります。

同じ手順で、縦方向テーブル(繰り返し)や、テーブルを囲うボックスなどにもクラスを割り当てれば、一覧全体の見た目を統一できます。

テーブル(CSS変更前)

テーブル(CSS変更後)

2. CSSクラスをグルーピングして複数指定する方法

次に、CSSクラスを「部品化」して複数組み合わせる話です。


2-1. 1つのエレメントに複数クラスを付ける

BloomMakerの「CSSクラス > クラス名」プロパティは、 スペース区切りで複数のクラス名を指定可能です。

例: demo-table is-striped

これにより、

・demo-table:テーブル全体の基本スタイル

・is-striped:行を縞々にするCSS

というように、役割ごとにクラスを分けておいて、必要なものを組み合わせる運用ができます。

Bulmaベースのエレメントで利用されるアイコン用プロパティ iconClass なども、複数クラスをスペース区切り、または文字列配列で指定できる仕様になっています。

この考え方をそのままテーブルにも流用すると、CSS設計がきれいになります。


2-2. 「見た目の部品」としてクラスを分割する

例えば通常版とコンパクト版(table-compact)の2つのテーブルがある想定で、 テーブル用のクラスを次のように分割しておきます。

/* ベースのテーブル */
.table-base {
  width: 100%;
  border-collapse: collapse;
}

/* 縞々 */
.table-striped tr:nth-child(even) {
  background-color: #fafafa;
}

/* コンパクト表示 */
.table-compact th,
.table-compact td {
  padding: 0.25rem 0.5rem;
  font-size: 0.85rem;
}

BloomMaker側では、用途に応じて次のようにクラス名を組み合わせて指定します。

・通常の一覧: table-base table-striped

・コンパクト版一覧: table-base table-striped table-compact

こうしておくと、2つのテーブル両方で、「縞々を取り除きたい」「縞々に色を付けたい」などの場合も .table-striped だけをCSSから調整するだけで済み、クラス設計の見通しが良くなります。

3. テーブルのCSSとクラスグルーピングの実装例

ここまでの内容を組み合わせて、 「コメント一覧テーブル」の見た目を整えるときの例を簡単にまとめます。


3-1. CSSエディタに記述するスタイル

/* ベース */
.table-base {
  width: 100%;
  border-collapse: collapse;
}

/* ヘッダ */
.table-header-basic thead th {
  background-color: #d555f5;
  border-bottom: 2px solid #d555f5;
}

/* ボーダー */
.table-border-basic th,
.table-border-basic td {
  border-bottom: 2px solid #049e1b;
  padding: 0.4rem 0.6rem;
}

/* 縞々 */
.table-striped tr:nth-child(even) {
  background-color: #faf0f9;
}

3-2. リッチテーブル側の設定

・対象:コメント一覧リッチテーブル

・プロパティ → CSSクラス → クラス名

table-base table-header-basic table-border-basic table-striped

縦方向テーブル側も同じようにクラスを分けておけば、「一覧部分の見た目だけ抜き差しする」といったこともやりやすくなります。

4. まとめ

・BloomMakerでは、CSSエディタCSSクラスプロパティを組み合わせることで、リッチテーブルや繰り返しテーブルの見た目を柔軟にコントロールできる

・「CSSクラス > クラス名」プロパティには 複数クラスを指定可能 で、Bulmaベースのアイコンなどでも同じ考え方が使われている

一覧画面の実装と並行して、CSSクラスを「部品」として設計しておくと、後からの調整がかなりラクになるので、早めにルールを決めておくのがおすすめです。

intra-mart標準バリデーションの注意点

はじめに

今回は、intra-mart標準バリデーションの注意点についてご紹介します。
バリデーションルールはいくつかありますが、本記事では、その中でもintegerを対象に、「01」や「-0」といった入力値に対する挙動を扱います。
バリデーションルールの詳細については以下のドキュメントをご参照ください。 document.intra-mart.jp

integerについて

上記の『バリデーションルール リファレンス』によると、integerは次のように定義されています。

値が整数型の数字であるかを検証します。整数型の数字ではない場合はエラーとします。

下の例のとおり、文字列(例:integer)を入れると「整数を入力してください」とエラーになります。
これは整数型の数字でないものをエラーにする挙動です。
ただしintegerは、「値が整数として解釈できるかどうか」しか見ていません。
そのため、整数として解釈できる値であれば、表記として次のような入力も通ってしまいます。

  • 01
  • -0

つまりintegerは「値が整数かどうか」だけ見ており、表記(先頭ゼロや -0 など)は別途ルールで制御する必要があります。

対処法

以下のような正規表現を使用することで、「0」または先頭ゼロのない整数だけを許可し、「01」 や 「-0」 の入力を防ぐことができます。

^(0|[1-9][0-9]*|-[1-9][0-9]*)$

また、正規表現で制御する代わりに、クライアント側の JavaScript やサーバ側の処理で数値として正規化するといった対処も可能です。
どちらで処理するかを決めて、挙動を統一しておくことをおすすめします。

おわりに

今回はintra-mart標準バリデーションのintegerに関する注意点を紹介しました。
integerだけでは、意図しない表記の値がデータベースに登録されてしまう可能性があります。
許容する値と表記のルールを明確にし、正規表現による厳密なバリデーションやプログラムでの正規化など、適切な対処を行いましょう。

Accel Studio テスト機能の紹介

はじめに

こんにちは。開発部のD.Yです。
今回の記事ではAccel Studio テスト機能を使って、WFの申請~承認のテストを自動化してみましたので、そのご紹介をしたいと思います。

Accel Studio テスト機能について

Accel Studio テスト機能 は、E2Eテストの自動化ツールです。
E2Eテストを自動化することで、以下の場合に、テストに費やす時間を短縮できます。

  • intra-mart Accel Platform のアップデート時
  • Accel Studio アプリケーションの変更時
  • ブラウザのアップデートや実行環境変更時

引用元 document.intra-mart.jp

環境構築

Accel Studio テスト機能のセットアップに関しては、下記を参照してください。

document.intra-mart.jp

WF申請~承認を自動化

今回は、以下の2ステップを自動化しました。

  1. 申請
    入力項目を埋めて申請処理を行い、案件が作成されていることを確認します。

  2. 承認
    コメントを入力して承認処理を行い、案件が完了していることを確認します。

申請画面

申請画面には以下のような入力項目があります。

項目 入力例 補足
タイトル 週次レポート 申請者が入力
日報 作業内容:タスクA完了、タスクB進行中 申請者が入力
提出日 2025/09/10 申請日をシステムで自動入力
申請者 青柳辰巳 申請者のユーザ名をシステムで自動入力

申請画面

承認画面

承認画面には以下のような入力項目があります。

項目 入力例 補足
コメント お疲れ様です。確認しました。 承認者が入力

承認画面

テストシナリオ

ここからは実際に作成したテストコードを紹介します。
申請と承認をそれぞれ独立したテストシナリオとして実装しました。

申請シナリオ

申請に必要な項目を入力し、システムが自動入力する項目に関しては既に入力されていることを確認します。
申請処理を行い、案件のステータスが「申請済み」になっていることを確認します。

import { test, expect } from '@playwright/test';
import * as workflowUtil from 'im-workflow-util';

test('test', async ({ page }) => {

  // ===== 対象のWFのフローIDと申請者 =====
  const TARGET_FLOW_ID = '8hq66svk2kg06gk-flow';
  const APPLY_USER_CD = 'aoyagi';

  // ===== 申請画面へ直接アクセス =====
  await page.goto('im_workflow/user/apply/apply_direct/' + TARGET_FLOW_ID);

  // ===== 入力操作 =====
  // タイトル入力
  await page.locator('#title').fill('週次レポート');

  // 日報入力
  await page.locator('#daily_report').fill('作業内容:タスクA完了、タスクB進行中');

  // ===== 自動入力項目の確認 =====
  // 提出日が空でないことを確認
  const submissionDate = await page.locator('#submission_date').inputValue();
  await expect(submissionDate).not.toBe('');

  // 申請者が空でないことを確認
  const applicant = await page.locator('#applicant').inputValue();
  await expect(applicant).not.toBe('');

  // ===== スクリーンショット =====
  await page.screenshot({ path: 'screenshot1.png' });

  // ===== 申請操作 =====
  // 申請ボタンをクリック
  await page.getByRole('button', { name: '申請' }).click();

  // モーダルで申請情報を入力
  await page.locator('#im-wf-inputs-flex-item-basic-information input[type="text"]')
    .fill('週次レポート申請');

  // モーダル内で申請ボタンをクリック
  await page.locator('#im-workflow-apply-modal').getByRole('button', { name: '申請' }).click();

  // 確認ダイアログで「はい」をクリック
  await page.getByRole('button', { name: 'はい' }).click();

  // ===== システム案件IDの取得とステータス確認 =====
  const systemMatterId = await workflowUtil.getSystemMatterIdFromActive(TARGET_FLOW_ID, APPLY_USER_CD);
  const status = await workflowUtil.getStatusInfo(systemMatterId);

  // ステータスが「申請済み」であることを確認
  expect(status).toBe('0');

});

承認シナリオ

コメントを入力して承認処理を行い、案件のステータスが「完了」になっていることを確認します。

import { test, expect } from '@playwright/test';
import * as workflowUtil from 'im-workflow-util';

test('test', async ({ page }) => {

  // ===== 対象のWFのフローIDと申請者 =====
  const TARGET_FLOW_ID = '8hq66svk2kg06gk-flow';
  const APPLY_USER_CD = 'aoyagi';

  // ===== システム案件IDの取得 =====
  const systemMatterId = await workflowUtil.getSystemMatterIdFromActive(TARGET_FLOW_ID, APPLY_USER_CD);

  // ===== 承認画面へ直接アクセス =====
  await page.goto('im_workflow/user/process/process_direct/' + systemMatterId);

  // ===== コメント入力 =====
  await page.locator('#approval_comment').fill('お疲れ様です。確認しました。');

  // ===== スクリーンショット =====
  await page.screenshot({ path: 'screenshot1.png' });

  // ===== 承認操作 =====
  await page.getByRole('button', { name: '処理' }).click();
  await page.getByRole('button', { name: '承認' }).click();
  await page.getByRole('button', { name: 'はい' }).click();

  // ステータスが「完了」であることを確認
  const status = await workflowUtil.getStatusInfo(systemMatterId);
  expect(status).toBe('1');

});

テスト実行

テスト定義詳細画面にて実行ボタンを押下するとテストを実行できます。

テスト定義詳細画面

テスト結果

実行したテストは、テスト結果詳細画面で確認できます。

テスト結果詳細画面

上記のように「実行に成功しました。」と表示され、テストがシナリオ通りに正常終了したことを確認することができます。
シナリオ内で取得したスクリーンショットや実行ログがこの画面で確認できます。

スクリーンショットを残すことで、実行ログだけではわかりにくい「画面の状態」を後から確認できるため、テストが失敗した場合でも原因調査がしやすくなります。

おわりに

今回はAccel Studio テスト機能を使ったWFのテスト自動化について紹介しました。
WFの申請~承認のような定型的な操作を自動化すれば、ヒューマンエラーを防ぎつつ、リグレッションテストを効率的に実行できます。
一度シナリオを作成しておけば、intra-mart Accel Platform のアップデートやブラウザ・実行環境の変更時にも繰り返し利用できるため、ぜひ積極的に自動化を進めて効率化と品質向上を実現していきましょう。

IM-Copilotの機能紹介 Wikiアシスタント編

はじめに

intra-mart 2024 springバージョンでは、生成AIを利用できる「IM-Copilot」がリリースされました。
そこからアップデートを経るごとに生成AIに関わる機能が増えてきました。
今回の記事ではintra-mart標準機能の Wikiアシスタント を使ってみましたので、そのご紹介をしたいと思います。

Wikiアシスタントでは、intra-martの「IM-Wiki」に蓄積されたデータを元に生成AIと会話形式で質問をすることができます。

IM-Wikiとは

IM-Wikiはナレッジを蓄積・集約するための機構を提供する標準アプリケーションである「IM-Knowledge」に対して、コンテンツの1つとして「Wiki」を作成・管理するための機能です。 ブラウザ上から社内規則、業務マニュアル、議事録といった業務文書を簡単に参照できるため、社員同士の情報共有を円滑に行うことができます。
引用元 document.intra-mart.jp

環境構築

IM-Copilot、Wikiアシスタントを利用するにあたり、
通常の環境構築公式ドキュメントと併せて IM-Copilot 利用ガイド を元に環境を作成してください。

document.intra-mart.jp

document.intra-mart.jp

※solrでベクトルデータベースを構築する際の注意点

公式ドキュメントの手順で配布されているsolr.zipを利用する際、
solrの起動やコア生成用の solr.cmd 内の改行コードが「LF」になっていますので、 テキストエディタを利用し、「CRLF」に変更してから利用するように注意してください。

実際の動作

・今回は仮データとして、テスト会社の勤怠申請細則を用意しました。(生成AIで作成しました。)


・まずはベクトルデータベースにデータを登録せずに、Wikiアシスタントを動かしてみます。

データがないため、明確な回答は返ってきませんでした。


・続いて、ベクトルデータベースにデータを登録した後、Wikiアシスタントを動かしてみます。

用意した勤怠申請細則を元に回答を作成していることが確認できました。


※ベクトルデータベースへのデータ登録は、以下のドキュメントに記載のあるジョブを実行してください。 document.intra-mart.jp

おわりに

今回は IM-Copilot の標準機能である Wikiアシスタント を使ってみました。
簡単な準備でintra-mart上の独自データを元に回答をする生成AIを利用することができました。

今後は生成AIを活用し、intra-mart利用者が資料を探す時間や問い合わせ対応の工数を大幅に削減することができるはずです。
引き続き弊社ではAIの利活用、導入を積極的に進めていきたいと思います。

intra-martワークフローとintra-mart Accel Collaborationの機能連携について

はじめに

システム開発部所属のO.Yです。
本日はintra-martのワークフローとintra-mart Accel Collaboration(以下iAC)の機能連携について紹介します。

intra-martではIM-LogicDesignerで作成したロジックフローを、ワークフローの拡張機能として使用することができます。
document.intra-mart.jp
今回はユーザプログラムに属するリソースの【案件終了処理】を使用して、案件の最終承認をトリガーとして自動でスケジュール登録を行うフローを作成します。

1.ワークフローの作成

intra-martでワークフローを作成する手段はいくつかありますが、 今回はAccelStudioのベーステンプレート「シンプルなワークフロー」を使用して作成します。
AccelStudioでのワークフローの作成方法について本記事では割愛しますので、必要であれば以下のチュートリアルガイドを参考にしてください。
document.intra-mart.jp

以下のキャプチャの通り、最低限の入力項目がある申請画面を作ります。
後述するロジックフローのスケジュール登録タスクで必要となる項目を、入力項目として用意しています。

申請画面

2.案件終了処理用ロジックフローの作成

次にIM-LogicDesignerを使用してロジックフローを作成します。
1で作成したAccelStudioのアプリの詳細画面で「リソースを追加」-「ロジックを新規作成」-「ロジックフロー」の順で選択して新規ロジックフローを作成します。

2-1. 入出力設定
まずは入出力設定を行います。
以下のドキュメントを参考に案件終了処理に対応した入力変数を定義し、案件情報を受け取れるようにします。
document.intra-mart.jp
処理に必要な変数のみ定義すれば問題ありませんが、この際にオブジェクトの構造は変更しないようにしてください。
出力設定も同様に上記のドキュメントを参考に設定します。

2-2. 最終処理結果ステータスによる分岐
ここからロジックフロー本体の作成に入りますが、1つポイントがあります。
【案件終了処理】は最終承認の完了だけでなく、否認や取止めなどで処理が終了した場合にも実行されます。
今回は最終承認が完了した場合のみ処理を実行したいため、ロジックフロー内で最終処理結果ステータスによる分岐を行います。
ここで先ほど設定した入力変数のimwMatterEndProcessオブジェクト配下のlastResultStatusの値を使用します。
分岐タスクの条件式に以下のEL式を設定します。

${$input.imwMatterEndProcess.lastResultStatus=="mattercomplete"}

2-3. 案件情報の取得
次に案件情報を取得します。
今回はIM-Repositoryのエンティティを用いてワークフローを作成しているため、【エンティティデータの取得】タスクを使用して案件情報を取得します。
入力値となるuserDataIdには2-1.入出力設定で入力値に設定したimwProcessCommonオブジェクト配下のuserDataIdを使用します。

2-4. 開始日と終了日の取得
次にスケジュール登録タスクの入力値として必要な開始日と終了日を取得する処理を実装します。
今回の申請フォームの構成上、有給取得日と開始時刻、終了時刻を別々に扱っているため、時刻情報を含めた有給取得開始日と有給取得終了日を取得する必要があります。
JavaScript定義を新規作成して、以下の入出力設定とスクリプトで処理を行います。

JavaScript定義 入出力設定

function run(input) {
  const startTime = input.start_time;
  const endTime = input.end_time;
  const holidayAcquisitionDate = input.holiday_acquisition_date;
  
  function combineDateAndTime(date, time) {
    const [hours, minutes] = time.split(':');
    const newDate = new Date(date);
    newDate.setHours(Number(hours));
    newDate.setMinutes(Number(minutes));
    return newDate;
  }

  return {
    startDate: combineDateAndTime(holidayAcquisitionDate,startTime),
    endDate: combineDateAndTime(holidayAcquisitionDate,endTime)
  };
}

2-5. スケジュール登録タスク
iACの【スケジュール登録タスク】を配置し、必要なパラメータの設定を行います。
以下に記載されているスケジュール登録タスクで設定可能な入力値に対してマッピングを行います。
document.intra-mart.jp
必須項目であるtitle(スケジュールのタイトル)については、今回は定数で設定したものを一律で使用します。
また、selectedLocaleId(選択ロケールID)とtimezoneId(タイムゾーンID)については、アカウントコンテキストの値を使用します。

スケジュール登録タスクのマッピングのポイントは、targetUserCd(実行ユーザコード)に、画面で入力された申請者本人のユーザコードを設定している点です。
これは、iACのスケジュールアクセス権についての考慮を省略するためです。
代案としては、スケジュールアクセス権除外ユーザのロールが付与された専用ユーザを実行ユーザとして設定する方法も考えられます。

2-6. 終了タスク
最後に、2-1.入出力設定で設定した出力値のerrorに、定数で定義したfalse値を設定します。
これは、ロジックの処理が正常に終了したことを示すために必要な設定です。

終了タスク マッピング

3.案件終了処理に登録

ここでは、AccelStudioを使用してワークフローを作成していることを前提とします。
IM-BISなどで作成した場合は、別途フロー設定のコンテンツ詳細から設定してください。

1の手順で作成されたアプリ内の「ワークフロー定義」を押下してワークフロー管理画面を開きます。
「フロー設定」-「基本設定」の処理タブにある案件終了処理の歯車ボタンを押下して処理設定画面を開き、「処理を追加」-「ロジックフローを追加」の順で押下して作成したロジックフローを設定します。

以上で、案件の最終承認をトリガーとしてスケジュール登録を実行するワークフローの作成が完了です。

おわりに

案件の最終承認をトリガーとしたスケジュール自動登録フローの作成方法について紹介しました。
ワークフローのリソースには、案件終了処理以外にも案件開始処理や到達処理などがあり、フローの任意のタイミングで処理を実行するように設定できます。
また、IM-LogicDesignerには今回使用したiACタスク以外にも多数のタスクが用意されているため、これらを使用してより機能的なワークフローを作成しましょう!

「ImJson」とビルトインの「JSON」の違い

はじめに

こんにちは。開発部のK.Sです。

今回はintra-martで利用できる「ImJson」とビルトインの「JSON」の違いについてです。

JSON (JavaScript Object Notation)とは、軽量のデータ交換フォーマットで、

ImJsonは、intra-martで利用できるJSON操作用のライブラリです。

業務で使用した際に気付いた両者の違いについていくつか紹介します。

JSON文字列変換時の型情報

   var obj = {
        name: "さとし",
        age: 25
    };
    var jsonWithType = ImJson.toJSONString(obj, true);
    var json = JSON.stringify(obj);
    Debug.print("ImJson: " + "\n"+ jsonWithType);
    Debug.print("ビルトインJSON: " + "\n"+ json);
ImJson:
 /* Object */
{
    /* String */
    "name" : "さとし",

    /* Number */
    "age" : 25
}


ビルトインJSON: 
{
    "name": "さとし",
    "age": 25
}

上記のようにImJsonでは、型情報がコメント形式で明示されるため、デバッグ時に非常に分かりやすいのが特長です。

一方で、ビルトインのJSON.stringifyでは、純粋なJSON形式が出力され、型情報は保持されません。

ただ、ImJsonではdebugFlgがtrueかfalseかの分岐がある分、ビルトインのJSONに比べ、多少負荷が大きくなる可能性があります。

そのため、デバッグ性を重視するならImJson、パフォーマンスを重視する環境ではビルトインJSONが適しているといえます。

日付型の変換

日付型の取り扱いにも明確な違いがあります。

   var date = new Date("2000/01/01")
    var obj = {
        birthDate: date
    };
    var jsonWithType = ImJson.toJSONString(obj, true); 
    var json = JSON.stringify(obj);
    Debug.print("日付: " + "\n" +date) 
    Debug.print("ImJson: " + "\n" + jsonWithType);
    Debug.print("ビルトインJSON: " + "\n" + json);
日付:
Sat Jan 01 2000 00:00:00 GMT+0900 (JST)

ImJson: 
/* Object */
{
    /* Date (Sat Jan 01 2000 00:00:00 GMT+0900 (JST)) */
    "birthDate" : new Date(946652400000)
}

ビルトインJSON:  
{
 "birthDate": "1999-12-31T15:00:00.000Z"
}

上記のようにImJsonでは、日付がDate型のまま出力され、JST(日本時間)で表示されます。

一方、ビルトインJSONではISO形式の文字列(UTC)として出力され、タイムゾーンによる日時のずれが生じます。

また、下記の様にビルトインJSONで一度文字列化した日付をJSON.parseで再パースしても、

元のDate型には戻らず、単なる文字列として扱われてしまいます。

   var date = new Date("2000/01/01")
    var obj = {
        birthDate: date
    };
    var json = JSON.stringify(obj);
    var parseJson = JSON.parse(json)
    Debug.print("元のオブジェクト: ")
    Debug.console(obj)
    Debug.print("再パース後のオブジェクト: ")
    Debug.console(parseJson)
元のオブジェクト:
/* Object */
{
    /* Date (Sat Jan 01 2000 00:00:00 GMT+0900 (JST)) */
    "birthDate" : new Date(946652400000)
}

再パース後のオブジェクト:
/* Object */
{
    /* String */
    "birthDate" : "1999-12-31T15:00:00.000Z"
}

JSONでDate型を取り扱う際には、日時の正確性や型の状態等を正確に把握しておくことが重要です。

対応の型

例えば、BigDecimal型を扱う例です。

   var obj = {
        value: new BigDecimal("123.45")
    };
    var jsonWithType = ImJson.toJSONString(obj, true);
    var json = JSON.stringify(obj);
    Debug.print("ImJson: " + jsonWithType);
    Debug.print("ビルトインJSON: " + json);
ImJson:
/* Object */
{
    /* BigDecimal */
    "value" : "123.45"
}"


"ビルトインJSON:
 {"value":{"plainString":"123.45"}}"

上記のようにImJsonでは、BigDecimal型がそのまま出力されます。

しかしビルトインJSONでは、BigDecimalがサポートされていないため、

内部的にはオブジェクトとして処理され、型情報が失われてしまいます。

他にもBigInteger型やFunction型等ImJsonでは対応していても、

ビルトインJSONでは対応していない型があるので注意が必要です。

まとめ

ImJsonとビルトインJSONの主な違いを整理すると、以下のようになります。

・ImJsonは型情報をコメント形式で出力できるため、デバッグに適している。

・ビルトインJSONはシンプルで高速だが、型情報が失われ、特に日付型ではUTCへの変換や再変換の手間が発生する。

・特殊なデータ型(BigDecimalなど)をそのまま扱いたい場合は、ImJsonの方が適している。

業務でJSONを扱う際には、単なるデータ変換だけでなく、

型の保持や日付の精度保持の仕方を考えることが重要です。

用途や目的に応じて、ImJsonとビルトインJSONをうまく使い分けていきましょう。

【参考】
intra-mart Accel Platform SSJS API Documentation

JSON.stringify() - JavaScript | MDN

Docusign APIの紹介

業務の一環でDocusignについてAPIの調査を行いましたので、今回はDocusignのAPIでどのようなことが出来るのか紹介したいと思います。

Docusignとは

Docusignは電子署名・電子契約を行うシステムです。 www.docusign.com

PDFなどの文章ファイルに署名欄・署名日欄などを設定して契約書のやり取りをすることができます。 ※Docusignでは契約書のやり取りをエンベロープ(envelope)と呼称しています。 また簡単なワークフローを作ることができ、契約書の作成者・署名者・確認者などの役割分担をすることも可能です。

APIは多数用意されていますが、その中でも今回調査したAPIについて紹介します。

エンベロープを作成するAPI

/restapi/v2.1/accounts/{accountId}/envelopes

エンベロープ作成と同時に文章ファイルを指定する場合はリクエストパラメータにbase64形式で設定する必要があります。 Docusign上で設定したテンプレートからエンベロープを作成することも可能です。その場合、リクエストパラメータにテンプレートIDを指定します。 (テンプレートでは文章ファイルの登録やワークフローの設定をあらかじめ行うことが可能です。)

また、エンベロープのステータスを設定することも可能です。 ステータスに「sent」を設定した場合は署名者に契約書を送信しますが、「created」を設定した場合は下書き状態になり、送信されません。 送信前に内容の確認や修正をする場合は「created」が利用できそうです。

文章中の署名欄を設定するAPI

/restapi/v2.1/accounts/{accountId}/envelopes/{envelopeId}/documents/{documentId}/tabs

署名欄など文章中に署名者が入力できる項目は「tab」と呼称されています。 署名欄を設定する場合は「signHereTab」、署名日を設定する場合は「dateSignedTab」をリクエストパラメータに設定します。

入力欄の位置は座標での指定と特定の文字が存在する場所への指定する方法があります。 座標指定の場合は「xPosition」「yPosition」などのパラメータを設定し、特定の文字で指定する場合は「anchorString」のパラメータを設定します。

契約書の受信者を動的に設定するAPI

/restapi/v2.1/accounts/{accountId}/envelopes/{envelopeId}/recipients

受信者には9つの役割が用意されており、リクエストパラメータに設定する必要があります。 調べたところでは、契約書を送信前に編集する人には「editors」、契約書に署名する人には「signers」、署名を確認する人には「witnesses」を設定します。

おわりに

以上、簡単ですがDocusignで利用できるAPIについて一部分を紹介しました。 各APIの具体的な利用方法や、他に設定可能なリクエストパラメータなどについては公式ドキュメントを参照して下さい。 developers.docusign.com

またPostmanのワークスペースが公開されており、Folkすることで自由に試すことも可能です。 www.postman.com

e Builderのフォーマッター関連の設定をGit経由で共有する方法

はじめに

こんにちは。開発部のA.Nです。

今回はe Builderのフォーマッター関連の設定をGit経由で共有する方法について紹介します。

プログラミングにおいて、ソースコードのフォーマットを整えることは非常に重要です。
チーム開発時に、フォーマットを揃えることでソースの可読性が向上し、作業の効率化に繋がります。

ぜひご活用ください!

e Builderのフォーマッター関連の機能について

e Builderには、ソースコードの書き方をチェックするツールや自動で整形する機能が備わっています。

  • CheckStyle
    CheckStyleとは、静的コード解析ツールで、コードのスタイルやコーディング規約に違反していないかを自動で検査するツールです。 違反している場合は下記のように背景が黄色になります。

CheckStyle警告画面

  • フォーマッター
    フォーマット定義の設定をもとにソースコードを自動で整形します。 Ctrl + Shift + Fでフォーマッターを利用できます。

フォーマッター関連の設定を共有する手順

フォーマッター関連の設定は、 ①e Builder上で設定を適用、②.settingsディレクトリのファイルをコミットの手順で共有が可能です。

CheckStyle・フォーマッターともにe Builder上で任意の設定ファイルを指定しますが、Gitでの共有時には各個人の環境に設定ファイルのインポートは不要です。

e Builder上で設定を適用

  • CheckStyle
    メニュー>ウィンドウ>設定>CheckStyleから任意の設定ファイルを適用します。

    CheckStyle設定画面

  • フォーマッター
    メニュー>ウィンドウ>設定>Java>コード・スタイル>フォーマッターから任意の設定ファイルを適用します。

    Formatter設定画面

また、下記設定で保存時にも自動でフォーマットされるようになります。

メニュー>ウィンドウ>設定>Java>エディター>保管アクション
(「ソース・コードのフォーマット」にチェックを入れる)

保存時Formatter適用設定画面

Gitにファイルをコミット

上記設定変更後に、.settings配下のファイルが変更されるため変更箇所をコミットしましょう。

おわりに

e Builderのフォーマッター関連の設定をGit経由で共有する方法について紹介しました。

今回の内容を活用して、チームでのフォーマット統一を効率的に行っていきましょう!

IM-BloomMakerのファイル添付機能をワークフローで使用する方法

はじめに

今回は、IM-BloomMakerのファイル添付機能をワークフローで使用する方法をご紹介します。
本記事ではAccel Studioでのワークフロー開発を前提とします。
利用するファイル添付機能の基本的な実装方法については、以下のドキュメントをご参照ください。 document.intra-mart.jp なお、公式ドキュメントではワークフローを使用しておらず、ユーザデータIDを取得する方法などが記載されていません。
ワークフローでファイル添付機能を使うにはユーザデータIDが必要となるため、本記事ではファイル添付機能の実装方法に加え、ユーザデータIDの取得方法についても解説します。

事前準備

単一ファイルアップロードの場合は5.3.1.2.2. IM-BloomMaker資材の編集(単一ファイルアップ ロードの場合)、複数ファイルアップロードの場合は5.3.1.2.3. IM-BloomMaker資材の編集(複数ファイルアップロードの場合)まで実装を完了させてください。

実装方法

1.申請時の添付ファイル保存設定(【Apply】アクション)

1-1. 申請ボタン押下時に実行される添付ファイル保存処理に必要なパラメータの取得
アクション>ワークフローの中にある「申請モーダルを表示する」のオプションから、以下の2つの出力値を変数に代入します。
・処理実行によるクローズであるか

$variable.state.closeModal

・ユーザデータID

$variable.state.entity.userDataId

【Apply】アクション

1-2.添付ファイル保存処理の実行条件の設定
「申請モーダルを表示する」の直後に「アクション Save Upload File を実行する」を配置し、$variable.state.closeModaltrue(処理実行による申請モーダルのクローズ)の時にのみ実行されるようにします。
※この条件が無い場合、申請処理を実行していなくても「アクション Save Upload File を実行する」が実行され、エラーが発生します。

「アクション Save Upload File を実行する」

2.添付ファイル保存処理(【Save Upload File】アクション)

2-1.添付ファイル保存処理に必要なパラメータの設定
$variable.endPoint.crud.requestParameter.businessKey$variable.state.entity.userDataIdを代入します。

【Save Upload File】アクション

3.画面初期表示時の添付ファイル取得処理(【Load Upload File Table】アクション)

3-1.添付ファイル取得処理に必要なパラメータの設定
$variable.endPoint.list.requestParameter.businessKey$input.imwUserDataIdを代入します。
※画面初期表示時に添付ファイルを取得する場合は、モーダルから$variable.state.entity.userDataIdが取得できないため$input.imwUserDataIdを使用します。

【Load Upload File Table】アクション

おわりに

IM-BloomMakerのファイル添付機能をワークフローで使用する方法について紹介しました。
IM-BloomMakerは豊富な機能と高いカスタマイズ性を備えており、業務ニーズに応じて柔軟に対応できます。
今後もこれらの機能を積極的に活用し、業務効率の向上と質の高いシステム構築を目指していきたいと思います。

IM-BloomMakerのラジオボタン・チェックボックスをワークフローで使用する方法

はじめに

今回は、IM-BloomMakerでラジオボタンチェックボックスをワークフローで使用する方法についてご紹介します。
本記事ではAccel Studioでのワークフロー開発(テンプレート「シンプルなワークフロー」を利用)を前提とします。

【参考】
4. テンプレート一覧 — Accel Studio テンプレートカタログ   第8版 2024-10-01   intra-mart Accel Platform

ラジオボタンの実装

ラジオボタンの実装は以下の手順で行います。

1.データ項目設定
2.送信値の設定
3.アイテムプロパティの設定

1.データ項目設定

ラジオボタンを実装する場合、項目のデータ型は"文字列"で設定します。

データ項目設定

2.送信値の設定

ラジオボタンを選択したときにサーバーに送信される値を、定数として固定の文字列に設定します。

「送信値の設定」

3.アイテムプロパティの設定

value
サーバーに送信する値を設定します。
この値には、「1.送信値の設定」で作成した定数を指定します。

・selected
ラジオボタンに入力が行われたとき、valueの値の保存先となる変数を設定します。
※ワークフローで利用するには、申請時に選択された値を承認画面で表示するために申請時DBに保存される変数を設定してください。

ラジオボタン プロパティの設定」

チェックボックスの実装

チェックボックスの実装は以下の手順で行います。

1.データ項目設定
2.アイテムプロパティの設定

1.データ項目設定

チェックボックスを実装する場合、項目のデータ型は"真偽値"で設定します。また、データ項目は実装するチェックボックスの選択肢分用意します。

データ項目設定

2.アイテムプロパティの設定

value
サーバーに送信する変数を設定します。
変数タブから環境情報より真偽値「true」の定数を指定します。

環境情報

・checked
チェックボックスに入力が行われたとき、valueの値の保存先となる変数を設定します。 変数の値が「true」の場合、チェックされた状態で表示されます。
「1.データ項目設定」で設定した変数を指定します。

これらのプロパティ設定により項目にチェックが入った場合「true」が、チェックが入らなかった場合は「false」がパラメータとしてサーバーに渡り、データ登録が可能となります。

チェックボックス プロパティの設定

おわりに

IM-BloomMakerのラジオボタンチェックボックスをワークフローで使用する方法について紹介しました。
IM-BloomMakerで使用する時に一つの例として参考にしてみてください。
ラジオボタンチェックボックスの項目についての詳細は以下リンクのintra-mart社によるIM-BloomMaker 標準部品についてのドキュメントからご確認ください。

document.intra-mart.jp

intra-martローコード資材のGit管理について

intra-mart Accel Platformの2024 Spring(Iris)バージョンからAccel StudioアプリケーションのGit連携機能が追加されました。
また、2024 Autumn(Jasmine)バージョンではGit連携先が拡充され、GitHub以外のサービス(GitLab、Backlog)と連携可能となりました。

今回の記事ではAccel StudioアプリケーションにおけるGit連携機能を、GitLabを用いて実際に使用してみましたので、その紹介を行います。

準備

GitLab側とintra-mart側での準備をそれぞれ記載します。

GitLab

1-1. Git連携を行うGitLabアカウントの個人設定から、「アクセストークン」画面を開きます。
1-2. Token nameに任意の名前を入力し、Select scopesで「read_repository」「write_repository」を選択し、アクセストークンを作成します。生成したアクセストークンはメモしておきます。

GitLabアクセストークン作成画面
GitLabアクセストークン作成画面

2-1. 連携したいAccel Studioアプリケーションを格納するためのGitLabプロジェクトを新規作成します。
※1つのAccel Studioアプリケーションに1つのGitLabプロジェクトが必要です。
2-2. 作成したプロジェクトのclone用のURLを確認しメモしておきます。

intra-mart

3-1. サイトマップ>Accel Studio>Git連携>Git認証定義画面を開き、上記1-1で生成したトークンと必要項目を入力して登録します。

Gitアップロード

Git連携ボタン(以下キャプチャの赤線に囲まれたボタン)を押下し、上記2-2で確認したclone用のURLを連携先URL入力欄に入力します。
アップロードコメントを入力し、「アップロード」ボタンを押下しGitアップロードを行います。

Gitアップロード
Gitアップロード

Gitインポート

初回インポート

サイトマップ>Accel Studio>Git連携>リモートリポジトリからインポート を押下し、
リポジトリのURL欄(以下キャプチャの赤線に囲まれたボタン)に、インポートしたいプロジェクトのclone用のURLを入力します。
取得したいブランチを選択し、「内容の確認へ」ボタンを押下し、インポートを実行します。

Gitインポート
Gitインポート

2回目以降インポート

※初回インポートを行ったAccel Studioアプリケーションに対しては、以下の2回目以降インポートの手順でインポートを行います。
※Gitのリモートリポジトリで更新された資材を反映するためにはインポート操作が必要です。

Accel Studioアプリケーション管理画面のGit連携メニュー内「インポート」ボタンを押下し、インポートを実行します。

Git連携の利点

ローコード資材のGit連携をすると以下のような利点があります。
・資材の保全性を高くすることができる。
・過去のバージョンを含む資材の管理が容易にできる。
・いつ誰がどのような資材変更を反映したかについて自明になる。

終わりに

GitLabを用いたGit連携の手順を紹介しました。
Accel StudioのGit連携は変更の差分が確認でき、開発において非常に便利な機能です。
ぜひみなさんの環境でも導入を検討してみてはいかがでしょうか。

本記事には記載していない制約などもありますので、
詳細は以下リンクのintra-mart社によるGit連携についてのドキュメントからご確認ください。

document.intra-mart.jp

Apache PDFBoxを用いたPDFファイルの画像変換処理

はじめに

こんにちは。開発部のK.Sです。

今回はJavaでのPDFからJPGへの変換処理の実装方法についてご紹介いたします。

こちらの処理を活用すれば、GIFやPNGなどJPG以外の形式への変換も可能です。ぜひご活用ください!

以下Apache PDFBoxライブラリを使用して、PDFからJPGに変換する手順を詳しく説明します。

JARファイルの追加

まず、Apache PDFBoxライブラリをプロジェクトに追加する必要があります。

Maven等のビルドツールを使用してライブラリを管理することをお勧めします。

Mavenを使用する場合は以下資料を参考にしてください。

pdfbox.apache.org

またビルドツールを使用しない場合は、以下からpdfbox-x.x.x.jar、pdfbox-tools-x.x.x.jarを直接ダウンロードし、

ダウンロードしたJARファイルをビルドパスに追加してください。

Java互換性、依存関係などに注意してファイルを選択してください) pdfbox.apache.org

ソースコード

// PDFファイル読み込み
PDDocument doc = PDDocument.load(
        new File("C:/test/sample.pdf"),
        MemoryUsageSetting.setupTempFileOnly()
);
// PDFのレンダリング
PDFRenderer pdfRenderer = new PDFRenderer(doc);
BufferedImage image = pdfRenderer.renderImageWithDPI(0, 300, ImageType.RGB);
// 画像のJPG形式への変換、出力
String path = "C:/test/convert/"; // 出力先パス
String fileName = "output"; // ファイル名
String fileFormat = ".jpg"; // 拡張子
ImageIOUtil.writeImage(image, path+fileName+fileFormat , 300);

上記のように記述することで、取得したPDFをJPGに変換し、任意の場所に出力することができます。

以下、ソースコードの詳細について説明します。

PDFの読み込み

PDFファイルを読み込みます。

// PDFファイル読み込み
PDDocument doc = PDDocument.load(
        new File("C:/test/sample.pdf"),
        MemoryUsageSetting.setupTempFileOnly()
);

第二引数ではPDFファイル読み込み時のメモリ使用設定を指定することができます。 MemoryUsageSetting.setupTempFileOnly()の場合、一時ファイルのみを使用する設定になります。

PDDocument.loadには他にもいくつか引数の指定方法があり、File型以外にもInputStream型等の利用やパスワード付のPDFを読み込むことも可能です。

※引数の指定等APIの詳細については以下を参考にしてください。 pdfbox.apache.org

PDFのレンダリング

PDFをレンダリングします。

// PDFレンダリング
PDFRenderer pdfRenderer = new PDFRenderer(doc);
BufferedImage image = pdfRenderer.renderImageWithDPI(0, 300, ImageType.RGB);

0: レンダリングするページ番号(0は最初のページを示します)。

300: DPI(dots per inch)。DPIが高いほど、画像の解像度が高くなります。

ImageType.RGB: 出力画像のカラーモード。ImageType.RGBはフルカラーのRGB画像を指定します。

※引数の指定等APIの詳細については以下を参考にしてください。 pdfbox.apache.org

画像のJPG形式への変換、出力

レンダリングしたデータをjpgとして出力します。

// 画像のJPG形式への変換、出力
String path = "C:/test/convert/"; // 出力先パス
String fileName = "output"; // ファイル名
String fileFormat = ".jpg"; // 拡張子
ImageIOUtil.writeImage(image, path+fileName+fileFormat , 300);

上記の例の場合、第二引数にパスを指定することで任意の場所に、ファイル名を指定して出力することが可能です。

また、この拡張子を変更することでGIFやPNGなどJPG以外の形式への変換も可能です

※引数の指定等APIの詳細については以下を参考にしてください。 pdfbox.apache.org

おわりに

以上、PDFBoxを用いてPDFからJPGに変換する方法についての紹介です。

Apache PDFBoxを活用することで、さまざまな画像形式への変換が容易に行えます。

PDFから画像形式への変換が必要になった際にはぜひ活用してみてください!

IM-BloomMakerを用いてコメント一覧表示画面を作成する~その2

はじめに

2021年度入社のY.Mです。

前回は、フローの処理済み完了案件から申請者、承認者のコメントを一覧画面として表示する機能の実装について、大まかな流れを紹介させていただきましたが、 今回は実装面について詳しく解説していこうと思います。

第1回目の記事: gsol.hatenablog.com

サーバ側の実装について

以下のような流れで実装を行います

1. 一覧画面の初期表示時にログインユーザのWorkflow処理済み完了案件をREST-APIで取得します

2. 取得した完了案件情報に含まれるシステム案件IDを使って案件の処理履歴を取得します

【カスタムスクリプト(案件履歴情報取得)】

   let matterurl = [];
   let resData = [];
  //案件番号を完了案件(処理済)から取り出して配列に格納する
   for(let i=0;i<$variable.im_workflow_rest_api.response.data.reords.length;i++){
       matterurl.push({
           url: "api/workflow/matters/" + 
           $variable.im_workflow_rest_api.response.data.records[i].systemMatterId 
           + "histories"
       });
  }
  //案件番号の数だけfor文で回し、非同期でリクエスト通信する
  for(let i=0;i<matterurl.length;i++){
      const http = new XMLHttpRequest();
      http.onreadystatechange = () => {
         if(http.readystate == "4" && http.status == "200"){
              //リクエストが返ってきた順番で案件履歴情報を格納する
             $variable.historyResData.push(JSON.parse(http.reponseText));
         }
      };
      http.open(
            "GET",
            "http://localhost:8080/bloom_comment/" + matterurl[i].url
     );
     http.send();
  }

※今回はカスタムスクリプトでREST-APIを実行しましたが、IM-BloomMakerの標準部品を使用してREST-APIを実行することもできます
https://document.intra-mart.jp/library/bloommaker/public/im_bloommaker_user_guide/texts/appendix/actions/regular.html#url

3. 取得した完了案件情報に含まれている以下の情報をそれぞれ変数に代入し、画面で表示します

  • 案件番号
  • 案件名
  • 完了日時
  • 処理履歴から取得したコメント

画面表示の実装について

IM-BloomMakerのアイテムについて(テーブル類、コンテナページ、変数等)

 今回の実装において、IM-BloomMakerで使用した主なアイテムは「フォーム部品」のリッチテーブル、「繰り返し(imui)」の縦方向のテーブル(繰り返し)です。 

リッチテーブルの画面側実装について

リッチテーブルのデータとして「dataSource」、列名として「headerRowString」を定義します。
 この「dataSource」に完了案件から取得した情報を代入しています。

【リッチテーブル画面】

縦方向のテーブル(繰り返し)の画面側実装について

縦方向のテーブル(繰り返し)について、REST-APIから取得したデータを、変数に代入します。

【縦方向テーブル画面(繰り返し)】

 ※補足として、コンテナページは1つの画面につき1つであり、別のコンテナページも埋め込んだりすることも可能です。ただし、デザイナ画面で複数のコンテナページを作成したとしても、それぞれ別なアクションを設定することはできません。
 設定する場合は別のコンテンツを新規作成して設定する、またはアクションを実行するときの条件を設定して分岐によって初期アクションを制御するといった方法があります。

IM-BloomMakerのアクション設定について(主にカスタムスクリプトやREST-API周り等)

カスタムスクリプトでのアクション設定

 カスタムスクリプトでは変数を使用することができ「$variable」で変数の値を取得したり代入したりすることができます。 他にも「$constant」で定数値、「$input」でhttpリクエストのリクエストパラメータなどで使用できる入力値も取得や代入が可能です。

今回設定したアクション設定

 カスタムスクリプトを用いてテーブルの行を動的に増やして案件番号などを代入しています。
行を動的に増やす方法ですが、エレメントのテーブル類に紐づいている配列や変数は配列やマップのメソッドも使用可能です。 今回の実装を例にすると、「 $variable.historyResData」がテーブルに表示したいデータを格納しているオブジェクトの配列なので、push()を使用してREST-APIから取得した案件履歴情報を代入しています。

REST-APIでのアクション設定

 REST-APIでのリクエストパラメータと、レスポンスパラメータはWorkflowの情報を取得したい場合だと、【参考資料】のIM-Workflow REST-APIのリクエストパラメータとレスポンスをそのまま変数として定義する必要があります。その際に、マップ型の変数の下にリクエストとレスポンスパラメータを配置することも必要です。

その他のアクション設定

 アクション設定で使用できるものとして「URLにリクエストを送信する」、「IM-LogicDesignerのフロールーティングにリクエストを送信する」といったアクションが設定でき、REST-APIを通じてIM-LogicDesignerのフローの実行、リクエストの送信が行えます。

終わりに

開発で苦労した点・注意する点

 開発で苦労した点では、IM-BloomMakerのintra-mart公式ドキュメントに書いてあるアイテムの詳しい説明や、応用的な使い方、カスタムスクリプトなどでの使用方法が記載されていませんでした。公式ドキュメントでのアイテム説明は全て簡易的なものであり、実際のサンプルはintra-martの開発サイトに遷移するリンクが記載されているだけで情報が少ないことが多く、実装にとても苦労しました。

 また、公式で記載されているチュートリアルは基本的な動きのみでありサンプル画面である共通マスタを取得・設定する画面で使用されているアイテムやアクションの説明も公式ドキュメントになく実際のサンプルを見て理解するしかなかったです。

 具体的には、カスタムスクリプトを使ってテーブルの行を動的に増やす処理が記載されておらず、サンプルの方ではpush()を使って実装しておりました。 また、カスタムスクリプトでは、ES6ベースでJavaScriptを使用できると記載があったが実際にはHttpリクエストを送信するfetch()メソッドがfetch(使用するURL)と書いても使用できずにエラーを吐いてしまったりしました。これに関しても、どのメソッドが使用可能でどんな記法で使えるのかの記載もなかったため、今回はXMLHttpRequestを使用しました。

参考資料

IM-BloomMaker ユーザ操作ガイド
https://document.intra-mart.jp/library/bloommaker/public/im_bloommaker_user_guide/index.html

IM-BloomMaker チュートリアルガイド
https://document.intra-mart.jp/library/bloommaker/public/im_bloommaker_tutorial_guide/index.html

IM-Workflow REST-API
https://document.intra-mart.jp/library/iap/public/im_workflow/im_workflow_specification/texts/api_guide/rest_api/index.html

最後に

以上で前回と今回で2回にわたって投稿させていただいたIM-BloomMakerを用いたコメント一覧表示画面の紹介を終わります。

ViewCreator日付検索機能の落とし穴

はじめに

今回は、intra-mart標準機能であるViewCreatorを利用した開発での注意点をご紹介します。

発生した事象

案件情報を表示する機能を開発中に、表示項目の「申請日」を検索する機能が予期せぬ動作をしました。
例えば「2024/05/31 10:20:30」に申請されたデータは、「2024/05/01~2024/05/31」という範囲検索を行っても、5月31日のデータとして抽出されませんでした。

ViewCreator標準検索機能
ViewCreator標準検索機能

原因と対処法

原因は、検索欄入力日付の「~2024/05/31」は内部では「2024/05/31 0時0分0秒以前」のデータを対象としているためでした。

  • intra-martの案件情報テーブルの「申請日」はデータ型がtimestamp型のため、時刻まで保存されている。

  • ViewCreatorの標準検索機能は「×日以前」という検索を処理する際に、「×日の0時0分0秒以前」としてデータの検索を行う。

これらの仕様への対処法は、「申請日」のデータを案件情報テーブルからそのまま使用するのではなく、 時分秒を無視する形で処理を作成することです。

具体的には、物理View作成時にSQLで時分秒を00:00:00に設定する、もしくは時分秒を切り捨てるような処理を追加します。
これにより、日付のみを基準にした検索が可能となり、期待通りのデータ抽出が行えるようになります。

【物理Viewの作成について】

document.intra-mart.jp

このような日付検索機能の仕様は、データの正確な抽出に影響を及ぼすため、開発時には気を付けてください。
正しいデータ抽出を保証するためにも、ViewCreatorの日付検索機能の仕様を理解し、適切な対策を講じていきましょう。