146 lines
5.0 KiB
JavaScript
146 lines
5.0 KiB
JavaScript
import { randomUUID } from 'crypto';
|
|
import db from '../../db.js';
|
|
import { badRequest, UUID } from '../../lib/http.js';
|
|
import { mapMachine } from '../../lib/mappers.js';
|
|
import { requireCrmEdit } from '../../middleware/auth.js';
|
|
|
|
const ALLOWED_LIST_STATUS = new Set([
|
|
'',
|
|
'PRUEFEN',
|
|
'VERSCHROTTET',
|
|
'SN_GEAENDERT',
|
|
'IN_BEARBEITUNG',
|
|
'UPDATE_RAUS',
|
|
]);
|
|
|
|
function normalizeListStatus(v) {
|
|
if (v == null || v === '') return '';
|
|
const s = String(v).trim();
|
|
return ALLOWED_LIST_STATUS.has(s) ? s : null;
|
|
}
|
|
|
|
/** @returns {{ ok: true, json: string | null } | { ok: false, message: string }} */
|
|
function parseExtrasField(extras) {
|
|
if (extras === null || extras === '') {
|
|
return { ok: true, json: null };
|
|
}
|
|
if (typeof extras === 'object' && extras !== null) {
|
|
try {
|
|
return { ok: true, json: JSON.stringify(extras) };
|
|
} catch {
|
|
return { ok: false, message: 'extras ist kein gültiges JSON-Objekt.' };
|
|
}
|
|
}
|
|
if (typeof extras === 'string') {
|
|
try {
|
|
JSON.parse(extras);
|
|
return { ok: true, json: extras };
|
|
} catch {
|
|
return { ok: false, message: 'extras ist kein gültiger JSON-String.' };
|
|
}
|
|
}
|
|
return { ok: false, message: 'extras hat ein ungültiges Format.' };
|
|
}
|
|
|
|
export function registerMachineRoutes(api) {
|
|
api.get('/machines', (_req, res) => {
|
|
const rows = db
|
|
.prepare('SELECT * FROM machines ORDER BY seriennummer ASC')
|
|
.all();
|
|
res.json(rows.map(mapMachine));
|
|
});
|
|
|
|
api.post('/machines', requireCrmEdit, (req, res) => {
|
|
const b = req.body || {};
|
|
const { name, typ, seriennummer, standort, listStatus } = b;
|
|
if (!name || !typ || !seriennummer || !standort) {
|
|
return badRequest(res, 'Pflichtfelder fehlen.');
|
|
}
|
|
const ls = normalizeListStatus(listStatus);
|
|
if (ls === null) return badRequest(res, 'Ungültiger Listen-Status.');
|
|
let extrasJson = null;
|
|
if (Object.prototype.hasOwnProperty.call(b, 'extras')) {
|
|
const p = parseExtrasField(b.extras);
|
|
if (!p.ok) return badRequest(res, p.message);
|
|
extrasJson = p.json;
|
|
}
|
|
const id = randomUUID();
|
|
const row = db
|
|
.prepare(
|
|
`INSERT INTO machines (id, name, typ, seriennummer, standort, list_status, extras, updated_at)
|
|
VALUES (?, ?, ?, ?, ?, ?, ?, datetime('now')) RETURNING *`,
|
|
)
|
|
.get(id, name, typ, seriennummer, standort, ls, extrasJson);
|
|
res.status(201).json(mapMachine(row));
|
|
});
|
|
|
|
api.get('/machines/:id', (req, res) => {
|
|
const { id } = req.params;
|
|
if (!UUID.test(id)) return res.status(404).json({ message: 'Nicht gefunden' });
|
|
const row = db.prepare('SELECT * FROM machines WHERE id = ?').get(id);
|
|
if (!row) return res.status(404).json({ message: 'Nicht gefunden' });
|
|
res.json(mapMachine(row));
|
|
});
|
|
|
|
api.put('/machines/:id', requireCrmEdit, (req, res) => {
|
|
const { id } = req.params;
|
|
if (!UUID.test(id)) return res.status(404).json({ message: 'Nicht gefunden' });
|
|
const cur = db.prepare('SELECT * FROM machines WHERE id = ?').get(id);
|
|
if (!cur) return res.status(404).json({ message: 'Nicht gefunden' });
|
|
const b = req.body || {};
|
|
const next = {
|
|
name: b.name ?? cur.name,
|
|
typ: b.typ ?? cur.typ,
|
|
seriennummer: b.seriennummer ?? cur.seriennummer,
|
|
standort: b.standort ?? cur.standort,
|
|
};
|
|
let listStatusVal = cur.list_status ?? '';
|
|
if (Object.prototype.hasOwnProperty.call(b, 'listStatus')) {
|
|
const ls = normalizeListStatus(b.listStatus);
|
|
if (ls === null) return badRequest(res, 'Ungültiger Listen-Status.');
|
|
listStatusVal = ls;
|
|
}
|
|
let extrasJson = cur.extras;
|
|
if (Object.prototype.hasOwnProperty.call(b, 'extras')) {
|
|
const p = parseExtrasField(b.extras);
|
|
if (!p.ok) return badRequest(res, p.message);
|
|
extrasJson = p.json;
|
|
}
|
|
const row = db
|
|
.prepare(
|
|
`UPDATE machines SET name = ?, typ = ?, seriennummer = ?, standort = ?, list_status = ?, extras = ?, updated_at = datetime('now')
|
|
WHERE id = ? RETURNING *`,
|
|
)
|
|
.get(
|
|
next.name,
|
|
next.typ,
|
|
next.seriennummer,
|
|
next.standort,
|
|
listStatusVal,
|
|
extrasJson,
|
|
id,
|
|
);
|
|
res.json(mapMachine(row));
|
|
});
|
|
|
|
api.delete('/machines/:id', requireCrmEdit, (req, res) => {
|
|
const { id } = req.params;
|
|
if (!UUID.test(id)) return res.status(404).json({ message: 'Nicht gefunden' });
|
|
const cur = db.prepare('SELECT * FROM machines WHERE id = ?').get(id);
|
|
if (!cur) return res.status(404).json({ message: 'Nicht gefunden' });
|
|
const tc = db
|
|
.prepare('SELECT COUNT(*) AS c FROM tickets WHERE machine_id = ?')
|
|
.get(id);
|
|
if (tc.c > 0) {
|
|
return res.status(409).json({
|
|
message:
|
|
'Maschine kann nicht gelöscht werden: Es existieren noch zugeordnete Tickets.',
|
|
});
|
|
}
|
|
const row = db
|
|
.prepare('DELETE FROM machines WHERE id = ? RETURNING *')
|
|
.get(id);
|
|
res.json(mapMachine(row));
|
|
});
|
|
}
|