プロセス管理の作業者を削除したい

JavaScriptでプロセス管理の作業者を削除したく、生成AIでコードを作成しているのですが
削除されない状態です。削除は無理なのでしょうか。

コードは下記です。
動き的には、ボタンをクリックすると、ステータスが、「対象ステータス(【修繕工事申請】支払い・入金済」または「【修繕工事申請以外】支払い・入金済」の場合、作業者を削除する…というものです。

もし何かわかりましたら、ご教示いただけないでしょうか。
よろしくお願いいたします。

コー(function() {
  'use strict';
  
  // 設定値
  var STATUS_FIELD_CODE = 'ステータス';  // ステータスフィールドのフィールドコード
  var TARGET_STATUS_1 = '【修繕工事申請】支払い・入金済';  // 対象ステータス1
  var TARGET_STATUS_2 = '【修繕工事申請以外】支払い・入金済';  // 対象ステータス2
  
  // 一覧画面の表示イベント
  kintone.events.on('app.record.index.show', function(event) {
    // すでにボタンが配置されている場合は処理をスキップ
    if (document.getElementById('clear-all-workers-button')) {
      return event;
    }
    
    // デバッグモード(詳細ログ出力)
    var debugMode = true;
    
    // ボタンを作成
    var button = document.createElement('button');
    button.id = 'clear-all-workers-button';
    button.innerHTML = '全ての対象レコードの作業者クリア';
    button.style.marginLeft = '10px';
    button.className = 'kintoneplugin-button-normal';
    
    // デバッグ用のログ関数
    function debugLog(message, data) {
      if (debugMode) {
        if (data) {
          console.log('[DEBUG] ' + message, data);
        } else {
          console.log('[DEBUG] ' + message);
        }
      }
    }
    
    // エラーログ関数
    function errorLog(message, error) {
      console.error('[ERROR] ' + message, error);
    }
    
    // ボタンクリック時の処理
    button.onclick = function() {
      // 確認ダイアログの表示
      if (!confirm('対象ステータス(【修繕工事申請】支払い・入金済、【修繕工事申請以外】支払い・入金済)の全レコードの作業者をクリアします。よろしいですか?')) {
        return;
      }
      
      // 処理中ダイアログの表示
      var progressDialog = document.createElement('div');
      progressDialog.id = 'progress-dialog';
      progressDialog.style.position = 'fixed';
      progressDialog.style.top = '50%';
      progressDialog.style.left = '50%';
      progressDialog.style.transform = 'translate(-50%, -50%)';
      progressDialog.style.background = 'white';
      progressDialog.style.padding = '20px';
      progressDialog.style.border = '1px solid #ccc';
      progressDialog.style.boxShadow = '0 0 10px rgba(0,0,0,0.2)';
      progressDialog.style.zIndex = '10000';
      progressDialog.innerHTML = '<p>対象レコードを検索中...</p>';
      document.body.appendChild(progressDialog);
      
      debugLog('処理開始: アプリID = ' + kintone.app.getId());
      
      // アプリのプロセス管理設定を取得
      kintone.api(kintone.api.url('/k/v1/app/status.json', true), 'GET', {
        app: kintone.app.getId()
      }).then(function(statusResp) {
        debugLog('アプリのプロセス管理設定を取得しました', statusResp);
        
        // プロセス管理情報を保持
        var processSettings = statusResp;
        
        // 対象ステータスのレコードを検索
        var query = STATUS_FIELD_CODE + ' in ("' + TARGET_STATUS_1 + '", "' + TARGET_STATUS_2 + '")';
        debugLog('検索クエリ: ' + query);
        
        return kintone.api(kintone.api.url('/k/v1/records.json', true), 'GET', {
          app: kintone.app.getId(),
          query: query
        });
      }).then(function(resp) {
        var records = resp.records;
        debugLog('検索結果: ' + records.length + '件のレコードが見つかりました', records);
        
        if (!records || records.length === 0) {
          document.body.removeChild(progressDialog);
          alert('対象ステータスのレコードが見つかりませんでした。');
          return Promise.reject('対象レコードなし');
        }
        
        // 処理ダイアログの更新
        progressDialog.innerHTML = '<p>' + records.length + '件のレコードを処理しています...</p>' +
                                  '<div id="progress-count">0 / ' + records.length + '</div>' +
                                  '<div id="current-record"></div>';
        
        var progressCount = document.getElementById('progress-count');
        var currentRecordDiv = document.getElementById('current-record');
        
        // 各レコードを処理する非同期関数(直列実行)
        async function processRecords() {
          var successCount = 0;
          var errorCount = 0;
          var resultDetails = [];
          
          for (var i = 0; i < records.length; i++) {
            var record = records[i];
            var recordId = record.$id.value;
            
            progressCount.textContent = (i + 1) + ' / ' + records.length;
            currentRecordDiv.textContent = 'レコードID: ' + recordId;
            
            debugLog('レコード処理開始: ID = ' + recordId);
            
            try {
              // 作業者削除の新しいアプローチを実行
              var result = await clearWorkerWithMultipleApproaches(recordId, record[STATUS_FIELD_CODE].value);
              
              if (result.success) {
                successCount++;
                debugLog('レコード処理成功: ID = ' + recordId);
              } else {
                errorCount++;
                errorLog('レコード処理失敗: ID = ' + recordId, result.error);
              }
              
              resultDetails.push({
                id: recordId,
                status: record[STATUS_FIELD_CODE].value,
                result: result
              });
              
              // 連続API呼び出しを避けるための遅延
              await new Promise(resolve => setTimeout(resolve, 500));
              
            } catch (error) {
              errorCount++;
              errorLog('レコード処理中の例外: ID = ' + recordId, error);
              
              resultDetails.push({
                id: recordId,
                status: record[STATUS_FIELD_CODE].value,
                error: error
              });
            }
          }
          
          return {
            success: successCount,
            error: errorCount,
            total: records.length,
            details: resultDetails
          };
        }
        
        // プロセス管理の作業者を複数の方法で削除する関数
        async function clearWorkerWithMultipleApproaches(recordId, status) {
          debugLog('作業者クリア処理開始: ID = ' + recordId + ', ステータス = ' + status);
          
          try {
            // 1. 最初のアプローチ: kintone UI経由でのプログラム的な操作
            var result = await clearWorkerThroughUI(recordId);
            if (result.success) {
              return result;
            }
            
            // 2. ステータスAPIを使用した直接的なクリア
            result = await clearWorkerWithStatusAPI(recordId, status);
            if (result.success) {
              return result;
            }
            
            // 3. 直接のレコード更新
            result = await clearWorkerWithDirectUpdate(recordId);
            if (result.success) {
              return result;
            }
            
            // 全ての方法が失敗
            return {
              success: false,
              method: 'all-failed',
              error: '全ての方法で作業者のクリアに失敗しました'
            };
            
          } catch (error) {
            return {
              success: false,
              method: 'exception',
              error: error
            };
          }
        }
        
        // UI操作を模倣して作業者をクリアする関数
        async function clearWorkerThroughUI(recordId) {
          try {
            debugLog('UI経由のクリアを試行: ID = ' + recordId);
            
            // レコードの詳細を取得
            var resp = await kintone.api(kintone.api.url('/k/v1/record.json', true), 'GET', {
              app: kintone.app.getId(),
              id: recordId
            });
            
            // 実際の処理
            // kintoneではUIからプロセス管理の作業者を変更する場合、内部的には特定のAPIが呼ばれる
            // これをシミュレートする
            
            // プロセス管理の内部フィールドを探す
            var processField = null;
            for (var fieldCode in resp.record) {
              if (fieldCode === 'Status' || 
                  fieldCode.indexOf('Status_') === 0 ||
                  fieldCode === '作業者' ||
                  fieldCode.indexOf('process') === 0) {
                
                debugLog('プロセス管理候補フィールド: ' + fieldCode, resp.record[fieldCode]);
                processField = fieldCode;
              }
            }
            
            if (!processField) {
              return {
                success: false,
                method: 'ui-simulation',
                error: 'プロセス管理フィールドが見つかりませんでした'
              };
            }
            
            // プロセス管理の担当者を直接空にする
            var updateData = {
              app: kintone.app.getId(),
              id: recordId,
              record: {}
            };
            
            // 空の配列を設定(作業者クリア)
            updateData.record[processField] = {
              value: []
            };
            
            await kintone.api(kintone.api.url('/k/v1/record.json', true), 'PUT', updateData);
            
            return {
              success: true,
              method: 'ui-simulation'
            };
            
          } catch (error) {
            return {
              success: false,
              method: 'ui-simulation',
              error: error
            };
          }
        }
        
        // ステータスAPIを使用して作業者をクリアする関数
        async function clearWorkerWithStatusAPI(recordId, status) {
          try {
            debugLog('ステータスAPIでのクリアを試行: ID = ' + recordId);
            
            // ステータスを変更せずに作業者だけをクリアするリクエスト
            await kintone.api(kintone.api.url('/k/v1/record/status.json', true), 'PUT', {
              app: kintone.app.getId(),
              id: recordId,
              assignee: []
            });
            
            return {
              success: true,
              method: 'status-api'
            };
            
          } catch (error) {
            return {
              success: false,
              method: 'status-api',
              error: error
            };
          }
        }
        
        // レコード更新APIを使用して直接作業者をクリアする関数
        async function clearWorkerWithDirectUpdate(recordId) {
          try {
            debugLog('直接更新でのクリアを試行: ID = ' + recordId);
            
            // レコードの詳細を取得
            var resp = await kintone.api(kintone.api.url('/k/v1/record.json', true), 'GET', {
              app: kintone.app.getId(),
              id: recordId
            });
            
            var updateData = {
              app: kintone.app.getId(),
              id: recordId,
              record: {}
            };
            
            // 作業者に関連する可能性のあるすべてのフィールドを探す
            var foundFields = false;
            
            for (var fieldCode in resp.record) {
              if (fieldCode === '作業者' || 
                  fieldCode.indexOf('Status_Assignee') === 0 || 
                  fieldCode.indexOf('Assignee') === 0 ||
                  fieldCode.indexOf('assignee') === 0) {
                
                debugLog('作業者関連フィールド: ' + fieldCode, resp.record[fieldCode]);
                
                // このフィールドを空にする
                updateData.record[fieldCode] = {
                  value: []
                };
                foundFields = true;
              }
            }
            
            if (!foundFields) {
              return {
                success: false,
                method: 'direct-update',
                error: '作業者関連フィールドが見つかりませんでした'
              };
            }
            
            // レコード更新を実行
            await kintone.api(kintone.api.url('/k/v1/record.json', true), 'PUT', updateData);
            
            return {
              success: true,
              method: 'direct-update'
            };
            
          } catch (error) {
            return {
              success: false,
              method: 'direct-update',
              error: error
            };
          }
        }
        
        // 処理を開始
        return processRecords();
        
      }).then(function(results) {
        // 処理完了
        document.body.removeChild(progressDialog);
        
        debugLog('全処理完了', results);
        
        // 結果アラート
        alert('処理が完了しました\n' +
              '成功: ' + results.success + '件\n' +
              '失敗: ' + results.error + '件\n' +
              '合計: ' + results.total + '件');
        
        // 詳細な結果をコンソールに出力
        console.log('=== 処理結果詳細 ===');
        results.details.forEach(function(detail, index) {
          console.log((index + 1) + '. レコードID: ' + detail.id + 
                      ', ステータス: ' + detail.status + 
                      ', 結果: ' + (detail.result && detail.result.success ? '成功' : '失敗') +
                      (detail.result && detail.result.method ? ' (方法: ' + detail.result.method + ')' : ''));
        });
        
        // 一覧を更新
        location.reload();
        
      }).catch(function(error) {
        // エラー処理
        if (error === '対象レコードなし') {
          return; // すでにアラート表示済み
        }
        
        errorLog('処理中にエラーが発生しました', error);
        
        if (document.getElementById('progress-dialog')) {
          document.body.removeChild(progressDialog);
        }
        
        alert('処理中にエラーが発生しました: ' + (error.message || error));
      });
    };
    
    // ヘッダーメニューにボタンを配置
    var headerMenuSpace = kintone.app.getHeaderMenuSpaceElement();
    if (headerMenuSpace) {
      headerMenuSpace.appendChild(button);
    }
    
    return event;
  });
})();ドをここに入力または貼り付け

質問ガイドライン にあるように

  • 発生した問題やエラーメッセージを具体的に書きましょう

の段落があると回答者が答えやすいと思います。


プロセス管理における作業者は、専用の REST API があるのでそれを使えば更新できます。

既存のレコードは API で作業者を外すとして、今後そのステータスに遷移するレコードについては、プロセス管理の設定で「【修繕工事申請】支払い・入金済」と「【修繕工事申請以外】支払い・入金済」に作業者を指定しなければ良いと思います。

「いいね!」 1

回答ありがとうございます。

エラーやメッセージなんですが、何も表示されなく…。
ただ処理が失敗しましたとだけ表示されます。