0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

rex0220 アプリマイスター・レイ アプリ作成後に関連レコードを追加

Posted at

rex0220 アプリマイスター・レイで、アプリ作成後に関連レコードを追加してみます。

概要

rex0220 アプリマイスター・レイを使って、レンタル機器管理を行うアプリを作成後に、関連レコードを追加してみます。

※関連レコードを追加の動作検証が目的なので、項目は最小限としています。

2025-11-26_21h40_47.png

アプリ作成コードを作っているレイ

Adobe Express - 2f510392-0857-4340-afb9-3c66b8e49f02.gif

アプリ作成

レンタル機器の管理要件を指定します。

レンタル機器管理を行いたい
レンタル機器マスタ:アイテムコード、アイテム名、価格
レンタル案件: アイテムコード(ルックアップ)、アイテム名

アプリ作成の回答

こんにちは!rex0220 アプリマイスター・レイです!🦊
レンタルの管理ですね。マスタと案件アプリを分けて管理する構成、拡張性が高くて素晴らしい選択です!

ご要望の「レンタル機器マスタ」と、それを参照する「レンタル案件管理」アプリを一括で作成するスクリプトを用意しました。
私のこだわりとして、**レンタル業務で絶対に必要になる「レンタル日数」と「合計金額(自動計算)」**もこっそり追加しておきました。これで現場での計算の手間が省けますよ!

ブラウザのコンソール(F12キー)で以下のコードを実行してください。

/**
 * 🦊 kintone App Meister Ray's Work
 * Project: レンタル機器管理システム構築(マスタ・案件連携)
 */
