nodebb-plugin-calendar-onekite 11.1.86 → 11.1.87
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/scheduler.js +83 -22
- package/package.json +1 -1
package/lib/scheduler.js
CHANGED
|
@@ -56,31 +56,92 @@ async function processAwaitingPayment() {
|
|
|
56
56
|
const user = require.main.require('./src/user');
|
|
57
57
|
|
|
58
58
|
async function sendEmail(template, toEmail, subject, data) {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
}
|
|
71
|
-
// Fallback for older/unusual builds (rare)
|
|
72
|
-
if (typeof emailer.send === 'function') {
|
|
73
|
-
// Some builds accept (template, email, language, params)
|
|
74
|
-
if (emailer.send.length >= 4) {
|
|
75
|
-
await emailer.send(template, toEmail, language, params);
|
|
59
|
+
if (!toEmail) return;
|
|
60
|
+
try {
|
|
61
|
+
// NodeBB core signature:
|
|
62
|
+
// Emailer.sendToEmail(template, email, language, params[, callback])
|
|
63
|
+
// Subject is NOT a positional argument; it must be provided in params.subject
|
|
64
|
+
// and optionally copied into the final email by filter:email.modify.
|
|
65
|
+
const language = (meta && meta.config && (meta.config.defaultLang || meta.config.defaultLanguage)) || 'fr';
|
|
66
|
+
const params = Object.assign({}, data || {}, subject ? { subject } : {});
|
|
67
|
+
|
|
68
|
+
if (typeof emailer.sendToEmail === 'function') {
|
|
69
|
+
await emailer.sendToEmail(template, toEmail, language, params);
|
|
76
70
|
return;
|
|
77
71
|
}
|
|
78
|
-
|
|
79
|
-
|
|
72
|
+
|
|
73
|
+
// Fallbacks for older/unusual builds
|
|
74
|
+
if (typeof emailer.send === 'function') {
|
|
75
|
+
// Some builds accept (template, email, language, params)
|
|
76
|
+
if (emailer.send.length >= 4) {
|
|
77
|
+
await emailer.send(template, toEmail, language, params);
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
// Some builds accept (template, email, params)
|
|
81
|
+
await emailer.send(template, toEmail, params);
|
|
82
|
+
}
|
|
83
|
+
} catch (err) {
|
|
84
|
+
// eslint-disable-next-line no-console
|
|
85
|
+
console.warn('[calendar-onekite] Failed to send email (scheduler)', {
|
|
86
|
+
template,
|
|
87
|
+
toEmail,
|
|
88
|
+
err: String((err && err.message) || err),
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function formatFR(ts) {
|
|
94
|
+
const d = new Date(ts);
|
|
95
|
+
const dd = String(d.getDate()).padStart(2, '0');
|
|
96
|
+
const mm = String(d.getMonth() + 1).padStart(2, '0');
|
|
97
|
+
const yyyy = d.getFullYear();
|
|
98
|
+
return `${dd}/${mm}/${yyyy}`;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
for (const rid of ids) {
|
|
102
|
+
const r = await dbLayer.getReservation(rid);
|
|
103
|
+
if (!r || r.status !== 'awaiting_payment') continue;
|
|
104
|
+
|
|
105
|
+
const approvedAt = parseInt(r.approvedAt || r.validatedAt || 0, 10) || 0;
|
|
106
|
+
if (!approvedAt) continue;
|
|
107
|
+
|
|
108
|
+
const reminderAt = approvedAt + holdMins * 60 * 1000;
|
|
109
|
+
const expireAt = approvedAt + 2 * holdMins * 60 * 1000;
|
|
110
|
+
|
|
111
|
+
if (!r.reminderSent && now >= reminderAt && now < expireAt) {
|
|
112
|
+
// Send reminder once
|
|
113
|
+
const u = await user.getUserFields(r.uid, ['username', 'email']);
|
|
114
|
+
if (u && u.email) {
|
|
115
|
+
await sendEmail('calendar-onekite_reminder', u.email, 'Location matériel - Rappel', {
|
|
116
|
+
username: u.username,
|
|
117
|
+
itemName: (Array.isArray(r.itemNames) ? r.itemNames.join(', ') : (r.itemName || '')),
|
|
118
|
+
itemNames: (Array.isArray(r.itemNames) ? r.itemNames : (r.itemName ? [r.itemName] : [])),
|
|
119
|
+
dateRange: `Du ${formatFR(r.start)} au ${formatFR(r.end)}`,
|
|
120
|
+
paymentUrl: r.paymentUrl || '',
|
|
121
|
+
delayMinutes: holdMins,
|
|
122
|
+
pickupLine: r.pickupTime ? (r.adminNote ? `${r.pickupTime} à ${r.adminNote}` : r.pickupTime) : '',
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
r.reminderSent = true;
|
|
126
|
+
r.reminderAt = now;
|
|
127
|
+
await dbLayer.saveReservation(r);
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
if (now >= expireAt) {
|
|
132
|
+
// Expire: remove reservation so it disappears from calendar and frees items
|
|
133
|
+
const u = await user.getUserFields(r.uid, ['username', 'email']);
|
|
134
|
+
if (u && u.email) {
|
|
135
|
+
await sendEmail('calendar-onekite_expired', u.email, 'Location matériel - Rappel', {
|
|
136
|
+
username: u.username,
|
|
137
|
+
itemName: (Array.isArray(r.itemNames) ? r.itemNames.join(', ') : (r.itemName || '')),
|
|
138
|
+
itemNames: (Array.isArray(r.itemNames) ? r.itemNames : (r.itemName ? [r.itemName] : [])),
|
|
139
|
+
dateRange: `Du ${formatFR(r.start)} au ${formatFR(r.end)}`,
|
|
140
|
+
delayMinutes: holdMins,
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
await dbLayer.removeReservation(rid);
|
|
80
144
|
}
|
|
81
|
-
} catch (err) {
|
|
82
|
-
// eslint-disable-next-line no-console
|
|
83
|
-
console.warn('[calendar-onekite] Failed to send email', { template, toEmail, err: String(err) });
|
|
84
145
|
}
|
|
85
146
|
}
|
|
86
147
|
|
package/package.json
CHANGED