Zoho ProjectsのCodeXスクリプトは、特定のルールや検証を適用するための高度な条件ロジックスクリプトです。CodeXスクリプトを使用すると、カスタムタブの作成、更新、削除の方法やタイミングを制御できます。
- function main() {
- const DATE_ORDER_ERROR = '終了日を開始日より前に設定することはできません';
- const START_REQUIRED_ERROR = '終了日を設定する場合は、開始日の入力が必要です';
- try {
- const record = current.record;
- const startDate = current.affectedFields.starting_date
- ? current.affectedFields.starting_date.newValue
- : record.starting_date;
- const endDate = current.affectedFields.ending_date
- ? current.affectedFields.ending_date.newValue
- : record.ending_date;
- if (endDate && !startDate) {
- throw new ScriptError('終了日を設定する場合は、開始日の入力が必要です');
- }
- if (!startDate || !endDate) return;
- const start = new Date(startDate);
- const end = new Date(endDate);
- start.setHours(0, 0, 0, 0);
- end.setHours(0, 0, 0, 0);
- if (end < start) {
- throw new ScriptError(DATE_ORDER_ERROR);
- }
- } catch (err) {
- const msg = err.getMessage ? err.getMessage() : err.message;
- if (msg === DATE_ORDER_ERROR || msg === START_REQUIRED_ERROR) {
- throw new ScriptError(msg);
- }
- throw new ScriptError('スクリプトでエラーが発生しました。ポータル管理者にお問い合わせください');
- }
- }
ユーザーごとの未完了データ数の制限
タブ内に未完了のデータがすでに10件を超えて存在する場合、ユーザーが新しいデータを作成できないようにします。
イベント:作成前
- function main() {
- const LIMIT_REACHED = '未完了のデータが10件以上あります。上限に達したため、これ以上作成できません';
- const MAX_OPEN = 10;
- try {
- const url = 'https://projectsforce.localzoho.com';
- const portalId = current.org.zohoOrgId;
- const moduleId = current.record.moduleId;
- const currentUser = current.user;
- let openCount = 0;
- let page = 1;
- const perPage = 100;
- let hasNext = true;
- while (hasNext && openCount <= MAX_OPEN) {
- let req = new HttpRequest();
- req.url(`${url}/api/v3/portal/${portalId}/module/${moduleId}/entities?page=${page}&per_page=${perPage}`);
- req.method('GET');
- req.connection('zconnect');
- const res = req.execute().asJson()?.statusMessage?.responseText;
- // throw new ScriptError(req.execute().asText());
- const records = res.entities || res;
- for (let i = 0; i < records.length; i++) {
- const rec = records[i];
- const createdBy = rec.created_by && rec.created_by.zpuid;
- const isOpen = rec.status && rec.status.is_closed_type === false;
- if (isOpen && createdBy === currentUser.id) {
- openCount++;
- if (openCount > MAX_OPEN) break;
- }
- }
- hasNext = res.page_info ? res.page_info.has_next_page === true : false;
- page++;
- }
- if (openCount > MAX_OPEN) {
- throw new ScriptError(LIMIT_REACHED);
- }
- } catch (err) {
- // throw new ScriptError(err);
- const msg = err.getMessage ? err.getMessage() : err.message;
- if (msg === LIMIT_REACHED) {
- throw new ScriptError(msg);
- }
- throw new ScriptError('スクリプトでエラーが発生しました。ポータル管理者にお問い合わせください');
- }
- }
作成時の過去の日付の制限
ユーザーが、開始日、終了日、またはレビュー完了日に過去の日付を設定してデータを作成できないようにします。
イベント:作成前
- function main() {
- const PAST_DATE_ERROR = '過去の日付は指定できません';
- const DATE_FIELDS = ['review_completion_date', 'starting_date', 'ending_date'];
- try {
- const record = current.record;
- const today = new Date();
- today.setHours(0, 0, 0, 0);
- for (let i = 0; i < DATE_FIELDS.length; i++) {
- const value = record[DATE_FIELDS[i]];
- if (!value) continue;
- const newDate = new Date(value);
- newDate.setHours(0, 0, 0, 0);
- if (newDate < today) {
- throw new ScriptError(PAST_DATE_ERROR);
- }
- }
- } catch (err) {
- const msg = err.getMessage ? err.getMessage() : err.message;
- if (msg === PAST_DATE_ERROR) {
- throw new ScriptError(msg);
- }
- throw new ScriptError('スクリプトでエラーが発生しました。ポータル管理者にお問い合わせください');
- }
- }
データを更新できるユーザーを、作成者や担当ユーザーなど、そのデータに関連付けられているユーザー、または管理者権限を持つユーザーのみに制限します。権限のないユーザーはデータを編集できません。
イベント:更新前
- function main() {
- const NOT_ALLOWED = 'このデータを編集する権限がありません';
- try {
- const url = 'https://projectsforce.localzoho.com';
- const record = current.record;
- const currentUser = current.user; // 操作ユーザー — 名前と構造を確認
- // 1. このデータに関連するユーザー(IDまたはZPUIDで比較)
- const relatedIds = new Set();
- if (record.created_by) relatedIds.add(record.created_by.id);
- if (record.review_module_cf_0002) relatedIds.add(record.review_module_cf_0002.id);
- if (Array.isArray(record.review_module_cf_0001)) {
- record.review_module_cf_0001.forEach(u => relatedIds.add(u.id));
- }
- if (relatedIds.has(currentUser.id)) {
- return; // 関連ユーザー -> 許可
- }
- // 2. 関連ユーザーではない -> 操作ユーザーの情報を取得し、管理者のみ許可
- let req = new HttpRequest();
- req.url(`${url}/api/v3.1/portal/${current.org.zohoOrgId}/users/${currentUser.id}`);
- req.method('GET');
- req.connection('zprojects');
- const user = req.execute().asJson().statusMessage.responseText; // すでにオブジェクト
- const role = (user.role && user.role.name || '').toLowerCase();
- if (role !== 'administrator') {
- throw new ScriptError(NOT_ALLOWED);
- }
- } catch (err) {
- const msg = err.getMessage ? err.getMessage() : err.message;
- if (msg === NOT_ALLOWED) {
- throw new ScriptError(msg);
- }
- throw new ScriptError('スクリプトでエラーが発生しました。ポータル管理者にお問い合わせください');
- }
- }
関連記事