Benutzer, Ticketzuweißungen
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import { randomUUID } from 'crypto';
|
||||
import db from '../../db.js';
|
||||
import { requireCrmEdit } from '../../middleware/auth.js';
|
||||
import { badRequest, UUID } from '../../lib/http.js';
|
||||
import { mergeAttachmentEventsForApi } from '../../lib/ticket-events-merge.js';
|
||||
import {
|
||||
@@ -36,9 +37,15 @@ ORDER BY
|
||||
CASE WHEN t.status IN ('OPEN','WAITING') AND datetime('now') > ${ticketSlaDueExpr} THEN ${ticketSlaDueExpr} ELSE '9999-12-31' END ASC,
|
||||
${ticketLastActivityExpr} DESC`;
|
||||
|
||||
function userLabelFromRow(row) {
|
||||
if (!row) return '—';
|
||||
const fn = [row.firstname, row.lastname].filter(Boolean).join(' ').trim();
|
||||
return fn || row.username || row.id;
|
||||
}
|
||||
|
||||
export function registerTicketRoutes(api) {
|
||||
api.get('/tickets', (req, res) => {
|
||||
const { status, priority, machineId, open } = req.query;
|
||||
const { status, priority, machineId, open, assignedTo } = req.query;
|
||||
const cond = ['1=1'];
|
||||
const params = [];
|
||||
const openFilter = open === '1' || open === 'true';
|
||||
@@ -56,12 +63,21 @@ export function registerTicketRoutes(api) {
|
||||
cond.push('t.machine_id = ?');
|
||||
params.push(machineId);
|
||||
}
|
||||
if (assignedTo === 'me' && req.session?.userId) {
|
||||
cond.push('t.assigned_user_id = ?');
|
||||
params.push(req.session.userId);
|
||||
} else if (assignedTo === 'not_me' && req.session?.userId) {
|
||||
cond.push(
|
||||
'(t.assigned_user_id IS NULL OR t.assigned_user_id <> ?)',
|
||||
);
|
||||
params.push(req.session.userId);
|
||||
}
|
||||
const sql = `${ticketJoinSelect} WHERE ${cond.join(' AND ')} ${ticketListOrderBy}`;
|
||||
const rows = db.prepare(sql).all(...params);
|
||||
res.json(rows.map(mapTicket));
|
||||
});
|
||||
|
||||
api.post('/tickets', (req, res) => {
|
||||
api.post('/tickets', requireCrmEdit, (req, res) => {
|
||||
const { machineId, title, description, status, priority, slaDays } =
|
||||
req.body || {};
|
||||
if (!machineId || !title || !description) {
|
||||
@@ -125,7 +141,7 @@ export function registerTicketRoutes(api) {
|
||||
res.json(mapTicket(row));
|
||||
});
|
||||
|
||||
api.put('/tickets/:id', (req, res) => {
|
||||
api.put('/tickets/: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 tickets WHERE id = ?').get(id);
|
||||
@@ -173,6 +189,46 @@ export function registerTicketRoutes(api) {
|
||||
`Fälligkeit: ${label(cur.sla_days)} → ${label(nextSlaDays)}`,
|
||||
);
|
||||
}
|
||||
|
||||
let nextAssignedUserId = cur.assigned_user_id ?? null;
|
||||
if (Object.prototype.hasOwnProperty.call(b, 'assignedUserId')) {
|
||||
const raw = b.assignedUserId;
|
||||
if (raw === null || raw === undefined || raw === '') {
|
||||
nextAssignedUserId = null;
|
||||
} else if (!UUID.test(String(raw))) {
|
||||
return badRequest(res, 'assignedUserId ungültig.');
|
||||
} else {
|
||||
const u = db
|
||||
.prepare(
|
||||
'SELECT id, username, firstname, lastname FROM users WHERE id = ? AND active = 1',
|
||||
)
|
||||
.get(String(raw));
|
||||
if (!u) {
|
||||
return badRequest(res, 'Zugewiesener Benutzer nicht gefunden oder inaktiv.');
|
||||
}
|
||||
nextAssignedUserId = u.id;
|
||||
}
|
||||
}
|
||||
if (nextAssignedUserId !== (cur.assigned_user_id ?? null)) {
|
||||
const prevU = cur.assigned_user_id
|
||||
? db
|
||||
.prepare(
|
||||
'SELECT id, username, firstname, lastname FROM users WHERE id = ?',
|
||||
)
|
||||
.get(cur.assigned_user_id)
|
||||
: null;
|
||||
const nextU = nextAssignedUserId
|
||||
? db
|
||||
.prepare(
|
||||
'SELECT id, username, firstname, lastname FROM users WHERE id = ?',
|
||||
)
|
||||
.get(nextAssignedUserId)
|
||||
: null;
|
||||
const fromLabel = prevU ? userLabelFromRow(prevU) : 'nicht zugewiesen';
|
||||
const toLabel = nextU ? userLabelFromRow(nextU) : 'nicht zugewiesen';
|
||||
lines.push(`Zuweisung: ${fromLabel} → ${toLabel}`);
|
||||
}
|
||||
|
||||
if (lines.length > 0) {
|
||||
const eid = randomUUID();
|
||||
db.prepare(
|
||||
@@ -184,6 +240,7 @@ export function registerTicketRoutes(api) {
|
||||
db.prepare(
|
||||
`UPDATE tickets SET title = ?, description = ?, status = ?, priority = ?, sla_days = ?,
|
||||
sla_anchor_at = CASE WHEN ? THEN datetime('now') ELSE sla_anchor_at END,
|
||||
assigned_user_id = ?,
|
||||
updated_at = datetime('now')
|
||||
WHERE id = ?`,
|
||||
).run(
|
||||
@@ -193,6 +250,7 @@ export function registerTicketRoutes(api) {
|
||||
next.priority,
|
||||
nextSlaDays,
|
||||
resetSlaAnchor ? 1 : 0,
|
||||
nextAssignedUserId,
|
||||
id,
|
||||
);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user