import type { AufgabenStand } from "./checklist"; import type { ChecklistArt } from "./checklist-print"; import type { Tx } from "./db"; import { jsonArrayFrom, jsonObjectFrom, zeitstempel } from "./db/json"; import { todayIso } from "./format"; import { besetzungenAbfrage, orgAsOf, pickPlacements } from "./placement"; // Was der Ausdruck einer Checkliste braucht — und nur das. // // Nicht loadEmployeeDetail: das holt offene Planstellen, Berichtslinien, den // Organisationsbaum und die Historie, wovon der Ausdruck nichts zeigt. Eine // eigene, schmale Abfrage in einer Rundreise (lib/db/json.ts). export type ChecklistKopf = { personnel_number: number; first_name: string; last_name: string; entry_date: string; /** Die Bezeichnung der Person; kann von der Planstelle abweichen. */ job_title: string; /** Aus der laufenden Besetzung — bei einer Person ohne Planstelle leer. */ position_number: string | null; position_title: string | null; }; export type ChecklistDruckDaten = { kopf: ChecklistKopf; staende: AufgabenStand[]; }; export async function loadChecklistPrint( tx: Tx, employeeId: string, art: ChecklistArt, today: string = todayIso() ): Promise { const tabelle = art === "offboarding" ? "offboarding_tasks" : "onboarding_tasks"; const gelesen = await tx .selectNoFrom((eb) => [ jsonObjectFrom( eb .selectFrom("employees") .select(["personnel_number", "first_name", "last_name", "entry_date", "exit_date", "job_title"]) .where("id", "=", employeeId) ).as("person"), jsonArrayFrom(besetzungenAbfrage(eb, [employeeId])).as("placementRows"), jsonArrayFrom( eb .selectFrom(tabelle) .select(["item_key", "erledigt", "wert", "kommentar", "updated_by_name"]) .select((x) => zeitstempel(x.ref("updated_at")).as("updated_at")) .where("employee_id", "=", employeeId) ).as("staende"), ]) .executeTakeFirstOrThrow(); const person = gelesen.person; if (!person) return null; // Derselbe Stichtag wie in der Akte: bei einer ausgetretenen Person ist die // Besetzung am Austrittstag beendet, und zu heute gefragt käme keine heraus // — der Kopf stünde dann ohne Planstelle da, obwohl es eine gab. const asOf = orgAsOf(person, today); const placement = pickPlacements(gelesen.placementRows as never, asOf).get(employeeId) ?? null; return { kopf: { personnel_number: person.personnel_number, first_name: person.first_name, last_name: person.last_name, entry_date: person.entry_date, job_title: person.job_title, position_number: placement?.positionNumber ?? null, position_title: placement?.jobTitle ?? null, }, staende: gelesen.staende as AufgabenStand[], }; }