プロセス管理のカスタマイズ

にメンテナンス済み

kintone のプロセス管理機能は、承認フローや業務ワークフローを標準機能として実現できる便利な仕組みです。JavaScript カスタマイズを組み合わせることで、ステータスに応じたフィールドの制御やバリデーション、外部連携など、より高度な業務フローを実装できます。

この記事では、プロセス管理に関連するイベントや API の活用方法を解説します。

プロセス管理イベントとは

プロセス管理が有効なアプリでは、ステータスの変更(アクションの実行)時に発火するイベントが用意されています。

イベント名発火タイミング
app.record.detail.process.proceedステータス変更の実行時(PC)
mobile.app.record.detail.process.proceedステータス変更の実行時(モバイル)

このイベントは、ユーザーがアクション(「承認する」「差し戻す」など)をクリックしたタイミングで発火します。

チェック

プロセス管理イベントは非同期処理(async/await)に対応しています。REST API を呼び出してから処理を続行するような実装が可能です。

ステータス変更時のバリデーション

ステータスを変更する前に、特定の条件を満たしているかチェックし、条件を満たしていない場合はステータスの変更をキャンセルすることができます。

process-validation.js
(() => {
  'use strict';

  const events = [
    'app.record.detail.process.proceed',
    'mobile.app.record.detail.process.proceed',
  ];

  kintone.events.on(events, (event) => {
    const record = event.record;
    const nextStatus = event.nextStatus.value;
    const action = event.action.value;

    // 「承認」アクション時に必須フィールドのチェック
    if (action === '承認する') {
      if (!record['承認コメント'].value) {
        event.error = '承認する場合はコメントを入力してください';
        return event;
      }

      if (!record['添付ファイル'].value.length) {
        event.error = '承認する場合は添付ファイルが必要です';
        return event;
      }
    }

    // 「差し戻し」アクション時に理由の入力チェック
    if (action === '差し戻す') {
      if (!record['差し戻し理由'].value) {
        event.error = '差し戻す場合は理由を入力してください';
        return event;
      }
    }

    return event;
  });
})();
チェック

event.error に文字列を設定して return event すると、ステータスの変更がキャンセルされ、エラーメッセージが画面上に表示されます。

ステータス変更時に外部システムに通知する

プロセス管理のステータスが変更されたタイミングで、外部のチャットツールや API に通知を送る例です。

process-notification.js
(() => {
  'use strict';

  /**
   * Slack の Incoming Webhook にメッセージを送信する
   * @param { string } webhookUrl - Webhook URL
   * @param { string } message - 送信するメッセージ
   */
  const sendSlackNotification = async (webhookUrl, message) => {
    await kintone.proxy(
      webhookUrl,
      'POST',
      { 'Content-Type': 'application/json' },
      JSON.stringify({ text: message })
    );
  };

  const events = [
    'app.record.detail.process.proceed',
    'mobile.app.record.detail.process.proceed',
  ];

  kintone.events.on(events, async (event) => {
    const record = event.record;
    const nextStatus = event.nextStatus.value;
    const action = event.action.value;

    const WEBHOOK_URL = 'https://hooks.slack.com/services/xxx/yyy/zzz';

    const message = [
      `📋 ステータスが変更されました`,
      `アクション: ${action}`,
      `新しいステータス: ${nextStatus}`,
      `タイトル: ${record['タイトル'].value}`,
      `申請者: ${record['申請者'].value}`,
    ].join('\n');

    try {
      await sendSlackNotification(WEBHOOK_URL, message);
    } catch (error) {
      console.error('Slack通知に失敗しました:', error);
      // 通知の失敗でステータス変更をブロックしたくない場合はエラーを無視する
    }

    return event;
  });
})();

ステータスに応じたフィールド制御

画面表示時のイベントで、現在のステータスに応じてフィールドの表示や入力可否を制御するパターンです。

