タスク用CodeXスクリプト

タスク用CodeXスクリプト

お知らせ:当社は、お客様により充実したサポート情報を迅速に提供するため、本ページのコンテンツは機械翻訳を用いて日本語に翻訳しています。正確かつ最新のサポート情報をご覧いただくには、本内容の英語版を参照してください。

Zoho ProjectsのCodeXスクリプトは、特定のルールや検証を適用するための高度な条件ロジックスクリプトです。タスクを作成、編集、または遷移できる条件やタイミングを制御できます。これにより、コンプライアンスの向上とプロセスの整合性を確保できます。

Info
CodeXスクリプトは、CN、JP、AEを除くすべてのデータセンターで利用できます。

活用例:

サブタスクの作成を1階層に制限

タスク階層をシンプルで管理しやすい状態に保つため、サブタスクの配下に別のサブタスクを作成できないようにし、サブタスクを1階層のみに制限します。
コード:
  1. function main() {
  2. if(current.record.parent_task !== current.record.root_task) {
  3. throw new ScriptError('サブタスクは2階層以上作成できません');
  4. }
  5. }

保留中のプロジェクトにおけるタスク作成の無効化

関連付けられているプロジェクトが保留中の場合、タスクの作成を制限します。
コード:
  1. function main() {
  2. const projectId = current.record.projectId;
  3. const moduleItr = client.getModules();
  4. let module
  5. console.log('開始');
  6. for (let mod of moduleItr) {
  7. console.log(`${mod}`);
  8. if (mod.name === 'Projects') {
  9. module = mod;
  10. }
  11. }
  12. if (!module) {
  13. return;
  14. }
  15. let projectDtl = client.getRecordById(module.id, projectId);
  16. let statusDtl = client.getStatusDetails(module.id, projectDtl.layoutId, projectDtl.status.id);
  17. console.log(statusDtl)
  18. if (statusDtl.name === 'zp.projstatus.onhold') {
  19. throw new ScriptError('保留中のプロジェクトではタスクを作成できません');
  20. }
  21. }

 ステータス更新後の手動による日付変更の制限

ステータスがレイアウトのデフォルトステータスではない場合、開始日、終了日、または期間の編集を制限します。
コード:
  1. function main() {
  2.  
  3. //base 条件 #1
  4. if (!current.affectedFields.start_date
  5. && !current.affectedFields.end_date
  6. && !current.affectedFields.duration_value
  7. && !current.affectedFields.duration_unit) {
  8. return;
  9. }
  10.  
  11. const statusDtl = client.getStatusDetails(current.module.id, current.record.layoutId, current.record.status);
  12. console.log(`${statusDtl}`);
  13.     
  14. if (!statusDtl.isLayoutDefault) {
  15. throw new ScriptError('開始日と終了日はデフォルトステータスの場合のみ変更できます');
  16. }
  17. }
  18.  

未完了のサブタスクがある場合のタスク完了の制限

未完了のサブタスクがある場合、親タスクのステータスを完了に変更できないようにします。これにより、すべてのサブタスクが完了するまで、親タスクを完了として設定できません。
コード。
  1.  
  2. function main() {
  3.  
  4. console.log(current.affectedFields.toString());
  5.  
  6. //base 条件の処理
  7. if (!current.affectedFields?.status) {
  8. return;
  9. }
  10.  
  11. const url = `https://projects.zoho.com/restapi/portal/${current.org.zohoOrgId}/projects/${current.record.projectId}/tasks/${current.record.id}/subtasks/`;
  12. let hasMore = true;
  13. const range = 200;
  14. let index = 1;
  15. console.log(url);
  16.  
  17. while (hasMore) {
  18. let request = new HttpRequest();
  19. request.url(url);
  20. request.connection('zprojects');
  21. request.params({ index, range });
  22.  
  23. const response = request.execute();
  24.  
  25. console.log(response.asText());
  26. /**
  27. * @type {[]}
  28. */
  29. const tasks = response.asJson()?.statusMessage?.responseText?.tasks;
  30.  
  31. //no 現在のタスクにサブタスクが存在するか確認
  32. if (!tasks || tasks.length == 0) {
  33. console.log('現在のタスクにサブタスクはありません');
  34. return;
  35. }
  36.  
  37. hasMore = tasks.length == range;
  38. index += range;
  39.  
  40. console.log(tasks);
  41. console.log(tasks.length);
  42.  
  43. for (let task of tasks) {
  44. console.log(task.completed);
  45. if (!task.completed) {
  46. throw new ScriptError('未完了のサブタスクがあるため、タスクを完了できません');
  47. }
  48. }
  49. }
  50.  
  51.  
  52. }

先行タスクが未完了の場合のステータス変更の制限

依存関係の整合性を維持するため、先行タスクのいずれかが未完了の場合はステータスの更新を制限します。これにより、後続タスクは先行タスクが完了した後にのみ進行できます。
コード。
  1. function main() {

  2. console.log(current.affectedFields.toString());
  3.     
  4. //base 条件の処理
  5. if(!current.affectedFields?.status) {
  6. return;
  7. }

  8. const url = `https://projects.zoho.com/restapi/portal/${current.org.zohoOrgId}/projects/${current.record.projectId}/tasks/${current.record.id}/`;
  9. console.log(url);
  10.     
  11. let request = new HttpRequest();
  12. request.url(url);
  13. request.connection('zprojects');

  14. const response = request.execute();
  15. const taskDependencyDtl = response.asJson()?.statusMessage?.responseText?.tasks[0]?.dependency;

  16. //no 前のタスクに依存関係があるか確認
  17. if(!taskDependencyDtl || !taskDependencyDtl?.predecessor) {
  18. return;
  19. }

  20. console.log(taskDependencyDtl);

  21. for(let predecessorId of taskDependencyDtl.predecessor) {
  22. console.log(predecessorId);
  23. if(!taskDependencyDtl.dependencyDetails[predecessorId]?.IS_COMPLETED) {
  24. throw new ScriptError('未完了の先行タスクがあります。続行するには先行タスクを完了してください');
  25. }
  26. }

  27. }

 サブタスク作成の制限

