feat: complete notdienst planning, quick wins and notifications
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
import { Prisma } from "@prisma/client";
|
||||
import { UserFacingError } from "./action-error";
|
||||
import { getNotdienstDays } from "./notdienst-days";
|
||||
import { todayKey } from "./staff/calculations";
|
||||
|
||||
export async function loadNotdienstDays(
|
||||
db: Pick<Prisma.TransactionClient, "termin">,
|
||||
kitaId: string,
|
||||
year: number,
|
||||
month: number,
|
||||
) {
|
||||
const closures = await db.termin.findMany({
|
||||
where: {
|
||||
kitaId,
|
||||
status: "CONFIRMED",
|
||||
type: { in: ["SCHLIESSTAG", "TEAMTAG"] },
|
||||
// Include closures crossing the month boundary and Berlin midnight.
|
||||
startDate: { lt: new Date(Date.UTC(year, month, 1)) },
|
||||
endDate: { gte: new Date(Date.UTC(year, month - 1, 1) - 86400000) },
|
||||
},
|
||||
select: { startDate: true, endDate: true },
|
||||
});
|
||||
return getNotdienstDays(year, month, closures);
|
||||
}
|
||||
|
||||
export async function assertChildrenRemovable(
|
||||
tx: Prisma.TransactionClient,
|
||||
kitaId: string,
|
||||
familyId: string,
|
||||
childIds: string[],
|
||||
) {
|
||||
if (childIds.length === 0) return;
|
||||
// Coordinate with the FK locks taken by concurrent assignment writes.
|
||||
await tx.$queryRaw`SELECT id FROM children WHERE "kitaId" = ${kitaId}
|
||||
AND "familyId" = ${familyId} AND id IN (${Prisma.join(childIds)}) ORDER BY id FOR UPDATE`;
|
||||
const obligation = await tx.notdienstAssignment.findFirst({
|
||||
where: {
|
||||
kitaId,
|
||||
childId: { in: childIds },
|
||||
child: { kitaId, familyId },
|
||||
OR: [
|
||||
{
|
||||
date: { gte: new Date(`${todayKey()}T00:00:00Z`) },
|
||||
plan: { kitaId, status: "PUBLISHED" },
|
||||
},
|
||||
{ alarms: { some: { kitaId, activeAssignmentId: { not: null } } } },
|
||||
],
|
||||
},
|
||||
select: { id: true },
|
||||
});
|
||||
if (obligation) {
|
||||
throw new UserFacingError(
|
||||
"Das Kind kann nicht entfernt werden, solange veröffentlichte Notdienste oder aktive Alarme bestehen. Bitte zuerst die Einteilung mit der Koordination klären.",
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user