343 lines
7.7 KiB
JavaScript
343 lines
7.7 KiB
JavaScript
const db = require("../db");
|
|
|
|
function listServices(req, res) {
|
|
const { q, onlyActive, patientId } = req.query;
|
|
|
|
// 🔹 Standard: Deutsch
|
|
let serviceNameField = "name_de";
|
|
|
|
const loadServices = () => {
|
|
let sql = `
|
|
SELECT id, ${serviceNameField} AS name, category, price, active
|
|
FROM services
|
|
WHERE 1=1
|
|
`;
|
|
const params = [];
|
|
|
|
if (q) {
|
|
sql += `
|
|
AND (
|
|
name_de LIKE ?
|
|
OR name_es LIKE ?
|
|
OR category LIKE ?
|
|
)
|
|
`;
|
|
params.push(`%${q}%`, `%${q}%`, `%${q}%`);
|
|
}
|
|
|
|
if (onlyActive === "1") {
|
|
sql += " AND active = 1";
|
|
}
|
|
|
|
sql += ` ORDER BY ${serviceNameField}`;
|
|
|
|
db.query(sql, params, (err, services) => {
|
|
if (err) return res.send("Datenbankfehler");
|
|
|
|
res.render("services", {
|
|
title: "Leistungen",
|
|
sidebarPartial: "partials/sidebar-empty",
|
|
active: "services",
|
|
|
|
services,
|
|
user: req.session.user,
|
|
lang: req.session.lang || "de",
|
|
query: { q, onlyActive, patientId },
|
|
});
|
|
});
|
|
};
|
|
|
|
// 🔹 Wenn Patient angegeben → Country prüfen
|
|
if (patientId) {
|
|
db.query(
|
|
"SELECT country FROM patients WHERE id = ?",
|
|
[patientId],
|
|
(err, rows) => {
|
|
if (!err && rows.length && rows[0].country === "ES") {
|
|
serviceNameField = "name_es";
|
|
}
|
|
loadServices();
|
|
},
|
|
);
|
|
} else {
|
|
// 🔹 Kein Patient → Deutsch
|
|
loadServices();
|
|
}
|
|
}
|
|
|
|
function listServicesAdmin(req, res) {
|
|
const { q, onlyActive } = req.query;
|
|
|
|
let sql = `
|
|
SELECT
|
|
id,
|
|
name_de,
|
|
name_es,
|
|
category,
|
|
price,
|
|
price_c70,
|
|
active
|
|
FROM services
|
|
WHERE 1=1
|
|
`;
|
|
const params = [];
|
|
|
|
if (q) {
|
|
sql += `
|
|
AND (
|
|
name_de LIKE ?
|
|
OR name_es LIKE ?
|
|
OR category LIKE ?
|
|
)
|
|
`;
|
|
params.push(`%${q}%`, `%${q}%`, `%${q}%`);
|
|
}
|
|
|
|
if (onlyActive === "1") {
|
|
sql += " AND active = 1";
|
|
}
|
|
|
|
sql += " ORDER BY name_de";
|
|
|
|
db.query(sql, params, (err, services) => {
|
|
if (err) return res.send("Datenbankfehler");
|
|
|
|
res.render("services", {
|
|
title: "Leistungen (Admin)",
|
|
sidebarPartial: "partials/admin-sidebar",
|
|
active: "services",
|
|
|
|
services,
|
|
user: req.session.user,
|
|
lang: req.session.lang || "de",
|
|
query: { q, onlyActive },
|
|
});
|
|
});
|
|
}
|
|
|
|
function showCreateService(req, res) {
|
|
res.render("service_create", {
|
|
title: "Leistung anlegen",
|
|
sidebarPartial: "partials/sidebar-empty",
|
|
active: "services",
|
|
|
|
user: req.session.user,
|
|
lang: req.session.lang || "de",
|
|
error: null,
|
|
});
|
|
}
|
|
|
|
function createService(req, res) {
|
|
const { name_de, name_es, category, price, price_c70 } = req.body;
|
|
const userId = req.session.user.id;
|
|
|
|
if (!name_de || !price) {
|
|
return res.render("service_create", {
|
|
title: "Leistung anlegen",
|
|
sidebarPartial: "partials/sidebar-empty",
|
|
active: "services",
|
|
|
|
user: req.session.user,
|
|
lang: req.session.lang || "de",
|
|
error: "Bezeichnung (DE) und Preis sind Pflichtfelder",
|
|
});
|
|
}
|
|
|
|
db.query(
|
|
`
|
|
INSERT INTO services
|
|
(name_de, name_es, category, price, price_c70, active)
|
|
VALUES (?, ?, ?, ?, ?, 1)
|
|
`,
|
|
[name_de, name_es || "--", category || "--", price, price_c70 || 0],
|
|
(err, result) => {
|
|
if (err) return res.send("Fehler beim Anlegen der Leistung");
|
|
|
|
db.query(
|
|
`
|
|
INSERT INTO service_logs
|
|
(service_id, user_id, action, new_value)
|
|
VALUES (?, ?, 'CREATE', ?)
|
|
`,
|
|
[result.insertId, userId, JSON.stringify(req.body)],
|
|
);
|
|
|
|
res.redirect("/services");
|
|
},
|
|
);
|
|
}
|
|
|
|
function updateServicePrice(req, res) {
|
|
const serviceId = req.params.id;
|
|
const { price, price_c70 } = req.body;
|
|
const userId = req.session.user.id;
|
|
|
|
db.query(
|
|
"SELECT price, price_c70 FROM services WHERE id = ?",
|
|
[serviceId],
|
|
(err, oldRows) => {
|
|
if (err || oldRows.length === 0)
|
|
return res.send("Service nicht gefunden");
|
|
|
|
const oldData = oldRows[0];
|
|
|
|
db.query(
|
|
"UPDATE services SET price = ?, price_c70 = ? WHERE id = ?",
|
|
[price, price_c70, serviceId],
|
|
(err) => {
|
|
if (err) return res.send("Update fehlgeschlagen");
|
|
|
|
db.query(
|
|
`
|
|
INSERT INTO service_logs
|
|
(service_id, user_id, action, old_value, new_value)
|
|
VALUES (?, ?, 'UPDATE_PRICE', ?, ?)
|
|
`,
|
|
[
|
|
serviceId,
|
|
userId,
|
|
JSON.stringify(oldData),
|
|
JSON.stringify({ price, price_c70 }),
|
|
],
|
|
);
|
|
|
|
res.redirect("/services");
|
|
},
|
|
);
|
|
},
|
|
);
|
|
}
|
|
|
|
function toggleService(req, res) {
|
|
const serviceId = req.params.id;
|
|
const userId = req.session.user.id;
|
|
|
|
db.query(
|
|
"SELECT active FROM services WHERE id = ?",
|
|
[serviceId],
|
|
(err, rows) => {
|
|
if (err || rows.length === 0) return res.send("Service nicht gefunden");
|
|
|
|
const oldActive = rows[0].active;
|
|
const newActive = oldActive ? 0 : 1;
|
|
|
|
db.query(
|
|
"UPDATE services SET active = ? WHERE id = ?",
|
|
[newActive, serviceId],
|
|
(err) => {
|
|
if (err) return res.send("Update fehlgeschlagen");
|
|
|
|
db.query(
|
|
`
|
|
INSERT INTO service_logs
|
|
(service_id, user_id, action, old_value, new_value)
|
|
VALUES (?, ?, 'TOGGLE_ACTIVE', ?, ?)
|
|
`,
|
|
[serviceId, userId, oldActive, newActive],
|
|
);
|
|
|
|
res.redirect("/services");
|
|
},
|
|
);
|
|
},
|
|
);
|
|
}
|
|
|
|
async function listOpenServices(req, res, next) {
|
|
res.set("Cache-Control", "no-store, no-cache, must-revalidate, private");
|
|
res.set("Pragma", "no-cache");
|
|
res.set("Expires", "0");
|
|
|
|
const sql = `
|
|
SELECT
|
|
p.id AS patient_id,
|
|
p.firstname,
|
|
p.lastname,
|
|
p.country,
|
|
ps.id AS patient_service_id,
|
|
ps.quantity,
|
|
COALESCE(ps.price_override, s.price) AS price,
|
|
CASE
|
|
WHEN UPPER(TRIM(p.country)) = 'ES'
|
|
THEN COALESCE(NULLIF(s.name_es, ''), s.name_de)
|
|
ELSE s.name_de
|
|
END AS name
|
|
FROM patient_services ps
|
|
JOIN patients p ON ps.patient_id = p.id
|
|
JOIN services s ON ps.service_id = s.id
|
|
WHERE ps.invoice_id IS NULL
|
|
ORDER BY p.lastname, p.firstname, name
|
|
`;
|
|
|
|
let connection;
|
|
|
|
try {
|
|
connection = await db.promise().getConnection();
|
|
|
|
await connection.query(
|
|
"SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED",
|
|
);
|
|
|
|
const [[cid]] = await connection.query("SELECT CONNECTION_ID() AS cid");
|
|
console.log("🔌 OPEN SERVICES CID:", cid.cid);
|
|
|
|
const [rows] = await connection.query(sql);
|
|
|
|
console.log("🧾 OPEN SERVICES ROWS:", rows.length);
|
|
|
|
res.render("open_services", {
|
|
title: "Offene Leistungen",
|
|
sidebarPartial: "partials/sidebar-empty",
|
|
active: "services",
|
|
|
|
rows,
|
|
user: req.session.user,
|
|
lang: req.session.lang || "de",
|
|
});
|
|
} catch (err) {
|
|
next(err);
|
|
} finally {
|
|
if (connection) connection.release();
|
|
}
|
|
}
|
|
|
|
function showServiceLogs(req, res) {
|
|
db.query(
|
|
`
|
|
SELECT
|
|
l.created_at,
|
|
u.username,
|
|
l.action,
|
|
l.old_value,
|
|
l.new_value
|
|
FROM service_logs l
|
|
JOIN users u ON l.user_id = u.id
|
|
ORDER BY l.created_at DESC
|
|
`,
|
|
(err, logs) => {
|
|
if (err) return res.send("Datenbankfehler");
|
|
|
|
res.render("admin_service_logs", {
|
|
title: "Service Logs",
|
|
sidebarPartial: "partials/admin-sidebar",
|
|
active: "services",
|
|
|
|
logs,
|
|
user: req.session.user,
|
|
lang: req.session.lang || "de",
|
|
});
|
|
},
|
|
);
|
|
}
|
|
|
|
module.exports = {
|
|
listServices,
|
|
showCreateService,
|
|
createService,
|
|
updateServicePrice,
|
|
toggleService,
|
|
listOpenServices,
|
|
showServiceLogs,
|
|
listServicesAdmin,
|
|
};
|