タスク構造をフラットに保つため、サブタスクの作成を制限します。
コード。
  1. function main() {
  2. let task = current.record;
  3. let startDate = task.start_date;
  4. if(task.parent_task || task.root_task) {
  5. Logger.info('サブタスクの作成は無効です');
  6. throw new ScriptError('サブタスクの作成は無効です');
  7. }
  8. }
  9.  

条件に基づくタスクの期間とステータスの更新

特定のカスタム項目と現在のステータスに基づいて、タスクの期間とステータスを更新します。
たとえば、このスクリプトでは、特定の条件を満たした場合にタスクの期間とステータスを更新します。
  1. タスクの現在のステータスが「保留中」の場合、ステータスを特定のID(例:「進行中」)に自動的に変更します。
  2. 複数選択カスタム項目で特定の値が選択されている場合、期間を30日に設定します。
  3. また、タスクの請求タイプと影響を受ける項目を確認し、ログに記録します。
コード:
  1. function main() {
  2. let task = current.record;
  3. const statusDetails = client.getStatusDetails(task.moduleId, task.layoutId, task.status);
  4. if(statusDetails.name === 'On Hold') {
  5. task.status = '5000000000362';
  6. client.save(task);
  7. }
  8. console.log(JSON.stringify(statusDetails));
  9.     if(task.weightage.includes('Medium') {//check 複数選択項目がいずれかの選択肢の場合
  10. console.log('ステータスを進行中に設定');
  11. task.duration_unit = TaskDurationUnit.DAYS;
  12. task.duration_value = 30;
  13. }
  14. }

アーカイブ済みプロジェクトの編集制限

プロジェクトがアーカイブされている場合、そのプロジェクト内のタスクが編集されないよう、タスクの更新を制限します。
コード:
  1. function main() {
  2. let task = current.record;
  3. let projectId = task.projectId;
  4. const moduleItr = client.getModules(0, 10);
  5. let moduleId;
  6. console.log(JSON.stringify(current.affectedFields));
  7. while(moduleItr.hasNext()) {
  8. let moduleObj = moduleItr.next();
  9. if(moduleObj.name == 'Projects') {
  10. moduleId = moduleObj.id;
  11. }
  12. }
  13. let project = client.getRecordById(moduleId, projectId);
  14. if(project.project_type == 'archived') {
  15. throw new ScriptError('アーカイブ済みプロジェクトは編集できません');
  16. }
  17. }

過去の開始日の設定制限

正確なスケジュールを維持するため、選択した開始日が過去の日付の場合にエラーを表示します。
コード:
  1. function main() {
  2. let task = current.record;
  3. let date = Date.now();
  4. for(let key of Object.keys(current)) {
  5. console.log(key);
  6. }
  7. const startDate = new Date(task.start_date)
  8. if(date > startDate) {
  9. console.log('開始日が過去の日付です');
  10. throw new ScriptError('開始日を過去の日付に更新することはできません');
  11. }
  12. }

条件に基づくタスク編集の制限

チェックボックス項目が有効な場合、チェックボックス自体の変更を除き、タスクの更新を制限します。これにより、意図しない変更を防止できます。
コード:
  1. function main() {
  2.  
  3. const affectedFields = current.affectedFields;
  4. const task = current.record;
  5.  
  6. if(affectedFields && typeof affectedFields['checkbox_cf'] != 'undefined') {
  7. return; //Do チェックボックス自体が更新された場合は何もしません。
  8. }
  9.  
  10. //boolean チェックボックス形式の項目の値
  11. if(task.checkbox_cf) {
  12. throw new ScriptError('チェックボックスが有効なため、タスクはロックされています。')
  13. }
  14. }
  15.  

カスタムステータス時のタスク日付の更新制限

タスクがカスタムステータスの場合、タスクの開始日と終了日の更新を制限します。
コード
  1. function main() {
  2. try {
  3. if (!current.affectedFields.start_date
  4. && !current.affectedFields.end_date
  5. && !current.affectedFields.duration_value
  6. && !current.affectedFields.duration_unit) {
  7. return;
  8. }
  9. const statusDtl = client.getStatusDetails(current.record.moduleId, current.record.layoutId, current.record.status.id);
  10. console.log(`${statusDtl}`);
  11. if (!statusDtl.isLayoutDefault) {
  12. throw new ScriptError('開始日と終了日は、初期設定のステータスでのみ変更できます');
  13. }
  14. } catch (err) {
  15. throw new ScriptError(err);
  16. }
  17. }
プロジェクトの設定でCodeXをどのように活用したいか、アイデアはありますか?以下のコメント欄でユースケースをお知らせください。

関連情報
ヘルプに戻る
プロジェクト向けCodeXスクリプト
CodeXスクリプトの使用方法