Files
boka-gasol247/src/app/[locale]/admin/bookings/[id]/actions.ts
2026-05-22 10:50:48 +02:00

93 lines
2.8 KiB
TypeScript

'use server';
import { revalidatePath } from 'next/cache';
import { prisma } from '@/lib/prisma';
import { requireAdmin } from '@/lib/requireAdmin';
import {
clampFulfillment,
deriveBookingStatus,
} from '@/lib/bookingStatus';
async function recomputeBookingStatus(bookingId: string) {
const booking = await prisma.booking.findUnique({
where: { id: bookingId },
include: { items: true },
});
if (!booking) return;
const next = deriveBookingStatus(booking.status, booking.items);
if (next !== booking.status) {
await prisma.booking.update({
where: { id: bookingId },
data: { status: next },
});
}
}
export async function setItemFulfillment(formData: FormData) {
await requireAdmin();
const bookingId = String(formData.get('bookingId') ?? '');
const itemId = String(formData.get('itemId') ?? '');
const deliveredRaw = Number(formData.get('delivered') ?? 0);
const returnedRaw = Number(formData.get('returned') ?? 0);
if (!bookingId || !itemId) return;
const item = await prisma.bookingItem.findUnique({ where: { id: itemId } });
if (!item || item.bookingId !== bookingId) return;
const { delivered, returned } = clampFulfillment(
item.quantity,
deliveredRaw,
returnedRaw,
);
await prisma.bookingItem.update({
where: { id: itemId },
data: { deliveredQuantity: delivered, returnedQuantity: returned },
});
await recomputeBookingStatus(bookingId);
revalidatePath(`/admin/bookings/${bookingId}`);
revalidatePath('/admin');
}
export async function markAllDelivered(formData: FormData) {
await requireAdmin();
const bookingId = String(formData.get('bookingId') ?? '');
if (!bookingId) return;
const items = await prisma.bookingItem.findMany({ where: { bookingId } });
await prisma.$transaction(
items.map((it) =>
prisma.bookingItem.update({
where: { id: it.id },
data: { deliveredQuantity: it.quantity },
}),
),
);
await recomputeBookingStatus(bookingId);
revalidatePath(`/admin/bookings/${bookingId}`);
revalidatePath('/admin');
}
export async function markAllReturned(formData: FormData) {
await requireAdmin();
const bookingId = String(formData.get('bookingId') ?? '');
if (!bookingId) return;
const items = await prisma.bookingItem.findMany({ where: { bookingId } });
// "Return all" means: everything that was handed out comes back. If nothing
// was marked delivered we treat it as a full handout + return cycle.
await prisma.$transaction(
items.map((it) => {
const delivered = it.deliveredQuantity > 0 ? it.deliveredQuantity : it.quantity;
return prisma.bookingItem.update({
where: { id: it.id },
data: { deliveredQuantity: delivered, returnedQuantity: delivered },
});
}),
);
await recomputeBookingStatus(bookingId);
revalidatePath(`/admin/bookings/${bookingId}`);
revalidatePath('/admin');
}