v1.22: Verwaltung sendet Direkt-E-Mails an Mieter mit CC an die Verwaltung
This commit is contained in:
@@ -1238,11 +1238,61 @@ app.patch('/api/users/:id', auth, adminOnly, async (req, res, next) => {
|
||||
await pool.query('UPDATE users SET aktiv = $1 WHERE id = $2', [Boolean(b.aktiv), req.params.id])
|
||||
if (b.einheitId !== undefined)
|
||||
await pool.query('UPDATE users SET einheit_id = $1 WHERE id = $2', [b.einheitId || null, req.params.id])
|
||||
if (b.email !== undefined) {
|
||||
const email = String(b.email || '').trim()
|
||||
if (email && !/^\S+@\S+\.\S+$/.test(email))
|
||||
return res.status(400).json({ fehler: 'Ungültige E-Mail-Adresse.' })
|
||||
if (email) {
|
||||
const { rows: fremde } = await pool.query(
|
||||
'SELECT id FROM users WHERE lower(email) = lower($1) AND id <> $2', [email, req.params.id],
|
||||
)
|
||||
if (fremde.length)
|
||||
return res.status(400).json({ fehler: 'Diese E-Mail-Adresse wird bereits verwendet.' })
|
||||
}
|
||||
await pool.query('UPDATE users SET email = $1 WHERE id = $2', [email, req.params.id])
|
||||
}
|
||||
const { rows: neu } = await pool.query('SELECT * FROM users WHERE id = $1', [req.params.id])
|
||||
res.json({ benutzer: oeffentlicherBenutzer(neu[0]) })
|
||||
} catch (e) { next(e) }
|
||||
})
|
||||
|
||||
// Direkte E-Mail der Verwaltung an einen Mieter (immer mit CC an die
|
||||
// Verwaltung, damit die Kommunikation dort vollständig nachvollziehbar ist)
|
||||
app.post('/api/users/:id/email', auth, adminOnly, async (req, res, next) => {
|
||||
try {
|
||||
const betreff = String((req.body || {}).betreff || '').trim()
|
||||
const text = String((req.body || {}).text || '').trim()
|
||||
if (!betreff || !text)
|
||||
return res.status(400).json({ fehler: 'Betreff und Nachricht erforderlich.' })
|
||||
const { rows } = await pool.query(
|
||||
`SELECT * FROM users WHERE id = $1 AND rolle = 'mieter'`, [req.params.id],
|
||||
)
|
||||
const mieter = rows[0]
|
||||
if (!mieter) return res.status(404).json({ fehler: 'Mieter nicht gefunden.' })
|
||||
if (!mieter.email)
|
||||
return res.status(400).json({ fehler: `${mieter.name} hat keine E-Mail-Adresse hinterlegt (Profil).` })
|
||||
const { rows: einheitRows } = await pool.query('SELECT * FROM units WHERE id = $1', [mieter.einheit_id])
|
||||
const label = mail.einheitLabel(mapUnit(einheitRows[0]))
|
||||
const html = mail.baueHtmlMail({
|
||||
titel: 'Nachricht der Verwaltung',
|
||||
untertitel: label,
|
||||
einleitung: `Persönliche Nachricht von ${req.user.name} (Hinterstein Immobilien):`,
|
||||
zeilen: [
|
||||
['Wohnung', label],
|
||||
['Mieter', mieter.name],
|
||||
],
|
||||
zitat: text,
|
||||
aktionenHtml: mail.buttonHtml('Zum Mieterportal', `${process.env.PORTAL_URL || 'https://mieterportal.hocks.eu'}/nachrichten`),
|
||||
})
|
||||
const cc = await mail.verwaltungEmails()
|
||||
const textVersion =
|
||||
`Nachricht der Verwaltung an ${mieter.name} (${label}):\n\n„${text}“\n\n` +
|
||||
`— Gesendet von ${req.user.name} über das Mieterportal`
|
||||
mail.sendeMail(mieter.email, betreff, textVersion, html, cc)
|
||||
res.json({ ok: true })
|
||||
} catch (e) { next(e) }
|
||||
})
|
||||
|
||||
// ── Registrierungscodes (nur Verwaltung) ─────────────────────
|
||||
app.get('/api/codes', auth, adminOnly, async (_req, res, next) => {
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user