お知らせ:当社は、お客様により充実したサポート情報を迅速に提供するため、本ページのコンテンツは機械翻訳を用いて日本語に翻訳しています。正確かつ最新のサポート情報をご覧いただくには、本内容の
英語版を参照してください。
Zoho Projects の CodeX Script は、高度な条件ロジックスクリプトで、特定のルールやバリデーションを強制できます。ユーザーは、タスクをいつ・どのように作成、編集、またはステータス変更できるかを制御できます。これにより、コンプライアンスの向上とプロセスの一貫性が確保されます。
CodeX Script は、CN、JP、AE を除くすべてのデータセンターでサポートされています。
ユースケース:
サブタスクの階層を 1 レベルまでに制限する
サブタスクの下にさらにサブタスクを作成できないようにし、サブタスクは 1 階層までに制限して、シンプルで管理しやすいタスク階層を維持します。
- function main() {
- if(current.データ.parent_task !== current.データ.root_task) {
- throw new ScriptError('Disable subtasks creation with more than 1 level');
- }
- }
ステータスが「保留中」のプロジェクトでタスク作成を禁止する
関連付けられているプロジェクトが「保留中」に設定されている場合、タスクを作成できないように制限します。
- function main() {
- const projectId = current.データ.projectId;
- const moduleItr = client.getModules();
- let タブ
- console.log('started');
- for (let mod of moduleItr) {
- console.log(`${mod}`);
- if (mod.name === 'Projects') {
- タブ = mod;
- }
- }
- if (!タブ) {
- return;
- }
- let projectDtl = client.getRecordById(タブ.id, projectId);
- let statusDtl = client.getStatusDetails(タブ.id, projectDtl.layoutId, projectDtl.status.id);
- console.log(statusDtl)
- if (statusDtl.name === 'zp.projstatus.onhold') {
- throw new ScriptError('Task Creation disabled for On Hold Projects');
- }
- }
ステータス更新後の手動日付変更を制限する
レイアウトのデフォルトステータス以外の場合、開始日、終了日、または期間を編集できないように制限します。
- function main() {
-
- //base condition #1
- if (!current.affectedFields.start_date
- && !current.affectedFields.end_date
- && !current.affectedFields.duration_value
- && !current.affectedFields.duration_unit) {
- return;
- }
-
- const statusDtl = client.getStatusDetails(current.タブ.id, current.データ.layoutId, current.データ.status);
- console.log(`${statusDtl}`);
-
- if (!statusDtl.isLayoutDefault) {
- throw new ScriptError('Start Date and End date change are only allowed in default status');
- }
- }
-
未完了のサブタスクがある場合はタスクをクローズできないようにする
未完了のサブタスクが存在する場合、親タスクのステータスを「クローズ」に変更できないように制限します。これにより、すべてのサブタスクがクローズされるまで、親タスクを完了としてマークできないようにします。
-
- function main() {
-
- console.log(current.affectedFields.toString());
-
- // 基本条件の処理
- if (!current.affectedFields?.status) {
- return;
- }
-
- const url = `https://projects.zoho.com/restapi/portal/${current.org.zohoOrgId}/projects/${current.record.projectId}/tasks/${current.record.id}/subtasks/`;
- let hasMore = true;
- const range = 200;
- let index = 1;
- console.log(url);
-
- while (hasMore) {
- let 要求 = new HttpRequest();
- 要求.url(url);
- 要求.connection('zprojects');
- 要求.params({ index, range });
-
- const response = 要求.execute();
-
- console.log(response.asText());
- /**
- * @type {[]}
- */
- const tasks = response.asJson()?.statusMessage?.responseText?.tasks;
-
- // 現在のタスクにサブタスクが存在しない場合
- if (!tasks || tasks.length == 0) {
- console.log('現在のタスクにはサブタスクがありません');
- return;
- }
-
- hasMore = tasks.length == range;
- index += range;
-
- console.log(tasks);
- console.log(tasks.length);
-
- for (let task of tasks) {
- console.log(task.completed);
- if (!task.completed) {
- throw new ScriptError('未完了のサブタスクがあるため、このタスクはクローズできません');
- }
- }
- }
-
-
- }
先行タスクが未完了の場合はステータス変更を制限する
後続タスクが、先行タスクがクローズされてからのみ進行できるように、いずれかの先行タスクが未完了の場合はステータス更新を制限します。
- function main() {
- console.log(current.affectedFields.toString());
-
- // 基本条件の処理
- if(!current.affectedFields?.status) {
- return;
- }
- const url = `https://projects.zoho.com/restapi/portal/${current.org.zohoOrgId}/projects/${current.record.projectId}/tasks/${current.record.id}/`;
- console.log(url);
-
- let 要求 = new HttpRequest();
- 要求.url(url);
- 要求.connection('zprojects');
- const response = 要求.execute();
- const taskDependencyDtl = response.asJson()?.statusMessage?.responseText?.tasks[0]?.dependency;
- // 先行タスクに依存関係が存在しない場合
- if(!taskDependencyDtl || !taskDependencyDtl?.predecessor) {
- return;
- }
- console.log(taskDependencyDtl);
- for(let predecessorId of taskDependencyDtl.predecessor) {
- console.log(predecessorId);
- if(!taskDependencyDtl.dependencyDetails[predecessorId]?.IS_COMPLETED) {
- throw new ScriptError('未完了の先行タスクがあるため、続行するには先にクローズしてください');
- }
- }
- }
サブタスク作成を制限する
タスク構造をフラットに保つために、サブタスクの作成を制限します。
- function main() {
- let task = current.データ;
- let startDate = task.start_date;
- if(task.parent_task || task.root_task) {
- Logger.info('サブタスクの作成は無効化されています');
- throw new ScriptError('サブタスクの作成は無効化されています');
- }
- }
-
条件に基づいてタスクの期間とステータスを更新する
特定のカスタム項目と現在のステータスに基づいて、タスクの期間とステータスを更新します。
たとえば、このスクリプトは、特定の条件が満たされたときにタスクの期間とステータスを更新します。
- タスクの現在のステータスが「保留中」の場合、自動的に特定のステータス ID(例:「進行中」)に変更します。
- マルチセレクト型のカスタム項目で特定の値が選択されている場合、期間を 30 日に設定します。
- また、タスクの請求タイプと影響を受けた項目を確認してログに出力します。
- function main() {
- let task = current.データ;
- const statusDetails = client.getStatusDetails(task.moduleId, task.layoutId, task.status);
- if(statusDetails.name === 'On Hold') {
- task.status = '5000000000362';
- client.save(task);
- }
- console.log(JSON.stringify(statusDetails));
- if(task.weightage.includes('Medium') {//マルチセレクト項目に特定のオプションが含まれているかをチェック
- console.log('setting status to In Progress');
- task.duration_unit = TaskDurationUnit.DAYS;
- task.duration_value = 30;
- }
- }
アーカイブ済みプロジェクトでの編集を制限
プロジェクトがアーカイブされている場合、そのプロジェクト配下のタスクには一切更新が行えないようにし、タスクの編集を防ぎます。
- function main() {
- let task = current.データ;
- let projectId = task.projectId;
- const moduleItr = client.getModules(0, 10);
- let moduleId;
- console.log(JSON.stringify(current.affectedFields));
- while(moduleItr.hasNext()) {
- let moduleObj = moduleItr.next();
- if(moduleObj.name == 'Projects') {
- moduleId = moduleObj.id;
- }
- }
- let project = client.getRecordById(moduleId, projectId);
- if(project.project_type == 'archived') {
- throw new ScriptError('アーカイブ済みプロジェクトでは編集できません');
- }
- }
過去日の開始日に制限を設定
選択した開始日が過去日の場合にエラーを表示し、スケジュールの整合性を保ちます。
- function main() {
- let task = current.データ;
- let date = Date.now();
- for(let key of Object.keys(current)) {
- console.log(key);
- }
- const startDate = new Date(task.start_date)
- if(date > startDate) {
- console.log('Start date is in past date');
- throw new ScriptError('開始日に過去の日付は設定できません');
- }
- }
条件付きでタスクの編集を制限
チェックボックス項目が有効な場合、そのチェックボックス自体を変更する場合を除き、タスクへの更新を禁止して意図しない変更を防ぎます。
- function main() {
-
- const affectedFields = current.affectedFields;
- const task = current.データ;
-
- if(affectedFields && typeof affectedFields['checkbox_cf'] != 'undefined') {
- return; //チェックボックス自体が更新されている場合は何もしません。
- }
-
- //チェックボックスタイプ項目のブール値
- if(task.checkbox_cf) {
- throw new ScriptError('チェックボックスが有効のため、このタスクはロックされています。 ')
- }
- }
-
プロジェクトのセットアップでの CodeX の使い方についてアイデアがありますか?ぜひ、下のコメント欄にユースケースをお寄せください。
関連ドキュメント