(async () => {
  try {
    console.log('🦊 レイ: レンタル管理システムの構築を開始します!安全第一で進めますね。');

    // =======================================================
    // Phase 1: レンタル機器マスタの構築
    // =======================================================
    
    // 1. マスタアプリ作成
    const createMasterBody = { name: 'レンタル機器マスタ' };
    const masterResp = await kintone.api(kintone.api.url('/k/v1/preview/app', true), 'POST', createMasterBody);
    const masterAppId = masterResp.app;
    console.log(`Step 1: レンタル機器マスタを作成しました (App ID: ${masterAppId})`);

    // 2. マスタのフィールド設定
    const masterFields = {
      app: masterAppId,
      properties: {
        'アイテムコード': {
          type: 'SINGLE_LINE_TEXT',
          code: 'アイテムコード',
          label: 'アイテムコード',
          unique: true,     // ルックアップのキーにするため重複禁止に設定
          required: true
        },
        'アイテム名': {
          type: 'SINGLE_LINE_TEXT',
          code: 'アイテム名',
          label: 'アイテム名',
          required: true
        },
        '価格': {
          type: 'NUMBER',
          code: '価格',
          label: '価格(日額)', // 分かりやすく日額と表記
          digit: true,      // 桁区切りON
          unit: '',
          unitPosition: 'AFTER'
        }
      }
    };
    await kintone.api(kintone.api.url('/k/v1/preview/app/form/fields', true), 'POST', masterFields);
    console.log('Step 2: マスタのフィールド設定完了');

    // 3. ★マスタアプリの公開 (Deploy)
    // ※ルックアップの参照先は公開されている必要があるため、ここで一度公開します
    console.log('Step 3: マスタアプリを先に公開します(連携準備)...');
    await kintone.api(kintone.api.url('/k/v1/preview/app/deploy', true), 'POST', { apps: [{ app: masterAppId }] });
    
    // 公開処理がシステムに反映されるまで、少し待ちます(5秒)
    console.log('⏳ (公開処理の反映を待っています...)');
    await new Promise(resolve => setTimeout(resolve, 5000));


    // =======================================================
    // Phase 2: レンタル案件管理の構築
    // =======================================================

    // 4. 案件アプリ作成
    const createProjectBody = { name: 'レンタル案件管理' };
    const projectResp = await kintone.api(kintone.api.url('/k/v1/preview/app', true), 'POST', createProjectBody);
    const projectAppId = projectResp.app;
    console.log(`Step 4: レンタル案件アプリを作成しました (App ID: ${projectAppId})`);

    // 5. 案件アプリのフィールド設定(ルックアップ含む)
    const projectFields = {
      app: projectAppId,
      properties: {
        '案件名': {
          type: 'SINGLE_LINE_TEXT',
          code: '案件名',
          label: '案件名',
          required: true
        },
        // --- ルックアップ設定 ---
        'アイテムコード': {
          type: 'SINGLE_LINE_TEXT',
          code: 'アイテムコード',
          label: 'アイテムコード(ルックアップ)',
          lookup: {
            relatedApp: { app: masterAppId }, // ★作成したマスタIDを指定
            relatedKeyField: 'アイテムコード',
            lookupPickerFields: ['アイテムコード', 'アイテム名', '価格'],
            fieldMappings: [
              { field: 'アイテム名', relatedField: 'アイテム名' },
              { field: '価格', relatedField: '価格' }
            ]
          }
        },
        // --- コピー先フィールド ---
        'アイテム名': {
          type: 'SINGLE_LINE_TEXT',
          code: 'アイテム名',
          label: 'アイテム名'
        },
        '価格': {
          type: 'NUMBER',
          code: '価格',
          label: '価格(日額)',
          digit: true,
          unit: '',
          unitPosition: 'AFTER'
        },
        // --- レイのこだわり追加フィールド ---
        'レンタル日数': {
          type: 'NUMBER',
          code: 'レンタル日数',
          label: 'レンタル日数',
          defaultValue: '1',
          unit: '',
          unitPosition: 'AFTER'
        },
        '合計金額': {
          type: 'CALC',
          code: '合計金額',
          label: '合計金額',
          expression: '価格 * レンタル日数', // 自動計算
          format: 'NUMBER_DIGIT',
          unit: '',
          unitPosition: 'AFTER'
        }
      }
    };
    await kintone.api(kintone.api.url('/k/v1/preview/app/form/fields', true), 'POST', projectFields);
    console.log('Step 5: 案件アプリのフィールド設定完了');

    // 6. 案件アプリのレイアウト設定
    const layoutBody = {
      app: projectAppId,
      layout: [
        { 
          type: 'ROW', 
          fields: [
            { type: 'SINGLE_LINE_TEXT', code: '案件名' }
          ]
        },
        { type: 'ROW', fields: [{ type: 'LABEL', label: '▼ レンタル機器選択' }] },
        { 
          type: 'ROW', 
          fields: [
            { type: 'SINGLE_LINE_TEXT', code: 'アイテムコード' }, // 取得ボタン
            { type: 'SINGLE_LINE_TEXT', code: 'アイテム名' }
          ]
        },
        { 
          type: 'ROW', 
          fields: [
            { type: 'NUMBER', code: '価格' },
            { type: 'NUMBER', code: 'レンタル日数' },
            { type: 'CALC', code: '合計金額' }
          ]
        }
      ]
    };
    await kintone.api(kintone.api.url('/k/v1/preview/app/form/layout', true), 'PUT', layoutBody);
    console.log('Step 6: レイアウトも美しく整えました');

    // 7. 案件アプリの公開 (Deploy)
    console.log('Step 7: 案件アプリを公開します...');
    await kintone.api(kintone.api.url('/k/v1/preview/app/deploy', true), 'POST', { apps: [{ app: projectAppId }] });

    // =======================================================
    // 完了メッセージ
    // =======================================================
    console.log('-------------------------------------------------------');
    console.log('🎉 レイ: 作業完了です!2つのアプリが作成されました。');
    console.log(`1. レンタル機器マスタ (App ID: ${masterAppId})`);
    console.log(`2. レンタル案件管理 (App ID: ${projectAppId})`);
    console.log('まずは「マスタ」にデータを登録してから、「案件」でルックアップを試してみてくださいね!');
    console.log('-------------------------------------------------------');

  } catch (error) {
    console.error('🦊 レイ: おっと、エラーが発生しました。内容を確認しましょう。', error);
    if (error.error) console.error(JSON.stringify(error.error, null, 2));
  }
})();

🦊 レイからのワンポイントアドバイス

  • マスタデータの登録: アプリ作成後、まずは「レンタル機器マスタ」にいくつかテストデータを登録してくださいね。そうしないと、ルックアップボタンを押しても何も出てきません。
  • フィールドコード: 今回は分かりやすく日本語のラベルと同じに設定しました。これで計算式の設定なども迷わずに行えます!

うまく動きましたか?次は一覧画面の設定などもお手伝いできますよ!

アプリ作成の実行

kintone 画面の console にコードをコピペして、実行します。

2025-11-26_21h45_16.png

関連レコードの作成依頼

アプリの作成結果をもとに、関連レコードの作成を依頼します。

レンタル機器マスタに、関連レコードでレンタル案件管理を表示
レンタル機器マスタ appId: 3882
レンタル案件管理 appId: 3883

関連レコード作成の回答

こんにちは!rex0220 アプリマイスター・レイです!🦊
レンタル機器マスタに、その機器がどの案件でレンタルされているかを確認できる「関連レコード一覧」を追加したいということですね。
これがあると、機器の稼働状況が一目でわかって便利です!

ご提示いただいたアプリID(マスタ: 3882、案件: 3883)を使って、レンタル機器マスタ側に「レンタル案件履歴」を表示する設定を行うスクリプトを作成しました。

ブラウザのコンソールで以下のコードを実行してください。

/**
 * 🦊 kintone App Meister Ray's Work
 * Project: レンタル機器マスタ改修(関連レコード追加)
 * Target App: 3882 (Master), Related App: 3883 (Project)
 */
