Files
prov/routes/vos.js
T
kerimatilganandClaude Opus 4.7 041df61b24 Per-Anbieter default VO with auto-select in the schaltung wizard
- New nullable anbieter.default_vo_id column (migration adds it to
  existing DBs); deleting a VO that some provider points at clears
  the reference automatically.
- GET /api/anbieter now includes default_vo_id + default_vo_nummer
  + default_vo_bezeichnung so the wizard can preselect without an
  extra round-trip.
- New PUT /api/anbieter/:id/default-vo endpoint. Validates the VO
  belongs to the given provider; accepts vo_id=null to clear.
- VO admin table grew a "Standard" column and an "Als Standard" /
  "Standard entfernen" button on each row.
- When the user picks a provider in step 1 of the wizard, the VO
  dropdown now preselects the default VO (falling back to the only
  VO if there is exactly one), and immediately loads the
  matching tariffs.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 16:46:03 +02:00

95 lines
4.0 KiB
JavaScript

const express = require('express');
const db = require('../db');
const asyncHandler = require('../middleware/asyncHandler');
const router = express.Router();
// List all VOs (optionally filtered by anbieter via ?anbieter_id=)
router.get('/', asyncHandler(async (req, res) => {
const { anbieter_id } = req.query;
if (anbieter_id) {
const rows = await db.all(
`SELECT v.*, a.name AS anbieter_name
FROM vos v JOIN anbieter a ON v.anbieter_id = a.id
WHERE v.anbieter_id = ? AND v.aktiv = 1
ORDER BY v.nummer`,
[anbieter_id]
);
return res.json(rows);
}
const rows = await db.all(
`SELECT v.*, a.name AS anbieter_name
FROM vos v JOIN anbieter a ON v.anbieter_id = a.id
ORDER BY a.name, v.nummer`
);
res.json(rows);
}));
router.post('/', asyncHandler(async (req, res) => {
const { anbieter_id, nummer, bezeichnung } = req.body || {};
if (!anbieter_id) return res.status(400).json({ error: 'Anbieter ist erforderlich' });
if (!nummer || !String(nummer).trim()) return res.status(400).json({ error: 'VO-Nummer ist erforderlich' });
try {
const result = await db.run(
'INSERT INTO vos (anbieter_id, nummer, bezeichnung) VALUES (?, ?, ?)',
[anbieter_id, String(nummer).trim(), bezeichnung ? String(bezeichnung).trim() : null]
);
res.json({ id: result.lastID, anbieter_id, nummer: String(nummer).trim(), bezeichnung: bezeichnung || null });
} catch (err) {
if (/UNIQUE/.test(err.message)) {
return res.status(400).json({ error: 'VO mit dieser Nummer existiert bereits für diesen Anbieter' });
}
throw err;
}
}));
router.put('/:id', asyncHandler(async (req, res) => {
const { id } = req.params;
const { nummer, bezeichnung, aktiv } = req.body || {};
const current = await db.get('SELECT * FROM vos WHERE id = ?', [id]);
if (!current) return res.status(404).json({ error: 'VO nicht gefunden' });
const nextNummer = nummer !== undefined ? String(nummer).trim() : current.nummer;
if (!nextNummer) return res.status(400).json({ error: 'VO-Nummer darf nicht leer sein' });
try {
await db.run(
'UPDATE vos SET nummer = ?, bezeichnung = ?, aktiv = ? WHERE id = ?',
[
nextNummer,
bezeichnung !== undefined ? (bezeichnung ? String(bezeichnung).trim() : null) : current.bezeichnung,
aktiv !== undefined ? (aktiv ? 1 : 0) : current.aktiv,
id,
]
);
res.json({ message: 'VO erfolgreich aktualisiert' });
} catch (err) {
if (/UNIQUE/.test(err.message)) {
return res.status(400).json({ error: 'VO mit dieser Nummer existiert bereits für diesen Anbieter' });
}
throw err;
}
}));
router.delete('/:id', asyncHandler(async (req, res) => {
const { id } = req.params;
// Prevent deletion if any tariff or schaltung references it.
const used = await db.get(
`SELECT
(SELECT COUNT(*) FROM tarife WHERE vo_id = ?) AS n_tarife,
(SELECT COUNT(*) FROM schaltungen WHERE vo_id = ?) AS n_schaltungen`,
[id, id]
);
if (used.n_tarife + used.n_schaltungen > 0) {
const parts = [];
if (used.n_tarife > 0) parts.push(`${used.n_tarife} Tarif(e)`);
if (used.n_schaltungen > 0) parts.push(`${used.n_schaltungen} Schaltung(en)`);
return res.status(400).json({ error: `VO kann nicht gelöscht werden: ${parts.join(', ')} verwenden diese VO` });
}
// Clear any anbieter pointing at this VO as their default before removing it.
await db.run('UPDATE anbieter SET default_vo_id = NULL WHERE default_vo_id = ?', [id]);
const result = await db.run('DELETE FROM vos WHERE id = ?', [id]);
if (result.changes === 0) return res.status(404).json({ error: 'VO nicht gefunden' });
res.json({ message: 'VO erfolgreich gelöscht' });
}));
module.exports = router;