import { UUidWithPrefix, getAusweisartFromUUID } from "#components/Ausweis/types.js" import { Enums } from "#lib/client/prisma.js" import { authorizationHeaders, authorizationMiddleware } from "#lib/middleware/authorization.js" import { mollieClient } from "#lib/mollie.js" import { prisma } from "#lib/server/prisma.js" import { PaymentMethod } from "@mollie/api-client" import { defineApiRoute, APIError } from "astro-typesafe-api/server" import { RechnungSchema } from "src/generated/zod/rechnung.js" import { z } from "zod" export const PATCH = defineApiRoute({ input: RechnungSchema.pick({ bezahlmethode: true, ort: true, plz: true, strasse: true, telefon: true, empfaenger: true, versand_empfaenger: true, versand_ort: true, versand_plz: true, versand_strasse: true, versand_zusatzzeile: true, abweichende_versand_adresse: true }), output: z.object({ checkout_url: z.string().optional(), id: UUidWithPrefix, }), middleware: authorizationMiddleware, headers: authorizationHeaders, async fetch(input, context, user) { // Wir holen uns die Rechnung const rechnung = await prisma.rechnung.findUnique({ where: { id: context.params.id, benutzer: { id: user.id } }, include: { bedarfsausweis_gewerbe: true, bedarfsausweis_wohnen: true, geg_nachweis_gewerbe: true, geg_nachweis_wohnen: true, verbrauchsausweis_gewerbe: true, verbrauchsausweis_wohnen: true } }) if (!rechnung) { throw new APIError({ code: "NOT_FOUND", message: "Rechnung konnte nicht gefunden werden oder gehört einem anderen Benutzer." }) } await prisma.rechnung.update({ where: { id: rechnung.id }, data: { bezahlmethode: input.bezahlmethode, ort: input.ort, plz: input.plz, strasse: input.strasse, telefon: input.telefon, empfaenger: input.empfaenger, versand_empfaenger: input.versand_empfaenger, versand_ort: input.versand_ort, versand_plz: input.versand_plz, versand_strasse: input.versand_strasse, versand_zusatzzeile: input.versand_zusatzzeile, abweichende_versand_adresse: input.abweichende_versand_adresse, } }) if (input.bezahlmethode === Enums.Bezahlmethoden.rechnung) { return { id: rechnung.id } } const ausweis = rechnung.verbrauchsausweis_gewerbe || rechnung.verbrauchsausweis_wohnen || rechnung.bedarfsausweis_gewerbe || rechnung.bedarfsausweis_wohnen || rechnung.geg_nachweis_gewerbe || rechnung.geg_nachweis_wohnen; if (!ausweis) { throw new APIError({ code: "NOT_FOUND", message: "Rechnung hat keinen verknüpften Ausweis" }) } const ausweisart = getAusweisartFromUUID(ausweis.id) if (!ausweisart) { throw new APIError({ code: "INTERNAL_SERVER_ERROR", message: "Ausweis ist ungültig." }) } const description = getPaymentDescription(ausweisart); // Wir erstellen eine Mollie Payment Referenz. const payment = await mollieClient.payments.create({ amount: { value: rechnung.betrag.toFixed(2), currency: "EUR", }, metadata: { rechnung_id: rechnung.id, }, method: input.bezahlmethode as PaymentMethod, description, redirectUrl: `https://ibcornelsen.de/payment/success?a=${ausweis.id}&r=${rechnung.id}`, webhookUrl: `http://ibcornelsen.de/api/webhooks/mollie?uid=${rechnung.id}`, }); const checkoutUrl = payment.getCheckoutUrl(); if (!checkoutUrl) { throw new APIError({ code: "INTERNAL_SERVER_ERROR", message: "Checkout URL konnte nicht erstellt werden.", }); } return { id: rechnung.id, checkout_url: checkoutUrl, }; }, }) function getPaymentDescription(ausweisart: Enums.Ausweisart) { switch(ausweisart) { case "BedarfsausweisWohnen": return "Bedarfsausweis Wohngebäude" case "BedarfsausweisGewerbe": return "Bedarfsausweis Gewerbegebäude" case "VerbrauchsausweisGewerbe": return "Verbrauchsausweis Gewerbegebäude" case "VerbrauchsausweisWohnen": return "Verbrauchsausweis Wohngebäude" case "BedarfsausweisGewerbe": case "GEGNachweisGewerbe": case "GEGNachweisWohnen": return "GEG Nachweis" default: return "" } }