status-field-control.js
(() => {
  'use strict';

  const events = [
    'app.record.detail.show',
    'app.record.edit.show',
    'mobile.app.record.detail.show',
    'mobile.app.record.edit.show',
  ];

  kintone.events.on(events, (event) => {
    const record = event.record;
    const status = record['ステータス'].value;

    switch (status) {
      case '下書き':
        // 下書き状態では全フィールドを編集可能
        break;

      case '申請中':
        // 申請中は申請者フィールドを編集不可に
        record['申請内容'].disabled = true;
        record['金額'].disabled = true;
        break;

      case '承認済み':
        // 承認済みは全フィールドを編集不可に
        record['申請内容'].disabled = true;
        record['金額'].disabled = true;
        record['承認コメント'].disabled = true;
        break;

      case '差し戻し':
        // 差し戻し時は修正可能だが、差し戻し理由は編集不可
        record['差し戻し理由'].disabled = true;
        break;
    }

    return event;
  });
})();
フィールドの入力制限・可否の変更
アプリの各フィールドの入力可否を操作する方法を解説します。ルックアップと関連付けたフィールドは入力不可になりますが、今回紹介する方法で手入力可能にできます。再度ルックアップを取得したタイミングや、データの取り込みを行ったタイミングで手入力部

REST API でステータスを変更する

REST API を使ってプログラムからステータスを変更することも可能です。

1 件のレコードのステータスを変更する

update-status.js
/**
 * REST API でレコードのステータスを変更する
 * @param { Object } params
 * @param { string | number } params.app - アプリID
 * @param { string | number } params.id - レコードID
 * @param { string } params.action - 実行するアクション名
 * @param { string } [params.assignee] - 次のステップの作業者のログイン名
 */
const updateStatus = (params) => {
  const { app, id, action, assignee } = params;
  const body = { app, id, action };

  if (assignee) {
    body.assignee = assignee;
  }

  return kintone.api(kintone.api.url('/k/v1/record/status.json', true), 'PUT', body);
};

// 使用例
updateStatus({
  app: kintone.app.getId(),
  id: 1,
  action: '承認する',
  assignee: 'user01',
}).then(() => {
  console.log('ステータスを更新しました');
});

複数レコードのステータスを一括変更する

bulk-update-status.js
/**
 * REST API で複数レコードのステータスを一括変更する
 * @param { Object } params
 * @param { string | number } params.app - アプリID
 * @param { Array<{ id: number; action: string; assignee?: string }> } params.records - レコード情報
 */
const bulkUpdateStatus = (params) => {
  const { app, records } = params;
  return kintone.api(kintone.api.url('/k/v1/records/status.json', true), 'PUT', {
    app,
    records,
  });
};

// 使用例: 一覧で選択されたレコードを一括承認
bulkUpdateStatus({
  app: kintone.app.getId(),
  records: [
    { id: 1, action: '承認する' },
    { id: 2, action: '承認する' },
    { id: 3, action: '承認する' },
  ],
}).then(() => {
  console.log('一括承認が完了しました');
});
チェック

一括ステータス変更の上限は 100 件です。100 件を超える場合は、分割して実行する必要があります。

event オブジェクトの構造

プロセス管理イベントの event オブジェクトには、通常のフィールドイベントに加えて以下のプロパティが含まれます。

プロパティ説明
event.action.valuestring実行されたアクション名(「承認する」「差し戻す」等)
event.status.valuestring現在のステータス
event.nextStatus.valuestringアクション実行後のステータス
event.recordobjectレコード情報

まとめ

  • app.record.detail.process.proceed イベントでステータス変更時に処理を実行できる
  • event.error を設定することで、条件を満たさない場合にステータス変更をキャンセルできる
  • プロセス管理イベントは非同期処理(async/await)に対応している
  • 画面表示イベントと組み合わせることで、ステータスに応じたフィールド制御が実現できる
  • REST API を使えば、プログラムからステータスの変更や一括処理が可能
#kintone #JavaScript #TypeScript