(async () => {
  try {
    const masterAppId = 3882; // レンタル機器マスタ
    const projectAppId = 3883; // レンタル案件管理

    console.log(`🦊 レイ: レンタル機器マスタ(ID: ${masterAppId}) に関連レコードを追加します!`);

    // -------------------------------------------------------
    // 1. 関連レコードフィールドの追加
    // -------------------------------------------------------
    const updateFieldsBody = {
      app: masterAppId,
      properties: {
        'レンタル案件履歴': {
          type: 'REFERENCE_TABLE',
          code: 'レンタル案件履歴',
          label: 'レンタル案件履歴',
          referenceTable: {
            relatedApp: { app: projectAppId },
            condition: {
              field: 'アイテムコード',      // マスタ側のキー
              relatedField: 'アイテムコード' // 案件側のキー(ルックアップフィールド)
            },
            filterCond: '',
            displayFields: ['案件名', 'レンタル日数', '合計金額'], // 表示したい項目
            sort: 'レコード番号 desc',
            size: 5
          }
        }
      }
    };

    // POSTでフィールドを追加(既に存在する場合はエラーになるので、PUTでの更新も検討できますが、今回は追加として扱います)
    // 既存のフィールドを上書き更新したい場合は 'PUT' を使いますが、関連レコードは新規作成として 'POST' が安全です。
    // エラーハンドリングで「既に存在する」場合はスキップするロジックも考えられますが、まずはシンプルに。
    try {
        await kintone.api(kintone.api.url('/k/v1/preview/app/form/fields', true), 'POST', updateFieldsBody);
        console.log('Step 1: 関連レコードフィールドを追加しました');
    } catch (e) {
        // 既にある場合のエラーを想定して、PUTで再トライ(設定変更)
        if (e.error && e.error.code === 'GAIA_FC004') { // 重複エラーコードなど
             console.log('ℹ️ フィールドが既に存在するため、設定を更新(PUT)します...');
             await kintone.api(kintone.api.url('/k/v1/preview/app/form/fields', true), 'PUT', updateFieldsBody);
        } else {
            throw e;
        }
    }

    // -------------------------------------------------------
    // 2. レイアウトへ配置
    // -------------------------------------------------------
    // 現在のレイアウトを取得
    const layoutResp = await kintone.api(kintone.api.url('/k/v1/preview/app/form/layout', true), 'GET', { app: masterAppId });
    let currentLayout = layoutResp.layout;

    // 既にレイアウトに配置済みかチェック
    const isExist = currentLayout.some(row => 
        row.fields && row.fields.some(field => field.code === 'レンタル案件履歴')
    );

    if (!isExist) {
        // レイアウトの末尾に追加
        currentLayout.push({
            type: 'ROW',
            fields: [{ type: 'LABEL', label: '▼ 稼働履歴(関連レコード)' }]
        });
        currentLayout.push({
            type: 'ROW',
            fields: [{ type: 'REFERENCE_TABLE', code: 'レンタル案件履歴' }]
        });

        const layoutBody = {
            app: masterAppId,
            layout: currentLayout
        };
        await kintone.api(kintone.api.url('/k/v1/preview/app/form/layout', true), 'PUT', layoutBody);
        console.log('Step 2: レイアウトにフィールドを配置しました');
    } else {
        console.log('Step 2: レイアウトには既に配置済みでした');
    }

    // -------------------------------------------------------
    // 3. アプリの公開 (Deploy)
    // -------------------------------------------------------
    console.log('Step 3: マスタアプリを公開します...');
    await kintone.api(kintone.api.url('/k/v1/preview/app/deploy', true), 'POST', { apps: [{ app: masterAppId }] });

    // =======================================================
    // 完了メッセージ
    // =======================================================
    console.log('-------------------------------------------------------');
    console.log('🎉 レイ: 設定完了です!');
    console.log(`レンタル機器マスタ(ID: ${masterAppId}) の詳細画面で、`);
    console.log('案件履歴が表示されるようになっているはずです。確認してみてください!');
    console.log('-------------------------------------------------------');

  } catch (error) {
    console.error('🦊 レイ: おっと、エラーが発生しました。', error);
    if (error.error) console.error(JSON.stringify(error.error, null, 2));
  }
})();

🦊 レイのチェックポイント

  • キーフィールド: 関連付ける条件として、双方の「アイテムコード」を使用しています。案件アプリ側の「アイテムコード」はルックアップフィールドですが、関連レコードの条件として問題なく機能します。
  • 表示項目: パッと見て状況がわかるように、「案件名」「レンタル日数」「合計金額」を表示するように設定しました。

設定が終わったら、マスタアプリの詳細画面を開いてみてくださいね!

関連レコードの作成の実行

kintone 画面で、コードを console にコピペして実行します。

2025-11-26_21h49_32.png

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?