ken_nogi/Pleasanter/新版営業積算システム/docs/gen-504322-notification-excel.js
Kenichiro NOGI ce58cb4be4 初回コミット: dev配下(NodeSrv/Pleasanter等)をGitea管理下に統合
GitHub(nextgroup2706/ken_nogi)は今後使わず自社Gitea運用に切替え。
NodeSrvは旧リポジトリの履歴を破棄しファイルのみ統合(Dokploy用サービスアカウントは
別途mygit-admin/NodeSrv.gitに履歴あり)。notepmエクスポート(12GB)とPleasanter
インストーラzip(208MB)はサイズが大きいため.gitignoreで除外。

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-04 15:37:06 +09:00

170 lines
5.4 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

const path = require("path");
const fs = require("fs");
const ExcelJS = require(path.join(__dirname, "..", "..", "node_modules", "exceljs"));
const siteDir = path.join(
__dirname,
"..",
"configs",
"production",
"site-504322_【デモ版】②問い合わせ内容管理"
);
const siteSettingsRaw = JSON.parse(
fs.readFileSync(
path.join(siteDir, "sitesettings", "site-504322_latest.json"),
"utf8"
)
);
const siteSettings =
siteSettingsRaw.Response.Data.SiteSettings || siteSettingsRaw.Response.Data;
const columns = siteSettings.Columns || [];
const processes = JSON.parse(
fs.readFileSync(path.join(siteDir, "processes.json"), "utf8")
);
const labelMap = new Map();
columns.forEach((c) => {
if (c.ColumnName && c.LabelText) labelMap.set(c.ColumnName, c.LabelText);
});
// [ColumnName] → [表示名] に変換。辞書にない([Url]や固定文字列等)はそのまま。
function toLabel(text) {
if (!text) return "";
return text.replace(/\[([A-Za-z0-9]+)\]/g, (m, name) => {
return labelMap.has(name) ? `[${labelMap.get(name)}]` : m;
});
}
const rows = [];
processes.forEach((p) => {
const n = (p.Notifications || [])[0];
if (!n) return;
rows.push({
process: p.DisplayName || p.Name,
from: `${p.CurrentStatus}${p.ChangedStatus}`,
subject: toLabel(n.Subject),
to: toLabel(n.Address) || "(なし)",
cc: toLabel(n.CcAddress) || "(なし)",
bcc: toLabel(n.BccAddress) || "(なし)",
body: toLabel(n.Body),
});
});
// ChoicesTextがUsersテーブル参照[[Users*]] 全件、または TableName:"Users" の絞込参照)のカラム
// = メール宛先に指定できる項目
const usersStarColumns = columns.filter(
(c) =>
typeof c.ChoicesText === "string" &&
(c.ChoicesText.replace(/\s/g, "").includes("[[Users*]]") ||
/"TableName"\s*:\s*"Users"/.test(c.ChoicesText))
);
function usersFilterNote(c) {
if (c.ChoicesText.replace(/\s/g, "").includes("[[Users*]]")) return "全ユーザー対象";
const notes = [];
if (/"DeptId"\s*:\s*"\[\\"25\\"\]"/.test(c.ChoicesText)) notes.push("部署ID25積算担当に絞込");
if (/"UserId"\s*:\s*"=\[@Class153\]"/.test(c.ChoicesText)) notes.push(`[${labelMap.get("Class153") || "Class153"}] を参照して絞込`);
if (/"Disabled"\s*:\s*"false"/.test(c.ChoicesText)) notes.push("有効ユーザーのみ");
return notes.length ? notes.join("") : "Usersテーブル参照絞込条件あり";
}
async function main() {
const wb = new ExcelJS.Workbook();
wb.creator = "野木 健一郎";
wb.created = new Date();
// 転置レイアウト: A列=項目名、B列以降=各プロセス
const ws1 = wb.addWorksheet("504322_プロセス通知メール仕様", {
views: [{ state: "frozen", xSplit: 1, ySplit: 1 }],
});
const itemLabels = ["ステータス遷移", "件名", "宛先(To)", "CC", "BCC", "本文"];
const itemKeys = ["from", "subject", "to", "cc", "bcc", "body"];
ws1.getColumn(1).width = 14;
rows.forEach((_, i) => {
ws1.getColumn(i + 2).width = 32;
});
const headerRow = ws1.addRow(["プロセス名", ...rows.map((r) => r.process)]);
headerRow.font = { bold: true };
headerRow.fill = {
type: "pattern",
pattern: "solid",
fgColor: { argb: "FFD9E1F2" },
};
headerRow.alignment = { vertical: "middle", horizontal: "center" };
itemLabels.forEach((label, i) => {
const key = itemKeys[i];
const row = ws1.addRow([label, ...rows.map((r) => r[key])]);
row.alignment = { vertical: "top", wrapText: true };
row.getCell(1).font = { bold: true };
row.getCell(1).fill = {
type: "pattern",
pattern: "solid",
fgColor: { argb: "FFF2F2F2" },
};
});
const ws2 = wb.addWorksheet("メール宛先指定可能項目(Users_)", {
views: [{ state: "frozen", ySplit: 1 }],
});
ws2.columns = [
{ header: "項目名", key: "label", width: 26 },
{ header: "複数選択", key: "multi", width: 12 },
{ header: "初期値", key: "default", width: 14 },
{ header: "備考", key: "note", width: 55 },
];
ws2.getRow(1).font = { bold: true };
ws2.getRow(1).fill = {
type: "pattern",
pattern: "solid",
fgColor: { argb: "FFD9E1F2" },
};
ws2.getRow(1).alignment = { vertical: "middle", horizontal: "center" };
usersStarColumns.forEach((c) => {
const notes = [usersFilterNote(c)];
if (c.Hide) notes.push("画面非表示項目");
ws2.addRow({
label: `[${c.LabelText}]`,
multi: c.MultipleSelections ? "○" : "",
default:
c.DefaultInput === "[[Self]]"
? "自分自身"
: c.DefaultInput
? c.DefaultInput
: "",
note: notes.join(""),
});
});
[ws1, ws2].forEach((ws) => {
ws.eachRow((row) => {
row.eachCell((cell) => {
cell.border = {
top: { style: "thin", color: { argb: "FFBFBFBF" } },
left: { style: "thin", color: { argb: "FFBFBFBF" } },
bottom: { style: "thin", color: { argb: "FFBFBFBF" } },
right: { style: "thin", color: { argb: "FFBFBFBF" } },
};
});
});
});
const outPath = path.join(
__dirname,
"site-504322_プロセス通知メール仕様.xlsx"
);
await wb.xlsx.writeFile(outPath);
console.log("[OK] 保存しました:", outPath);
console.log("Users*項目件数:", usersStarColumns.length);
}
main().catch((e) => {
console.error(e);
process.exit(1);
});