import { UUidWithPrefix } from "#components/Ausweis/types.js"; import { adminMiddleware } from "#lib/middleware/authorization.js"; import { mollieClient } from "#lib/mollie.js"; import { getPrismaAusweisAdapter } from "#lib/server/ausweis.js"; import { Prisma, prisma } from "#lib/server/prisma.js"; import { RefundStatus } from "@mollie/api-client"; import { APIError, defineApiRoute } from "astro-typesafe-api/server"; import { z } from "zod"; export const PUT = defineApiRoute({ input: z.object({ ausweis_id: UUidWithPrefix }), middleware: adminMiddleware, async fetch(input, context, transfer) { const adapter = getPrismaAusweisAdapter(input.ausweis_id) as Prisma.VerbrauchsausweisWohnenDelegate; if (!adapter) { throw new APIError({ code: "BAD_REQUEST", message: "Ungültige 'uid_ausweis'" }) } const ausweis = await adapter.findUnique({ where: { id: input.ausweis_id } }) if (!ausweis) { throw new APIError({ code: "NOT_FOUND", message: "Ausweis konnte nicht gefunden werden." }) } const response = await adapter.findUnique({ where: { id: input.ausweis_id }, select: { rechnung: true } }) if (!response || !response.rechnung) { await adapter.update({ where: { id: input.ausweis_id }, data: { storniert: true } }) throw new APIError({ code: "NOT_FOUND", message: "Rechnung konnte nicht gefunden werden aber Ausweis wurde storniert." }) } const rechnung = response.rechnung; await adapter.update({ where: { id: input.ausweis_id }, data: { storniert: true, rechnung: { update: { status: "canceled", storniert_am: new Date() } } }, select: { rechnung: { select: { betrag: true, bezahlmethode: true, status: true } } } }) if (rechnung.betrag > 0 && rechnung.bezahlmethode !== "rechnung" && rechnung.status === "paid" && rechnung.transaktions_referenz) { const refund = await mollieClient.paymentRefunds.create({ description: "Rückerstattung IBCornelsen", paymentId: rechnung.transaktions_referenz, amount: { currency: "EUR", value: rechnung.betrag.toFixed(2) }, metadata: { rechnung_id: rechnung.id }, testmode: true }) if (refund.status === RefundStatus.failed) { throw new APIError({ code: "INTERNAL_SERVER_ERROR", message: "Rückerstattung konnte nicht durchgeführt werden, Mollie hat die Rückerstattung abgelehnt." }) } } }, })