/* =====================================================================
aether-police / Ansicht: Asservatenkammer
Jedes Objekt trägt eine lückenlose Verwahrkette: wer hat es
eingelagert, ausgegeben, zurückgenommen oder vernichtet.
===================================================================== */
"use strict";
(() => {
const { sicher, zeit, aufruf, meldung, fenster, bestaetigen, $ } = App;
const z = {
daten: null,
offen: null,
filterKategorie: "",
filterStatus: "",
suche: "",
};
const katSymbol = {
waffe: "🔫", drogen: "💊", bargeld: "💵", schmuck: "💍",
datentraeger: "💾", dokument: "📄", sonstiges: "📦",
};
const statusArt = {
eingelagert: "gut", ausgegeben: "warn",
vernichtet: "kritisch", zurueckgegeben: "neutral",
};
const statusText = {
eingelagert: "Eingelagert", ausgegeben: "Ausgegeben",
vernichtet: "Vernichtet", zurueckgegeben: "Zurückgegeben",
};
function katName(id) {
const treffer = (z.daten.kategorien || []).find((k) => k.id === id);
return treffer ? treffer.name : id;
}
/* ---- Übersicht ---------------------------------------------------- */
function uebersicht(behaelter) {
const d = z.daten;
behaelter.innerHTML = `
Asservatenkammer
Jeder Schritt wird mit Namen festgehalten — die Verwahrkette bleibt lückenlos.
${d.rechte.einlagern ? `
` : ""}
Eingelagert
${d.bestand.eingelagert || 0}
Ausgegeben
${d.bestand.ausgegeben || 0}
Zurückgegeben
${d.bestand.zurueckgegeben || 0}
Vernichtet
${d.bestand.vernichtet || 0}
${d.asservate.length ? `
${d.asservate.map((a) => `
${katSymbol[a.kategorie] || "📦"}
${sicher(a.bezeichnung)}
${a.menge ? `${sicher(a.menge)}` : ""}
${sicher(a.kennung)} · ${sicher(katName(a.kategorie))} · ${sicher(a.lagerort)}
${a.aktenzeichen ? " · " + sicher(a.aktenzeichen) : ""}
verantwortlich: ${sicher(a.dienstnummer || "")}
${sicher((a.firstname || "") + " " + (a.lastname || ""))} · ${zeit(a.eingelagert_am)}
${sicher(statusText[a.status] || a.status)}
`).join("")}
`
: `
Keine Asservate gefunden.
`}
`;
const neu = $("as-neu");
if (neu) neu.addEventListener("click", () => einlagernDialog(behaelter));
const suchfeld = $("as-suche");
suchfeld.addEventListener("keydown", (e) => {
if (e.key === "Enter") { z.suche = suchfeld.value.trim(); rendern(behaelter); }
});
$("as-kategorie").addEventListener("change", (e) => {
z.filterKategorie = e.target.value; rendern(behaelter);
});
$("as-status").addEventListener("change", (e) => {
z.filterStatus = e.target.value; rendern(behaelter);
});
behaelter.querySelectorAll("[data-asservat]").forEach((el) =>
el.addEventListener("click", () => oeffne(behaelter, +el.dataset.asservat)));
}
/* ---- Einzelansicht ------------------------------------------------ */
function einzelAnsicht(behaelter, d) {
const a = d.asservat;
behaelter.innerHTML = `
${katSymbol[a.kategorie] || "📦"} ${sicher(a.bezeichnung)}
${sicher(a.kennung)} · ${sicher(katName(a.kategorie))}
${a.status === "eingelagert" && d.rechte.ausgeben
? `` : ""}
${a.status === "ausgegeben" && d.rechte.ausgeben
? `` : ""}
${a.status === "eingelagert"
? `` : ""}
${a.status !== "vernichtet" && d.rechte.vernichten
? `` : ""}
Objekt
${sicher(statusText[a.status] || a.status)}
Kennung${sicher(a.kennung)}
Kategorie${sicher(katName(a.kategorie))}
Menge${sicher(a.menge || "—")}
Lagerort${sicher(a.lagerort)}
Verantwortlich${sicher(a.dienstnummer || "")}
${sicher((a.firstname || "") + " " + (a.lastname || ""))}
Eingelagert${zeit(a.eingelagert_am)}
Zuordnung
${a.aktenzeichen ? `
Akte
${sicher(a.akte_titel || "")}
${sicher(a.aktenzeichen)}
` : ""}
${a.beweis_kennung ? `
Beweis
${sicher(a.beweis_bezeichnung || "")}
${sicher(a.beweis_kennung)}
` : ""}
${!a.aktenzeichen && !a.beweis_kennung
? `
Keine Zuordnung hinterlegt.
` : ""}
Verwahrkette
${d.historie.length} Schritte
${d.historie.map((h, i) => `
${i + 1}
${sicher(h.aktion)}
${sicher(h.dienstnummer || "")}
${sicher((h.firstname || "") + " " + (h.lastname || ""))} · ${zeit(h.am)}
${h.notiz ? `
${sicher(h.notiz)}
` : ""}
`).join("")}
`;
$("as-zurueck").addEventListener("click", () => { z.offen = null; rendern(behaelter); });
const ausgeben = $("as-ausgeben");
if (ausgeben) ausgeben.addEventListener("click", () => {
bestaetigen({
titel: "Asservat ausgeben",
inhalt: `
${sicher(a.kennung)} — ${sicher(a.bezeichnung)}
`,
bestaetigenText: "Ausgeben",
bestaetigt: async (el, zu) => {
try {
await aufruf("asservat", "ausgeben", {
id: a.id,
empfaenger: el.querySelector("#aa-empf").value.trim(),
grund: el.querySelector("#aa-grund").value.trim(),
});
zu(); meldung("Ausgegeben.", "gut"); oeffne(behaelter, a.id);
} catch (f) { meldung(f.message, "fehler"); }
},
});
});
const zurueckgeben = $("as-zurueckgeben");
if (zurueckgeben) zurueckgeben.addEventListener("click", () => {
fenster({
titel: "Zurücknehmen",
inhalt: `
`,
knoepfe: [
{ text: "Abbrechen", klick: (_, zu) => zu() },
{ text: "Zurücknehmen", klick: async (el, zu) => {
try {
await aufruf("asservat", "zurueckgeben", {
id: a.id,
lagerort: el.querySelector("#az-ort").value.trim(),
notiz: el.querySelector("#az-notiz").value.trim(),
});
zu(); meldung("Zurückgenommen.", "gut"); oeffne(behaelter, a.id);
} catch (f) { meldung(f.message, "fehler"); }
}},
],
});
});
const umlagern = $("as-umlagern");
if (umlagern) umlagern.addEventListener("click", () => {
fenster({
titel: "Umlagern",
inhalt: `
`,
knoepfe: [
{ text: "Abbrechen", klick: (_, zu) => zu() },
{ text: "Umlagern", klick: async (el, zu) => {
try {
await aufruf("asservat", "umlagern", {
id: a.id, lagerort: el.querySelector("#au-ort").value.trim(),
});
zu(); meldung("Umgelagert.", "gut"); oeffne(behaelter, a.id);
} catch (f) { meldung(f.message, "fehler"); }
}},
],
});
});
const vernichten = $("as-vernichten");
if (vernichten) vernichten.addEventListener("click", () => {
bestaetigen({
titel: "Asservat vernichten",
gefahr: true,
inhalt: `
Endgültige Maßnahme
🔥
${sicher(a.kennung)} — ${sicher(a.bezeichnung)} wird als vernichtet
gekennzeichnet.
📄
Der Datensatz bleibt bestehen — vernichtet wird der Gegenstand,
nicht seine Dokumentation. Alle Beamten werden benachrichtigt.
`,
bestaetigenText: "Vernichtung bestätigen",
bestaetigt: async (el, zu) => {
try {
await aufruf("asservat", "vernichten", {
id: a.id,
zeuge: el.querySelector("#av-zeuge").value.trim(),
grund: el.querySelector("#av-grund").value.trim(),
});
zu(); meldung("Vernichtung dokumentiert."); oeffne(behaelter, a.id);
} catch (f) { meldung(f.message, "fehler"); }
},
});
});
}
/* ---- Einlagern ---------------------------------------------------- */
function einlagernDialog(behaelter) {
fenster({
titel: "Asservat einlagern",
inhalt: `
ℹ
Du wirst als verantwortlich eingetragen. Jede weitere Bewegung
des Objekts wird in der Verwahrkette festgehalten.
`,
knoepfe: [
{ text: "Abbrechen", klick: (_, zu) => zu() },
{ text: "Einlagern", klick: async (el, zu) => {
try {
const ergebnis = await aufruf("asservat", "einlagern", {
kategorie: el.querySelector("#an-kat").value,
bezeichnung: el.querySelector("#an-bez").value.trim(),
menge: el.querySelector("#an-menge").value.trim(),
lagerort: el.querySelector("#an-ort").value.trim(),
akte: +el.querySelector("#an-akte").value || null,
beweis: +el.querySelector("#an-beweis").value || null,
notiz: el.querySelector("#an-notiz").value.trim(),
});
zu(); meldung("Eingelagert als " + ergebnis.kennung + ".", "gut");
oeffne(behaelter, ergebnis.id);
} catch (f) { meldung(f.message, "fehler"); }
}},
],
});
}
/* ---- Laden -------------------------------------------------------- */
async function oeffne(behaelter, asservatId) {
try {
const d = await aufruf("asservat", "oeffnen", { id: asservatId });
z.offen = asservatId;
// Kategorien für die Benennung mitführen
if (!z.daten) z.daten = { kategorien: [] };
einzelAnsicht(behaelter, d);
} catch (f) { meldung(f.message, "fehler"); }
}
async function rendern(behaelter) {
try {
z.daten = await aufruf("asservat", "liste", {
kategorie: z.filterKategorie, status: z.filterStatus, begriff: z.suche,
});
if (z.offen) await oeffne(behaelter, z.offen);
else uebersicht(behaelter);
} catch (f) {
behaelter.innerHTML = `Asservate
Konnte nicht geladen werden: ${sicher(f.message)}
`;
}
}
App.registriereAnsicht("asservat", { rendern });
App.registriereSuche(async (begriff) => {
try {
const d = await aufruf("asservat", "liste", { begriff });
return (d.asservate || []).slice(0, 5).map((a) => ({
bereich: "Asservat", titel: a.bezeichnung,
unter: a.kennung + " · " + a.lagerort,
}));
} catch (e) { return []; }
});
})();