613 lines
14 KiB
JavaScript
613 lines
14 KiB
JavaScript
const db = require("../db");
|
|
|
|
function showCreatePatient(req, res) {
|
|
res.render("patient_create");
|
|
}
|
|
|
|
function createPatient(req, res) {
|
|
const { firstname, lastname, birthdate } = req.body;
|
|
|
|
db.query(
|
|
"INSERT INTO patients (firstname, lastname, birthdate, active) VALUES (?, ?, ?, 1)",
|
|
[firstname, lastname, birthdate],
|
|
(err) => {
|
|
if (err) {
|
|
console.error(err);
|
|
return res.send("Datenbankfehler");
|
|
}
|
|
res.redirect("/dashboard");
|
|
}
|
|
);
|
|
}
|
|
|
|
function listPatients(req, res) {
|
|
const { firstname, lastname, birthdate } = req.query;
|
|
|
|
let sql = "SELECT * FROM patients WHERE 1=1";
|
|
const params = [];
|
|
|
|
if (firstname) {
|
|
sql += " AND firstname LIKE ?";
|
|
params.push(`%${firstname}%`);
|
|
}
|
|
if (lastname) {
|
|
sql += " AND lastname LIKE ?";
|
|
params.push(`%${lastname}%`);
|
|
}
|
|
if (birthdate) {
|
|
sql += " AND birthdate = ?";
|
|
params.push(birthdate);
|
|
}
|
|
|
|
sql += " ORDER BY lastname, firstname";
|
|
|
|
db.query(sql, params, (err, patients) => {
|
|
if (err) return res.send("Datenbankfehler");
|
|
res.render("patients", {
|
|
patients,
|
|
query: req.query,
|
|
user: req.session.user,
|
|
});
|
|
});
|
|
}
|
|
|
|
function showEditPatient(req, res) {
|
|
db.query(
|
|
"SELECT * FROM patients WHERE id = ?",
|
|
[req.params.id],
|
|
(err, results) => {
|
|
if (err || results.length === 0)
|
|
return res.send("Patient nicht gefunden");
|
|
res.render("patient_edit", {
|
|
patient: results[0],
|
|
error: null,
|
|
user: req.session.user,
|
|
returnTo: req.query.returnTo || null,
|
|
});
|
|
}
|
|
);
|
|
}
|
|
|
|
function updatePatient(req, res) {
|
|
const id = req.params.id;
|
|
const returnTo = req.body.returnTo;
|
|
|
|
const {
|
|
firstname,
|
|
lastname,
|
|
dni,
|
|
birthdate,
|
|
gender,
|
|
email,
|
|
phone,
|
|
street,
|
|
house_number,
|
|
postal_code,
|
|
city,
|
|
country,
|
|
notes,
|
|
} = req.body;
|
|
|
|
if (!firstname || !lastname || !birthdate) {
|
|
req.session.flash = {
|
|
type: "warning",
|
|
message: "Vorname, Nachname und Geburtsdatum sind Pflichtfelder",
|
|
};
|
|
return res.redirect("back");
|
|
}
|
|
|
|
db.query(
|
|
`UPDATE patients SET
|
|
firstname = ?,
|
|
lastname = ?,
|
|
dni = ?,
|
|
birthdate = ?,
|
|
gender = ?,
|
|
email = ?,
|
|
phone = ?,
|
|
street = ?,
|
|
house_number = ?,
|
|
postal_code = ?,
|
|
city = ?,
|
|
country = ?,
|
|
notes = ?
|
|
WHERE id = ?`,
|
|
[
|
|
firstname,
|
|
lastname,
|
|
dni || null,
|
|
birthdate,
|
|
gender || null,
|
|
email || null,
|
|
phone || null,
|
|
street || null,
|
|
house_number || null,
|
|
postal_code || null,
|
|
city || null,
|
|
country || null,
|
|
notes || null,
|
|
id,
|
|
],
|
|
(err) => {
|
|
if (err) {
|
|
console.error(err);
|
|
return res.send("Fehler beim Speichern");
|
|
}
|
|
|
|
if (returnTo === "overview") {
|
|
return res.redirect(`/patients/${id}/overview`);
|
|
}
|
|
|
|
res.redirect("/patients");
|
|
}
|
|
);
|
|
}
|
|
|
|
function showPatientMedications(req, res) {
|
|
const patientId = req.params.id;
|
|
const returnTo = req.query.returnTo || null;
|
|
|
|
const patientSql = "SELECT * FROM patients WHERE id = ?";
|
|
const medsSql = `
|
|
SELECT
|
|
v.id,
|
|
m.name AS medication,
|
|
f.name AS form,
|
|
v.dosage,
|
|
v.package
|
|
FROM medication_variants v
|
|
JOIN medications m ON v.medication_id = m.id
|
|
JOIN medication_forms f ON v.form_id = f.id
|
|
ORDER BY m.name, v.dosage
|
|
`;
|
|
|
|
const currentSql = `
|
|
SELECT
|
|
pm.id,
|
|
m.name AS medication,
|
|
f.name AS form,
|
|
v.dosage,
|
|
v.package,
|
|
pm.dosage_instruction,
|
|
pm.start_date,
|
|
pm.end_date
|
|
FROM patient_medications pm
|
|
JOIN medication_variants v ON pm.medication_variant_id = v.id
|
|
JOIN medications m ON v.medication_id = m.id
|
|
JOIN medication_forms f ON v.form_id = f.id
|
|
WHERE pm.patient_id = ?
|
|
ORDER BY pm.start_date DESC
|
|
`;
|
|
|
|
db.query(patientSql, [patientId], (err, patients) => {
|
|
if (err || patients.length === 0) {
|
|
return res.send("Patient nicht gefunden");
|
|
}
|
|
|
|
db.query(medsSql, (err, meds) => {
|
|
if (err) return res.send("Medikamente konnten nicht geladen werden");
|
|
|
|
db.query(currentSql, [patientId], (err, currentMeds) => {
|
|
if (err)
|
|
return res.send("Aktuelle Medikation konnte nicht geladen werden");
|
|
|
|
res.render("patient_medications", {
|
|
patient: patients[0],
|
|
meds,
|
|
currentMeds,
|
|
user: req.session.user,
|
|
returnTo,
|
|
});
|
|
});
|
|
});
|
|
});
|
|
}
|
|
|
|
function moveToWaitingRoom(req, res) {
|
|
const id = req.params.id;
|
|
|
|
db.query(
|
|
`
|
|
UPDATE patients
|
|
SET waiting_room = 1,
|
|
discharged = 0
|
|
WHERE id = ?
|
|
`,
|
|
[id],
|
|
(err) => {
|
|
if (err) return res.send("Fehler beim Verschieben ins Wartezimmer");
|
|
res.redirect("/patients");
|
|
}
|
|
);
|
|
}
|
|
|
|
function showWaitingRoom(req, res) {
|
|
db.query(
|
|
"SELECT * FROM patients WHERE waiting_room = 1 AND active = 1 ORDER BY lastname",
|
|
(err, patients) => {
|
|
if (err) return res.send("Datenbankfehler");
|
|
|
|
res.render("waiting_room", {
|
|
patients,
|
|
user: req.session.user,
|
|
});
|
|
}
|
|
);
|
|
}
|
|
|
|
function showPatientOverview(req, res) {
|
|
const patientId = req.params.id;
|
|
|
|
const patientSql = `
|
|
SELECT *
|
|
FROM patients
|
|
WHERE id = ?
|
|
`;
|
|
|
|
const notesSql = `
|
|
SELECT *
|
|
FROM patient_notes
|
|
WHERE patient_id = ?
|
|
ORDER BY created_at DESC
|
|
`;
|
|
|
|
const medicationVariantsSql = `
|
|
SELECT
|
|
mv.id AS variant_id,
|
|
m.name AS medication_name,
|
|
mf.name AS form_name,
|
|
mv.dosage,
|
|
mv.package
|
|
FROM medication_variants mv
|
|
JOIN medications m ON mv.medication_id = m.id
|
|
JOIN medication_forms mf ON mv.form_id = mf.id
|
|
ORDER BY m.name, mf.name, mv.dosage
|
|
`;
|
|
|
|
db.query(patientSql, [patientId], (err, patients) => {
|
|
if (err || patients.length === 0) {
|
|
return res.send("Patient nicht gefunden");
|
|
}
|
|
|
|
const patient = patients[0];
|
|
|
|
// 🇪🇸 / 🇩🇪 Sprache für Leistungen
|
|
const serviceNameField =
|
|
patient.country === "ES"
|
|
? "COALESCE(NULLIF(name_es, ''), name_de)"
|
|
: "name_de";
|
|
|
|
const servicesSql = `
|
|
SELECT
|
|
id,
|
|
${serviceNameField} AS name,
|
|
price
|
|
FROM services
|
|
WHERE active = 1
|
|
ORDER BY ${serviceNameField}
|
|
`;
|
|
|
|
const todayServicesSql = `
|
|
SELECT
|
|
ps.id,
|
|
ps.quantity,
|
|
COALESCE(ps.price_override, s.price) AS price,
|
|
${serviceNameField} AS name,
|
|
u.username AS doctor
|
|
FROM patient_services ps
|
|
JOIN services s ON ps.service_id = s.id
|
|
LEFT JOIN users u ON ps.created_by = u.id
|
|
WHERE ps.patient_id = ?
|
|
AND ps.service_date = CURDATE()
|
|
AND ps.invoice_id IS NULL
|
|
ORDER BY ps.created_at DESC
|
|
`;
|
|
|
|
db.query(notesSql, [patientId], (err, notes) => {
|
|
if (err) return res.send("Fehler Notizen");
|
|
|
|
db.query(servicesSql, (err, services) => {
|
|
if (err) return res.send("Fehler Leistungen");
|
|
|
|
db.query(todayServicesSql, [patientId], (err, todayServices) => {
|
|
if (err) return res.send("Fehler heutige Leistungen");
|
|
|
|
db.query(medicationVariantsSql, (err, medicationVariants) => {
|
|
if (err) return res.send("Fehler Medikamente");
|
|
|
|
res.render("patient_overview", {
|
|
patient,
|
|
notes,
|
|
services,
|
|
todayServices,
|
|
medicationVariants,
|
|
user: req.session.user,
|
|
});
|
|
});
|
|
});
|
|
});
|
|
});
|
|
});
|
|
}
|
|
|
|
function assignMedicationToPatient(req, res) {
|
|
const patientId = req.params.id;
|
|
const { medication_variant_id, dosage_instruction, start_date, end_date } =
|
|
req.body;
|
|
|
|
if (!medication_variant_id) {
|
|
req.session.flash = {
|
|
type: "warning",
|
|
message: "Bitte ein Medikament auswählen",
|
|
};
|
|
return res.redirect(`/patients/${patientId}/overview`);
|
|
}
|
|
|
|
db.query(
|
|
`
|
|
INSERT INTO patient_medications
|
|
(patient_id, medication_variant_id, dosage_instruction, start_date, end_date)
|
|
VALUES (?, ?, ?, ?, ?)
|
|
`,
|
|
[
|
|
patientId,
|
|
medication_variant_id,
|
|
dosage_instruction || null,
|
|
start_date || new Date(),
|
|
end_date || null,
|
|
],
|
|
(err) => {
|
|
if (err) {
|
|
console.error(err);
|
|
return res.send("Fehler beim Verordnen");
|
|
}
|
|
|
|
req.session.flash = {
|
|
type: "success",
|
|
message: "Medikament erfolgreich verordnet",
|
|
};
|
|
|
|
res.redirect(`/patients/${patientId}/overview`);
|
|
}
|
|
);
|
|
}
|
|
|
|
function addPatientNote(req, res) {
|
|
const patientId = req.params.id;
|
|
const { note } = req.body;
|
|
|
|
if (!note || note.trim() === "") {
|
|
return res.redirect(`/patients/${patientId}/overview`);
|
|
}
|
|
|
|
db.query(
|
|
"INSERT INTO patient_notes (patient_id, note) VALUES (?, ?)",
|
|
[patientId, note],
|
|
(err) => {
|
|
if (err) return res.send("Fehler beim Speichern der Notiz");
|
|
res.redirect(`/patients/${patientId}/overview`);
|
|
}
|
|
);
|
|
}
|
|
|
|
function callFromWaitingRoom(req, res) {
|
|
const patientId = req.params.id;
|
|
|
|
db.query(
|
|
"UPDATE patients SET waiting_room = 0 WHERE id = ?",
|
|
[patientId],
|
|
(err) => {
|
|
if (err) return res.send("Fehler beim Entfernen aus dem Wartezimmer");
|
|
res.redirect(`/patients/${patientId}/overview`);
|
|
}
|
|
);
|
|
}
|
|
|
|
function dischargePatient(req, res) {
|
|
const patientId = req.params.id;
|
|
|
|
db.query(
|
|
"UPDATE patients SET discharged = 1 WHERE id = ?",
|
|
[patientId],
|
|
(err) => {
|
|
if (err) return res.send("Fehler beim Entlassen des Patienten");
|
|
res.redirect("/waiting-room");
|
|
}
|
|
);
|
|
}
|
|
|
|
function showMedicationPlan(req, res) {
|
|
const patientId = req.params.id;
|
|
|
|
const patientSql = "SELECT * FROM patients WHERE id = ?";
|
|
const medsSql = `
|
|
SELECT
|
|
m.name AS medication,
|
|
f.name AS form,
|
|
v.dosage,
|
|
v.package,
|
|
pm.dosage_instruction,
|
|
pm.start_date,
|
|
pm.end_date
|
|
FROM patient_medications pm
|
|
JOIN medication_variants v ON pm.medication_variant_id = v.id
|
|
JOIN medications m ON v.medication_id = m.id
|
|
JOIN medication_forms f ON v.form_id = f.id
|
|
WHERE pm.patient_id = ?
|
|
AND (pm.end_date IS NULL OR pm.end_date >= CURDATE())
|
|
ORDER BY m.name
|
|
`;
|
|
|
|
db.query(patientSql, [patientId], (err, patients) => {
|
|
if (err || patients.length === 0) {
|
|
return res.send("Patient nicht gefunden");
|
|
}
|
|
|
|
db.query(medsSql, [patientId], (err, meds) => {
|
|
if (err) return res.send("Medikationsplan konnte nicht geladen werden");
|
|
|
|
res.render("patient_plan", {
|
|
patient: patients[0],
|
|
meds,
|
|
});
|
|
});
|
|
});
|
|
}
|
|
|
|
function movePatientToWaitingRoom(req, res) {
|
|
const patientId = req.params.id;
|
|
|
|
db.query(
|
|
`
|
|
UPDATE patients
|
|
SET waiting_room = 1,
|
|
discharged = 0
|
|
WHERE id = ?
|
|
`,
|
|
[patientId],
|
|
(err) => {
|
|
if (err) {
|
|
console.error(err);
|
|
req.session.flash = {
|
|
type: "danger",
|
|
message: "Fehler beim Zurücksetzen ins Wartezimmer",
|
|
};
|
|
return res.redirect(`/patients/${patientId}/overview`);
|
|
}
|
|
|
|
req.session.flash = {
|
|
type: "success",
|
|
message: "Patient wurde ins Wartezimmer gesetzt",
|
|
};
|
|
|
|
res.redirect("/waiting-room");
|
|
}
|
|
);
|
|
}
|
|
|
|
function deactivatePatient(req, res) {
|
|
const id = req.params.id;
|
|
|
|
db.query("UPDATE patients SET active = 0 WHERE id = ?", [id], (err) => {
|
|
if (err) {
|
|
console.error(err);
|
|
req.session.flash = {
|
|
type: "danger",
|
|
message: "Patient konnte nicht gesperrt werden",
|
|
};
|
|
return res.redirect("/patients");
|
|
}
|
|
|
|
req.session.flash = {
|
|
type: "success",
|
|
message: "Patient wurde gesperrt",
|
|
};
|
|
|
|
res.redirect("/patients");
|
|
});
|
|
}
|
|
|
|
function activatePatient(req, res) {
|
|
const id = req.params.id;
|
|
|
|
db.query("UPDATE patients SET active = 1 WHERE id = ?", [id], (err) => {
|
|
if (err) {
|
|
console.error(err);
|
|
req.session.flash = {
|
|
type: "danger",
|
|
message: "Patient konnte nicht entsperrt werden",
|
|
};
|
|
return res.redirect("/patients");
|
|
}
|
|
|
|
req.session.flash = {
|
|
type: "success",
|
|
message: "Patient wurde entsperrt",
|
|
};
|
|
|
|
res.redirect("/patients");
|
|
});
|
|
}
|
|
|
|
async function showPatientOverviewDashborad(req, res) {
|
|
const patientId = req.params.id;
|
|
|
|
try {
|
|
// 👤 Patient
|
|
const [[patient]] = await db
|
|
.promise()
|
|
.query("SELECT * FROM patients WHERE id = ?", [patientId]);
|
|
|
|
if (!patient) {
|
|
return res.redirect("/patients");
|
|
}
|
|
|
|
// 💊 AKTUELLE MEDIKAMENTE (end_date IS NULL)
|
|
const [medications] = await db.promise().query(
|
|
`
|
|
SELECT
|
|
m.name AS medication_name,
|
|
mv.dosage AS variant_dosage,
|
|
pm.dosage_instruction,
|
|
pm.start_date
|
|
FROM patient_medications pm
|
|
JOIN medication_variants mv
|
|
ON pm.medication_variant_id = mv.id
|
|
JOIN medications m
|
|
ON mv.medication_id = m.id
|
|
WHERE pm.patient_id = ?
|
|
AND pm.end_date IS NULL
|
|
ORDER BY pm.start_date DESC
|
|
`,
|
|
[patientId]
|
|
);
|
|
|
|
// 🧾 RECHNUNGEN
|
|
const [invoices] = await db.promise().query(
|
|
`
|
|
SELECT
|
|
id,
|
|
invoice_date,
|
|
total_amount,
|
|
file_path,
|
|
status
|
|
FROM invoices
|
|
WHERE patient_id = ?
|
|
ORDER BY invoice_date DESC
|
|
`,
|
|
[patientId]
|
|
);
|
|
|
|
res.render("patient_overview_dashboard", {
|
|
patient,
|
|
medications,
|
|
invoices,
|
|
user: req.session.user,
|
|
});
|
|
} catch (err) {
|
|
console.error(err);
|
|
res.send("Datenbankfehler");
|
|
}
|
|
}
|
|
|
|
module.exports = {
|
|
listPatients,
|
|
showCreatePatient,
|
|
createPatient,
|
|
showEditPatient,
|
|
updatePatient,
|
|
showPatientMedications,
|
|
moveToWaitingRoom,
|
|
showWaitingRoom,
|
|
showPatientOverview,
|
|
addPatientNote,
|
|
callFromWaitingRoom,
|
|
dischargePatient,
|
|
showMedicationPlan,
|
|
movePatientToWaitingRoom,
|
|
deactivatePatient,
|
|
activatePatient,
|
|
showPatientOverviewDashborad,
|
|
assignMedicationToPatient,
|
|
};
|