v1.34: Eigenobjekt-Kennzeichen, Belegzuordnung nutzt Mietobjekt-Adresse; Ticket-Delete Fix
This commit is contained in:
@@ -175,6 +175,9 @@ ALTER TABLE buildings ADD COLUMN IF NOT EXISTS grundstuecksflaeche NUMERIC(9,1);
|
||||
-- v1.29: Heizungsart (Dropdown) in Haus- und Wohnungsverwaltung
|
||||
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS heizungsart TEXT NOT NULL DEFAULT '';
|
||||
ALTER TABLE units ADD COLUMN IF NOT EXISTS heizungsart TEXT NOT NULL DEFAULT '';
|
||||
-- v1.34: Eigenobjekt (z. B. Rechnungsempfänger-Adresse der Verwaltung) –
|
||||
-- wird von der automatischen Beleg-Zuordnung ausgeschlossen
|
||||
ALTER TABLE buildings ADD COLUMN IF NOT EXISTS eigenobjekt BOOLEAN NOT NULL DEFAULT FALSE;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS costs (
|
||||
id TEXT PRIMARY KEY,
|
||||
|
||||
+37
-13
@@ -195,6 +195,7 @@ const mapBuilding = (b) => ({
|
||||
grundstuecksflaeche: b.grundstuecksflaeche === null || b.grundstuecksflaeche === undefined
|
||||
? null : Number(b.grundstuecksflaeche),
|
||||
heizungsart: b.heizungsart ?? '',
|
||||
eigenobjekt: Boolean(b.eigenobjekt),
|
||||
})
|
||||
const mapKosten = (k) => ({
|
||||
id: k.id, building: k.building, unitId: k.unit_id, jahr: k.jahr,
|
||||
@@ -555,15 +556,26 @@ app.patch('/api/tickets/:id', auth, adminOnly, async (req, res, next) => {
|
||||
|
||||
// Schadensmeldung löschen inkl. verknüpfter Unterhaltung und Nachrichten (v1.33)
|
||||
app.delete('/api/tickets/:id', auth, adminOnly, async (req, res, next) => {
|
||||
const client = await pool.connect()
|
||||
try {
|
||||
const { rows } = await pool.query('DELETE FROM tickets WHERE id = $1 RETURNING id', [req.params.id])
|
||||
if (!rows.length) return res.status(404).json({ fehler: 'Schadensmeldung nicht gefunden.' })
|
||||
const { rows: threads } = await pool.query('DELETE FROM threads WHERE ticket_id = $1 RETURNING id', [req.params.id])
|
||||
await client.query('BEGIN')
|
||||
const { rows: threads } = await client.query('DELETE FROM threads WHERE ticket_id = $1 RETURNING id', [req.params.id])
|
||||
for (const th of threads) {
|
||||
await pool.query('DELETE FROM messages WHERE thread_id = $1', [th.id])
|
||||
await client.query('DELETE FROM messages WHERE thread_id = $1', [th.id])
|
||||
}
|
||||
const { rows } = await client.query('DELETE FROM tickets WHERE id = $1 RETURNING id', [req.params.id])
|
||||
if (!rows.length) {
|
||||
await client.query('ROLLBACK')
|
||||
return res.status(404).json({ fehler: 'Schadensmeldung nicht gefunden.' })
|
||||
}
|
||||
await client.query('COMMIT')
|
||||
res.json({ ok: true })
|
||||
} catch (e) { next(e) }
|
||||
} catch (e) {
|
||||
await client.query('ROLLBACK').catch(() => {})
|
||||
next(e)
|
||||
} finally {
|
||||
client.release()
|
||||
}
|
||||
})
|
||||
|
||||
// ── Zählerstände (Strom / Wasser / Gas) ─────────────────────
|
||||
@@ -1041,8 +1053,12 @@ async function belegAutoZuordnung(text) {
|
||||
return fund
|
||||
}
|
||||
}
|
||||
// Sekundär: Hausname/Adresse im Volltext
|
||||
const { rows: haeuser } = await pool.query('SELECT name, adresse FROM buildings')
|
||||
// Sekundär: Hausname/Adresse im Volltext. Eigenobjekte (z. B. die
|
||||
// Rechnungsempfänger-Adresse der Verwaltung) werden übersprungen – sonst
|
||||
// landet jeder Beleg, auf dem die Empfängeradresse steht, am falschen Haus.
|
||||
const { rows: haeuser } = await pool.query(
|
||||
'SELECT name, adresse FROM buildings WHERE eigenobjekt IS NOT TRUE',
|
||||
)
|
||||
for (const h of haeuser) {
|
||||
const name = normalisieren((h.name || '').trim())
|
||||
const adr = normalisieren((h.adresse || '').trim())
|
||||
@@ -1211,12 +1227,14 @@ app.post('/api/buildings', auth, adminOnly, async (req, res, next) => {
|
||||
const heizung = String(b.heizungsart || '').trim()
|
||||
const { rows } = await pool.query(
|
||||
`INSERT INTO buildings (name, adresse, strasse, hausnummer, plz, ort, lage,
|
||||
baujahr, stockwerke, etagenhoehe, wohneinheiten, wohnflaeche, grundstuecksflaeche, heizungsart)
|
||||
VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14) RETURNING *`,
|
||||
baujahr, stockwerke, etagenhoehe, wohneinheiten, wohnflaeche, grundstuecksflaeche, heizungsart,
|
||||
eigenobjekt)
|
||||
VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15) RETURNING *`,
|
||||
[name, hausAdresseAus(b), String(b.strasse).trim(), String(b.hausnummer).trim(),
|
||||
String(b.plz).trim(), String(b.ort).trim(), String(b.lage || '').trim(),
|
||||
Number(b.baujahr), Number(b.stockwerke), Number(b.etagenhoehe),
|
||||
Number(b.wohneinheiten), Number(b.wohnflaeche), grund, heizung],
|
||||
Number(b.wohneinheiten), Number(b.wohnflaeche), grund, heizung,
|
||||
Boolean(b.eigenobjekt)],
|
||||
)
|
||||
res.json({ building: mapBuilding(rows[0]) })
|
||||
} catch (e) { next(e) }
|
||||
@@ -1245,12 +1263,13 @@ app.patch('/api/buildings/:name', auth, adminOnly, async (req, res, next) => {
|
||||
await client.query(
|
||||
`UPDATE buildings SET name = $1, adresse = $2, strasse = $3, hausnummer = $4, plz = $5, ort = $6, lage = $7,
|
||||
baujahr = $8, stockwerke = $9, etagenhoehe = $10, wohneinheiten = $11,
|
||||
wohnflaeche = $12, grundstuecksflaeche = $13, heizungsart = $14
|
||||
WHERE name = $15`,
|
||||
wohnflaeche = $12, grundstuecksflaeche = $13, heizungsart = $14,
|
||||
eigenobjekt = $15
|
||||
WHERE name = $16`,
|
||||
[neuName, hausAdresseAus(b), String(b.strasse).trim(), String(b.hausnummer).trim(),
|
||||
String(b.plz).trim(), String(b.ort).trim(), String(b.lage || '').trim(),
|
||||
Number(b.baujahr), Number(b.stockwerke), Number(b.etagenhoehe), Number(b.wohneinheiten),
|
||||
Number(b.wohnflaeche), grund, heizung, req.params.name],
|
||||
Number(b.wohnflaeche), grund, heizung, Boolean(b.eigenobjekt), req.params.name],
|
||||
)
|
||||
// Haus umbenannt → Bezüge in Wohnungen und Zählern mitziehen
|
||||
if (neuName !== alt.name) {
|
||||
@@ -1362,6 +1381,11 @@ app.delete('/api/units/:id', auth, adminOnly, async (req, res, next) => {
|
||||
['documents', 'unit_id', 'Dokumente'],
|
||||
['costs', 'unit_id', 'Kostenpositionen'],
|
||||
['users', 'einheit_id', 'zugeordnete Benutzer'],
|
||||
['transactions', 'unit_id', 'Zahlungen'],
|
||||
['tickets', 'unit_id', 'Schadensmeldungen'],
|
||||
['threads', 'unit_id', 'Unterhaltungen'],
|
||||
['registration_codes', 'einheit_id', 'Registrierungscodes'],
|
||||
['belege', 'unit_id', 'Belege'],
|
||||
]) {
|
||||
const { rows: r } = await pool.query(`SELECT COUNT(*)::int AS n FROM ${tabelle} WHERE ${spalte} = $1`, [req.params.id])
|
||||
if (r[0].n > 0) blocker.push(`${r[0].n} ${label}`)
|
||||
|
||||
Reference in New Issue
Block a user