+29
-3
@@ -51,6 +51,18 @@ function extraEmailsFor(key) {
|
||||
return String(map[key] || '').split(',').map(s => s.trim()).filter(Boolean);
|
||||
}
|
||||
|
||||
// Item-Group-routed recipients (Admin → System Settings → "Notify by Item
|
||||
// Group") — ALWAYS notified in addition to the step/module recipients above,
|
||||
// keyed by the order's MAIN PRODUCT's SAP Item Group (ItmsGrpCod), not every
|
||||
// component's group. Callers resolve the group code themselves (they already
|
||||
// have SAP/HANA access; notifyStore.js deliberately doesn't) and pass it in
|
||||
// as `itemGroupCode`.
|
||||
function groupExtraEmailsFor(groupCode) {
|
||||
if (groupCode == null || groupCode === '') return [];
|
||||
const map = appSettingsStore.notifyItemGroupEmails();
|
||||
return String(map[String(groupCode)] || '').split(',').map(s => s.trim()).filter(Boolean);
|
||||
}
|
||||
|
||||
function esc(s) { return String(s == null ? '' : s).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>'); }
|
||||
|
||||
function buildHtml({ title, lines, url }) {
|
||||
@@ -67,19 +79,33 @@ function buildHtml({ title, lines, url }) {
|
||||
// from both are combined and de-duplicated. `excludeUsernames` drops the
|
||||
// actor who just performed the action (no need to notify yourself) — by
|
||||
// username rather than email since the JWT payload doesn't carry email.
|
||||
async function notify({ stepFullKey, moduleKey, title, lines, url, excludeUsernames }) {
|
||||
async function notify({ stepFullKey, moduleKey, itemGroupCode, title, lines, url, excludeUsernames }) {
|
||||
try {
|
||||
if (!appSettingsStore.notifyEmailsEnabled()) return;
|
||||
const exclU = new Set((excludeUsernames || []).filter(Boolean).map(u => u.toLowerCase()));
|
||||
const emails = new Set();
|
||||
if (stepFullKey) {
|
||||
let anyStageEnabled = false;
|
||||
// Per-step opt-out (Admin → System Settings → "Stage-Change Email
|
||||
// Notifications" → per-step list) — when a step/module is listed there,
|
||||
// NOTHING fires for it: not the assigned users, not the fixed extra
|
||||
// recipients either. Distinct from the global notifyEmailsEnabled
|
||||
// switch checked above (silences everything) and a user's own
|
||||
// emailNotify opt-out (silences everything for just them) — this keeps
|
||||
// one specific stage silent for everyone, on purpose.
|
||||
if (stepFullKey && appSettingsStore.isNotifyStepEnabled(stepFullKey)) {
|
||||
anyStageEnabled = true;
|
||||
(await usersForStep(stepFullKey)).forEach(u => u.email && !exclU.has((u.username || '').toLowerCase()) && emails.add(u.email.toLowerCase()));
|
||||
extraEmailsFor(stepFullKey).forEach(e => emails.add(e.toLowerCase()));
|
||||
}
|
||||
if (moduleKey) {
|
||||
if (moduleKey && appSettingsStore.isNotifyStepEnabled(moduleKeyOf(moduleKey))) {
|
||||
anyStageEnabled = true;
|
||||
(await usersForModule(moduleKey)).forEach(u => u.email && !exclU.has((u.username || '').toLowerCase()) && emails.add(u.email.toLowerCase()));
|
||||
extraEmailsFor(moduleKeyOf(moduleKey)).forEach(e => emails.add(e.toLowerCase()));
|
||||
}
|
||||
// Item-Group routing rides on the same stage being enabled at all — if
|
||||
// this step/module's email is switched off entirely, the group-mapped
|
||||
// recipients shouldn't fire for it either.
|
||||
if (anyStageEnabled) groupExtraEmailsFor(itemGroupCode).forEach(e => emails.add(e.toLowerCase()));
|
||||
if (!emails.size) return;
|
||||
await mailer.sendMail({ to: [...emails], subject: title, html: buildHtml({ title, lines, url }) });
|
||||
} catch (e) {
|
||||
|
||||
Reference in New Issue
Block a user